I'm making by a requirement a code able to send an E-mail to an specific list of E-mails, due the fact that I must to include the attachments of the record I decided to use an apex class instead an e-mail alert. This object (A custom object ) must populate some fields in an email template with some of the record´s fields. I implemented the following code

Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
for (ContentVersion document: documents) 
   Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

I understood that to make the fields merge it´s necesary to use the WhatId method. In the related code, I have commented it because It generates an error (INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.)

My question is, if is it possible to do this with a custom object. I´m a little confuse with salesforce documentation beacuse it looks like the method supports a custom object, or maybe If I am forggeting something to include in the code.

enter image description here

If i keep the WhatID line commented, effectively the email is sent with the attachments and the Template but it is not populated.

I really need this kind of solution because the org have in this object at least 20 email templates, for me will be easier just to pass the Id of the template instead of makig a code with 20 different html codes for each situation

Thanks a lot

  • Can you clarify this statement -- the email is sent with the attachments and the Template but it is not populated. -- what is not populated? whatId is optional, so if you don't really need it, you can ignore setting that.
    – Jayant Das
    Nov 14, 2018 at 21:57

1 Answer 1


As the documentation says from your screenshot of the documentation, you can't use whatId for anything other than Contacts. The solution to this would probably be to use the renderStoredEmailTemplate method in the Messaging class. In other words, instead of using the template ID directly, you render the message, then set the body in the message.

Messaging.SingleEmail message = Messaging.renderStoredEmailTemplate(
  templateId, whoId, whatId, Messaging.AttachmentRetrievalOption.METADATA_WITH_BODY, true);

Keep in mind if you are doing this in a trigger, this method will use SOQL calls, so you might need to use asynchronous code to finish rendering the templates.

This is essentially the same code as what you wrote manually, but you get the text already rendered, and then you can change the target and save as activity fields before sending.

  • It totaly works! Thanks for your advice. I implemented the method you mentioned but just passsing the first three parameters. And effectly it merge the fields in the template with the record's information, also keeping the attachments. Nov 15, 2018 at 17:57
  • @CamiloAndresGamarra Always glad to help!
    – sfdcfox
    Nov 15, 2018 at 17:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .