Automating Emails to Opportunity Contact Roles

UPDATED June 3, 2018 – you can now add email addresses to cc or bcc in the configuration step. See updated code.

The Opportunity Contact Role is an odd beast, perhaps because it exists largely for information purposes in the B2B sales world for which Salesforce is built, but takes on weightier roles in nonprofit usage. In the nonprofit world, opportunities represent donations, grants applied for and won, and sometimes memberships and event registrations. From there arise a lot of solid use cases for sending automated emails to Contacts linked by Opportunity Contact Roles, but Email Alerts don’t allow you to access these contacts for automated mailing.

Facing this constraint, I built this Apex class that allows you to send an Opportunity-based email to contact roles using Process Builder to Call Apex and to define the template, roles of the desired recipients, and an attachment as needed. The class and related test class are below, or you can download them in a single text file; the image shows how to configure a Process Builder Action to take the place of an email alert to send your email based on the criteria you defined elsewhere in the flow.

Configuration

There are three required fields when you select this class: OpportunityID, which should be set as a field reference to the related opportunity; TemplateID, the id of the email template you’d like to use (be it html, Visualforce, or plain text), and one or more toRoleNames.

Like ccRoleNames and bccRoleNames, toRoleNames takes a comma-separated list of role names. If you want to send to the primary opportunity contact, use the name Primary, which shouldn’t also be the name of a Contact Role. To function correctly the role names need to be in proper case, and there should be no extra spaces before or after the role names. If multiple “to” contacts are specified, you have no control over which of them will end up being the “to” of record, for mail merge and links to the generated activity. If your list of roles doesn’t yield a “to” contact for a given opportunity, the primary contact will be used instead.

You can optionally define the displayName and replyTo for the email, list a single ID for a resource to attach, and set the boolean field saveAsActivity. By default, the class *will* save the email as an activity. If you prefer that it not do so, you must define this parameter as False.

A couple of potential improvements for you intrepid developers out there: adding trim() and toLowerCase() so that spacing and capitalization don’t cause issues; the ability to send separate emails to all of the “to” addresses; and the ability to add multiple attachments. Please share the code back here if you make those improvements.