Hi, it’s been awhile! I’ve been in hibernation mode taking care of my two small kids and watching hours upon hours of videos about machine learning (but that’s a blog post for another day). After thinking about it for a long time, today I finally figured out how to schedule an email from a Salesforce screen flow and I had that spark of inspo to write a blog post. (Almost) no one here (work) will be as excited about the technical footwork (that’s why it’s my job!) but I KNOW folks here (TDAA blog) will be excited and/or find this post later if they have the same problem.
the story
We use Salesforce to manage the process for giving grants to nonprofits. In the past 2 years, we changed our entire grantmaking process from being an “invite only” foundation to being a foundation that releases Requests for Proposals. After proposals are submitted, staff follow a very consistent review process and calendar. We strive to tell all grantseekers good news/bad news on the same day for each cycle. This introduces a crunch for staff – how can you write 100+ personalized emails on the same day? Answer: you can’t.
the disqualified solutions
Salesforce has a couple of different options for Schedule Send emails. Let’s review them and why they didn’t work for us.
- Standard Salesforce Email Action (and Pop Out ability) – we know that we can draft emails in Salesforce and even pop-out and minimize the email window. This is useful for viewing other record pages in Salesforce and then finishing your email. However, there is no “save draft” option and if you log out or refresh the page, you lose your work.
- Save Draft of Salesforce List Email – Salesforce List Email is kind of like the equivalent of Mail Merge. I love it and I’ve used it all sorts of different ways. This lets you save drafts AND schedule send (yay) but unfortunately, you can’t personalize the emails enough. While we could do a workaround with very complicated templates and text fields that spliced custom parts of emails into a franken-email, I’m pretty sure that this would be extremely cumbersome and result in disjointed emails.
- It sounds like Service Cloud (now known as Agentforce Service) has a draft feature, but that is more for approving emails from a quality control standpoint than for schedule-sending your own emails.
- It is possible to have a scheduled path for Record-Triggered Flows but unfortunately, this is not available in Screen Flows. We are not willing to compromise on the Screen Flow aspect of how we do this. Screen Flows are SO SO helpful because we can guide people through multi-step processes (including the email part! but also things like updating fields or creating related records).
- Researching this, Google AI (boooo) suggested a very convoluted option of creating new fields to store dates and running a scheduled, record-triggered flow to evaluate that date and send an email template. This would not work for reasons explained above. Also, storing a date field in perpetuity for sending out one measly email? No thanks!
My team was starting to fear that this just wasn’t possible.
the winning design: a subflow with pause
I knew I wanted to keep as much the same as possible – we already like the Screen Flow that we have for drafting emails, picking recipients, and updating data. We just need to schedule it to send in the future. THAT’s the only thing changing here!
- I’m not including a lot of detail here on building Screen Flows and Email Actions, so if these are new concepts it might be helpful to brush up on them before diving in.
First, I added two, simple components to my screen flow Screen Element where staff are already composing their email body. I also did some optional enhancements like making the “Schedule Date/Time” component conditionally viewable (depending on if the email needs to be scheduled) and changing the label on the “Finish” button.
Tip: Give your Date/Time component a descriptive API name, since you’ll be using it again! I chose: Var_Scheduled_Time.
Next, add a Decision Element (I’ll show you mine below) and two different paths for the two email send behaviors.
Now, my Screen Flow canvas looks like this (Ignore some of the elements that we haven’t discussed yet):
The next step is to create the Subflow that you see in the Schedule logic branch above.
We will be using an Autolaunched Flow for this. Create a new one/
When you have your Flow Canvas open, the first step is to create all of your variables. I knew which variables to create because I could see what was populated in my original “Send Email” action. Here is a picture of my variables (they are all type “text” except for the Date/Time one). It is important to select available for input when you are setting these up.
My Autolaunched Flow has only 2 elements. The first is a “pause” element and the second is a “Send Email” action. Look at how my Pause (“Wait Until Date”) element references the Scheduled Time that we set up in the first Flow and (will) pass into this flow using a variable.
Now is a good time to map all of your variables to your Send Email action as well. You might have different email properties than me… feel free to just configure whatever you need!
Save and Activate this Flow and give it a descriptive name. Mine is “Autolaunch Flow: Send Email”
Finally, you need to configure your Subflow element in your original Screen Flow. Add a Subflow element on the Schedule path. This is where you “connect” the data from your screen flow to the email-subflow-variables. I like to think of this like passing the baton in a track race (while this simile seems pretty universally applicable, I want to assure you that I have never ran in a track race and I have no plans to ever run in a track race).
After the Send Email Later subflow has completed and we delete the “temporary” task record, my decision element closes and we do all of the same record updates that we would have done before.
Enhancements
At this point, I was confident that my Screen Flow was activating my subflow and sending emails at the time that I asked (usually about 5 minutes after the requested time). So this solution already did all of the things that I wanted! However, we quickly realized that there were a few “gotchas” that we wanted to address.
1- There is no easy way to see which records have pending emails. This is a HUGE problem for staff who are setting up 100+ of these and may get distracted. It would be so embarrassing to send the same person 2 emails because we didn’t know we had already scheduled one. To fix this, I created a “Task” record which symbolizes that there is a “paused Flow Interview” in the queue – this is the technical name for what the subflow is doing when it is waiting to send the email. After the email successfully sends, I created a “delete” step in my flow to find the “Task” and delete it. When the email sends, there will be an Email record in the Activity History and the Task record will poof disappear.
2- We realize that after scheduling an email, staff may want to see it and make changes. This system is NOT ideal for this, because once there is a Paused Flow Interview, we can’t change the text in the email or easily display it on the screen. However, in extreme situations, we CAN delete the Paused Flow Interview and allow staff to create a new email. In order to do this, we need the unique ID for the Flow Interview. I mapped this field to the Task record so that a staff member can find this, send it to an Admin, and we can delete the Paused Flow Interview from the queue in the Setup menu.
Learning
1- Scheduling an email and saving a draft are two different things which are often conflated! “Draft” implies that you want to come back to it and make changes. Ultimately, I wasn’t able to do this part of the process with the tools that I have. The design I created is pretty inflexible and requires an Admin to go and delete the scheduled email if the person wants to make changes.
2- The built in fields for sorting Paused Flow Interviews are VERY, very limited. I tried several ‘dead end’ solutions to improve the Flow Interview Label or to link a Flow Interview to a Record Id and so far, none of them worked (hence, the GUID idea). If someone was working with higher data volumes, this could become unwieldy. However, there are no platform limits that I am aware of that would prevent this from working (besides data storage in general).
3- I would say, I’m maaayyyybe “intermediate” when it comes to Flow design. I think there’s a lot more learning I could do regarding chopping Flows into smaller, modular pieces and having more Subflows and fewer Record Triggered Flows with dozens upon dozens of decision elements. Some experts in the field think this is a more elegant solution… I’m not sure what I think yet!
