3

I have developed a flow which will sends an email when a contact is created or edited using default email functionality (i.e. 'Send Email' action in flows as I don't want to use Email alerts via workflow or other options). The same Flow also contains an option to upload the Images using 'File Upload' feature.

As per my requirement, I need to send a welcome email along with the uploaded attachments to the contact who is an external contact and doesn't have a salesforce login. Any thoughts on the approach will be helpful.

Reference link to create contact & upload attachments is https://jenwlee.com/2021/02/01/view-the-uploaded-file-list-after-uploading-the-files-via-screen-flow/

1 Answer 1

7

You can't do this out of the box with Flow Send Email action (or any declarative automation tool).

The best you can do within strictly Flow (no invocable apex), is add a public link within your email body. You'd do so by creating a ContentDistribution for your files - which would then allow you to retrieve the DistributionPublicURL to include in the body of the email.

(Note: this is assuming these are all new files uploaded through your flow, if they're existing files you may want to check if a ContentDistribution record exists for the file already if someone has generated a share link in the UI).

When creating a Content Delivery (ContentDistribution) record, you'll want to pass the ContentVersionId of the file, set a Name, as well as set preferences on the behavior of the link to meet your needs

  • PreferencesAllowOriginalDownload
  • PreferencesAllowPDFDownload
  • PreferencesAllowViewInBrowser
  • PreferencesExpires
  • PreferencesLinkLatestVersion
  • PreferencesNotifyOnVisit
  • PreferencesNotifyRndtnComplete

After creating it, you'll want to re-query it to get the generated URL in DistributionPublicURL to add to the body of the email. In the Flow, it'd look something like this:

enter image description here


For doing this with attachments on the email, you'd have to use invocable apex to send the email.

If that's a blocker for you, unofficialsf has a Send Better Email Flow Action that has done the work above (apex invocable) already and adds lots of other features. Unlocked package install link is at the bottom of their page.

If you've used any of their packages before, you can simply follow the instructions. You'd just get any ContentDocumentLink records you uploaded and pass the collection of them into the relevant input of the flow action.

Note: It seems it's dependent on the following basepacks being installed beforehand if you've never used their packages

  • Flow Actions BasePack
  • Flow Screen Components Base Pack

If the above is too heavy for this (hesitation to install a lot of components) - you can take a look at their source code and just take the relevant pieces to do yourself. You can see the source code for the unlocked package. I've listed relevant apex classes below and all code snippets provided are copied from the source code:

If you're only interested in adding attachments to email, then you'd pay closer attention to how they do it in apex. The Ids you provide to their LWC action takes ContentDocumentIds (a collection) in a variable called contentDocumentAttachments.

In SendBetterEmail, it simply loops through all the ContentDocumentLink records to add the ContentDocument Id to a set of Ids

 if (curRequest.contentDocumentAttachments != null) {
     for (ContentDocumentLink contentLink : curRequest.contentDocumentAttachments) {
          contentDocumentIds.add(contentLink.ContentDocumentId);
     }
 }

It then uses sendBetterUtil.getMapContentDocumentIdByContentVersions() to do as the method implies, get the relevant content version per ContentDocument Id you provided.

public static Map<Id, List<ContentVersion>> getMapContentDocumentIdByContentVersions(
    Set<Id> contentDocumentIds
  ) {
    Map<Id, List<ContentVersion>> mapContentDocumentIdByContentVersion = new Map<Id, List<ContentVersion>>();
    for (ContentVersion cv : [
      SELECT
        Id,
        PathOnClient,
        Title,
        VersionData,
        VersionNumber,
        FileType,
        ContentDocumentId,
        FileExtension
      FROM ContentVersion
      WHERE ContentDocumentId IN :contentDocumentIds
    ]) {
      if (
        !mapContentDocumentIdByContentVersion.containsKey(cv.ContentDocumentId)
      ) {
        mapContentDocumentIdByContentVersion.put(
          cv.ContentDocumentId,
          new List<ContentVersion>{ cv }
        );
      } else {
        ContentVersion lastFound = mapContentDocumentIdByContentVersion.get(
          cv.ContentDocumentId
        )[0];
        if (lastFound.VersionNumber < cv.VersionNumber) {
          mapContentDocumentIdByContentVersion.get(
            cv.ContentDocumentId
          )[0] = cv;
        }
      }
    }
    return mapContentDocumentIdByContentVersion;
  }

It then takes both the list of ContentDocumentLink records provided and the map built above to add attachments to the SingleEmailMessage utilized in apex to send email. This is done through setEntityAttachments

public static Messaging.SingleEmailMessage addAttachments(
    Messaging.SingleEmailMessage mail,
    List<ContentDocumentLink> contentDocumentLinks,
    Map<Id, List<ContentVersion>> mapContentDocumentIdByContentVersion
  ) {
    Set<Id> contentVersionIds = new Set<Id>();

    if (contentDocumentLinks != null && !contentDocumentLinks.isEmpty()) {
      for (ContentDocumentLink cdl : contentDocumentLinks) {
        Id contentDocumentId = cdl.ContentDocumentId;
        if (
          mapContentDocumentIdByContentVersion.get(contentDocumentId) != null &&
          mapContentDocumentIdByContentVersion.get(contentDocumentId).size() > 0
        ) {
          for (
            ContentVersion cv : mapContentDocumentIdByContentVersion.get(
              contentDocumentId
            )
          ) {
            contentVersionIds.add(cv.Id);
          }
        }
      }
    }

    if (contentVersionIds.size() > 0) {
      mail.setEntityAttachments(new List<Id>(contentVersionIds));
    }

    return mail;
  }

It then takes the email message (and any other you want) in a list to be sent by Messaging.sendEmail

4
  • 1
    Have an upvote for being honest.
    – identigral
    Commented Feb 25, 2022 at 16:07
  • 1
    The unofficialSF libary is so useful that biting the bullet for the base pack install was worth it for me
    – cropredy
    Commented Feb 25, 2022 at 17:25
  • Hi Kris, Thanks for your time. Is there any option to create link for sharing the attachment which requires no login as I can't go outside of flows.
    – Rv1
    Commented Mar 1, 2022 at 10:18
  • Yes. You can query against ContentDistribution with your ContentDocumentId to get the DistributionPublicUrl to put into an email. Will add an edit Commented Mar 1, 2022 at 12:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .