Routing Plugin
Operational Mode: Plugin
This article explains how to extend Plauti Assign matching and assignment by switching a MatchGroup to "Operational Mode: Plugin" and implementing a custom Apex class that follows global interface srrPluginInterface
.
Overview
A plugin lets you override the standard MatchRules and AssigneeRules executed by Plauti Assign.
When a MatchGroup is set to Plugin mode, Plauti Assign fires two events that your class may handle:
Event | Purpose |
---|---|
MATCHGROUP_MATCH | Decide if the incoming record matches the MatchGroup, or defer to normal rules. |
MATCHGROUP_ASSIGN | Decide how a matched record is assigned (specific user, queue, round-robin, load-balance). |
isAvailable(eventType)
is invoked first; return true for the events your plugin supports.
Implementation
Core interface & example
The sample plugin checks the record’s LastName
: it flags “Carpenter” as a direct match, “Meadow” as no-match, and “Gilmore” as “run rules,” otherwise it does nothing. If the record is a match, it assigns “Carpenter” records to the user with alias jos, throws an exception for “Meadow,” routes “Gilmore” to the MatchGroup’s queue user, and load-balances any other surname.
global class MySrrPlugin implements srrPluginInterface {
// Define which events this plugin supports
private static final Set<String> SUPPORTED = new Set<String>{
'MATCHGROUP_MATCH', 'MATCHGROUP_ASSIGN'
};
// isAvailable is called by the framework to check if we handle a given event
public Boolean isAvailable(srrPlugin.PluginEventType evt) {
// Only opt in for events in our SUPPORTED set
return SUPPORTED.contains(evt.name());
}
// execute dispatches incoming events to the appropriate handler
public Object execute(srrPlugin.PluginEventType evt, Object data) {
switch on evt {
when MATCHGROUP_MATCH {
// Cast data to MatchGroupMatchInput and invoke our match logic
return match((srrPluginModel.MatchGroupMatchInput) data);
}
when MATCHGROUP_ASSIGN {
// Cast data to MatchGroupAssignInput and invoke our assign logic
return assign((srrPluginModel.MatchGroupAssignInput) data);
}
when else {
// Unhandled events return null
return null;
}
}
}
/* ---------- Matching logic ---------- */
private srrPluginModel.MatchGroupMatchOutput match(
srrPluginModel.MatchGroupMatchInput in) {
// Prepare output container
srrPluginModel.MatchGroupMatchOutput out =
new srrPluginModel.MatchGroupMatchOutput();
// Fetch the LastName field from the record being matched
String lastName = String.valueOf(in.objectToMatch.get('LastName'));
// Custom matching rules based on LastName value
if (lastName == 'Carpenter') {
// Always treat 'Carpenter' as a match
out.matchResult = srrPluginModel.MatchResult.MATCH;
} else if (lastName == 'Meadow') {
// Always skip 'Meadow' (no match), continue to next MatchGroup
out.matchResult = srrPluginModel.MatchResult.NO_MATCH;
} else if (lastName == 'Gilmore') {
// Defer to the MatchGroup's own rules for 'Gilmore'
out.matchResult = srrPluginModel.MatchResult.RUN_RULES;
}
// Return the chosen MatchResult
return out;
}
/* ---------- Assignment logic ---------- */
private srrPluginModel.MatchGroupAssignOutput assign(
srrPluginModel.MatchGroupAssignInput in) {
// Prepare output container
srrPluginModel.MatchGroupAssignOutput out =
new srrPluginModel.MatchGroupAssignOutput();
// Fetch the LastName field from the record being assigned
String lastName = String.valueOf(in.objectToAssign.get('LastName'));
if (lastName == 'Carpenter') {
// Query the User with alias 'jos'
User u = [SELECT Id FROM User WHERE Alias='jos' LIMIT 1];
// Find the matching Assignee__c in the provided list
out.assignee = in.assigneeList.find(a => a.leadassist__User__c == u.Id);
// Instruct SRR to assign to that specific user
out.assignResult = srrPluginModel.AssignResult.ASSIGNED;
} else if (lastName == 'Meadow') {
// Throw an exception if trying to assign a record we declared NO_MATCH
throw new srrPlugin.PluginException(
'Plugin declared NO_MATCH – assignment prohibited.');
} else if (lastName == 'Gilmore') {
// Send 'Gilmore' records to the MatchGroup’s Queue User
out.assignResult = srrPluginModel.AssignResult.QUEUE;
} else {
// All other matched records are load-balanced across assignees
out.assignResult = srrPluginModel.AssignResult.RUN_LOAD_BALANCED;
}
// Return the chosen AssignResult (and assignee if applicable)
return out;
}
}
Step 1 — Create the Apex Class
Create a global
class (visibility is required so Type.forName
can instantiate it) that implements srrPluginInterface
.
Step 2 — Handle MATCHGROUP_MATCH
- Input: matchGroup, objectToMatch.
- Return one of
MATCH
,NO_MATCH
,RUN_RULES
.
Step 3 — Handle MATCHGROUP_ASSIGN
- Input: matchGroup, assigneeList, objectToAssign.
- Return one of
ASSIGNED
,QUEUE
,RUN_ROUNDROBIN
,RUN_LOAD_BALANCED
. - If you return
ASSIGNED
, the chosenAssignee__c
must exist in or be added to the list.
Step 4 — Register the Plugin
In Setup › Custom Metadata Types › SRR Options (leadassist__SRR_Options__mdt
) edit the record with Developer Name = Plugin_Class_Name and set Value to the fully-qualified class name (e.g. MySrrPlugin
).
Step 5 — Enable Plugin Mode on the MatchGroup
Open the MatchGroup, edit Operational Mode, choose Plugin, and save.
Supported Results
Enum | Meaning |
---|---|
MatchResult: MATCH | Record instantly matches this MatchGroup. |
MatchResult: NO_MATCH | Record bypasses this MatchGroup. |
MatchResult: RUN_RULES | Plauti Assign evaluates the group’s MatchRules to decide. |
AssignResult: ASSIGNED | Assign to the specific Assignee__c supplied by the plugin. |
AssignResult: QUEUE | Assign to the MatchGroup’s Queue User. |
AssignResult: RUN_ROUNDROBIN | Assign to the next assignee in round-robin order. |
AssignResult: RUN_LOAD_BALANCED | Assign to the least-loaded assignee in the group. |
flowchart TD A["Record Received"] --> B{"MatchGroup in Plugin Mode?"} B -- "No" --> C["Standard Plauti Assign Process"] --> Z["End"] B -- "Yes" --> D["MATCHGROUP_MATCH (plugin)"] D --> E{"MatchResult"} E -- "MATCH" --> H["MATCHGROUP_ASSIGN (plugin)"] E -- "NO_MATCH" --> I["End (No Match)"] E -- "RUN_RULES" --> F["Evaluate MatchRules"] F --> G{"Matched after rules?"} G -- "Yes" --> H G -- "No" --> I H --> J{"AssignResult"} J -- "ASSIGNED" --> P1["Assign to specific assignee (plugin)"] J -- "QUEUE" --> P2["Assign to MatchGroup queue user"] J -- "RUN_ROUNDROBIN" --> P3["Assign next assignee (round-robin)"] J -- "RUN_LOAD_BALANCED" --> P4["Assign least-loaded assignee"] P1 --> P["Record Assigned"] P2 --> P P3 --> P P4 --> P
The plugin receives full context objects so you can query additional data, log diagnostics, or dynamically buildAssignee__c
records as needed.
Updated 9 days ago