Send Rich Email (Send HTML Email Action)

Note: There’s a version of this action that uses a Custom Property Editor to provide a more usable configuration experience. It requires a Spring ’20 Org that has been activated for the Custom Property Editor Pilot. Learn more here.

Video introduction

Installation (See bottom of page)

Source code

Flow provides a built-in Send Email action but it’s something of an underachiever. The sendHTMLEmail action uses the power of Apex and Flow Actions, easily installed and used from within Flow Builder. MVP Jeremiah Dohn pioneered this space several years back with his well received HTML Email Flow action. The version here is similar and adds a several of additional capabilities.

This improved email flow action supports:

  • Rich, HTML email bodies that can use all of the capabilities of Flow’s Text Templates, including Bold, Italics, Underline, Bullets and Numbers, Left/Center/Right justification, URLs, images, fonts, and text size
  • Email Templates (both Classic and Lightning) with field merge and letterheads
  • Any combination of the following, for To, CC, and BCC
    • A single email address
    • A string collection of email addresses
    • A collection of Contacts
    • A collection of Users
    • A collection of Leads
  • Organization-Wide Email Addresses
  • Attachments
  • Ability to toggle on/off the use of the Salesforce per-user email signature
  • Ability to provide a plain text body, an html body, or both
  • Ability to set the ReplyTo email address and the Sender Display Name
  • Multi-Language Support for Lightning Email Templates

Each email requires several components, but they may be constructed in many ways using the component parameters. The package includes a flow that produces emails in several scenarios. See Examples below.

Currently unsupported features include:

  • Support for the MassEmailMessage API, enabling higher volumes
  • Character Set setting

NOTE: Scratch orgs have a strict cutoff after sending just 50 email messages

If you’re interested in extending this class, please do so!


There are many configurable options for this Action Component. Decide what and how your email needs to communicate, then choose the best combination to provide the needed communication.

Addresses (To, CC, BCC)

You can generate addresses from any of the following sources:

  • A single email address
  • A string collection of email addresses
  • A collection of Contacts
  • A collection of Users
  • A collection of Leads

Example: Create a collection variable of strings and add individual email addresses to it:

Add a collection variable
Populate the collection variable
// for a string
String exampleSingleEmailAddress = "";
// or for collections
List<String> exampleStringCollection = new List<String>{"",""};
List<Contact> exampleContactCollection = [SELECT Id Contact Limit 2];

Example: configure inputs with sources of email addresses:


Addressees are manually assigned using the following parameters (Type List<> is a Collection):

Name Type
SendTOthisStringCollectionOfEmailAddressesList<String> (or Collection of String in Flow)
SendTOtheEmailAddressesFromThisCollectionOfContactsList<Contact> (or Collection of Contact in Flow)
SendTOtheEmailAddressesFromThisCollectionOfUsersList<User> (or Collection of User in Flow)
SendTOtheEmailAddressesFromThisCollectionOfLeadsList<Lead> (or Collection of Lead in Flow)
SendCCthisStringCollectionOfEmailAddressesList<String> (or Collection of String in Flow)
SendCCtheEmailAddressesFromThisCollectionOfContactsList<Contact> (or Collection of Contact in Flow)
SendCCtheEmailAddressesFromThisCollectionOfUsersList<Lead> (or Collection of Lead in Flow)
SendBCCthisOneEmailAddressString (or Collection of String in Flow)
SendBCCthisStringCollectionOfEmailAddressesList<String> (or Collection of String in Flow)
SendBCCtheEmailAddressesFromThisCollectionOfContactsList<Contact> (or Collection of Contact in Flow)
SendBCCtheEmailAddressesFromThisCollectionOfUsersList<User> (or Collection of User in Flow)
SendBCCtheEmailAddressesFromThisCollectionOfLeadsList<Lead> (or Collection of Lead in Flow)

Sender (From)/Reply-To

These seetings determine what addresses the email will appear to be coming from. NOTE: Unless you’ve made special arrangements in your Org, the message will always appear to be coming from (Example):; on behalf of; Do Not Reply <> .

You can either 1) use an OrganizationWideEmailAddress or 2) specify your own Reply-To Email Address and Sender Display Name. If you provide an OrganizationWideEmailAddress, that will take precedence and any Reply-To Email Address and/or Sender Display Name you’ve also provided will be ignored.

Using Organization-Wide Email Address

To use an OrganizationWideEmailAddress , pass the Id of one that you have defined into the action via the “Use This Organization-Wide Email Address Id”. (If you want to get the benefit of Verified sending, you can’t just paste the email address into the Reply-To Email Address field. You have to use the Use This Organization-Wide Email Address Id field.). to find the ID, search the OrgWideEmailAddress object for the appropriate Id. NOTE: you cannot use OrganizationWideEmailAddress and

  1. In Lightning Setup, go to Organization-Wide Addresses and click Edit on the address you want to use:

2. Examine the URL of this web page. It should look something like this:

3. The Id of the Organization-Wide Email Address is the character between the 2 “%2F” strings. So in the example above, you would extract “0D2560000008PGP” and insert it as an input:

Using Custom Reply-To and/or Sender Display Name

You can change both the “Reply-To” (using the “replyEmailAddress” attribute) and how you wish that name to be displayed (using the senderDisplayName attribute).

The optional In-Reply-To field of the outgoing email identifies the email or emails to which this email is a reply (parent emails) , and the name that appears on the From line of the email. The display name cannot be set if the object associated with a setOrgWideEmailAddressId has defined its DisplayName field.


Subject can be set directly via the subject parameter. Note that if you choose to use an Email Template Id, the subject will be specified in the template, and the subject parameter in this action will be ignored. Don’t try to use both at the same time. See below for more information on using email templates.

NOTE: If you specify Subject when using an Email Template, that value will override the Template’s Specified Subject. Emails without a subject (either specified or part of the template) will not be sent/delivered.


To specify the body of the email, you can use any of these combinations :

  1. HTML Body. The body is composed using a text (or rich text) variable, then passed to the Action in the HTMLbody parameter. Flow variables and Global variables can be included for merge in the text at the time of invocation using the standard merge syntax (e.g., {!stringCollectionEmailAddresses} ). You cannot use HTMLBody and a template.
    1. Advantages. Very quick to create, assemble, and test.
    2. Disadvantages. May be difficult to find and might require developer (as opposed to Administrator) support to modify. Also, can be very tricky using multi-linguistic sites. (Hint: USE LABELS!!)
  2. Plain Text Body. Even when you’re sending out an HTML email, a plain text alternative can be desirable. Multi-part MIME (Multipurpose Internet Mail Extensions) bundles together a simplified plain-text version of your email along with the HTML version of your email. You cannot use plainTextBody and a template.
  3. Both an HTML Body and a plain text body. Use this to send out and HTML email with a bundled plaint-text version. You cannot combine this option with a template.
  4. Email Templates (Classic or Lightning Email Template). Use Email Templates to save time and standardize email sent by you or others in your organization. Use merge fields or enhanced letterhead if you need them. This has been an evolving function within SalesForce, so if you are unfamiliar with email template options, you may want to review this. Details on how to use EmailTemplates in multilingual environments can be found here.
    1. Advantages. Consolidates standard communications within the SalesForce email structure (both Classic and Lightning). If you’re using Lightning Email Templates, you have the full range of public, private, and specified sharing capabilities for who can use what and it helps enforce communication standards by making the development of templates and communication more of a communication and policy role rather than a developer or administrator role.
    2. Disadvantages. Users need to understand the concept of templates and sometimes the differentiation between Classic, Lightning, and (sometimes) VisualForce templates.
  5. Multi-Lingual Email Templates (only tested with Lightning EmailTemplates).

Body – HTML Body

Rich Text HTML email bodies can use all of the capabilities of Flow’s Text Templates, including Bold, Italics, Underline, Bullets and Numbers, Left/Center/Right justification, URLs, images, fonts, and text size.

To send a rich text (HTML) body, create a resource of type “Text Template” and specify that resource when sending the email with the sendHTMLEmail action.

Text Template Resource named “HTMLTextTemplate”
HTMLbody Parameter in sendHTMLEmail Action

Body – Plain Text

Even when you’re sending out an HTML email, a plain text alternative can be desirable. Multi-part MIME (Multipurpose Internet Mail Extensions) bundles together a simplified plain-text version of your email along with the HTML version of your email. You cannot use plainTextBody and a template.

To send a plain body text:

  1. [Optional] Create a text resource, either variable or a formula if you wish to insert line breaks:
  2. You can just enter text, or specify the resource in the action input values.

Body – Both an HTML Body and a plain text body

[RFU] Previous versions of SalesForce allowed for templates which automatically attached text-only versions in the event a recipient did not desire and/or have the capability to use HTML-based email. As of this writing, it appears the Lightning Email always sends the HTMLBody, but does not attach the plainTextBody.


You can decide whether or not to include the User email signature if the context user has one configured. The default is true, meaning if the user has a signature it is included in the email unless you specify false. Note: You must enable this parameter AND set it to $GlobalConstant.false if you want to shut it off.


You can attach files to your emails. Provide a collection of ContentDocmentLink records. To learn how to attach documents using CDLs, see more here.

Using Email Templates

For a nice introduction on how to use email templates, letterheads and even graphics, you may wish to start here: Configure an Email Letterhead and Template.

You can use Email Templates with this Action.

There are 3 core concepts:

  1. The Template. The template contains the format of the email (including Letterhead) and syntax for merging fields into that communication. A merge field is a placeholder in an email template or letterhead. When you send the email, the placeholder is replaced with the Salesforce data from the record or records of the people you are emailing. Fields that can be merged include those from the TargetObject, another sObject record, and global variables. NOTE: the merging done by the template system is different from the merging done by Flow, and there is currently limited ability to pass dynamic values from Flow into the template system. HOWEVER, see this post for an easy technique that will allow you to get full rich dynamic merging.
  2. The Target Object Record. This is who the email is being sent to, usually a Contact, User, Lead or Group. Depending on the type of template you are using, other fields from this Target Object can also be merged into the template as part of the send email (e.g., Dear Dear {{{Recipient.Name}}}). In templates, the merge fields for “recipient” come from the specified object Id.
  3. The Related Record. If you specify a contact for the Target Object  field, you can specify an optional Related Record  to merge fields in the template from that record. For the most predictable results, Use the Handlebars Merge Language in Lightning Email Templates and Enhanced Letterhead which merges fields from the record into the email using the format {{{[Related Record Type].[Field]}}} (e.g.,  {{{Case.CaseNumber}}}) and convert your Classic Templates to LightningEmailTemplates with Enhanced Letterhead.

Using Email Templates

For a standard template, the Template ID and the Template Target Record Id (Recipient) are required. Optionally a related record can be specified using the Template/Activity RecordId(whatId/recordId) Input Value.

Adding Multilingual Email Template Support

SendHTMLEmail provides multi-lingual support within the same flow by allowing a set of related email templates to be created in different languages. In the flow, specify the desired language. To make this work, the names of the email templates must follow some rules:

  • Each language localization has its own template with all localizations sharing a common EmailTemplate.Name.
  • To differentiate the localizations, add the following text to the EmailTemplate’s Description fieldt: ‘Language=”en_US”‘ (or whatever corresponding to your organization localizations).

For more on how to add localization to an email template set, please refer to Send HTML Email with Multi-Language Support for Lightning Email Templates.

Saving Activity History

You can record the sending of an email as a record activity. This is based on setSaveAsActivity(saveAsActivity) and is Optional. The default value is true. If this is set, you must also specify a valid Related Record ID(recordID) for where the email activity should be saved. This argument only applies if the recipient list is based on targetObjectId or targetObjectIds. If HTML email tracking is enabled for the organization, you will be able to track open rates.

Operational Considerations

This action makes use of the standard Salesforce email infrastructure, the same service that you use when you send a single email directly from a lightning experience page or a classic case feed. As such, any emails you send will be included in your usage, so be aware of the limits and guidelines. (Developer note: this action makes use of the Apex Messaging service API’s.)

This action does not use or involve Email Alerts, which are used in Workflow Rules and exist in Flow as separate actions you can drag into your flow. Be mindful of this so you don’t accidentally confuse the Email Alerts, the Email Templates, and the Flow Text Templates.


The sendHTMLEmail package ships with two screen flows that can be used to test and demonstrate the action, ‘Send HTML Email Testflow’ and ‘sendHTMLEmail Test – Create Test Templates if Needed’. You do not have to activate these flows to use them. Open ‘Send HTML Email Testflow’ then select “Debug” (or “Run”).

Some of these examples may require prior setup of records. Where necessary, this is described in each of the selected examples. Examples/Tests include:

  1. Simple Email Text – with To, Sender, Reply-To, Subject, Body (All text)
  2. Simple Email with Address Collections – Using Address Collections to Send to Multiple Recipients
  3. Email with Attachments – Simple Email (1) With Attachments
  4. Email Using Template – An email using a Lightning EmailTemplate
  5. Multi-Lingual Using Email Templates – An email using a Lightning EmailTemplate selected by language

Choose the example you would like to see and the instructions are in each of the examples. You will also find in these examples the use of Text Templates for formatted Rich Text messages (Example 1), using Plain Text (Example 2), and logging the email as an activity on the related object (Example 5).

Select Test Flow and Start an example

To see how the Send HTML Email Action is configured for each of these examples, click on the appropriate Action (they are labeled) and look at the Input Variables. You may also want to look at some of the logic in the setup to those examples for ideas in creating your own flows.

Example 1 – Simple Email Text – with To, Sender, Reply-To, Subject, Body (All text)

This sends out a rich text email predefined as a text template () l to the addressee in [Recipient Email Address] from [ReplyTo Email Address] with the name [Sender Name] using [Subject] and [Body]

All of the above can be created by assigning variables. To create a body with line breaks, use a formula variable (see example variable testPlainTextLineFeeds)

Note: To get the full effect of rich text, edit the formula plainTextBody instead of modifying the field on this screen.

Example 2 – Simple Email with Address Collections

This sends out a simple plaintext email from [ReplyTo Email Address] with the name [Sender Name] using [Subject] and [Body]

All of the above can be created by assigning variables. To create a body with line breaks, use a formula variable (see example variable testPlainTextLineFeeds)

The addressees can be built from multiple collections. This example builds a collection of strings from the two email strings and/or from collections you can set up external to the example flow by creating contacts with names containing the text entered in [Contact Contains Match].

By default, this example builds a collection of strings from the two recipient email addresses and will send all collections to To, CC, and BCC (so 6 emails will be sent – minimum)

Example: Create two contacts with valid email addresses and names containing “testContact”, then specify “testContact” in [Contact Contains Match]

Note: To get the full effect of rich text, edit the formula plainTextBody instead of modifying the field on this screen.

Example 3 – Simple Email with Address Collections

For this example, you will need to create or use a record to which attachments can be made (e.g., a Contact). Create the record and then use the recordId of that record to attach files.

This sends out a simple plaintext email with attachments from uploaded files to the addressee in [Recipient Email Address] from [ReplyTo Email Address] with the name [Sender Name] using [Subject] and [Body]

All of the above can be created by assigning variables. To create a body with line breaks, use a formula variable (see example variable testPlainTextLineFeeds)

Note: This example as distributed uses the formula variable “testPlainTextLineFeeds” to create a plain text body without signature

Example 4 – Email Using Template

This sends out an email using a specified EmailTemplate with the addressee specified through the TargetObjectId and optionally (dependent on your Template) merge fields with an associated object record using that record’s Id.

For this example, you will need to create or use a template. Templates also require that you have a recipient record (targetObjectId) (e.g., Contact, User, . . .) which must also pre-exist. You will be required enter the ID for that record as the (targetObjectId). Additionally if you intend to test merge fields (RelatedTo) with your template, you must also pre-create the related object record and have available the Id for that record as an ID for the Record Object Id (RecordId).

This example also creates an activity for the email which will be assigned to the running user and related to the RecordId.

You can create test templates (sendHTMLEmailTest) by running example 5.

If you use the default test templates (sendHTMLEmailTest) the Target ID should be a ContactId and the Related Record should be an AccountID.

Example 5 – Multi-Lingual Using Email Templates

SendHTMLEmail provides multi-lingual support within the same flow by allowing the language to be specified, then selecting the appropriate template for that language. For this functionality, each language localization has its own template with all localizations sharing a common EmailTemplate.Name. To differentiate the localizations, add a tag to the EmailTemplate.Description field in the format: ‘Language=”en_US”‘ (or whatever corresponding to your organization localizations)

This example uses the template set sendHTMLTest with english (en_US) and spanish (es_MX) versions. If the templates do not exist, this example will automatically create them for you (sendHTMLEmailTest).

You will also need to:

1) Create a Contact (for Target Object) and have its Id available.

2) Create an Account (for Related Record) and have its Id available.

You can, of course, vary the templates and object records to reflect your organization’s needs.

This sends out an email using a specified EmailTemplate with the addressee specified through the TargetObjectId and optionally (dependent on your Template) merge fields with an associated object record using that record’s Id.

For this example, you will need to create or use one or more templates. Templates also require that you have a recipient record (targetObjectId) (e.g., Contact, User, . . .) which must also pre-exist. You will be required enter the ID for that record as the (targetObjectId). Additionally if you intend to test merge fields (RelatedTo) with your template, you must also pre-create the related object record and have available the Id for that record as an ID for the Record Object Id (RecordId).

If you use the default test templates (sendHTMLEmailTest) the Target ID should be a ContactId and the Related Record should be an AccountID.


Name Or LabelTypeDescription
contentDocumentAttachmentsList<ContentDocumentLink>(or Collection of ContentDocumentLink in Flow)
Related Record ID(whatId/recordId) String If you specify a contact for the targetObjectId field, you can specify an optional whatId as well. This helps to further ensure that merge fields in the template contain the correct data. This is used for merge fields and for associating activities and attachments.
SendBCCtheEmailAddressesFromThisCollectionOfContactsList<Contact>(or Collection of Contact in Flow)
SendBCCtheEmailAddressesFromThisCollectionOfLeadsList<Lead>(or Collection of Lead in Flow)
SendBCCtheEmailAddressesFromThisCollectionOfUsersList<User>(or Collection of User in Flow)
SendBCCthisStringCollectionOfEmailAddressesList<String>(or Collection of String in Flow)
SendCCtheEmailAddressesFromThisCollectionOfContactsList<Contact>(or Collection of Contact in Flow)
SendCCtheEmailAddressesFromThisCollectionOfLeadsList<Lead>(or Collection of Lead in Flow)
SendCCtheEmailAddressesFromThisCollectionOfUsersList<User>(or Collection of User in Flow)
SendCCthisStringCollectionOfEmailAddressesList<String>(or Collection of String in Flow)
SendTOtheEmailAddressesFromThisCollectionOfContactsList<Contact>(or Collection of Contact in Flow)
SendTOtheEmailAddressesFromThisCollectionOfLeadsList<Lead>(or Collection of Lead in Flow)
SendTOtheEmailAddressesFromThisCollectionOfUsersList<User>(or Collection of User in Flow)
SendTOthisStringCollectionOfEmailAddressesList<String>(or Collection of String in Flow)
Template LanguageStringUsed in conjunction with Template Name, Finds templates with the name matching Template Name for ‘Language=”xxx_YY”‘ in the Description.  Template Selection criteria order first found Name with: 1)If empty, Org LanguageLocaleKey 2)Language found in Description 3)First without ‘Language=”‘
Template NameStringUsed in conjunction with Template Language. Finds templates with the name matching Template Name for \’Language=”xxx_YY”\’ in the Description.
Template Target Record IdStringIf you are passing in a template Id, you need to also pass in the Id of context record. It can be a Contact, Lead, or User. It will determine which data gets merged into the template’

Related Actions


Unofficial SF releases generally come in two flavors: Managed and Unmanaged. Unmanaged packages allow you to see and (if necessary) customize the source code for the components, but have the disadvantage that they may not be upgradeable.

If you are having trouble updating/upgrading the component, you may want to look at: Tips & Tricks – Update/Upgrade an Unmanaged Package

WARNING!!!! For Releases after 1.33 (1.33.1 and higher) Email activities will no longer be saved in the Activity stream unless explicitly using saveAsActivity = true. If you wish to use that feature and did not explicitly specify, you will need to edit your existing flows and add the explicit, “true”.

  • 1.33.1 Unmanaged sendHTMLEmail (with Flow Examples/Tests) – Minor update Addresses issues  #308 and #316 to fill in Task Comments and Recipients and improved documentation.
  • 1.33.1 Unmanaged sendHTMLEmail(Without Examples) – Core Component without Examples/Flow Testing (Added documentation, validations)

Old versions

Notify of
Inline Feedbacks
View all comments
Evan McHugh

I’m excited to be able to use this. however my instance is Spring ’20 and installation is consistently failing on the managed versions with an error “No such column ‘LastViewedDate’ on entity ‘Account’. I was able to install the managed version, however the apex action isn’t showing up. Anything I’m missing from install instructions?

Anna Proviz

Hello, I have tried to install, both versions – with and without examples etc. to our Salesforce and get this error: This app can’t be installed. There are problems that prevent this package from being installed. Apex compile failureApex class opportunityFillProdcts: line 13, column 14: Variable does not exist: Administrator__cApex compile failureApex class opportunityFillProdcts: line 15, column 18: Variable does not exist: Administrator__cApex compile failureApex class opportunityFillProdcts: line 18, column 29: Variable does not exist: Administrator__cApex compile failureApex class opportunityFillProdcts: line 24, column 14: Variable does not exist: Administrator__cApex compile failureApex class opportunityFillProdcts: line 26, column 25: Variable does not… Read more »

Alex Edelstein

This component doesn’t have anything to do with ‘opportunityFillProdcts’, so what’s happening is that you’ve got some invalid apex on your org that’s generating those errors. It’s going to block _all_ package installation, so you want to figure it out. The most straightforward thing to do, if you can, is uninstall that apex class opportunityFillProdcts. Alternative, figure out why it can’t find that variable.

Anna Proviz

Hi Alex,

Thanks for your quick reply.

We don’t have a class called “opportunityFillProdcts”.

Any another suggestions?

Thanks in advance,


Jack Pond

Anna, When you do the install, it is highly likely on install that other test classes or triggers are being run that are not related to this component. opportunityFillProdcts is likely either a custom Apex Class that is either being run as part of another Apex Test Class or a trigger that is being executed. Either may be part of another installed package. You should be able to see this class (in lightning) as a system administrator using Setup–>Custom Code–>Apex Class. If it does not allow you to see the code, then it is part of another installation package. You… Read more »

Anna Proviz

Hi Alex,

Thanks for your reply again 🙂

I understand what you say but we don’t have any managed or unmanaged apex class called “opportunityFillProdcts” I looked in the Apex classes.


Please add a warning at the top of this page that the Send HTML Email component can only send a maximum of 10 emails per transaction (which often equates to a limit of 10 emails per flow).

Jack Pond

Good point @davcondev, we are adding MassEmail support with 1.33.2 (Summer ’20), but some of the limitations are still organizational. For example, you can only send 10 for ANY dev, scratch, . . .


The simple Email action already has an option to send Email Addresses (comma-separated) and use vairables is there a way to do that here?

Alternatively, is there a way to add people in the cc contacts without the data being hardcoded? Currently, when adding the Assignment the Value field only takes constants. It doesn’t seem to work with Record (Single) Variables, Collection Variables or Variables. 

Shawna Richardson

are there any workarounds to add an image to the text template? I did read that the image insert isn’t working, I’m assuming this is still the case as I’m unable to get it to work.

Jack Pond

I have never been able to get the text template working with images. HOWEVER, I have had MUCH better luck using the Lightning EmailTemplate. Might just mean I’m not smart enough or there’s some trick, but the new Lightning EmailTemplate makes it a piece of cake.

Shawna Richardson

Unfortunately I need to merge fields from objects other than lead and/or contact, so I don’t think this will work for me because I can’t figure out how to merge fields from opportunities.

Jack Pond

I can’t get this to post an image here, but opportunity is one of the pull-down options in the Email Template Related Entity Type field.

Last edited 1 month ago by Jack Pond
Shawna Richardson

on the lighting email template? The only related entity field options I have are contact/lead. If I’m using the this package, I can pull in oppty fields but can’t get an image to display.

Shawna Richardson

What’s weird is in the image above for his example for rich text he shows an image.

Alex Edelstein

The problem here is that you can insert an image but it doesn’t get properly extracted from the Text Template and converted to HTML. It also doesn’t properly get packaged for use in Change Sets. On our list to fix.

Lisa Mensink

I have a question about the HTML Body functionality. I would like to create a dynamic email “template” using flow, where the field from a new Lead displays in the “follow-up email” only if there is some data in the field. Empty fields do not display in the email.   I want the labelled lines with field data in the email to be separated by <br> tags, as I am adding the fields one by one with flow logic and need to add each one on a new line. Can I create a text variable with HTML tags in it,… Read more »

Jack D. Pond

Lisa, you piqued my curiosity. Copied (Send HTML Email Testflow) and saved as a new flow (TestForLisa). I added the following formula(
“<H1>This is a test</H1><br/>UserID: “+{!UserIdRunningFlow}+”<br/><p>Thank you!</p>”
that incorporated yet another formula: {!UserIdRunningFlow} which is basically nothing more than {!User.Id}
I then modified the Action to use this formula and turned off the plaint text body.
Got the following results in the email (Properly formatted, just can’t show that here):
This is a test
UserID: 0059A000002QSdY
Thank you!
Was this what you were looking for?

Last edited 1 month ago by Jack Pond
Lisa Mensink

If it turns out properly formatted, using the tags, I’m all set! (Your comment above wasn’t able to show a new line when it was tagged as such, but obviously it was not showing the tags in the result.)   Just before reading your comment I had just installed the managed package (confusing, since “Winter 20” is under “Old Versions” and I was looking for a “current” version) to try it out myself. I am not seeing the new “Send HTML Email” option (shown in the video) when I try to create a new Action. When I try to create… Read more »

Jack Pond

Lisa, I would recommend:
1.33.1 Unmanaged sendHTMLEmail (with Flow Examples/Tests) – Minor update Addresses issues #308 and #316 to fill in Task Comments and Recipients and improved documentation. You may have to manually uninstall the managed package first.

Last edited 1 month ago by Jack Pond
Lisa Mensink

Thanks for your help, got the package working. One more question: Is there a way to use a Public Group as the email recipient. OR is there a way to build a node into my Flow such that I can bring the members of my Public Group into, say, a collection variable, then loop through and string them together into a variable to put into the recipient field? I don’t want to hard code a list of recipients. This group is all over the place and I don’t want to hard code their emails and have to update everywhere. I… Read more »

Gidi Abramovich

Lisa Hi, I’ve created a Subflow that sends an email to the members of a specific Public Group (the admins Public Group). This way, I can reuse it whenever I like.   In order to create it, I’ve used only 2 elements: ‘ExecuteSOQL‘ Apex Action – Inside the ‘soqlQuary’ you need to add a Variable/Text Template with the query (such as: Select Email from User Where IsActive = true and Id IN (SELECT UserOrGroupId from GroupMember where Group.DeveloperName ='[Public Group API Name’)) Send HTML EmaiL– define the Subject and the Body, and add the Apex Action’s output in the ‘SendTOtheEmailAddressesFromThisCollectionOfUsers’… Read more »

Alex Edelstein
Lisa Mensink

Everything is working, and I now have the dynamic Lead follow-up email I’ve been wanting, displaying only the fields with content. I wrote my own flow loop through GroupMembers of the Public Group input to create a collection of email addresses to send the email to (wrote it before I saw your answer). Thanks for all your help and for this much-needed functionality that is allowing me to pare down proliferating workflow rules by using this dynamic flow functionality. Also thanks for your shout-out to this helpful site in your Release Readiness Live presentation! Looking forward to using the HTML… Read more »

Sujatha M

I get the following error message when I use the SendHTMLEmail : An Apex error occurred: SendHTMLEmail.InvocableActionException: SendEmail failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_OR_READONLY, Not profiled to access this Org-wide Email Address: []
|FlowActionCall|SendHTMLTEmplate .. Is there a documentation for troubleshooting ?

Jack Pond

This is a permissions error on your Org-Wide Email address, which usually means whatever user is running the process doesn’t have access to that address – check your sharing. Which version are you using? (all > 1.3x.x use without sharing, so you shouldn’t be seeing this)

Chase Kaiser

Hi Jack, I am using version 1.33.1 and I am also receiving this error when trying to send from a scheduled flow.

Gidi Abramovich

I’m looking for a way of sending an email to multiple recipients on Custom Object by using an Email Template.
Is there a way of doing it?

Jack Pond

Hey Gidi,   I know this is confusing and we are trying to make it less so in 1.33.2, but   1.33.1 Allows bulkification of sendHTMLEmail. You can loop through and send to each recipient using templateTargetObjectId(“Template Target Record Id”) you can add merge fields from the recordId(“Related Record ID(whatId/recordId)”). Note: the target id is the contact, lead, or user to which the email will be sent. The related record Id has the merge fields of your custom object of any of the following types: Account Asset Campaign Case Contract Opportunity Order Product Solution Custom   With Dev and Scratch Orgs… Read more »

Last edited 1 month ago by Jack Pond

Yeah, i’m hitting limits with this in a scheduled flow. I’m not using an email template, but a text template in the flow. Were you saying the action can handle more than 10 executions in a single run if I used an email template instead? I just need this to work for more than 10 different emails (with different attachments and different recipients) in one run

Jack Pond   10 per invocation is definitely the limit for SingleEmail Messaging (used in sendHTMLEmail 1.33.1), though if the request could be bulkified, theoretically could do 10 requests of 10   1.33.2 has both MassEmail and SingleEmail messaging, but adding that made the parameters so complex that realistically no one can understand it, so it hasn’t been released. Working on Custom Parameter Editor for Summer ’20 release, but I can’t figure out whether or not MassEmail is going to help limits through bulkification in either scenario (yet). Haven’t tested it in a prod environment, though I can tell you in… Read more »

Josh Dayment

I am using this action to send multiple emails to multiple recipients using a loop and a dummy action to overcome the 10 limit. In the screenshot I am taking a list of “candidates”(really community members/users) and sending each one an email using a template in this use case. The dummy action is just that its a dummy apex action that breaks up the look and the consecutive transaction to overcome the 10 emails per transaction since its a new transaction each time. You can also use a wait/pause in an autolaunched flow to do the same thing.

Last edited 1 month ago by Josh Dayment
Josh Dayment


Jack Pond

Now THAT is a brilliant workaround. Thanks for posting – been noodling this one for a while!

Gidi Abramovich

Jack Hi,
Thank you for your answer, but I’m still confused 🙁
I want to send an email to a group of recipients while using merging fields from a custom objects’ Email Template.
I can create a Record Collection that will include my recipients information, but how can I use it?
As per my understanding, the ‘Template Target Record Id’ can be a Contact, Lead, or User.
Regarding ‘Related Record ID(whatId/recordId)’ – it says that I need to add a Contact.
So how this can be achieved?

Jack Pond

If you want to use a Related Record Id, you also MUST use a Template Target Record Id. sendHTMLEmail was originally written to only send one message at a time. With that said, the only way you can do this right now is to specify a single templateTargetObjectId with a matching recordId(‘Related Record ID(whatId/recordId)’). For sending multiple messages with this flow, I would recommend you look at
Josh Dayment’s solution above (for now).

Gidi Abramovich

Thank you, Jack, for your answer.
I understand now that this is a limitation.
I have a different workaround since Josh’s solution looks a bit risky for my requirement since I need an activity to be created on each record.
So I am using a generic Flow template, without merging fields.
By the way, for those of you who are looking for an asynchronic solution – I think it is possible to use Mass Action Scheduler by Doug Ayers and limit the batch size to 1.

Last edited 1 month ago by Gidi Abramovich
erik lopez

I love the idea of this action and am very close to implementing it. However, ever time I send my email template, and add the related to record Id, I get this error:
Error Occurred: An Apex error occurred: SendHTMLEmail.InvocableActionException: SendEmail failed. First exception on row 0; first error: INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.: [whatId, 0062900000BpWYX]
the Target Id field I am using is the opportunity owner and the related Id field is for the opportunity that started my flow. How do I resolve this?

Jack Pond

This component uses. This has the following limitation:
If you specify a contact for the targetObjectId field, you can specify a whatId as well. This field helps to further ensure that merge fields in the template contain the correct data. The value must be one of the following types:

  • Account
  • Asset
  • Campaign
  • Case
  • Contract
  • Opportunity
  • Order
  • Product
  • Solution
  • Custom

The message is a platform error message (not a component error message). It seems to intimate that you cannot add a related record (WhatId) if you are sending to a UserId. I will look into this, but it kinda caught me unaware too.

Last edited 1 month ago by Jack Pond
erik lopez

Oh! So if I understand what you are saying correctly, if I specify a contact (maybe a dummy Id or something) this then should work with the opportunity I put in the whatid/recordid space? Ill give that a go! Thanks for the quick reply, Jack!

Jack Pond

Great attitude Erik!
That’s why we love SF. There’s usually a workaround once we find why it isn’t working. Formula field workarounds are often helpful too.

erik lopez

Jack! That totally worked! I put in a dummy contact id in there and I was able to go ahead and send out my html email. However, it is weird that I can’t send the HTML email to my opportunity owner by specifying that in the TargetObjectId field. Weird. But thanks for helping me puzzle that out!

Micah Perry

Where did you put this dummy contact Id? I’m running into the same issue and I can’t resolve it.   I have my custom object record in “Related Record ID(whatId/recordId)”   I have “saveAsActivity” set to False.   I have “Template Target Record Id” set to my custom object created By User Id   And I have “templateID” set to my email template record Id.   I continue to get the error message:   “Error Occurred: An Apex error occurred: SendHTMLEmail.InvocableActionException: SendEmail failed. First exception on row 0; first error: INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.:… Read more »

Jack Pond

We ran into this over the weekend. Though it is not documented anywhere I could find, apparently you cannot use a Related Record ID(whatId/recordId) if your ‘Template Target Record Id’ is a User. See the above chain for a workaround.

erik lopez

The other issue I am running into is when I use a lightning template. When I specify my template as a lightning template, I get this error:   SENDHTMLEMAIL (APEX): Notify_BP_Contacts Inputs: recordId = {!Get_Current_Opportunity.Id} (0062900000BpWYXAA3) saveAsActivity = false SendCCthisStringCollectionOfEmailAddresses = {!collectedEmailAddress} ([]) SendTOtheEmailAddressesFromThisCollectionOfContacts = {!Get_All_Contacts_That_Can_Be_BP_Notified} ([Contact (0032900000WSnsOAAT)]) SendTOthisOneEmailAddress = templateTargetObjectId = 0032900000WSnsOAAT templateID = 00X29000000F2GAEA0 Error Occurred: An Apex error occurred: SendHTMLEmail.InvocableActionException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, We don’t recognize the field prefix Account. Ensure that you are using an associated record when sending the email.: []   Am I using the right… Read more »

Jack Pond

Same type of problem as above, different field (targetObjectId):
Required if using a template, optional otherwise. The ID of the contact, lead, or user to which the email will be sent. The ID you specify sets the context and ensures that merge fields in the template contain the correct data.

erik lopez

Ok Ill try a few more things out. As always, thanks Jack. I appreciate the response. This has been super helpful 🙂

Timothy Williams

I am trying to set up a simple email with attachments flow. I want to get the record, attach files, use a template, and send it based upon a criteria of status. I have tried, but I am not sure how. I looked at the examples, but I don’t see how they pull the attached documents from the record. Would appreciate any assistance.

Steven Hamilton

Hi guys, Great solution, thank you for making available to the community!   One issue I’m experiencing – it could be me, so apologies if it is!! However I don’t seem to be getting the attachments linked to the activity which is being created to log the email send. Is this expected?   I am receiving the attachments in the email itself, but I’d like this capturing against the activity as well. I have SFDC setup to send all files as attachments up to the SFDC limit – so this could be part of the behaviour, so could the activity… Read more »

Steven Hamilton

Thinking more about this, or at least return the ID of the activity that is created so I have the ability to update the task how I see fit…

Jack Pond

Great Idea – I’ll add the taskId (if any) to 1.33.2, Enhancement Issue #392.

Last edited 29 days ago by Jack Pond

[…] can provide Send Rich Email with a collection of Email addresses, but how do you get that information out of a Public Group? […]


It seems as though, with 1.33.01, I could pass in a null collection of Contacts to the TO SendTOtheEmailAddressesFromThisCollectionOfContacts along with a single email in the SendTOthisOneEmailAddress and the email would work most of the time. Sometimes our collection has Contacts and other times it is empty. With 1.33.1, it seems I can no longer pass a null collection. Is that confirmed, planned functionality? I am afraid doing a Decision node in Flow for each of the ‘send email’ actions (~20) would be unwanted and cluttering work, if the package could just check for null and ignore it if null.… Read more »

Jack Pond

I successfully ran a test with 1.33.2 which had valid subject, plain text body, SendTOthisOneEmailAddress, and SendTOtheEmailAddressesFromThisCollectionOfContacts = null
Email message was received. Could you run a debug and show me the debug output for SENDHTMLEMAIL with the failure conditions set? Thanks
How the Interview Started
Jack Pond (005R0000006cd7m) started the flow interview.
plainTextBody = Testing
SendTOtheEmailAddressesFromThisCollectionOfContacts = null
SendTOthisOneEmailAddress =
subject = Testing Null Contacts
templateUsed (null)
errors (null)
taskId (null)
isSuccess (true)


Thanks Jack, happy to … where/how do i install 1.33.2?

Jack Pond

Ryan, just run the same test with 1.33.1 – that part of the code wasn’t changed (I think).


The issue seems to be with 1.33.1 After I added contacts to the collection, it worked. Before, here was the error:
recordId = {!recordId} (a083C000003zT7fQAE)
plainTextBody = {!txt_introToListingAgent_buyerSide} (Hi…)
saveAsActivity = true
SendCCtheEmailAddressesFromThisCollectionOfUsers = {!colAgent_Users} ([User (0056A000001LSsIQAW)])
SendCCthisOneEmailAddress = {!Agent.Email} (phil@***.com)
SendCCthisStringCollectionOfEmailAddresses = {!listingAgentsCcList} (null)
SendTOtheEmailAddressesFromThisCollectionOfContacts = {!listingAgents} (null)
subject = {!txt_subject_Intro} (Congrats, We’re Under Contract!)
UseSalesforceSignature = {!c_useSignatureTF} (false)
Error Occurred: An Apex error occurred: System.NullPointerException: Attempt to de-reference a null object

Jack Pond

saveAsActivity = true, can’t save activity if no object. Is what’s causing the problem. Any ideas on how to remediate? something like check to see if any objects were specified, gotta noodle this one.   setSaveAsActivity(saveAsActivity) Optional. The default value is true, meaning the email is saved as an activity. This argument only applies if the recipient list is based on targetObjectId or targetObjectIds. If HTML email tracking is enabled for the organization, you will be able to track open rates.   After further looking at this, prior to 1.33.2, saveAsActivity conflated two different functionalities, the ability to save the email activity on the… Read more »

Last edited 27 days ago by Jack Pond

Thanks Jack. I have the Related Record ID(whatId/recordId) set to log the activity to the record that the flow is running on (i.e. recordId), which logs successfully, on the record when the flow finishes successfully, with at least one Contact in the SendTOtheEmailAddressesFromThisCollectionOfContacts. The email is not logged on the contact. But, if the SendTOtheEmailAddressesFromThisCollectionOfContacts is null, it doesn’t work, so it doesn’t seem related to the saveAsActivity.

Jack Pond

There’s a very simple way to test this. Could you Set saveAsActivity to false and see what you get?


Weird. Now it’s working with null collections (SaveAsActivity still TRUE). Sorry for the false alarm.

Jack Pond

NP, and that IS weird, but stuff like that happens to all of us. Working on 1.33.2 and will have it available ASAP.


I think this is just awesome! I haven’t tried all the functionality that comes with it but I just passed a list of emails and a rich text and work perfectly!!
Thank for all of this amazing tools for flows.


Just one thing. I set a list of contacts and the save Activity but received the following:
Error Occurred: Unable to convert value ‘Tue Jun 16 18:20:58 GMT 2020’ to Apex type Datetime for Apex action SendHTMLEmail field Contact.LastModifiedDate
Assuming I need either whatIds or TemplateIds right?
Thank you guys!!

Jack Pond

Hey Paulina, you got me on the “unable to convert time”, and frankly I’m a little awed you got there. Could you do me a favor and run this in debug mode and copy the results before and after you hit the sendHTMLEmail action? If you are using saveActivity you MUST also use ‘Related Record ID(whatId/recordId)’. This is because we conflated Email Activities and Task Activities with Email in <1.33.1 – and (since I’m not close enough for you to hit me with anything you could throw), the separation won’t be fixed until 1.33.2. In the mean time, if you… Read more »


I will and let you know! i just saw this, not getting notification sorry. I am testing this again in another sandbox and I will debug the code to see what might be the problem. Just so you know that maybe will give some idea, we are using CEST but I don’t think that might make a difference.


How can I manage to install the package in my sandbox?


Copy the URL link for the install and change the ‘login’ at the beginning to ‘test’ and then login with your sandbox creds.

Jack Pond

Serge, when logging in for installation, you may also have to choose “Log In with a Different Username” in the login, then “Use Custom Domain” and enter the URL of your sandbox.

Last edited 25 days ago by Jack Pond

Hi Jack,

I think I have missed something on installing/setting up the unmanaged package, but for some reason the body of the email template doesn’t populate in a test email.

  1. run flow: Send HTML Email Testflow (also tested own version)
  2. select option 4 (send email template)
  3. input Template Id, lead record id in targetobjectid, send display name and subject

All information pulls through apart from the body in the received email. Have I missed something obvious?

Could you assist please?

Alex Edelstein

I believe the Body field of the Send Rich Email action will overwrite the body content of your template if it has a value, so make sure it doesn’t, if you want the template’s body to be used.

[…] discussed in the Email Templates section of the Send Rich Email action, Salesforce Lightning Email Templates have an ability to merge data in dynamically, but […]

Bobby K

I am using v1.33.1 and can’t get attachments into the apex action using old school attachments. V1.2 mentioned attachments support, but my collection variable with attachment records is not available for selection unless I change it to a record variable rather than a collection. Any idea why that could be the case?

Jack Pond

Bobby K, today has been a blur for me – will try and look at this tomorrow, but if you’d like to dig a little deeper yourself, I would start looking at the requirement that attachments need to be CDL (Content Document Links), as passed in contentDocumentAttachments. The attachment example in the test flows would be a good place to look at how that is done.

Bobby K

Hi Jack – thanks for the quick response! I think I am just misunderstanding the capabilities…Attachments from the old Notes & Attachments wouldn’t have CDLs (I don’t think). I guess this is extra motivation to go through the conversion over to Files. Thanks!


The emails I’ve sent doesn’t appear as activity in the related record page. Anyone else got troubles with it? :/

Alia Burdick

Hi there! Such a great resource. Implementing for my first solution and have a question on the ActivitySave parameter. When I set this to TRUE it appears that 3 different tasks are getting created for each email send (I am also leverage Classic email templates). Task 1: One of the activities has the Subject “Sent Email: [merge fields from subject line on template] … ex: Sent Email : {!advpm__Matter__c.Loan_Number__c} – {!advpm__Matter__c.Name_of_Borrower__c} to recipient(s):“ There is no additional data saved in the task and the status is Open so it is appearing in my Upcoming and Overdue task list. Its… Read more »

John M

Jack P, we are getting two tasks created, Task 1 and Task 2 in Alicia’s comment. Task 1 for us has status Closed, but is probably Open at some point as users are getting Task Completion update reminders for these.

Can we get Task 1 removed completely? It is redundant to the more informative Task 2 that has the email contents.

Edit: To be clear, Task 2 is actually the Message Activity entry, not a Task. I will test with options to see what is produced in different configs.

Last edited 17 days ago by John M
Jack Pond

There are multiple issues that require addressing on this. Specifically, sendHTMLEmail – Separate Email Activity from Email Task Activity The Class development work has already be done and is available in, but the new parameters are undocumented, and, frankly, to complex to be meaningfully useful. I think I’m going to take a couple days off work and get this done. This keeps popping up, but is dependent on sendHTMLEmail CPE For Summer ’20 Release , which I have not done yet.

Last edited 17 days ago by Jack Pond
Joel McDonald

Just adding my a comment to say I just ran into the same issue where a sent email is logged, but an open task is also created.

Jennifer Sanchez

Love this! And very helpful documentation!! Just installed and configured yesterday and I am trying to send 4) Email Using Template – An email using a Lightning EmailTemplate. There are no errors, email sends and logs an activity to the related record. My only issue is that the body of the email is blank? The LE email template is related to a contact and an opportunity. I can manually send it from SFDC but through the flow the body displays blank. Even when I send through the screen test flow, the body is blank. Am I missing something? besides part of… Read more »

Jack Pond

Jennifer, have you checked to make sure HTML Body and Plain Text parameters are both null, and that you (or the effective user when running the flow) have access to the opportunity you are using as your relatedto record? (and there’s nothing wrong with your brain – I think we’ve all run into this one)

Last edited 17 days ago by Jack Pond
Jennifer Sanchez

Hi there, thanks for your reply! HTML Body and Plain Text parameters are both null and the flow is running in system access to all data, and I am sys admin with full permissions. So it works in prod and does not work in sandbox. The main difference is that sandbox is summer 20. I am using SendHTMLEmail version 1.33.1. Is this the latest version? or any issues with summer 20? Thank you!

Jack Pond

Jennifer, development for 1.33.1 was done on Summer ’20, and the scratch orgs don’t seem to be having this issue. HOWEVER, these are the type of anomalies that sometimes come back to haunt us, so if you find out why (or even if always) this issue is arising, please drop a note. Have you tried enabling Enhanced Email on the sandbox? (Settings–>Enhanced Email)

Jennifer Sanchez

Hi Jack, the issue was related to setting the subject line in the component and already having the subject line set in the email template. Apex seems to not know what to do with it and sends a blank email. So lessoned learned, don’t set the subject line if you are sending and html email template. And thanks for your help! This was annoying to figure out. lol!

Jack Pond

Jennifer, THANKS! Will consider adding a check to see if subject line in both places. Worst case, you’ve helped others figure out how to fix. Thank you!

Jennifer Sanchez

Never mind. I figured it out. The issue is related to sandbox. There must be some setting preventing the email body to display. I just tested in prod and it works as expected.

[…] how you can use community built flow actions – in this post, we will use the Send Rich Email (Send HTML Email Action) – to enhance the power of flow from […]

Paul Carass

Hey Alex, I have tried to utilize this Action in a Field Service Flow. It works fine when I’m debugging on desktop, but as soon as I test it on the Field Service Mobile App, I am getting an error on the screen (See Attachement) stating that “Access to entity ‘ContentDocumentLink’ denied” What’s strange is that I’m not referencing any Content Document Links in my flow. The only place where the option to, is on this email action, and that is turned off. I had tried putting a global constant of ‘False‘ into that area, but that’s not even supported.… Read more »

Alex Edelstein

Field Service Flows can’t run Flow Actions at all, unfortunately. (

You can work around this by breaking things into two parts. Use the Field Service Mobile flow to create a custom record that stores the content, or references to the content, that you want to email. Then use the new Record-Change Triggered Flow type in Summer ’20 to trigger whenever one of these records is created, and call Send Email there.

Paul Carass

Thanks Alex. That’s cool.
I ended up splitting it into two parts. The Field Service Flow is creating a Product Transfer record. So the piece at the end of my FSL Flow with the Send HTMl Email, I migrated to a standalone auto-launched flow, fired off by Process Builder upon creation of a Product Transfer Record.

Have you much involvement with the Field Service Flow product?
Do you foresee it coming on par with standard flows in the near future? It seems to have so many limitations.

Elad Asulin

Hi guys, thanks for a magnificent package!

I am having issues including email templates. I have tried to use both classic and lightning email templates with no luck whatsoever. No matter what I do I get output template null result. I am including it here. any ideas?

SENDHTMLEMAIL (APEX): Send_Email_To_Patient
contentDocumentAttachments = {!Get_CDLs_0} ([ContentDocumentLink (06A4H00000HcAVTUA3)])
recordId = {!Get_Contact_Id.Account.Id} (0014H00002f7Av2QAE)
replyEmailAddress =
senderDisplayName = Tali Test
SendTOthisOneEmailAddress = {!Get_Contact_Id.Email} (
subject = Nerivio Test
templateTargetObjectId = {!varContactId} (0034H00002G0g6EQAR)
templateID = 00X4H000002OyHEUA0
templateUsed (null)
errors (null)
isSuccess (true)

Jennifer Sanchez

Don’t include the subject line. I ran into the same issue. See comments above from Jennifer Sanchez.

Elad Asulin

Thank you Jennifer you are a life saver!