Servicely Administration
Scripting
Trigger
5 min
overview a trigger automates business logics before/after a record creation/update/deletion for example, a trigger can automatically set a record’s field to a particular value, after you make a certain change on that record it runs on the server side, has access to the current record being created/updated/delete and access to classes and functions within script libraries javascript knowledge is required creating a trigger field name field type description example trigger name string name of the trigger incident location based on requested for location table reference records on this table will run this trigger incident field reference if nominated, the field here have to change before the trigger runs description text for administrative purposes, provide information what trigger is about set an incident’s location based on requested for’s location if it isn’t set yet active boolean if active, run the trigger yes trigger when? choice before runs the trigger before the record is saved into the database before is recommended if your business logic is to modify/enforce some of the current record’s fields doing those prior to writing into the database will save the number of database transactions in other words, you can set values without writing current update() do not update the current record in a before trigger (i e do not include current update()); after runs the trigger after the record is saved into the database after is recommended if your business logic is to create/update/delete records on other tables or make api calls, etc as you want the changes for the current table to be written into the database first async runs the trigger asynchronously and not sequentially/directly after a record is saved into the database before on transition(s) multiple reference workflow transition(s) off the table’s workflow on create boolean if set to yes, the trigger will run when the record is about to be created checked on update boolean if set to yes, the trigger will run when the record is about to be updated checked on delete boolean if set to yes, the trigger will run when the record is about to be deleted unchecked order integer determines the order of when this trigger should run relative to other triggers for the same table that match the same conditions (trigger when? on transitions(s), on create, on update and on delete) the lower the order results in the trigger to run earlier this will mean if you reference a field that is set of a trigger that runs earlier than another one, you can access the changed script in the later trigger 20 stop on exception boolean if set to yes and this trigger hits an exception/error, then other triggers that are supposed to run after this one, will not run if this trigger runs on before and it hits an exception, all triggers running on after will not run either example of exception includes if you have syntax issue or you are trying to access a non existent field or relationship of a table no overrides reference if this trigger is to override specific triggers running on the table’s parent table when set, the trigger nominated in this field will not run script script the script you want run to automate business logic of your choice within the script, you have access to the current record via the “current” object + the previous version of the record via the “previous” object you also have information on the operation currently executed via the “operation” variable the possible values returned by “operation” is either “create” or “update” or “delete” updating current record’s fields here does not require a current update() if the trigger runs “before” as the record creation/update hasn’t been written into the database yet including it will potentially cause a recursive trigger call if (!current location hasvalue() && current requestedfor hasvalue()) { current location(current requestedfor() location value()); } examples the following is aimed to give some general examples of what triggers can be used for/can do you may also look at out of box triggers for reference such as the ones for incident management or request management auto assign an incident to a user that progresses it from new to work in progress field name value table incident trigger when? before on transition(s) whatever it is to transition workflow status from new to work in progress refer to workflow on create false (unchecked) on update true (checked) on delete false (unchecked) script // set the group (either one of the user's groups or the currently assigned group if the user is a member of it) let grouptoassign = ""; let currentgroup = current assignmentgroup value(); let agrouprec = table("group") and( equal("selectable", true), or( subquery( "accessiblefrom", in("table", \["incident"]) ), not( subquery( "accessiblefrom" ) ) ), subquery( "member", equal("id", user getid()) ) ) query(); while (agrouprec next()) { let currentgroupid = agrouprec getid(); if (currentgroupid == currentgroup) { grouptoassign = currentgroupid; break; } else if (grouptoassign == "") { grouptoassign = currentgroupid; } } if (grouptoassign != "") { current assignmentgroup(grouptoassign); } // finally set the assignee current assignee(user getid()); on creation or update of a user account, synchronise to the conversation user account table, for whatsapp sofi chat purposes field name value table user trigger when? after on create true (checked) on update true (checked) on delete false (unchecked) script // if user's mobile number has changed if (current mobile haschanged() && current mobile hasvalue() && current active() && !current lockedout()) { let number = current mobile(); if (number startswith("+")) { // whatsapp doesn't like + number = number replace("+", ""); } let cuarec = table("conversationuseraccount") equal("user", current getid()) query(); if (cuarec next()) { // if there is already a conversation user account for the user, update it cuarec externalid(number); cuarec externaldisplayname(current displayvalue()); cuarec update(); } else { // if there isn't already a conversation user account for the user, create it cuarec = table("conversationuseraccount") newrecord(); cuarec externalid(number); cuarec user(current getid()); cuarec externaldisplayname(current displayvalue()); cuarec create(); } } else if (current mobile hasvalue() && ((current active haschanged() && current active() && !current lockedout()) || (current active() && current lockedout haschanged() && !current lockedout()))) { // if user's mobile number hasn't changed but user has been re activated let number = current mobile(); if (number startswith("+")) { // whatsapp doesn't like + number = number replace("+", ""); } let cuarec = table("conversationuseraccount") equal("user", current getid()) query(); if (!cuarec next()) { cuarec = table("conversationuseraccount") newrecord(); cuarec externalid(number); cuarec user(current getid()); cuarec externaldisplayname(current displayvalue()) cuarec create(); } } else if ((current active haschanged() && !current active()) || (current lockedout haschanged() && current lockedout())) { // if user is deactivated or locked out, delete the conversation user account record let cuarec = table("conversationuseraccount") equal("user", current getid()) query(); if (cuarec next()) { cuarec delete(); } } make an api call to synchronise an incident across to another ticketing system, using thirdpartyreference field that captures the other system’s ticket id this requires the use of a script library in this example, we would need one created called “incidentintegrationutil” that has a function called “synchtoothersystem” creating code to make outbound http api calls, you can refer to outbound http requests (scripted) field name value field name value table incident trigger when? after on create true (checked) on update true (checked) on delete false (unchecked) script if (current thirdpartyreference hasvalue()) { // if this ticket is already linked to another system's ticket // note for this example, we are assuming here that we have a script library called "incidentintegrationutil" that packages the api payload and send across to the other system let returnmessage = incidentintegrationutil synchtoothersystem("update", current); current workjournal(returnmessage); current disabletriggers(); // we do not want to cause a loop by running other triggers as we only want to write to the work journal current update(); } else { // if this ticket is not linked to another system's ticket yet // note for this example, we are assuming here that we have a script library called "incidentintegrationutil" that packages the api payload and send across to the other system let returnmessage = incidentintegrationutil synchtoothersystem("create", current); current workjournal(returnmessage); current disabletriggers(); // we do not want to cause a loop by running other triggers as we only want to write to the work journal current update(); }