Script Types

Triggers

// Example of a custom time-based access control mechanism in an account trigger update.
var hour = new Date().getUTCHours();
if (!(hour >= 8 && hour <= 17)) {
    throw new Error('Updates are only allowed between 8am and 5pm GMT');
}

// Update the c_random property each time the instance is updated (not directly writable by the account holder).
script.arguments.new.update('c_random', Math.random(), {grant: 8});

Triggers can be setup to run before and/or after creation, update, and deletion of object instances, as well as before and after session authentications (to allow for custom authentication mechanisms).

Before Trigger

All before triggers are run inline, that is they return false or throw an error from the script to cancel the operation. In object instance before triggers, changes can be made inline to instance properties directly from the script, and made as either the script's calling principal or given a grant. These changes are recorded in the audit logs as separate events.

All before update trigger code should be idempotent - they should return the same result after every operation - as they may run more than once during update conflict resolution events.

After Trigger

An after script runs after the operation that triggered it has completed and is ideally suited for sending notifications. These triggers are guaranteed to run only once.

Routes

A route script creates new API endpoints for an organization. Route matching is available using wildcards, named-parameters and regular expression matching. A route can be set to run as the calling principal or as any other available org principal. ACL can also be applied at the configuration level in order to restrict endpoint access to a set of roles or specific accounts.

// example of utilizing a path parameter to output an xml-document.
// This route was configured as GET /routes/multiply/:a/:b

var req = require('request'),
    res = require('response'),
    xml = require('xml');

var response = {
    total: req.params.a * req.params.b
};

res.setHeader('Content-Type', 'text/xml');
res.write( xml.toXml(response) );

PUT and POST routes can be configured to parse application/x-www-form-urlencoded form data, as well as accept text/ content-types. When accepting text/ content, the request body will be in raw form. Otherwise, application/json and application/x-www-form-urlencoded are parsed into json objects.

Jobs

import notifications from 'notifications';
import moment from 'moment';

// load administrators.
const adminIds = org.objects.accounts
  .find({roles: '000000000000000000000004'})
  .paths('_id')
  .skipAcl(true)
  .grant(4)
  .map(doc => doc._id);

// set desired time periods.
const startDate = moment(new Date()).utc().subtract(1,'day').startOf('day').toDate(),
      endDate = moment(new Date()).utc().subtract(1,'day').endOf('day').toDate();

// aggregate counts.
const cursor = org.objects.c_widgets.aggregate()
  .match({created: {$gte: startDate, $lte: endDate}})
  .group({_id: null, count: {$count: '_id'}});

const count = cursor.hasNext() ? cursor.next().count : 0;

// create report.
const report = {
  c_num_new_widgets: count
};

// send notification to admins.
adminIds.forEach(_id =>
  notifications.send('c_daily_report', report, {recipient: _id})
);

Jobs are scheduled using standard cron syntax and are suited for maintenance tasks, statistics gathering and data post-processing.

Libraries

A library is a CommonJS library that can be loaded by triggers, jobs, routes, and other library scripts. The format follows that of a common js module. A library is configured with an Export property, the name that will be used to import into other scripts. The name follows the same c_ naming convention as the rest of the api.

For example, a library script with the Export name of c_utils could look like the following:

IMAGE HERE

With the following script:

/**
 * Utility Library
 */

module.exports = {

    foo: function() {
        return 'bar';
    },

    baz: function() {
        return 'qux';
    }

}

And could then be imported into other scripts like the following

/**
 * My Script
 */

import utils from 'c_utils'

return utils.foo() // returns 'bar'

Last updated