In part 1 of this series, we looked at the new feature released in Spring ’15 called Lightning Processes and we did a basic comparison between it and Worflows. In part 2, we looked at how to use Lightning Processes to create and update related records. In today’s post, we’ll be looking at how to extend the Lightning Process Builder beyond it’s out of the box capabilities by invoking Apex inside your Processes.
While the Process Builder is very flexible out of the box, it cannot do everything. Salesforce realized that there would be scenarios they couldn’t cover by default, so they allow us to extend the Process Builder by writing Apex code that meets certain criteria, and then invoking the Apex from our Processes.
As an example for today, let’s say we have a custom field on Account called Sample Field 1, and the requirement is whenever Industry is changed we want to copy the value to Sample Field 1.
While we could use a standard field update or a formula field to achieve this, we’re going to use Apex so that we can see how we can extend Processes to do something much more complicated.
To start, we need to learn about a new Apex annotation introduced with Spring ’15: @InvocableMethod. This annotation lets us mark an Apex method as being something that can be ‘invoked’, or called, from somewhere other than Apex. In our case, we’re going to call it from a Process. It also defines some metadata about the method like a human friendly label and description of what the method will do when it’s called. There are some specific requirements that must be followed to make a method invocable, so make sure you read the documentation carefully. In our case, the code is very simple:
Once we have this class saved, we can go to the Process Builder and use it. Most of the setup is the same as before, but when choosing an action to perform we’ll now chose a type of Apex:
Once you’ve filled out the required fields, you’ll have a process that’s now calling your apex class!
To test it out, let’s first try updating an existing record:
That worked! Now let’s try it when we create a new record:
That also works. In general, processes get executed after the record has been soft saved to the database (roughly the same time that workflows would run), so they have an ID already by the time this Apex executes.
When I first wrote this Apex class, I wasn’t originally looking up the record from the database and updating that copy. I tried to instead update the record directly:
It seemed like I should be able to do this, since this is what I would do in a before trigger normally (I also hadn’t yet figured out when exactly Processes run in the pipeline – in hindsight it’s obvious this wasn’t going to work). When I attempted to run the Apex which updated the record directly, I got a nasty error on the form:
Unfortunately, that’s all the detail you can get from the user’s point of view, which isn’t super helpful. There also doesn’t appear to be a way to customize how it’s displayed, which is slightly disappointing. If you’re an administrator in the organization, you’ll receive an email which is more helpful:
The important thing to note here are the Process ID in the email and the details of the Apex error. The Process ID corresponds with the ID the user sees in the error message and can be used for correlation if multiple Processes are having problems. In my case, I was more interested in the Apex details, which states that the records that are passed in to the Apex class are read-only.
Obviously this example is very simple, but the Apex you use could be quite a bit more complicated. The core lesson here is that we can invoke Apex from Processes if we give it the appropriate annotation and follow the rules in the documentation, allowing us a greater degree of freedom. We hope you find this new power useful. If you come up with any creative ways to use Processes, please feel free to share in the comments below!