Out of the box, Salesforce Chat uses Omni Channel to route your chats to agents, is totally straight forward and super easy to setup. BUT I know I’m not the only one when I say I don’t know if I’ve ever had a straight forward out of the box implementation of anything 😂🤦. If you have unique use cases like I do, it’s going to take a little more finessing, maybe a couple bandaids, and some time.
When my service managers first told me how they wanted their chats routed, I was like yeah no problem, we can do anything. I was super confident in that answer 1) because it’s Salesforce and I can basically make it do anything, but 2) because in the Summer ’21 release we were getting routing via Flow with Omni Channel Flows, and it’s Flow and I have ALL THE POWER, and 3) because sometimes I’m just super cocky and confident and say I can do things before I even truly think about them.
But then hiccup number one happened. Omni Channel Flow… it doesn’t work with Einstein Bots. Yet. And now I was doing some serious face palming 🤦 because that was going to be my whole routing solution and it was going to be so amazing and now I’m thinking there’s no way I’m going back to them and saying I can’t deliver on this… I gotta figure this out.
Here’s what they actually asked for
- Prioritize chats by customer subscription level
- Only certain agents should receive chats from specified subscription levels
- Display queue position to customer while they wait
- If customer is chatting about existing case, see if case owner is online and route to them
These don’t seem like huge asks, right? And actually, I think they’d actually all be fairly simple to implement if it weren’t for one thing… my Einstein Bot, Robot Downey, Jr. As awesome as it is, it complicates a lot and everything seems to take much more calculated planning. Let’s talk about how we accomplish these things.
Prioritize routing by a field in the transcript
This is actually out of the box and maybe the easiest to setup. This can be accomplished with Secondary Routing Priority. This allows you to select a field and assign priority to it. In a queue, priority is decided by how long the work item has been waiting in a first-in, first-out model. In order to prioritize our different customer levels in the queue, I enabled the Secondary Routing Priority and then in my Chat service channel, selected Customer Level as my field. I set Pro customers with a priority of 1 and Standard customers with a priority of 2. (0 is the highest priority.) So now as chats flow in, not only are they evaluated for wait time, but if a standard customer is already in the queue when a pro customer enters, the pro customer will get routed before the standard customer.
To get my customer level into the chat transcript to be evaluated, I added an update step to a flow I run when the chat is first initiated. Look out for another post all about just that!
Certain agents in the queue should get certain customer levels
This requirement also seemed fairly straight forward to me. The different customer levels could be setup as skills and skill based routing rules could be setup for the chat transcript object. In the routing configuration, you can choose to use skills-based routing rules, and its all tied together on your chat button which specifies your queue, which is tied to a routing configuration. Whew. Keep in mind that chat skills are assigned slightly differently than normal skills. Rather than adding them on a service resource record, you actually assign users to the skill on the skill record itself. I found this actually super confusing and it took me over a week to even notice that. With service resource records, our support managers have the power to update skills as necessary for their teams. They do not have the same permissions to update a skill in the setup menu.
Display queue position to customer while they wait
This requirement is also straight out of the box. On your chat button, you need to make sure that you have Enable Queue checked and then set your queue size. Then, in your Embedded Service Deployment, check the box for “show queue position”. Done. This will now show the customer’s place in line as they wait to be connected with an agent. If you are more code savvy, there is also a way to show estimated wait time instead of just the queue position. I’ve definitely been staring at this and have added it to my to-do list for future phases of the implementation. I think showing an estimated wait time would be more valuable to customers and would give them more power in deciding if they want to wait or just submit a case instead. This feature is currently still in beta, so I have hopes that they will add this to the declarative settings in the Embedded Service settings eventually. You can read more about Estimated Wait Time here!
Route to existing case owner if they are online
This is where the power of the Omni Channel Flow was going to come in! With the flow, you can route work items directly to a specific agent. It would be really simple to lookup the case owner of the related case and route the chat to them. If that agent was not online, the chat would default to the backup queue that you specify. I built this out and then was super confused when it wasn’t working… and that’s when I found that if you are transferring chats with an Einstein Bot, you can’t use Omni Channel Flow. But that’s ok – I’m keeping it on my list of things I want to add in future phases. I have faith they’ll continue to develop Einstein Bots and the Omni Channel Flow routing and eventually I have no doubt that they will play nice.
So where’d my headache come from?
When you look at all of these things separately, they are all solved for (minus that last one!) and what am I even complaining about? Well, when you put all of the requirements together and add an Einstein Bot, things get complicated. For starters, Einstein Bots don’t support Skills-Based Routing Rules. So first I was like OH NO, banging my head on my desk. I decided that if I couldn’t use skills for routing by my customer levels, then I’d have to create a different queue for each customer level and make sure only the agents who should talk to those customers were in those queues. Then I could tell Robot Downey, Jr. to transfer the pro customer to the pro queue and be done. In theory, this was great. I set it up, it was working fine… until I noticed that you can only enable the queueing and display the queue position for the queue associated with the chat button. So when solving for one request, I totally broke another. Ok, well then what if I could transfer to a different button? But Robot Downey, Jr. can only transfer to another bot, a queue, or a skill. But wait, I thought Skills Based Routing doesn’t work with bots? There’s a workaround.
In this help article (which I didn’t find for like 2 weeks somehow), they outline an apex class that you can create and then call in a Bot Action to assign a skill variable. Then you can transfer to that destination variable. I decided to not use an apex class, but actually do this in Flow because that’s where all my other chat actions are coming from. Consistency! I actually added this to my pre-chat flow that I mentioned earlier that I will totally devote a whole post to. But anyway, I’m getting the Id’s of the skills I need for this particular chat when the chat is initiated and then outputting those into a Bot Variable that I can then use for my Transfer Rule. Are you still with me?
And this totally worked and I was relieved for my first rounds of testing until we tested with only people who didn’t have the skill for what we wanted routed. For example, if I had a pro customer chat, I would send it to the pro skill and it would be routed to an agent with that skill. That’s great, that’s exactly what we wanted. BUT if no pro skilled agents were online, the customer is presented with a no agent available dialogue and can’t get routed anywhere. Instead of defaulting to the chat button settings, it just wasn’t going anywhere. This is definitely NOT what we wanted to happen, and confusion set over as I read this documentation over and over again. It very clearly says that if all agents are at capacity, the bot will review the settings of the button and start queuing. I had agents online and ready to accept chats, they just didn’t have that skill. I think as I read and re-read this statement, what I was missing was the ‘at capacity’ part. I didn’t have pro agents that had reached capacity, I just didn’t have any online period. So really what my requirement is now is this: prioritize chats by a certain customer level, but if I can’t then just route it to someone. Here’s where my stress nightmare set in.
I was thinking about this requirement all day and all night and I couldn’t sleep and then when I finally fell asleep all I dreamt about was building and rebuilding this routing. I went through every scenario and it was one of the worst nights of sleep ever. But when I woke up in the morning, I went straight to my desk and started looking at my skill mapping for the chat transcript object. What if I set these skills as Additional Skills and gave them a priority? And then what if set a timeout for those additional skills so that they’d drop off and we didn’t need to evaluate them anymore? So that’s what I did. And then we tested and re-tested and tested some more. This totally seemed to do the trick, but I’m still not 100% on WHY it worked since the documentation says that it doesn’t use the Skills-Based Routing Rules… but it works and I am so relieved.
In the end, I didn’t get everything I wanted for my routing (YET!) but what I do have, is chats that get prioritized by customer level, routed to the agents with the right skills, and if I don’t have agents online with the right skills they just get routed to a person. And a person is better than no person. Whew.
I guess the moral of my story is don’t be quick to a solution. Or it could be test your little heart out and then test some more. Or maybe its don’t put all your eggs in the basket that is still in beta and just came out in this release? Or maybe just that nothing is as simple as it seems and you need to apply thought, logic, and a stress nightmare (or maybe just some googling?) to find the answers and solutions you need.