The Silver Lining

Lessons & Learnings from a salesforce certified technical architect.

Salesforce: Using basic email templates from Apex code

with 23 comments

A few weeks ago I noticed a number of questions in the forums around how to use email templates from Apex classes. I Googled a few keywords and come up with very little. I then trawled the documentation but came up empty-handed. Eventually it was Eclipse that provided the knowledge required, and I thought I’d share it with the good ol’ developer community.

One part of the process is discovering that Salesforce stores all sorts of items as records in objects; some of them being email templates, user information and even Apex class bodies (scandalous). All you have to do is query them. The other major part is finding that the method you need is missing from the Apex documentation.

There are a number of email template types, and if you’ve found this post because you’re stuck, I’m sure you’re aware that they are:

  • Text
  • HTML
  • Custom
  • Visualforce

Each has its own application and you can make them looking very spiffy if you, or someone you know has mad design skillz. But we’re getting off-topic here. The largest difficulty I found is that the method used to associate a template with an email isn’t listed in the Apex documentation, but with the ever useful Auto-Complete capabilities of Eclipse you’ll notice a method called ‘setTemplateId’. How should we use it? It’s easy-peasy really, just like this:

	Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

	Contact recipient = [SELECT id, firstname FROM Contact LIMIT 1];
	EmailTemplate et = [SELECT id FROM EmailTemplate WHERE developerName = 'MyTemplate'];

	mail.setSenderDisplayName('Your Loving Administrator');

	mail.setTargetObjectId(recipient.id); // Specify who the email should be sent to.
	mail.setTemplateId(et.id);

	Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});

As you can see, it’s quite straight forward. Notice how there’s no need to specify the to-addresses, the subject, or the email body, they’re all pulled from the template. Nice huh?

A few other tips that I have on offer are:

  • When querying for an email template always use the ‘developerName’ field. If a power user decides to change the name of the template they’re less likely to change the unique name too, this way you have a tiny bit of a safety net. Of course you should always wrap this query in an exception handler.
  • Visualforce templates can’t be used in bulk emails (don’t shoot! I’m just the messenger).
  • After you’ve created a template you need to make sure that you set it as ‘Available to Use’ (an option on the template detail page), or emails won’t be sent.
Advertisements

Written by Wes

May 8, 2010 at 4:45 pm

23 Responses

Subscribe to comments with RSS.

  1. Excellent tip but I think last part should read Visualforce templates “can’t” be used in bulk emails

    Jason

    May 8, 2010 at 9:23 pm

  2. I would murder a hobo for the ability to add CCs to email templates. Trying to email a group of people from apex redefined the meaning of pain for me.

    Chris Peterson

    May 10, 2010 at 5:19 pm

    • Yeah things like email and async calls are still a bit young on the platform, are there any Ideas around this stuff? Let’s vote em up.

      Wes

      May 10, 2010 at 5:27 pm

      • I am working on comparing an account owner list of id’s with a list of id’s from the AccountTeamMember object to ensure when sending out the email notifications to the accountteammembers on updates to the events on an account thay belong to, I don’t send duplicates in the rare case that the owner of the account is also in fact, listed as an accoutteammember. Any ideas on how to set if statement up for this??

        Patrick

        June 3, 2010 at 3:59 pm

  3. @Patrick you can store the Ids in a Set which is like a list but only contains unique values. That way if you do try to add a duplicate it get’s ‘thrown away’.

    Wes

    June 3, 2010 at 4:18 pm

    • Awesome Wes! I will try that! Thanks man!

      Patrick

      June 3, 2010 at 5:24 pm

  4. Wes,

    Is it possible for a Customer Portal user to send emails through this API code ?
    Am facing this problem and stumble upon your blog.
    The error I get is “FIELD_INTEGRITY_EXCEPTION, Portal user can’t own an activity” .

    Rancho

    August 20, 2010 at 10:09 pm

    • There are some objects that Portal users can’t create and it seems activity is one of them. These are created by default when you send emails but you can turn this functionality off by calling the email class method setSaveAsActivity with a argument value of false.

      Wes

      August 21, 2010 at 10:52 am

  5. Hi, I would like to check is there any apex code that allow email to directly insert to “Notes & Attachment” in the Custom Object Section?

    As currently I understand the email will be insert in “Active History”. But i would like those email to be trigger to “Noted & attachment”

    Sorry for the trouble and thanks in advance.

    Li

    October 28, 2010 at 3:29 am

  6. I just found this post and I had done all the things you say but I am getting the following error:

    INVALID_FIELD_WHEN_USING_TEMPLATE, When a template is specified the plain text body, html body, subject and charset may not be specified

    I am setting the same fields you set and no more! I’ve tried using different templates with no luck. None of the templates are VF.

    Any thoughts on my problem?

    Thanks

    Elly

    January 19, 2011 at 3:44 pm

    • I’d need a bit more info. If you post all your code to the forums and link back here I’ll try help 🙂

      Wes

      January 20, 2011 at 7:56 pm

    • Did you ever find a solution for this Elly? I am facing the same issue too.
      Thanks a lot
      Pradhap

      Pradhap

      February 20, 2012 at 5:16 pm

      • If you drop some code into a force.com forum post I’ll see if I can help.

        Wes

        February 21, 2012 at 5:13 pm

  7. A+ article. Thanks for the write up – it helped a lot.

    colemab

    August 18, 2011 at 9:10 pm

  8. […] One last thing that I would like to add here is that there might be a scenario when you might want to use the Email templates in Salesforce.com to use while reverting back to the anonymous user. In that case, take a look into this post Salesforce: Using basic email templates from Apex code. […]

  9. Hi, Wes. I am writing a email for my firm that involves couple objects:

    o2bc__Subscription__c subs = [SELECT o2bc__Account__c, Campaign__c, Discount_Start_Date__c, Discount_End_Date__c, o2bc__Discount__c, o2bc__Item__c,
    o2bc__Billing_Start_Date__c, o2bc__Next_Bill_Date__c, o2bc__Bill_Cycle__c, o2bc__Rental__c, Free_Trial_Finish_Date__c
    FROM o2bc__Subscription__c WHERE Id = :sc.Id LIMIT 1 ];

    Account a = [ SELECT Id, FirstName FROM Account WHERE Id = :subs.o2bc__Account__c LIMIT 1 ];
    Campaign cp = [ SELECT Id, Name from Campaign WHERE Id = :subs.Campaign__c LIMIT 1 ];

    Datetime cDT = System.now();
    tDay = dateFormat(cDT);
    free_Start_Date = dateFormat(subs.o2bc__Billing_Start_Date__c);
    free_End_Date = dateFormat(subs.Free_Trial_Finish_Date__c);
    next_Bill_Date = dateFormat(subs.Discount_End_Date__c);

    // check the condition if there is only one contact
    Contact c = [ SELECT Id, FirstName, Email FROM contact WHERE AccountId = :subs.o2bc__Account__c LIMIT 1];

    Credit_Card__c cd = [ SELECT CC_Last_Name__c, CC_First_Name__c, Credit_Card_Number__c, Credit_Card_Type__c,
    Expiry_Year__c, Expiry_Month__c
    FROM Credit_Card__c WHERE Account__c = :a.Id ];
    if ( cd.Credit_Card_Number__c != NULL ) {
    last4 = cd.Credit_Card_Number__c.subString(8, 12);
    }

    // looking for the price
    Campaign_Discount__c cDisc = [ SELECT c.Campaign__c, c.Item__c, c.Free_Trial_Type__c, c.Discount_Final_Price__c
    FROM Campaign_Discount__c c WHERE c.Campaign__c = :subs.Campaign__c AND c.Seq__c = ‘1’];

    Actually I am not sure why so many project involved.
    I did the code in the trigger –

    htmlInvoice =
    ‘[During your free trial, you may cancel your subscription by contacting our Customer Service Department at ‘
    + ‘1-866-321-8726 Monday through Friday from 8am-6pm, ET (note: from outside the U.S. or Canada, please call ‘
    + ‘212-321-5200). Once your free trial ends and your subscription begins, the subscription fee will not be’
    + ‘reimbursed or refunded. ‘
    + ‘When your free trial expires, your subscription will automatically convert to the following payment plan:] ‘
    + ‘Subscription Period: ‘ + subs.o2bc__Bill_Cycle__c + ”
    + ‘Paid Subscription Start Date: ‘ + next_Bill_Date + ‘ ‘ …

    But due we want build friendly user interface let force user to use them as email templates – I am not sure if you have any suggestions – due I am a new backend coder. thanks in advace.

    Apple

    Lisa Tan

    November 14, 2011 at 8:32 pm

  10. Hi, is there a way to use custom objects?

    IE:

    myObecjt recipient = [SELECT id, firstname FROM myObecjtLIMIT 1];

    gast1981

    March 13, 2012 at 8:45 pm

  11. Im a trying to create a visualforce email template pulling in a rich text field that contains an image, when i send the email the image does not appear do you know why?

    Rosey

    January 30, 2013 at 8:58 pm

  12. Not to resurrect a dead thread, but you can get the template ID without SOQL by just looking at the page address when you view it in the GUI (under Communication Templates | Email Templates). This saves a query and processing time.

    Chris Patten

    February 1, 2013 at 7:54 pm

  13. Can not get test coverage more than 69%. Might be bug around here)

    Max

    March 17, 2013 at 8:29 pm

  14. Thanks Wes,
    It was very helpful
    Also I wanted to know how we can add user defined body to the mail template and the reciever’s mail id also is entered from the user’s side and not from the contact list already present.Just as the details asked before posting to this page.

    Aakash Jain

    August 2, 2013 at 5:49 am

  15. Hi Wes,
    My requirement is send Email template to custom object email field. Is this one possible.
    Please reply me.

    Surendran

    October 21, 2013 at 2:16 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: