I have a VF email template as below which has relatedTOType as Job_Application__c and recipientType as User. I am using some merge field in this template:

<messaging:emailTemplate subject="TEST" recipientType="User" relatedToType="Job_Application__c">
<messaging:htmlEmailBody >
Hello {!relatedTo.Job_Opening__r.Hiring_Manager__r.Name},

Project : {!relatedTo.Job_Opening__r.Account__r.Name}<br/>
SO: {!relatedTo.Job_Opening__r.SO__c}<br/>
Candidate Name : {!relatedTo.Candidate__r.Name}<br/>
Candidate Phone: {!relatedTo.Candidate__r.Mobile__c}<br/>
Candidate Email: {!relatedTo.Candidate__r.Email__c}<br/>


Please <a href="mailto:[email protected]?Subject=Interview Assign {!relatedTo.Id}&body=Enter Employee ID :" target="_top">Reply with Employee Id</a> to Assign an interviewer 
or click <a href="mailto:[email protected]?Subject=Interview Assign {!relatedTo.Id}&body=Smart Assign" target="_top">Smart Assign</a> to automatically assign an interviewer <br/>


Thank You<br/>
Candid Application Admin

When I use a singleemailmessaging class to send an email I get an email with empty body. I researched a bit to find out the I need to mention whatID to be used as relatedToType object id. I had to comment- setTargetObjectId as I do not have contacts in my org(My org does not have Sales cloud) and setSaveAsActivity as false. Doing this I get a blank email body. Part of my code which send email:

     EmailTemplate et = [Select Id,Name from EmailTemplate where Name = 'The VF email template name'];

              Contact cnt = [select id, Email from Contact where email != null limit 1];
     mail.setToAddresses( toAddresses );
     mail.setSubject(Candidate.Name +' '+'has been assigned to the project'+' '+'"'+jobopenEmail.Account_Name__c+'"' +' '+'('+' '+'SO#'+' '+jobopenEmail.SO__c +')' + ' '
                     +' '+jobapp.id);
     Savepoint sp = Database.setSavepoint();
     Messaging.SendEmailResult [] r = 
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});   


     Messaging.SingleEmailMessage emailToSend = new Messaging.SingleEmailMessage();
     Messaging.SendEmailResult [] sndmail = 
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {emailToSend});   

I think my solution should be here - https://appirio.com/tech-blog/sending-emails-without-targetobject-id-apex Any suggestion what I might be missing here?

  • What he is doing there is putting a contact id in setTargetObjectId then surrounding the send with a rollback (so the email doesn't send), so he can then use the body that was generated by the template. But never actually sent to the dummy contact. Pretty slick. Granted I didn't actually try it, but it makes sense. I'm sure you will have to tweak up his example a bit. Commented Nov 3, 2016 at 18:26
  • I get this error - System.EmailException: SendEmail failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Either the plain text body or html body must be supplied. This is when I send the email and use the email content of the rolledback mail
    – SfdcBat
    Commented Nov 3, 2016 at 18:28
  • @JesseMilburn Pls see my edit on how I used the code
    – SfdcBat
    Commented Nov 3, 2016 at 18:32
  • Try like they did and make your message list prior to the Savepoint then use the variable inside the rollback. If the answer works let me know and I will whip up a clean solution for this thread that is a bit easier to read than the blog post. Commented Nov 3, 2016 at 20:52
  • Also debug the original list after the rollback to check if the body is there with the merge fields acting as expected with your WhatId. Commented Nov 3, 2016 at 20:59

2 Answers 2


Following link has an answer to the question: Using APEX to assemble HTML Letterhead Emails

Summer 16 introduced new method:

Messaging.SingleEmailMessage email = 
            Messaging.renderStoredEmailTemplate(templateId, whoId, whatId);

Instead of using Messaging.SingleEmailMessage email=new SingleEmailMessage(); we have to use

 Messaging.SingleEmailMessage email = 
            Messaging.renderStoredEmailTemplate(templateId, whoId, whatId);

This will take care of retrieving the body and merging the field in VF email templates


I think you just need to change your query to:

EmailTemplate et = [Select Id, Name, Body from EmailTemplate where Name = 'The VF email template name'];

And add:

  • 1
    No, that's not correct! SetHTMLBody is used to set message body which is like a string. If you want to set email template then you need to use setTemplateId
    – SfdcBat
    Commented Nov 3, 2016 at 18:18
  • 1
    You'd be breaking all the merge fields if you do that. Not the right solution. Commented Nov 3, 2016 at 19:09

You must log in to answer this question.

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