Einstein Copilot in Action
Einstein Copilot is a new feature from Salesforce that launched in February 2024. This article gives a quick overview of what Einstein Copilot is, but the main focus is to share a step-by-step guide on how I created a custom action to quickly identify available users in the org to assign cases on the fly based on current users capacity. This practical activity is part of the #BuiltWithEinstein challenge, which runs until June 30, 2024.
Let's dive in. So, what exactly is Einstein Copilot? It's an add-on for Salesforce that uses AI to help you get answers to your questions, generate content, and automate various tasks. It can do things like search your company's data and answer questions, create content, and trigger different actions in the Salesforce system. Here's what it can do out-of-the-box (ready to use through standard actions):
So here's the breakdown of what makes Einstein Copilot work:
Einstein Copilot has a lot of potential to boost your productivity in Salesforce, but it's important to get used to the tool first and run some tests and more tests before you roll it out to everyone. Just to be on the safe side, make sure it works smoothly and won't cause any surprises for your team.
My Quest - Step by Step
In this section, I'll explain what I've done for the #BuiltWithEinstein quest challenge. You might think that what I've created doesn't strictly require Copilot, and that's a fair point. The idea here is to explore and get hands-on with the technology—it’s a starting point to spark ideas about what Copilot can do. I also highly suggest checking out what other trailblazers have built for this challenge to see more examples.
The image above shows the final result of this activity. Let's imagine a case that needs immediate attention. Maria, the case manager at Solars, uses Einstein Copilot to 'Find available users' (1), and she finds that Alice and John are currently available. John seems to have fewer open cases than Alice (2). In the same conversation, Maria also uses the Summarise Case button (3) to generate a summary for the case (4), giving John a quick overview of what the case is about. Then Maria updates the case (5 and 6). Done. Maria is happy with her experience and the quick way she can use Einstein to gain a quick insight of her team.
Note: To make this work in a trial environment, I created two fake users and logged in separately as each one. Since my org doesn't have enough Salesforce licenses, It disabled my two fake users from seeing Cases, so the 'Custom assigned to' field is used to mimic the Case owner field.
1 - Enable Copilot (Setup -> Einstein Copilot -> Turn on 'Einstein Copilot for Salesforce). This creates a copilot that has its on set of configuration (Details, Actions, System Messages and Language Settings). The copilot could be activated, allowing users to view the Einstein icon on the top of of the screen next to favourites. However, only standard actions would be available to users
Okay, with Einstein enabled, the next step is to create a custom action that allows managers to find available agents in the system.
2 - If you're still in setup, search for 'Einstein Copilot Actions', then select 'New Copilot Action'. The custom action I am creating will use a flow to run the logic before providing managers with their answers.
Click 'Next', and the final step in creating this action is to provide the instructions it should follow. You'll want to be as descriptive yet straightforward as possible, specifying what inputs it accepts and what outputs it provides.
领英推荐
Before clicking on 'Finish', let's explore what the 'Find Available Users' flow does. This includes understanding the inputs it accepts and the outputs it generates.
Flow - Find available users.
It's an autolaunched flow that calls an invokable Apex method. This method queries active sessions in Salesforce and the number of open cases associated with each user, then returns a list of sObject types stored in an Apex-defined variable. The flow then iterates through this list and, for each item, transforms it from an object into a single string. These strings are collected into a collection, which is then output to the user.
The invokable method does not receive any inputs as attributes. Ideally, it would accept the user who is asking the question via the Copilot, but instead, I decided to add a line of code in the Apex code that checks the running user. It's worth noting that if you look at the previous image of the Custom Action screen, you'll see that we're receiving a 'userID' as an input. However, I'm not using it anywhere (and it's also not required for the action). I tried creating an action without any input, but I encountered an error—it seems that an input property is required. This is a straightforward flow, but as is often the case in tech, there are many ways to achieve the same goal.
Below is the apex code used:
public class GetAvailableUsers {
@InvocableMethod(label='Get available users' description='Find Users who are currently available')
public static List<AvailableUserResultWrapper> getCurrentLoggedInUsers(){
// Get the ID of the user running this code
String userRunningApex = UserInfo.getUserId();
Datetime now = Datetime.now();
// Store active sessions of other users
Map<String, String> activeUserSessions = new Map<String, String>();
// Query to get UI sessions for users other than the current user
for(AuthSession session : [SELECT Id, CreatedDate, LoginType, LastModifiedDate, NumSecondsValid, SessionType, SessionSecurityLevel, Users.Name, UsersId, UserType, IsCurrent FROM AuthSession WHERE SessionType='UI' AND UsersId != :userRunningApex]){
Datetime sessionExpiry = session.LastModifiedDate.addHours(session.NumSecondsValid / 3600);
if(sessionExpiry > now){
activeUserSessions.put(session.UsersId, session.Users.Name);
}
}
//query an aggregate count of cases assigned to users
AggregateResult[] groupedResult = [SELECT Custom_assigned_to__c, COUNT(Id) FROM Case GROUP by Custom_assigned_to__c];
List<AvailableUserResult> results = new List<AvailableUserResult>();
//loop through the results
for (AggregateResult ar : groupedResult) {
String userId = (String) ar.get('Custom_assigned_to__c');
Integer caseCount = (Integer) ar.get('expr0');
if(userId != null && activeUserSessions.containsKey(userId)) {
String userName = activeUserSessions.get(userId);
//construct an instance of what is to be added to the returned array
results.add(new AvailableUserResult(userId,userName,caseCount));
}
}
// Wrap the results in a list of AvailableUserResultWrapper and return
List<AvailableUserResultWrapper> finalResult = new List<AvailableUserResultWrapper>();
finalResult.add(new AvailableUserResultWrapper(results));
return finalResult;
}
}
AvailableUserResult class:
public class AvailableUserResult {
public AvailableUserResult(String UserId, String UserName, Integer numberOfCases) {
this.UserId = UserId;
this.UserName = UserName;
this.numberOfCases = numberOfCases;
}
@AuraEnabled @InvocableVariable public String UserId;
@AuraEnabled @InvocableVariable public String UserName;
@AuraEnabled @InvocableVariable public Integer numberOfCases;
}
AvailableUserResultWrapper
public class AvailableUserResultWrapper {
public AvailableUserResultWrapper(List<AvailableUserResult> availableUsers){
this.availableUsers = availableUsers;
}
@InvocableVariable
public List<AvailableUserResult> availableUsers;
}
That's pretty much it. If you look at the Copilot Builder, you can see which action was triggered when interacting with Einstein, along with the input provided for the action and the output generated at the end.
This isn't a complex step-by-step guide, but it's a good way to get familiar with this powerful tool and serves as a starting point for generating new ideas. The salesforce trailhead platform provides a few materials to enhance your skills on this (some of which will be provided in the resource list). If you're willing to take it a step further, here are some suggestions:
If you got this far, thank you for reading and you're amazing! :)
Resource: