Salesforce Field Service: Create Batches of Appointments with Service Appointment Generator

Last update: January 31, 2022

Authors: Leigh-Anne Nugent and Christopher Albanese

Watch the Video. Send us Feedback!

Business Requirements 

Customers need to be able to build a solution that supports the following scenarios for teamwork and multi-stage work:

  1. Wanting in day changes to the Crew Member/Job Assignment i.e. a crew member called in sick on Monday and we need to send someone in just for that day
  2. Partial job assignment to a new Crew Member for a single day of the multi-day i.e. tech assigned on Monday but will see the whole week on the mobile app and also doesn’t get alerted or have an Assigned Resource created
  3. When various resources are required throughout the duration of the job i.e. need someone with troubleshooting skills for the first day, then a mechanic the second day, then an electrician the third day (team approach)

This will provide a stop-gap accelerator-style solution that will be an unmanaged package with access to the source code for customers to modify.

General Capabilities and Principles

  • Leverage the knowledge of the dispatcher to generate a collection of Service Appointments (SAs), assigned to designated Service Resources (SRs or techs) by creating Assigned Resource (AR) records. It improves the end-user experience for the creation and maintenance of a large number of SAs which would be administratively burdensome, if not impossible, to do with the out of the box capabilities.  
  • This tool provides an alternative to using the Salesforce Field Service Crew Management and Multiday Work features.  This does not provide an automatic, project-like scheduling tool, it’s intended to enhance multi-resource assignment capabilities.  
  • Generate SAs and Assignments based on the Dispatcher’s direction.
    • Create 2 weeks’ worth of SAs, with the option to include Saturday and/or Sunday, for Gloria and Alan for this Work Order.
  • Generate an ad hoc batch of SAs to staff a night shift for a given period of time.
    • The customer reduced the due date which requires an overnight shift to be added for the job to finish on time.
  • View the SAs for a Work Order and edit them in an easy, spreadsheet-style way.
    • The customer wants the job finished sooner, which means we need to add 2 hours to each SA Duration.
  • Selectively Delete SA and Delete all SAs. 
    • The customer called and says we can’t be on-site for a set of days or wanted to cancel the whole job.
  • Move jobs from one resource to another.
    • Fred is out for 3 days so move a set of his appointments to another Service Resource.
  • Push some or all of the jobs N days into the future or to a new date.
    • The customer says we can’t be on-site for a set of days, so shift all appointments to when we can go back on site.

Phase 1  Features

(MVP) As a Scheduler, I know what jobs my resources are working on. I should be able to:

  • Set the Service Appointment Parameters I need to determine the first date on-site, the last date on-site (or in the batch), the Start Time, the Duration on-site. 
  • When I’m scheduling jobs outside of my Timezone, I want to be able to be clear about what Timezone I am creating the Service Appointments for so that I can properly offset the Start Time in the Service Appointment Creation Parameters screen.  
  • I need to be able to select from a list of Service Resources that have a Primary or Secondary Territory Membership record of the Service Territory of the Work Order (or manually selected). 
  • In the Resource selection list, I want to know if the Service Resources have any existing Absences and/or Service Appointments already assigned to them during the date range selected so I can select the Service Resources that have the most availability.  
  • In the Service Appointment Creation Review list, I need the ability to NOT create some Service Appointments for some Service Resources on some dates because they only need to be on-site for some of the days in the batch.
  • I need all created and Assigned Service Appointments to appear on the dispatcher console as soon as they are assigned and I need any updates made in the dispatcher console to reflect in the data table Service Appointment review screen (and vice versa).
  • I need the ability to create and assign additional batches of Service Appointments that may include night shift and/or off-shift coverage to shorten the elapsed duration of the job. 
  • When I create new assignments, I’d like to be guided by the dates of the SAs that have already been created so I know where to create the next batch of SAs (visibility on the summary table).
  • When I create additional assignments, I’d like to be guided by the overall Work Order Start and End Dates so I don’t create SAs outside of this date range (visibility on the summary table).
  • I want the option to create a single batch of Service Appointments for more than 14 days (up to 16 weeks) if I know I only need 1 or 2 resources to assign work and know I will be well below the tool limits of 1000 SAs in the Data Table.
  • I want to be able to review all of the Service Appointments and Assignments across all of the days so I can see everyone who has been assigned.
  • I need to be able to move all or some of the Service Appointments to another start date so I don’t have to manually update each appointment start date/time.
  • I want to be able to edit the Scheduled Stat and/or the Duration of selected Service Appointments and have the Scheduled End recalculate for me so I don’t have to worry about calculating and updating that field myself.
  • I want to mass delete all or selected open assignments if the job gets rescheduled or canceled to simplify the data management of deleting each one manually.
  • I want to reassign all or some of the open assignments if a resource becomes unavailable (team shuffle) to simplify the data management of reassigning each one manually.

End-User Guide

  1. Create SA Screen
    1. Parameter screen
      1. When there aren’t any Service Appointments for the Work Order, you will be presented with the Service Appointment Parameters including the technicians you want to surface.
      2. The Start Time is presented in the Users Salesforce Time Zone. Consider the TimeZone offset if you are creating Service Appointments in a different TimeZone.
    2. Service Resource selection table
      1. This Data Table will show you all the Service Resources a dispatcher can select to assign work to.
      2. Select as many resources you would want to add to the job.
    3. Service Appointment selection table
      1. This Data Table will show you all draft SAs for the entire duration of the job and for each tech.
      2. Select the SAs to keep; you can select all the rows and deselect the ones you don’t want. 
      3. Can sort by Scheduled Start Date or Service Appointment.
      4. Can inline edit the Scheduled Start Time and Duration. 
  2. Edit SA Screen
    1. When there are Service Appointments for the Work Order, you will be presented with two options: Edit SAs or Create SAs.
    2. Edit SAs
      1. This Data Table will show you all Final SAs for the entire duration of the job and for each tech.  Can inline edit the Scheduled Start Time and Duration. 
      2. You will have three new options as well as a Data Table.
        1. Change Service Resource – Use this feature when you have to shift a set of SAs to new Service Resource.
          1. Select the SAs you would like to reassign in the Data Table.
          2. Select the Service Territory and Skills to build the list of Service Resources to select.
          3. Select the Service Resource from the Data Table.
          4. All Assigned Resource records will be updated to the new Service Resource.
        2. Shift Appointment Dates – Use this feature when you have to shift a set of SAs to new start date.
          1. Input the start date and the end date range of the SAs to move.
          2. Input the new date to shift the SAs to.
        3. Delete Service Appointments – Use this feature when you have to delete an ad hoc set of SAs.
          1. Select the SAs you would like to delete in the Data Table.
    3. Create SAs
      1. You will be redirected to the create Service Appointment parameters screen.
  3. Delete All SAs
    1. Use this when you need to delete all of the Service Appointments.


  1. Datatable presents date/time in the user’s machine settings, not Salesforce User TimeZone or the Service Territory TimeZone. 
  2. The max number of rows of Service Appointments the Data Table can display is 1000 rows.  Keep this in mind when creating your Service Appointment batches. Its recommended to create batches 2 weeks at a time to keep the numbers down for performance.
  3. Validation rules are caught when you try to save the records (you won’t see them in the table).
  4. Any scheduling conflicts will have to be resolved in the Gantt based on rule violations.
  5. You won’t see the list of Skills each Service Resource has in the table.
  6. If you don’t select any rows in the Service Appointment creation table, you could possibly not create any SAs.
  7. It’s not recommended to mass edit the Date/Time fields in the Data Table Service Appointment.  It will update all the records to be the same date and time; you won’t only just update the date value. 
  8. If you back out of the flow or sit in the flow screen for over 10 minutes, you might have SAs in a Draft status until the Delete Service Appointment Triggered Flow comes in to delete them (but this time frame can be changed in the flow).
  9. If an appointment is shifted and crossed a daylight saving transition period, this will have to be manually adjusted as it is not accounted for in the solution.
  10. The Service Appointment edit table is not filtered by status but can be configured if desired.
  11. Consider the implications when the package is retired if/when this feature is added to the Product long term roadmap
    1. It is recommended to document the configuration in detail to then determine if something would require refactoring or removal.   

Developer Guide

Data Model

Service Appointment Fields

  • MR Service Resource – this is the Service Resource that the Dispatcher has assigned. It is used to create the Assigned Resource record when creating a new Service Appointment.
  • MR Parent Work Order – this is the Work Order that owns the Service Appointment.
  • MR Creation Status – Picklist of Draft, Confirmed, Deleted, This is used to drive the creation process as well as the automatic deletion of Draft SAs that don’t get confirmed or deleted (user just exits the flow with completing)

Work Order Fields

  • MR_Estimated_Calendar_Days__c
  • MR_Hours_Actual__c
  • MR_Hours_Completed__c
  • MR_Hours_Created__c
  • MR_Hours_Scheduled__c
  • MR_Hours_To_Be_Assigned__c
  • MR_Hours_To_Be_Created__c
  • MR_Number_of_Techs_Needed__c
  • MR_Total_Hours_Required__c
  • MR_Trigger_Cleanup__c – Used by the time based workflow to delete Draft SAs
  • MR_Trigger_Date_Time__c – Used by the time based workflow to delete Draft SAs

Service Territory Member Fields

  • MR Resource Name – formula field to display Service Resource Name
  • MR Service Territory – formula field to display Service Territory Name



  • MR DT Service Appointment Main (name = Multi Resource Assignment Wizard) – calls Creator, Review and Delete
  • MR DT Service Appointment Creator
  • MR DT Delete Service Appointments – Mass delete all of the SAs for a Work order
  • MR DT Service Appointment Review – Update, Change Techs and Delete selected SAs
  • MR DT Trigger Delete Flow – Time Based flow which deletes Draft SAs that have not been confirmed within 10 minutes (parameter can be changed)
  • MR DT Update sched end time – Record Triggered flow to recalculate SchedEndTime if SchedStartTime and/or Duration change. 

Apex Classes

  • WOSchedulePayload – Class  used to contain the parameters set by the user and pass them to the batch apex job
  • MRDTAssignment – Assigns SAs to their Assigned Resource – called by MR DT Service Appointment Creator
  • MRDTGETSTMs – Returns filtered list of STMs based on Territory and Skills and Start / End Dates
  • MRDTReassignTechs – Called by MR DT Service Appointment Review Flow and used to reassign existing SAs to a new Resource
  • MRDTSchedMultiVisit – called by MR DT Service Appointment Creator and is used to create the SAs initially
  • MRDTDateShift – move selected appointments to a new date
  • MRDTSAValidateUpdate – update any discrepancies between manual updates to SA, like a drag and drop, with the MR_Service_Resource field. return list of SAs to the Review flow along with count of SAs.
  • MRDTGetTimeZoneInfo – returns the timezone offset between the running users timezone and selected service territory’s timezone. This is used by the MR DT Service Appointment Creator flow to generate a warning message to the user if the timezone offset is not 0.

Test Classes

  • WOSchedulePayloadTestClass
  • MRDTAssignmentTestClass
  • MRDTGETSTMsTestClass
  • MRDTReassignTechsTestClass
  • MRDTSchedMultiVisitTestClass
  • MRDTDateShiftTestClass
  • MRDTSAValidateUpdate
  • MRDTGetTimeZoneInfoTestClass


Permission Sets

  • MR DT Permission Set – grants access to all of the fields and classes above

Other Requirements

  • Prior to use, you must deactivate Service Appointment Validation Rule called: Dont_allow_scheduled_or_dispatched

Installation Steps

  1. Install Base and Screen Base packs
  2. Install Datatable
  3. Install the Service Appointment Generator package 
    1. Sandbox Installation Link:
    2. GitHub Repository: 
  4. Deactivate Validation Rule on Service Appointment called: Dont_allow_scheduled_or_dispatched
  5. Assign Permission Set to Users who will use this package: MR DT Permission Set
  6. Add flow to work order page: Multi Resource Assignment Wizard

Optional Configuration Steps

  1. Update Flow Screen messaging to suit your business process 
  2. Other fields to display in the Data Tables to suit your business process

Related Requests, that are not related to the SA Generator solution

We heard these other requirements that would improve the end-user experience.  Consider building something yourself to help with these.

  1. As a Scheduler, I want to be able to go to the Dispatcher console and visibly identify the Service Appointments for the Work Order so I don’t get confused with all the jobs on the Gantt. 
  2. As a Scheduler, I want an easy way to clone a Service Appointment from another Service Appointment on the Dispatcher Console so that it is easy to add another appointment for one more day.

Feature Requests

Jobs to be DoneStatusNext Steps
As a Scheduler, I’d like the flexibility to select the Timezone I’d like the Service Appointments to be scheduled in when setting up the initial parameters.  Design note: Data table renders the Date/Time fields in the context of the MACHINE settings.  Also, mass edit doesn’t only update the start time, it updates the date and the times.CapturedReview and determine next step
As a Scheduler, in the draft Service Appointments list, I want to know if that SA has an existing Absence or Service Appointment on that date so I can immediately see the conflicting record for that specific Service Appointment (or use any ensuing Gantt violations as guard rails for the dispatcher to use to tweak the schedule for a given Work Order).CapturedReview and determine next step
As a Scheduler, I want to define the Skills required at the Work Order and have the Match Skills rule consider that the combined Skills of the people I have Assigned to the WO will fulfill the Work Order Skill Requirements.CapturedReview and determine next step
As an Admin, I want to be able to modify the screen flow so that I can insert another Data Table displaying the individual dates with start times and durations before seeing the Resources to select so that the rough schedule can be created before selecting the resources that will be assigned.CapturedReview and determine next step
As a Scheduler, when I am deleting a set of SAs, I’d like an additional confirmation screen so that I don’t accidentally delete records.CapturedReview and determine next step
As a Scheduler, I want the option to let the scheduling engine select the resource based on a defined Role required for each SA (extended match).CapturedReview and determine next step
As a Scheduler, I’d like to have a job template that could create WOLIs with the required skills (sub-work types) that can be applied for each Task.CapturedReview and determine next step
As a Tech using the app, I need to see who else is going to be on-site on the same day so that I can see if I can carpool with someone.CapturedReview and determine next step
As a Tech using the app, I need to see the tool that was assigned to me so that I can bring the right tool on site.CapturedReview and determine next step
As a Site Supervisor using the app, I need to see all of the people who are staffed on the job each day so that I know who to expect and when (they are ok seeing the data table in the App).CapturedReview and determine next step
As an Admin, I’d like to have access to Setup Controls to help identify which automation to enable.

– Status Filters for SA edits
– Align Earliest Start and Due date if the Scheduled Start/Scheduled End is updated
– Set how long the Draft SAs stay in Draft
– Error Message and Screen Message Templates
CapturedReview and determine next step
As an Admin, I want to be able to bring the component into Custom Gantt Actions to Create SAs, Edit SAs (make the component a VF Custom Gantt Action)CapturedReview and determine next step

Use Voice IVR data in an Omni Flow

I wrote a post recently about how to set up routing for Service Cloud Voice, which now uses Flows in Salesforce to decide what queue to route to. One of the questions I got back was how to leverage data captured from the IVR to drive the routing decision. It’s a great use-case, as it allows us to take the power of an AWS LEX Voice Bot and combine it with both the CRM data in Salesforce and the end Routing decisions, to enhance the customer and the agent experience.

One simple approach is to set fields on the Voice Call record, but it’s actually possible to pass any field from an Amazon Contact Flow into a variable in Salesforce with just two simple steps laid out below.

Step 1: Map the Variables

To get IVR data (or any other inputs) from Amazon Connect into a Salesforce Flow, we just need to pass in the parameters when the Omni routing flow gets invoked.

To do this, we can define input parameters to the Invoke AWS Lambda Function action where we’re running the executeOmniFlow method. For those of us using the default Subflow ‘Sample SCV Inbound Subflow’ this is just the first node.

The input parameter in AWS should have the destination key value of flowInput-[variableName], where variableName is the name of the variable in the Omni Flow.

In the below example, imagine that we had our AWS IVR configured to ask the customer what product they were calling about, and want to pass it into the Omni Flow. We stored the customer’s answer in a variable on the AWS Contact flow called productAnswer, and then we pass it into an equivalent variable in the Omni Flow called customerProduct. Make sure that the Flow variable is set to be Available for Input.

Step 2: Use the IVR data to do powerful stuff in the Omni Flow

Once we’ve got the IVR data into Salesforce, the opportunities are endless for us to use it both to lookup/update Salesforce data, and then to combine the two in defining the routing behaviour.

In the example below, I did a few things:

  1. Grabbed the contact from the phone number
  2. Looked to see if there’s an Asset linked to the contact with the name that the customer gave in the IVR
  3. Created a Case with the Contact and Asset details
  4. Marked all three to Screen-pop when the agent accepts the call
  5. Checked the Product Type field on the Asset to route the call to the correct team

There are many, many, more things that could be done. This is just one example, and hopefully it is helpful, but I’ll look forward to seeing what exciting use-cases others come up with.

Routing for Salesforce Chat


Traditionally with Chat, there was a 1:1 relationship between the Chat Button and a Queue, so it was never easy to build dynamic routing logic in. If we wanted some chats to go to the sales team, and others to service, or if we wanted to prioritize VIP customers over others, we had to either use a Chatbot as a proxy, or code it into the pre-chat form somehow.

As of Winter ’22 though, it’s so much easier, with the launch of Omni Flows for Chat, and this post will help show us how to do that.

Two notes before we start, Omni Flow routing isn’t supported when using an Einstein Bot, though it is on the roadmap.

Also, make sure that you’ve read Build your first Omni Flow

Setup guide

We start off by building an Omni Flow. There’s a pre-built template for Chat or we can make it from scratch. The good thing about the template is that it gives an example of loading pre-chat data and using it to route based on that data.

Pre-chat data

When an Omni Flow is configured on a chat button, any customer inputs collected in the Embedded Service pre-chat form will be passed in automatically. If you’re not using the template, make sure to define an input variable of type Conversation Context Entry, with the ‘Allow multiple values’ checkbox selected.

Within the flow, you can loop over that collection, and check the Title (pre-chat field name) and Value (customer input) of each entry. This can then be used for whatever you need in the flow, linking the Contact, Creating a Lead or Case, or informing a Routing decision.

Decide where to Route the Chat

Once we’ve got the pre-chat data and loaded the Contact or other related information, we need to decide where to Route it.

The Route Work action will support us sending to a Queue, to a set of Skill Requirements, or Direct to a named Agent.

We can also set the Priority and Size of the Chat by changing the Routing Config or moving into a Queue with different values (allowing for us to escalate VIP customers to the front of the queue), and define what records will open when the agent accepts the chat via the Screen Pop action.

The below screenshot shows a simple example of a routing decision based on the subject in pre-chat, but we can ultimately define any logic that we want to (which is the great power of Flow, combined with all of the data about the Chat).

Add routing requirements to the Chat Button

Once we’ve built the Omni Flow, the last step is to map it to the Chat Button.
Now, if selecting the Omni-Channel routing type, you have the option to either provide a Queue (for simple scenarios) or to define an Omni Flow (for dynamic routing).

Update it by checking the box and selecting the Omni Flow that we just created, then we’re good to go. All new chats to this button will use that Flow to decide where to go!

Note: The go-forward routing type is Omni-Channel and we should use this for all newly configured Chat Buttons.

Extra notes

Heads up, when configuring the Flow from one of the templates, the Route Work actions are pointed to placeholder Channels, Queues, and Routing Configurations, and so you’ll need to swap these out for your own routing requirements before the Flow will work.

Service Cloud Voice Routing – Technical deep dive

How it works (under the covers)

The great thing about the upgrades for Routing of Service Cloud Voice that are GA in Spring is that it makes setup for Voice routing simpler and more powerful at the same time. It keeps all of the existing flexibility of Amazon, but enhances it with Salesforce data, and unifies it with other channels, such that the admin doesn’t need to worry about how it’s working in the back-end. What’s even better is that it’s all taken care of for us, so we just need to go into the Contact Center setup screen and point to the Routing rules.

But it’s interesting to know how it’s actually working, and I’ve seen quite a few folks wanting to understand more, so I thought I’d type up a quick post walking through the underlying details.

What’s been done is to deliver the best of both worlds, where the Routing Requirements (which queue does a call go into) are defined upfront inside Salesforce, while the Routing Execution (which agent in the Queue receives the call) is run inside Amazon.

When the call gets to the stage of doing the routing, the AWS Contact Flow invokes a dedicated routing API in Salesforce via Lambda (this is all pre-configured in a sub-flow for you), which runs the Omni Flow to get the routing requirements and returns a Queue ID to place the call into. There’s a queue mapping stored in Salesforce, pairing a Salesforce Queue to an equivalent Amazon queue which is what makes the whole thing work.

This allows the admin and supervisor to get a unified experience with all of their other channels, while the full power of the AWS connect system is still delivering the call in exactly the same way as before in the background.


The below diagram shows the data flow across channels. The conversation (Email, Chat, Phone) first goes into its respective automation layer (IVR, Chatbot, Case Classification) before being passed to Omni where the business rules for routing and queues are defined.

For Voice, within Salesforce, three key things are synced to the back-end phone engine,

  1. The Agents presence (are they online for this channel or not)
  2. Capacity (does the agent have capacity to receive work or not)
  3. Routing requirements (where do we want to send the phone call)

With all of that info sent back, the phone engine can then determine which agent to deliver the call to and pass that request into Salesforce.

Routing for Service Cloud Voice with Omni Flow


In Spring 22 there’s a massive leap forward in making the setup for Routing both easier and more powerful with the GA of Omni Flows for Service Cloud Voice (for Amazon Connect).

In the past, we needed to configure all of the Routing Requirements inside an Amazon Contact Flow. While an incredibly powerful tool, this comes with a few challenges that are resolved by moving the Routing Setup inside of Salesforce.

Some key benefits:

  1. Configure routing rules for ALL channels in one place, inside Salesforce
  2. Easily leverage Salesforce data and shared business rules in Routing requirements for Voice and other channels
  3. Share all Voice Queue data to Omni Supervisor, and in general for Reports inside Salesforce

This Blog post is to get you a quick start in trying out, but make sure that you’ve read Build your first Omni Flow before going any further.

Setup guide

For more information on how this works under the covers, see Service Cloud Voice Routing – Technical deep dive. There’s a video version of this at the bottom of the post as well.

We start off by building an Omni Flow. There’s a pre-built template for Voice or we can make it from scratch. The good thing about the template is that it gives a simple but great example right from the start of the power that we get, where we can easily look up the Contact, and use data in Salesforce to drive the Routing decision.

Note: As inputs to the Flow, you should get in both the Voice Call record (with data on it like the customer phone number) and any custom IVR variables that you choose to pass in from Amazon.

Create the Queues inside Salesforce and Amazon

The key to making this work is mapping of the Queues. To do this, we create the queues in both systems (stay tuned for an upcoming release where we’ll be automating the Amazon part!).
There’s a simple 3-step process to do this.

Step 1: Create the queues in Salesforce
Create the queue the same way that you would any Omni Channel queue, but with a few key and critical notes to make sure:

  1. Voice Call is the only object in the Queue
  2. The Routing Configuration is marked as External Routing in the Routing Model field

Optional: If you want to report on it or see in Omni Supervisor, you should add users to the Queue. Note that currently this data isn’t used, as membership is defined in Amazon (step 2). Also note that Amazon doesn’t support adding individuals to queues, only groups (via Routing Profiles) so I’d recommend managing the membership via Public Groups to keep it easy.

Step 2: Create the queues in Amazon

As above, log into the Amazon Connect management console and configure the same queues.
Note that these queues are the master source for queue membership.

Step 3: Map the Queues in Salesforce

Inside Setup→Amazon Contact Centers, select your contact center and scroll down to see a few new sections. This first of these, Queue Mapping, allows you to add a new entry for each Queue.

Mapping the Omni Flow to the Phone Number

The last step to do is to define the Routing requirements for the Phone number.

Inside Setup→Amazon Contact Centers, for your CC, you can now add each Phone number as a Channel (exactly like how we setup SMS phone numbers in Messaging). Within that, we’re offered the option to either route all queues to a specific queue (for simple use-cases) or to define our Omni Flow created above. And that’s it! No need to configure anything more in Amazon, the system will automatically take care of it for us.

[Upgrade notes] for Voice Orgs created before Spring ’22 or without Omni Flows

If your Org was created prior to Spring ‘22, or didn’t have these new features enabled, then it’s likely that the routing rules are defined inside an AWS Contact Flow and you’ll need to make some small changes to get it working. Don’t fear though, we’ve made it really easy to do.

Just go into the Contact Flow, remove any existing routing logic (Transfer to Queue nodes), drag on the Subflow node, and point it to the new “Sample SCV Inbound Subflow”. And that’s it, no need to do anything else. We’ll cover in other posts how to pass in IVR data, but for now you should be good to go, Salesforce will use the details from the setup screens above to drive everything else.

Video walkthrough

A video guide of setting it up in an org.

UnofficialSF has a new Service Cloud Channels Section has added a new section devoted to Service Cloud channel functionality, which is increasingly driven by flow-based services.

Check it out here. If you know of a good post or page on the topic, don’t hesitate to let us know via the form on the home page.

Build your first Omni Flow

So, you’re ready to build your first Omni Flow? Here’s a quick blog post to walk you through some of the basics. We’ll set up routing for a Case, but the fundamentals here will be true for other channels like Voice, Chat, SMS, Leads, Custom objects, or whatever you want to route.

In your Omni Flow, you’ll see we’ve exposed all of the Omni inputs as Actions on the left hand pallet. Now you’ll have complete flexibility to use any logic you like to determine what those inputs to the routing engine are, Queue/Skills/Agent, Priority, Size, you name it. Plus also, because it’s a flow, you can encapsulate all of your other business logic for the channel in here as well, like Creating a Case or linking the Contact.

You’ll also see some exciting new features that are only available in Omni Flow, like routing Direct to an Agent, or defining Screen Pop rules.

Either follow the steps below, or watch the video guide at the bottom of the post. Either way, you should be up and running in less than 10 minutes!

Create the Flow

Let’s start with the basics. There’s now a dedicated Flow type of Omni Flow to help you get started. (though some of the actions we’re about to see can be used in other Flows like autolaunched, record-changed, or screen flows).

Go to Setup→Flows, hit new Flow, then in All+Templates section create a new/blank Omni-Channel Flow.

Overview of the Actions

There are three key actions on the left hand-side (with more to come, and access to all other standard Flow actions)

  1. Route Work – This is where you define the routing requirements:
    1. What Queue, Skills, Agent to go to,
    2. What the size or priority of the work is,
    3. etc.
  2. Add Skill Requirements – Helps you to build up a list of Skill requirements for Skills-based routing
  3. Add Screen Pop – Define what records will open on the screen when the agent accepts the work

Quick Guide

I’ll write other posts on more complex scenarios, but just to get you started we’ll show how to build a quick bit of Queue based routing logic. In this scenario we’ll check for some keywords in the Case.

Step 1: Define Flow input variables

Once created, you’ll need to define an input variable to get in the ID of the work item that you plan to route. Optionally, you can also pass in the record itself. These aren’t critical for Case routing as you could manually grab the ID if you wanted, but for the real-time channels like Voice or Chat they’re passed in and so you’ll need to define them to be able to use them later.

  • recordId – type Text
  • input_record – type Record

Step 2: Add some routing logic to the Flow

Let’s grab a decision node and check the Case subject. Here I made one that looks for some keywords like Billing or Tech Support.

Step 3: Route the work

Herein lies the fun part. Drag on the Route Work action where we’ll see a whole range of inputs to decide where we want to route the Case, and it’s priority.

Some key things to define:

  • Record ID – this is the ID of the Work Item to route
    • use the recordId variable from before
  • Service Channel – the object type that we’re routing
    • select ‘Cases’ or whatever you’ve named your Case Service Channel
  • Route to – the type of routing you want to use (Queue, Skills, Direct to Agent)
    • select Queue here
  • Queue – the name of the Queue that you want
    • Use the lookup and pick a Queue from your org to route to

Step 4 (last one): Invoke the Omni Flow

For real-time channels like Chat, Messaging, or Voice you can define the Omni Flow to run from their setup screens.

For other objects like Cases, Leads, or Custom-objects though you can invoke routing at any point, so here we’ll just use a trigger flow to kick it off whenever the case is created. Alternatively you might build a screen flow for transfer, or another record triggered flow to route whenever a customer re-opens the case. The world is your oyster.

We can kick off the Omni Flow as a sub-flow, just make sure to pass in the Case ID to the recordId input variable!


And with that, you’re good to go. Create a Case and test it. Then come back and share what you built, or read some other posts for more advanced scenarios like Skills-based routing, or the exciting new Direct to Agent routing options!

Video Guide

Omni-Channel Flows, an Introduction


With Salesforce, we’re fortunate to have an incredibly powerful and flexible work/channel routing engine, that has helped thousands of customers to automate the assignment of Support Cases.

With great power and flexibility though came a lot of variation in the setup options available. Whether it was Case assignment rules, Queues on Chat buttons, Skills-based routing rules, Apex code, external logic for Voice systems, Bots calling flows or apex, there were a lot of ways to configure routing requirements, and not every channel supported every feature.

Now ALL of the above can be consigned to the history books.

With the Winter ’22 release Salesforce GA’d Omni-Channel Flows, which are now the place you should go to configure routing requirements for all scenarios and use-cases.

With this, it achieved 3 key benefits:

  1. Provided a unified setup experience for routing rules across all channels (Voice, Chat, Messaging, Case, and others)
  2. Increased flexibility to write business rules, while at the same time making it easier to set up and configure
  3. Built a Channel Orchestration layer for upfront Business rules, with a lot more planned than just routing to come (Sneak peak for Screen Pop, Channel-Object Linking, Einstein Case Classification, Einstein Bots, Einstein Article Recommendations, and much more to come)

It’s also a platform on which all new Omni features will be centralized, meaning that as soon as a new Omni capability is launched, it’ll be available for all channels right away. Read more for some exciting examples, like the new Direct to Agent routing.

If you want to get started, I wrote up another post on how to Build your first Omni Flow