4

I suspect the answer here is "No", but I thought I'd ask anyway. Can I send an email, using a VFTemplate, to an arbitrary email address, as opposed to a Contact, User, or Lead?

I need to send a fairly complex email, which will require a VF email template. All merge fields in the template will come from the relatedTo object (case), nothing from recipient. These emails will be sent to an email-to-fax service, where the email-to-fax address is stored in a custom field on an account. When creating the email template in the UI, the options for Recipient Type are Contact, User, and Lead. And the documentation for SingleEmailMessage.setTargetObjectId() says "Required if using a template, optional otherwise".

So, do I have any option besides creating a "dummy" contact on the affected accounts to stor the email-to-fax email address?

4 Answers 4

5

No there's not - it has to be a record in the system, and it has to be a Contact/User/Lead and not a custom object. I recently found this out the hard way.

You can send emails to any address via Apex, but you can't reference VF templates directly that way. For HTML emails like this, I often use Apex and have a class which is specifically designed to create and handle the HTML for me.

4

It turns out there is a way to do this that I learned from John Conners. You can set the relatedTo as your user, and then setToAddresses/setBCCAddresses/setCCAddresses.

This causes any merge fields related to the recipient to be filled in with your user (or some dummy user/contact/lead)'s data, but if that doesn't matter for your use case this can be particularly useful - especially for sending a templated email to multiple addresses.

This only works with visualforce email templates.

Example code that will send to your user's email address, as well as example@example.org:

Id templateId = '00Xd0000000Y058';
Id someAccount = '001d000001MMNin';
Messaging.singleEmailmessage em = new Messaging.singleEmailMessage();
em.setTemplateId(templateId);
em.setTargetObjectId(UserInfo.getUserId());
em.setWhatId(someAccount);
em.setSaveAsActivity(false);
em.setToAddresses( new List<String>{ 'example@example.org' } );
Messaging.sendEmail( new List<Messaging.Email>{em} );

It comes across looking like this:

enter image description here

7
  • Hmm. set relatedTo or recipient? relatedTo is the case (set via setWhatId), so I'd need to set the recipient via setTargetObjectId(UserInfo.getUserId()). But, will this still send an email to the user, or only to the address(es) set via setToAddresses? And any issues doing this from inside a Trigger? Feedback requested, but I'll probably give this a try in an org. Oct 11, 2013 at 22:51
  • Docs for SingleEmailMessage.setToAddresses() claim, "This argument is allowed only when a template is not used." No time to test at the moment, but looking grim for Mudville. Oct 11, 2013 at 22:56
  • Apex email APIs have a huge amount of undocumented behaviors. You're right that you'd have to send email to a user in the process, but that can be any user, it doesn't have to be the running user. Oct 11, 2013 at 23:07
  • Just edited the answer with sample code and proof it works, even if it's an ugly hack for not having a better email API. Oct 11, 2013 at 23:09
  • 1
    Works with a contact instead of a user; specifically works with a contact that has an @example.com email address, which is reserved (tools.ietf.org/html/rfc2606) and won't go anywhere. I don't know if there are any concerns sending email to an unreachable email address. Oct 14, 2013 at 13:45
2

This is a late answer so maybe the solution was implemented sometime after the question was posted, but you can do this with the method setTreatTargetObjectAsRecipient(false) and then no email will be sent to the targetObjectId. Then you can set toAddresses to whoever you want the actual email recipient to be. They still require you to set some targetObjectId, otherwise no email will send at all, but you don't have to use it for anything.

1

I just wrote a blog posting on a semi-related topic. http://www.techplustalk.com/2013/10/custom-mail-merge.html

Essentially, my use-case was to use email addresses stored in custom object records and then merge different data into an email template. I used a custom object (Email__c) with a rich-text field to define my HTML email content (complete with "fake" merge fields) and then when constructing each message in my apex controller, I replace the "fake" merge fields with the data that I want.

        // create email for each application (each applicant) that satisfies criteria
        for (Application__c app : appList) {
            Email__c e = emails.get(0);  // get applicable "template"

            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setToAddresses(new String[] { app.Email__c });  // set email address from application
            email.setSenderDisplayName('CARPOOL - TAMU');  // can set any name here
            email.setSubject(e.Subject__c);

            // 'hack' to replace the merge fields with values from custom object
            String body = e.Body__c.replace('{!app.name}', app.First_Name__c);

            email.setHtmlBody(body);  // rich text field is actually html content 

            // add email to emailList -- this list will hold all the emails to be sent
            emailList.add(email);
        }

        // send all individual emails using one sendEmail call
        List<Messaging.SendEmailResult> results = Messaging.sendEmail(emailList);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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