Although the regular Super Round Robin MatchRules and AssigneeRules are quite extensive, sometimes you might need more options. In that case you can define your own match and assign logic with an Apex Plugin.
The Apex Plugin handles two events: MATCHGROUP_MATCH and MATCHGROUP_ASSIGN.
MATCHGROUP_MATCH
When a MatchGroup is set to Operational Mode: Plugin, a record is not matched against the matchgroup's MatchRules to see if it needs to be processed by that matchgroup, but by the logic you defined in the plugin's Apex Class. The record can then get one of three MatchResults: MATCH
, NO_MATCH
, or RUN_RULES
. Meaning it can be considered a 'match' or ‘no match’ with the matchgroup, regardless of the matchrules of the matchgroup. Or it can be forwarded to be matched against the matchrules of the matchgroup after all, and take a match or no match from those rules.
MATCHGROUP_ASSIGN
If the record is considered a match with the MatchGroup, it can then be assigned according to further logic you define in the plugin's Apex Class. The record can take one of four AssignResults: ASSIGNED
, QUEUE
, RUN_ROUNDROBIN
, or RUN_LOAD_BALANCED
. Meaning it can be assigned to the assignee defined in the Apex Class, to the Queue User, to an assignee of the matchgroup in round-robin fashion, or to an assignee of the matchgroup in load-balanced fashion.
If you assign a record to a specific assignee defined in the Apex Class, by applying AssignResult ‘ASSIGNED’, that assignee needs to be in the assignee list of the matchgroup.
However, in all AssignResults you can create a new Assignee__c record as well, and assign it to the assignee variable. The new assignee record will be added to the assignee list of the matchgroup.
To match and assign records using an Apex Plugin:
- Create a new Apex Class containing your matching and assigning logic. Example data can be found below.
- Add the name of the Apex Class to SF Custom Metadata Types
- In the MatchGroup you want to use, set Operational Mode to “Plugin”
Creating the Apex Plugin Class
To create the Apex Class:
- Go to Salesforce Setup > Apex Classes and click New.
- Enter your Apex code and click Save.
Model Classes
global with sharing class srrPluginModel {
global enum MatchResult {
MATCH,
NO_MATCH,
RUN_RULES
}
global enum AssignResult {
ASSIGNED,
QUEUE,
RUN_ROUNDROBIN,
RUN_LOAD_BALANCED
}
global class MatchGroupAssignInput {
global MatchGroup__c matchGroup;
global List<Assignee__c> assigneeList;
global Sobject objectToAssign;
}
global class MatchGroupAssignOutput {
global Assignee__c assignee;
global AssignResult assignResult;
}
global class MatchGroupMatchInput {
global MatchGroup__c matchGroup;
global Sobject objectToMatch;
}
global class MatchGroupMatchOutput {
global MatchResult matchResult;
}
}
Example Code
In the example code below:
- The record will be matched to a MatchGroup named ‘Plugin Group’.
- If the Last Name on the record equals ‘Carpenter’, the record will be considered a match with the MatchGroup, regardless of the MatchRules.
- If the Last Name on the record equals ‘Meadow’, the record will be considered no match with the MatchGroup, regardless of the MatchRules, and will be forwarded for matching with the next MatchGroup in line.
- If the Last Name on the record equals ‘Gilmore’, the record will run through the group's MatchRules and determined to be a match or no match accordingly.
- If the Last Name on the record equals ‘Carpenter’, the record will be assigned to a user with alias ‘jos’.
- If the Last Name on the record equals ‘Meadow’, an error is thrown because the record is not a match with the MatchGroup according to the plugin.
- If the Last Name on the record equals ‘Gilmore’, the record will be assigned to the Queue User of the MatchGroup.
- All other records that match the group will be assigned to the assignees of the group in a load-balance fashion.
Instead of the name of the MatchGroup, and the example parameter “Last Name equals”, you can enter your own logic to match a record.
Global class srrPluginExample implements leadassist.srrPluginInterface {
private static Set<String> implementedEvents = new Set<String>{ 'MATCHGROUP_MATCH', 'MATCHGROUP_ASSIGN' };
public Boolean isAvailable(leadassist.srrPlugin.PluginEventType eventType) {
return srrPluginExample.implementedEvents.contains(eventType.name());
}
public Object execute(leadassist.srrPlugin.PluginEventType eventType, Object eventData) {
switch on eventType {
when MATCHGROUP_MATCH {
return runMatch((leadassist.srrPluginModel.MatchGroupMatchInput) eventData);
}
when MATCHGROUP_ASSIGN {
return runAssignment((leadassist.srrPluginModel.MatchGroupAssignInput) eventData);
}
when else {
return null;
}
}
}
private leadassist.srrPluginModel.MatchGroupMatchOutput runMatch(leadassist.srrPluginModel.MatchGroupMatchInput input) {
leadassist.srrPluginModel.MatchGroupMatchOutput output = new leadassist.srrPluginModel.MatchGroupMatchOutput();
system.debug('check input sObject: ' + input.objectToMatch);
system.debug('check input matchGroup: ' + input.matchGroup);
if (input.matchGroup.Name == 'Plugin Group' &&
String.valueOf(input.objectToMatch.get('LastName')) == 'Carpenter') {
output.matchResult = leadassist.srrPluginModel.MatchResult.MATCH; // When the plugin returns 'MATCH', the matchgroup will be seen as matched.
} else if (input.matchGroup.Name == 'Plugin Group'&&
String.valueOf(input.objectToMatch.get('LastName')) == 'Meadow') {
output.matchResult = leadassist.srrPluginModel.MatchResult.NO_MATCH; // When the plugin returns 'NO_MATCH', the matchgroup will be seen as not matched and the record will continue to the next match group
} else if (input.matchGroup.Name == 'Plugin Group'&&
String.valueOf(input.objectToMatch.get('LastName')) == 'Gilmore') {
output.matchResult = leadassist.srrPluginModel.MatchResult.RUN_RULES; // When the plugin returns 'RUN_RULES', the matchgroup will proceed as usual. It will run the record through all the group's matchrules and determine the record as match or no match accordingly.
}
return output;
}
private leadassist.srrPluginModel.MatchGroupAssignOutput runAssignment(leadassist.srrPluginModel.MatchGroupAssignInput input) {
leadassist.srrPluginModel.MatchGroupAssignOutput output = new leadassist.srrPluginModel.MatchGroupAssignOutput();
if (
input.matchGroup.Name == 'Plugin Group' &&
String.valueOf(input.objectToAssign.get('LastName')) == 'Carpenter'
) {
User user = [SELECT Id, Alias FROM User WHERE Alias = 'jos' LIMIT 1];
for (leadassist__Assignee__c ass : input.assigneeList) {
if (ass.leadassist__User__c == user.Id) {
output.assignee = ass;
output.assignResult = leadassist.srrPluginModel.AssignResult.ASSIGNED;
}
}
} else if (
input.matchGroup.Name == 'Plugin Group' &&
String.valueOf(input.objectToAssign.get('LastName')) == 'Meadow'
) {
throw new leadassist.srrPlugin.PluginException('THIS CANNOT BE REACHED! \nPlugin was told there are no matches!');
} else if (
input.matchGroup.Name == 'Plugin Group' &&
String.valueOf(input.objectToAssign.get('LastName')) == 'Gilmore'
) {
output.assignee = null;
output.assignResult = leadassist.srrPluginModel.AssignResult.QUEUE;
} else if(input.matchGroup.Name == 'Plugin Group' ) {
output.assignResult = leadassist.srrPluginModel.AssignResult.RUN_LOAD_BALANCED;
}
return output;
}
}
Adding the Apex Class to SF Custom Metadata Types
- Still in Salesforce Setup, go to Custom Metadata Types > SRR Optional Parameter.
- Click Manage SRR Optional Parameters > Apex Plugin Class Name > Edit.
- At Value, enter the name of your class.
- Click Save.

Setting a MatchGroup to use the Apex Plugin
- Open the MatchGroup where you want to use the Apex Plugin.
- At left, at Operational Mode, click Edit
- In the picklist, select Plugin.
- Click Save.