I boosted the productivity of my service users with this simple apex code
Hi! Let's talk about productivity today. We all have our proper idea about what is productivity. Elon Musk, for example(I don't know him, so don't reach me on Linkedin to get his phone number, I don't have it!), objectively, looks productive. According to the internet(which could not be accurate), he may do weeks of 80-100 hours, which is huge. Concerning myself, I am not always as productive as I want. Sometimes, I write two articles in a week, and some other times, zero. I am still convinced that it's not a bad thing to be not productive every time. I also like the idea that we can build anything, whether it's useful or not. For example, I am pretty much convinced that this article won't have any impact on our lives. But I enjoyed writing it! By reading this, please, don't take it literally. Even if work is taking a huge part in our lives, it's just work. It can be fun sometimes, or painful some other times, but we are not all doctors, aircraft pilots, or other life-saving job. I am proud of what I do and who I am, but let's be honest: I am just writing some lines on my computer, and say 'Tadaaaaaa' when it's working. And sometimes it isn't!
Step one: What do we want
We want to boost the productivity of the service users. So, to begin, we have to ask ourselves two questions:
How to measure productivity?
What to do when productivity is low?
To measure productivity, I have been thinking about getting the average time a specific user has been scrolling on Salesforce. Some tools can make it possible, but installing a new package on our org would make our implementation a little less straightforward. The most straightforward solution for me is to calculate the number of closed cases and compare it with the total number of assigned cases. If the user has a low number of closed cases, 'we are not happy'. Now, what could we do when we are not happy with him? We send him an SMS. 4 PM is the perfect hour because the day is not finished, but at the same time, the day is almost finished. Yes, I know, it's not something we want to see anywhere. But it's still interesting to see how it's working, so be ready!
The beginning of everything
Do you know what is missing on the case object on Salesforce? A field telling us the date when a Case has been opened for the last time. I've searched about this field and didn't find it. The Date/Time Opened only works on the case's creation. So I created a field called Datetime_of_last_opening__c, of Datetime type. We can't use a formula field here(which would have been useful), because the functions ISCHANGED and PRIORVALUE don't exist on them for now. So instead, we have used an Apex trigger. If you want, you can do this step with a flow, it would work. And even more, it's considered a "best practice" by Salesforce to use declarative tools whenever you can. In my case, I preferred to use apex code from the beginning until the end, to be able to optimize the performance of the algorithm(maps are not available yet on flows), and to keep all the logic in the same place(which is also a "best practice")
Now that the field is created, we have to give it some data. We moved all the logic inside a handler that we called CaseManager. Doing this allows us to get a cleaner trigger. In the trigger, we only verify the context(before, insert, update...), and according to the actual context, we call the method we want. We also don't need to define a list and make a proper insert or update because we are modifying the current record during the transaction, which is (again) simplifying the logic.
Now, when the methods onBeforeUpdate and onBeforeInsert have done their job(which means 'saving into a field the last time a user(or a machine) opened the case'), we can move to the rest of the logic. The first thing to do is to get all the case records. We are interested in pretty much every case record, except for those that have been closed before today. And by using the returned list of cases, the ultimate goal is simply to get a map, with the agent's phone number as a key, and the percentage of closed cases as a value. Also, I've created a Profile called 'Customer Service User', but it's up to you to call it as you want.
To lower the amount of data involved, we only saved into the map the agents who don't perform(ie who didn't close 80% of their cases). Also, the percentage in the map is a String, not an Integer, to reuse it on the SMS message. And the last thing, we consider that the most straightforward way to develop our solution is to want to automate the Sending SMS task. For this, we will need to implement the Schedulable interface. We already integrated Salesforce with the Twilio API to send some alerts before meetings. We simply improved this development, to reuse it. For doing it, we transformed some variables into the method's parameters.
Note: As I said, the Twilio integration pattern I used is the same as the one I used to integrate Twilio API with Salesforce in previous development. The only difference is that I've quickly rewritten my methods to be more easily reusable(basically by transforming some variables into method parameters. Let's make room for...THE NEW TWILIOHANDLER CLASS!!! Yes, I know, this class is so much better than the previous one.
Ok, now that everything is in place, we just have to send an SMS at 4 PM every day, from Monday to Friday