I'm working on a fluent email builder, but I've hit a bit of a snag. Namely, there does not seem to be any simple way to completely clone a
Messaging.SingleEmailMessage instance without sharing a reference.
Why would I want to do such a thing? Well, it seems pretty common to have a collection of emails with common properties such as subject, recipients, template, etc.
The simplest attempt code-wise would be to serialize and de-serialize to break the reference:
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); Messaging.SingleEmailMessage clone = (Messaging.SingleEmailMessage) JSON.deserialize(JSON.serialize(email), Messaging.SingleEmailMessage.class);
However, this code throws a run-time error:
System.JSONException: Unrecognized field "debug" at [line:1, column:83]
Apparently it is not even possible to re-serialize back to the same type here!
Fine, I thought, I'll just use all of the getters and manually copy over each property:
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); // set various properties Messaging.SingleEmailMessage clone = new Messaging.SingleEmailMessage(); clone.setBccAddresses(message.getBccAddresses); // and so on
However, a couple Boolean flags on this object lack getters:
Method does not exist or incorrect signature: [Messaging.SingleEmailMessage].getTreatBodiesAsTemplate()
Method does not exist or incorrect signature: [Messaging.SingleEmailMessage].getTreatTargetObjectAsRecipient()
Is there any simple or elegant way to clone a
Messaging.SingleEmailMessage instance? I'm pursuing other design routes (like making the builder
virtual) but it's frustrating to not be able to clone such a basic system object. The only way I can think to do it would be to pull out the properties from an untyped map, which is not a satisfying long term solution:
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); Map<String, Object> data = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(email)); Boolean treatBodiesAsTemplate = data.get('treatBodiesAsTemplate'); Boolean treatTargetObjectAsRecipient = data.get('treatTargetObjectAsRecipient');