Creating Dispatch Rules in the ServiceForms Connector

Adam Gurley
Adam Gurley

Each dispatch rule can have a dispatch mapping defined as a block of Javascript code. This code modifies the payload of data that is sent to Device Magic as part of the form dispatch. The SF namespace provides the following:


All dispatch mapping code is executed inside a Node vm2 sandbox. In addition to the SF namespace, the following external modules are available:

To make changes to the data that is dispatched as part of a form, modify the contents of SF.payload accordingly.


To stop a form from being dispatched, set SF.payload.prevent_dispatch to true. This is useful for negative matches (e.g., dispatch a form for all job types except one).


Dispatch Data Mappings

A dispatch rule can optionally define how data is prefilled into the dispatched form’s fields. By default, the following data will be prefilled:



Dispatch Mapping Rule Examples

/* Rename ‘servicetrade_assets’ to ‘asset_list’ */

SF.payload.asset_list = SF.payload.servicetrade_assets;


/* Add the location’s state to each asset in the ‘servicetrade_assets’ array */

SF.payload.servicetrade_assets.forEach(function(a) {
a.location_state = SF.payload.servicetrade_location_state;


/* Convert an asset property Unix timestamp to Device Magic friendly date format */

SF.payload.servicetrade_assets.forEach(function(a) {
a.properties_manufacture_date = Moment(a.properties_manufacture_date, ‘X’).format(‘YYYY-MM-DD’);


/* Don’t dispatch this form for emergency service calls */
if (SF.job.type === 'emergency_service_call') {
SF.payload.prevent_dispatch = true;


/* Remove the job description */

SF.payload.servicetrade_job_description = undefined;


/* Get a value that might or might not be defined, using ‘Get’ */

SF.payload.servicetrade_contact_email = Get(SF,'');
// the old way was:
SF.payload.servicetrade_contact_email = SF.job && SF.job.location && SF.job.location.primaryContact ? : null;


/* Organize all child assets under their parents */

// separate parents from children
const parentAssets = SF.payload.servicetrade_assets.filter(a => !a.parent || === 'Location - Building');
const childAssets = SF.payload.servicetrade_assets.filter(a => a.parent && !== 'Location - Building');

// add child array container for each parent
parentAssets.forEach(p => p.children = []);

// assign children to their parents
childAssets.forEach(c => {
const foundParent = parentAssets.find(p => === c.parentId);
if (foundParent) {

// servicetrade_assets is now only the parents (with their nested children underneath)
SF.payload.servicetrade_assets = parentAssets;


const servicetrade_assets_sprinkler_system_group = SF.payload.servicetrade_assets_sprinkler_system_group || [];

const servicetrade_assets_sprinkler = SF.payload.servicetrade_assets_sprinkler || [];
servicetrade_assets_sprinkler_system_group.forEach(p => p.servicetrade_assets_sprinkler = []);
// assign children to their parents
servicetrade_assets_sprinkler.forEach(c => {
const foundParent = servicetrade_assets_sprinkler_system_group.find(p => === c.parentId);
if (foundParent) {
// this everything that's outside the subform group
asset_id: c.asset_id,
// this is everything inside the subform group
Sprinkler_Information: c
// servicetrade_assets is now only the parents (with their nested children underneath)
SF.payload.servicetrade_assets_sprinkler_system_group = servicetrade_assets_sprinkler_system_group;


For information on creating destination rules in the ServiceForms Connector, read this article.



All support requests for ServiceForms should be emailed to

Was this article helpful?