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,'job.location.primaryContact.email');
// the old way was:
SF.payload.servicetrade_contact_email = SF.job && SF.job.location && SF.job.location.primaryContact ? SF.job.location.primaryContact.email : null;

/* Organize all child assets under their parents */

// separate parents from children
const parentAssets = SF.payload.servicetrade_assets.filter(a => !a.parent || a.parent.name === 'Location - Building');
const childAssets = SF.payload.servicetrade_assets.filter(a => a.parent && a.parent.name !== '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 => p.id === 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 => p.id === 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 serviceforms@servicetrade.com.

Did this answer your question?