Tell me more ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I am having an html email template which uses certain merge fields from a custom object. Now I am using following apex code to send certain emails to users.

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

        mail.setTargetObjectId(t.OwnerId); 
        mail.setTemplateId(et.Id);
        mail.setWhatId(t.Id); 
        mail.SaveAsActivity = false;
        Messaging.sendEmail(new Messaging.singleemailMessage[] {mail});

Code is saved without error but when I run it it says "can't use whatId when sending email to users". Can anyone explain me how to overcome this error? When I use a visualforce template then same code works fine.

share|improve this question

3 Answers

You can get around this by grabbing the user's email address from their user record (you've already got their ID so that's a trivial query) and then using that with the setToAddresses method of SingleEmailMessage, then you shouldn't need to set the target object ID and as such will bypass this restriction.

share|improve this answer
The downside to this approach is you can't use any merge fields dependent on the target object id. – Ralph Feb 25 at 17:38

It would seem that you can't set the WhatId (which you have) when the target object Id is a UserId. You can set it when the target is a contact or such. This post i found seems to confirm that hunch http://stackoverflow.com/questions/11105086/setwhatid-in-salesforce-using-email-template

share|improve this answer
2  
Note that it does work in visualforce email templates as @doga mentioned. It's a rather arbitrary restriction on non-VF templating. – ca_peterson Oct 1 '12 at 20:54

This is a glaring hole that I'm sad to say has been here since the beginning. Particular frustrating since workflow alerts seem to have no problems merging a custom object template when sending to a user. You can work around it by creating a contact with the users email and then deleting it after the email has been sent.

private static void sendMyTemplate(Id userId, Id mergedObjectId) {
  User user = [select email, firstName, lastName from User where id = :userId];
  Contact tempContact = new Contact(email = user.email, firstName = user.firstName, lastName = user.lastName);
  insert tempContact;
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  mail.setTargetObjectId(tempContact.id); 
  mail.setTemplateId(template.Id);
  mail.setWhatId(mergedObjectId); 
  Messaging.sendEmail(new Messaging.singleemailMessage[] {mail});
  delete tempContact;
}
share|improve this answer
Ralph, plus 1 for a creative idea. – zachelrath Oct 2 '12 at 13:17
The one glaring whole is validation rules. If you're org creates a new contact validation rule it'll break this code ... in which case @LaceySnr suggestion will be a better route – Ralph Oct 8 '12 at 20:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.