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. 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
    Nov 3, 2016 at 18:28
  • @JesseMilburn Pls see my edit on how I used the code
    – SfdcBat
    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. 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. 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
    Nov 3, 2016 at 18:18
  • 1
    You'd be breaking all the merge fields if you do that. Not the right solution. 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 .