Basic Concepts

What is Scriptr.io?

Scriptr.io is a very powerful cloud service to run your server-side code. With scriptr.io, you use scripts to create the custom back-end APIs needed to power your Internet of Things (IoT) and other projects. Scriptr.io allows you to get productive quickly by providing an integrated web-based environment for developing, running and debugging your code. 

What are Scripts?

Scripts are units of execution, after you create a script, it immediately becomes a web service with a unique secure HTTP end-point and ready to run as soon as it is invoked. Scripts can be created to be used as web services or as modules for other scripts. You can invoke directly your new scriptr.io APIs from an IoT, mobile or web project or from other web services.

What is the Difference between Using scriptr.io and Running Your Own Servers?

With scriptr.io, you don't need to handle hosting, deployment, management and upgrade of servers such as application containers, database servers or libraries to integrate with social networks and other web services. When your product goes to production and you need quick reliable scaling, you don't have to figure-out server architecture, scalability strategies, fault-tolerance, etc... You only concentrate on improving the business logic needed to power your project while we make sure that everything else is running smoothly for you.

Supported Languages

For now our script containers support JavaScript. We will be adding other languages in the future.

What about Authentication and Security?

Scripts can be invoked as secure web services using HTTPS and by providing unique secure tokens associated with each account.

Invoking scriptr.io URLs

Scriptr.io scripts are invokable based on the following patterns for the POST and GET methods respectively:

POST
curl -X POST -F <requestParameter> -d <postBody> -H "Authorization: bearer <authorizationToken>" "https://api.scriptrapps.io/<scriptName>"
GET
curl -X GET -H "Authorization: bearer <authorizationToken>" "https://api.scriptrapps.io/<scriptName>?<requestParameter>"
ParameterDescription
httpMethodHTTP Verb:  POST, GET.
timestamp

A UNIX timestamp denoting the current time when the request is issued.

requestParameterRequest parameter specific to what your script is expecting.
postBody
"value1":"some value", "value2":"some value", "value3":"some value".
authorizationTokenUnique token provided for each account.
scriptNameThe unique name per account that you have given to the script you want to invoke.

What are Experimental Features? 

At scriptr.io, we keep improving our product to bring you the best. You might encounter several features that our team is still developing - they are labelled with the Experimental tag. You may tinker with them as much as you want, but beware that these experimental features might change, break, or disappear at any time.

Getting Started

Open an Account

You can create a new scriptr.io account from this page by providing your email and a password, or signing in with your GitHubTwitter or Facebook account. 

Write Your First Script and Run It

Once you log in to scriptr.io, you land on your workspace. There are plenty of very useful features in it. For now, we will just go ahead and create our first script by clicking New Script at the lower left corner of the screen.

In the scriptr.io editor, simply add a line to return the traditional "Hello world":

return "Hello world";
Once done, do not forget to name your script and save it before you execute it. Note that script names should abide by the following rules:
  • Must be minimum 3 characters and maximum 128 characters long, including any folders.
  • Can consist of up to 5 folders and the script file name separated by the character '/'.
  • Must begin with an alphabetic character.
  • Must end with an alphanumeric character or underscore (_).
  • Can contain alphanumeric characters, underscores (_) and periods (.).
  • Cannot have two or more consecutive periods.

Now run your script by clicking Run on the top-right part of the editor. Notice the console in the lower half of the screen where you can see the result of the execution. The first line of the console is the curl instruction to issue from an HTTP client to trigger the execution of your script.

What Can a Script Do? 

Well, actually, a lot. When using scripts, you have access to a very rich set of features and modules that are provided to you by scriptr.io, such as storage, gateways to IoT platforms, gateways to external web services, social networks, etc... Scripts allow you to implement all the business logic for your IoT solution.

Check the example below where we create a back-end API for a smart home ambiance regulator. Our script does the following:

  • Requires (imports) the scriptr.io http module.
  • Retrieves a location from the request it receives (sent by the regulator).
  • Invokes a remote weather REST API to obtain the weather forecast for the day.
  • Executes a function defined in the script to determine the ambiance according to the obtained temperature and humidity forecast.
  • Returns the resulting ambiance to the calling device.
// import the scriptr.io http module to issue calls to remote APIs
var http = require("http");

// retrieve the station parameter from the request
var station = request.parameters.station; // use location = 260

var weatherStationAPI = "http://fawn.ifas.ufl.edu/controller.php/today/obs/" + station + ";json";
// invoke the weatherStationAPI third party API
var callResult = http.request({
		"url" : weatherStationAPI
	});
// parse the result of the call using regular JSON object
var weatherInfo = JSON.parse(callResult.body); // returns an array of today's observations
var latestInfo = weatherInfo[0]; // get latest observation, first one on the list
var temperature2m = latestInfo.t2m;
var windSpeed = latestInfo.ws;
// return the result of the function call
return getAmbianceConfiguration(temperature2m, windSpeed);

// define a bespoke function
function getAmbianceConfiguration(temp, wind) {
	var tempCategory = (temp < 18) ? "Cold" : (temp >= 18 && temp <= 25) ? "Cool" : "Hot";
	var windCategory = wind < 20 ? "No Wind" : (wind > 20 && wind < 50) ? "Windy" : "Strong Wind";
	return {
		"temp" : tempCategory,
		"wind" : windCategory
	};
}

Authentication and Security

What are Tokens?

Tokens are credentials that you send to your scripts in order to authenticate you as the owner of the application. As a consequence, they grant you all privileges within the script. Note that you should keep your token secret and not distribute it.

Upon registration, scriptr.io provides you with the "scriptr" device and its token. You can send this token along with your requests in order to authenticate yourself as the owner of the application. Note that you should keep your token secret and not distribute it.

However, you can always create more devices and tokens to control who has access to your application.

What is an Anonymous Token?

Sometimes you will want to allow end users / devices to invoke your scripts without any authentication. Yet you still want to control who / what is able to do so. For that purpose, scriptr.io provides you with an Anonymous Token (similar to API keys) that you can distribute to those users.

How to Get Your Tokens?

Two tokens have automatically been generated for you when you first registered to scriptr.io. You can find them in your account's Info tab by clicking your username at the top-left corner of your workspace, then selecting Account. Moreover, you can create more tokens from the Device Directory section.

How to (Re)Generate Your Tokens?

Under the Device Directory overlay, in the Device tab, click the regenerate icon in order to create a new token.

Icon

After your generate a new token, all requests using the former version will fail to authenticate.

How to Use Your Tokens?

When invoking scriptr.io, you can pass a token to the request in one of the following ways:

  • In the request's Authorization header, such as "Auhtorization: bearer yourToken".
  • In the request's auth_token parameter.

Real-time Communication

Scriptr.io supports WebSocket connections to enable asynchronous 2-way communication allowing devices, scripts, and other "things" to communicate in a real-time fashion. You can call scriptr.io scripts through WebSockets as follows:

  1. Create a WebSocket connection to scriptr.io:
    wss://api.scriptrapps.io/
    <bearerToken>
    The bearerToken can be any token created under the Device Directory overlay or the anonymous token that you can find in the Accounts dialog in your scriptr.io account.
  2. Send a JSON message using the following format:
    {"method":"<scriptName>","params":{"<param1>":"<value1>","<param2>":["<value2>","<value3>",...]}}

The keys of the JSON message are explained in the table below:

Key
Description
methodThe script name to be called, i.e. the API endpoint such as Publish or Subscribe.
paramsThe parameters expected by the API being called.

Publish-Subscribe over WebSockets

Scriptr.io offers the Publish, Subscribe and Unsubscribe APIs over WebSockets. They all return a JSON object with the following properties:

PropertyDescription
idIdentifier that maps WebSocket client messages to server messages.
statusEither "success" or "failure" indicating the status of the operation.
statusCodeCode indicating the status of the operation.

Publish 

To publish a message to a specified channel that will be distributed to its subscribers, send a JSON message with the method set to "Publish" along with the following parameters:

Parameter
Description
channelThe channel name.
messageThe message to be distributed to subscribers.
Example
wscat -c wss://api.scriptrapps.io/PDIyODI2REM5MTpzY3JpcHRyOjBCNERBNzgyOTRFRTQwODI0RjdGM0ZGMaU5QzgwREVG
connected (press CTRL+C to quit)
< {"id":"7fea5a83","status":"success","result":"connected."}
> {"method":"Publish","params":{"channel":"myChannel","message":"Hello World!"}}
< { "id": "df7c3daa-be7f-ab40-08f9-713fb3a79b4e", "status": "success", "statusCode": "200"}

Subscribe

To subscribe the WebSocket connection to a channel in order for it to read all the messages published to that channel, send a JSON message with the method set to "Subscribe" along with the following parameter:

Parameter
Description
channelThe channel name.
Example
wscat -c wss://api.scriptrapps.io/TkU5MkMyMTg0NjpzJpcHAyOjb3OEI2ODQ0RDc0MjBCNDB3MkY4NUQ3RUE2NDc3RUEy
connected (press CTRL+C to quit)
< {"id":"7fea5a82","status":"success","result":"connected."}
> {"method":"Subscribe","params":{"channel":"myChannel"}}
< { "id": "df6c3daa-be7f-ab40-08f9-713fb3a79b4e", "status": "success", "statusCode": "200"}

Unsubscribe 

To unsubscribe a resource from a channel in order to stop receiving future messages, send a JSON message with the method set to "Unsubscribe" along with the following parameter:

Parameter
Description
channelThe channel name.
Unsubscribing from a Channel Example
wscat -c wss://api.scriptrapps.io/TkU5MkMyMTg0NjpzJpcHAyOjb3OEICNERBNzgyOjBCNDB3MkY4NUQ3RUE2NDc3RUEy
connected (press CTRL+C to quit)
< {"id":"7fea5a84","status":"success","result":"connected."}
> {"method":"Unsubscribe","params":{"channel":"channelName"}}
< { "id": "df8c3daa-be7f-ab40-08f9-713fb3a79b4e", "status": "success", "statusCode": "200"}
Icon

You can control whether anonymous or authenticated devices are allowed to subscribe and/or publish to your channels by setting their ACLs:

  • The publishACL determines which tokens can be used to publish to the channel.
  • The subscribeACL determines which tokens can be used to subscribe and unsubscribe from the channel.

Scriptr.io IDE

IDE Overview 

Scriptr.io provides an efficient web based IDE that gets you productive as soon as you sign up. 

Cloud Based IDE Overview Cloud Based IDE Overview
i
Create a new script by clicking on "New Script".
i
Create a new blockly script by clicking on the arrow icon next to the + New Script button then select New Blockly Script.
i
All the scripts you created are listed under "My Scripts". If you grouped your scripts into folders, click on the arrow next to the folder name to expand its content.
i
A merged list of your scriptr.io scripts and the scripts that you have under your GitHub repository will be displayed under "Synchronize". A contextual menu will give you the option of committing and updating the selected files.
i
When creating a new script, you need to give it a name. You can specify here the path (folders) to your script. For modifying the name of an existing script, click on the pencil icon.
i
Edit your script code in this section.
i
Navigate through the scripts that you already opened in the IDE by clicking on their respective tab.
i
You can run a script by clicking on "Run" and specify request parameters by clicking on the drop-down arrow.
i
Open the Schedule overlay so you can schedule your scripts. You have the option to pick either a one-time schedule or a recurrent schedule.
i
Subscribe the active script to a channel so that it can read and execute business logic on all the messages published to that channel.
i
Manage and configure your application.
i
Explore all scriptr.io REST APIs.
i
Show the cheat sheet to view the list of the IDE shortcuts.
i
The Allow Anonymous Requests checkbox displayed at the top of the editor controls whether or not the current script can be executed anonymously.
i
The console is where the outcome of your script is displayed. It also contains the curl instruction that was used to invoke your script.
i
The Notifications is where the outcome of your GitHub commit or update is displayed.
i
Hide/show/minimize/maximize the console.
 
  1. Create a new script by clicking New Script.
  2. Create different script or file types by clicking the arrow icon next to the New Script button, then selecting desired type such as Blockly Script, Google Charts or HTML file.
  3. All the scripts you created are listed under My Scripts. If you grouped your scripts into folders, click the arrow next to the folder name to expand its content.
  4. A merged list of your scriptr.io scripts and the scripts that you have under your GitHub repository will be displayed under Synchronize. A contextual menu will give you the option of committing and updating the selected files.
  5. When creating a new script, you need to give it a name. You can specify here the path (folders) to your script. For modifying the name of an existing script, click the pencil icon.
  6. Edit your script code in this section.
  7. Navigate through the scripts that you already opened in the IDE by clicking their respective tab.
  8. You can run a script by clicking Run. If you want to pass request parameters to the script, click the drop-down arrow then click Run....
  9. Open the Schedule overlay so you can schedule your scripts. You have the option to pick either a one-time schedule or a recurrent schedule.
  10. Subscribe the active script to a channel so that it can read and execute business logic on all the messages published to that channel.
  11. Manage and configure your application.
  12. Explore all scriptr.io REST APIs.
  13. Show the cheat sheet to view the list of the IDE shortcuts.
  14. The Allow Anonymous Requests checkbox displayed at the top of the editor controls whether or not the current script can be executed anonymously.
  15. The Console is where the outcome of your script is displayed. It also contains the curl instruction that was used to invoke your script.
  16. The Notifications is where the outcome of your GitHub commit or update is displayed.
  17. Hide/show/minimize/maximize the console.

Generating Code Using Blockly

Blockly is a library for building visual programming editors. The below example illustrates a Blockly block.

IoT Code Generator Using Blockly

Under the Scriptr menu you will find scriptr.io's specific blocks such as reading parameters, emailing and storage.

Icon

Note that Blockly is still an experimental feature, and not all its features are supported yet. The remaining features will be supported once we get out of the beta phase.

Creating Charts

The scriptr.io Chart Editor allows you to graph your data online, manage the graph and embed the visualization.

To create a new chart script, use the New Script drop-down list and select Google Chart. The editor opens in the workspace showing a customized version of the google chart editor. By default, a sample column chart is displayed on the right with pre-defined data.

The input data for the Google chart is returned by another script, called a data source script. You can select an existing script in your scriptr.io library from the drop-down list, or create a new script by clicking the New Script icon "+" next to the "select script" drop-down list. As soon as you select the data source script, the script gets executed and its result gets displayed in the chart. However, if the data returned by that script does not fit the format required by the selected chart, or the script encounters an error during its execution, an error message gets displayed.

Once the data source is selected, you can start customizing your chart on the fly. The Google chart Editor recommends charts based on the data you have selected to display, in the Recommended charts section.  

While working with a chart, there is context checking to ensure your data matches the selected chart type. If you select a chart type and afterwards select a data source with an incompatible data format, you get a message stating they do not match. All available chart types can be viewed by selecting More next to the Recommended charts section.

The tabs on the editor's right side contain additional information. The Data tab shows information about the script along with the successful execution data output. You can click Edit Script to open the script and perform updates to the data source script.

The Embed URL tab contains the information you need to serve your chart link, or embed it in your website inside an iframe. Clicking the link will serve your chart in a new browser tab. You may need to select Allow Anonymous Requests to allow the script to be run. 

From the HTML tab, you can copy the HTML source code of your chart and paste it anywhere in order to serve it. In this HTML code, you have the customization of the chart type you have selected and an AJAX call to scriptr.io to fetch your data source in order to populate your chart.

The Samples tab contains a list of data samples for testing.

Once the data source and the chart type are selected and customized, you can provide a name for your chart and save it like any other scriptr.io script. Once saved it will appear under My Scripts.

Creating Web Pages and Text Files

Our IDE simplifies the creation of multiple file types including text, HTML, JS and CSS giving you the power to visualize the data collected from your IoT devices.

In order to create files, go to New Script drop down list, then click File and select the type. The file will open with the selected type, however the extension is not added to the file name automatically upon selection; you need to add it manually e.g., homepage.html.

Cloud Based IDE for Applications on IoT Devices

You can serve the created files by clicking Run. This will open a new tab that will display the file content.

Creating a Finite State Machine

To create a Finite State Machine click the New Script drop-down list then select State Machine.

From the FSM editor, you can use the controls on the left side to add states and connect them with transitions. The transitions by default return true; you can edit the script to add the conditions for the transition.

In order to view the source code of the FSM, click the Editor View icon displayed on the FSM menu on the left side of the editor.

Once you save the FSM, you can run it and view the results in the Console tab. Moreover, you can schedule the FSM to run on a specific date or recurrent. You can also subscribe it to the channels you create.

Organizing Your Code

Scriptr.io allows you to store an arbitrary number of scripts and organize them into folders and folders hierarchy.

  • When naming your script, add the path of the folders before its name and the folder hierarchy will be created if it doesn't exist (e.g., folder1/folder2/scriptname). Note that a script can be created inside a hierarchy of maximum 5 folders.
  • You can put an existing script into a folder or move it from one folder to another by simply renaming it using the above notation.
  • As soon as you save the script, your list of scripts (left side of the screen) gets updated with the corresponding folder structure.

Running Your Script and Viewing the Result

Once you are done implementing your code and have saved it, just click Run button on the top of the code editor to run the script. The result is displayed in the console underneath the code editor.

From the console you can see:

  • The curl instruction that can be used to trigger your script from a remote HTTP client.
  • The messages logged in your script.
  • The response returned by your script.
  • The history of all the preceding executions of this script.

Passing Request Parameters from the IDE

Another cool feature of the scriptr.io IDE is that you can dynamically pass request parameters to your script before running it.

  • Click the drop-down arrow at the right of the Run button, then click Run...
  • Enter the expected parameter names and values. You can add more parameters by clicking the plus icon "+"
  • Once done, click Run to execute your script

IoT IDE Cloud Platform for Developers

Tip

Icon

If you need to send an array of parameters, just click the "+" sign to add the same field name multiple times with different values.

Script Scheduling

The Script Scheduler enables you to automatically perform routine tasks by running a chosen script. It can be used to execute scripts at specific times or on a recurrent schedule.

Icon

You cannot add more than 5 triggers per script.

To schedule a script, click Schedule and then click Add Trigger from the overlay. Once you start adding a new trigger you will get the following two options:

  1. Run On: this defines a one-time schedule. A calendar opens allowing you to pick a specific date and time for this trigger.
  2. Run Every: this defines a recurring schedule. You have two modes for entering the recurrent schedule information as described below:
    1. Basic: it is selected by default. In this mode you can visually select the recurrence period such as every hour, day, etc... You can choose multiple dates and times for a recurrent cron job.
    2. Advanced: you can switch to this mode by clicking the Advanced link displayed on the right side. In the advanced mode you can enter a cron expression to create a schedule which is a string made up of 5 or 6 space separated fields. The cron expression determines at what time intervals the script will run; its specs as well as some examples are described in the following sections.

When a script is scheduled, a clock icon appears next to its name in the My Scripts tab tree.

Icon
  • If you rename or delete a scheduled script, all the cron jobs associated with that script will be deleted.
  • Some advanced cron expressions cannot be displayed in basic mode.

Cron Expression Specs

The cron expression fields' definitions are as follows:

Field NameMandatoryAllowed ValuesAllowed Special Characters
MinutesYES0-59, - * /
HoursYES0-23, - * /
Day of MonthYES1-31, - * ? / L W
MonthYES1-12 or JAN-DEC (case insensitive), - * /
Day of WeekYES1-7 or SUN-SAT (case insensitive), - * ? / L #
YearNOempty, 1970-2099, - * /

The definitions of the special characters are as follows:

Special CharacterDefinitionExample
*

Used to select all values.

* in the hours fields means every hour.
?Used when no specific value is required.If 15 is used in the day of month field and ? is used in the day of week field, it means that the trigger will fire on the 15th irrespective of the day of week.
-Used to specify ranges.5-8 means every hour between 5 and 8, inclusive.
,Used to specify several values.MON,WED,FRI means that the trigger will fire on Mondays, Wednesdays, and Fridays.
/Used to specify increments. When no value is specified before the / it is equivalent to having 0.

5/20 in the minutes field means that the trigger will fire at minutes 5, 25, and 45.

/6 in the hours field means that the trigger will fire at hours 12 AM, 6 AM, 12 PM, and 6 PM.

LUsed to refer to the Last value in the field's allowed values.

6L in the day of week field means the last Friday of the month.

L in the day of month field means the last day of the month.

WUsed to specify the Weekday nearest to the specified day.

If 14W is specified, and the 14th is a Tuesday, it fires on Tuesday. However, if it is a Saturday it fires on Friday the 13th, and if it's a Sunday it fires on Monday the 15th. Note that if you specify 1W and the 1st is a Saturday, it fires on Monday the 3rd, as it does not jump to another month.

#Used in the day of week field to specify the nth day of the month.2#4 in the day of week field means the 4th Monday of the month.

Cron Expression Examples

ExpressionMeaning
0 0 * * ?Fire at midnight every day.
30 18 ? * *Fire every day at 6:30 PM.
43/5 * * * ? 2015Fire every hour at minutes 43, 48, 53 and 57 in 2015.
/10 15,20 * * ?Fire every 10 minutes starting at 3 PM and ending at 3:50 PM; and fire every 10 minutes starting at 8 PM and ending at 8:50 PM, every day.
20 9 ? * TUE-THUFire at 9:20 AM every Tuesday, Wednesday and Thursday.
45 13 ? * 7LFire at 1:45 PM on the last Saturday of every month.
30 10 ? * 4#1Fire at 10:30 AM on the first Wednesday of every month.
Icon

Note that you can also schedule a script using the built-in schedule function.

GitHub Integration

With GitHub integration, scriptr.io allows you to backup, version and import projects, from your workspace.

To configure the GitHub integration refer to the section GitHub below.

Synchronize View

The synchronize view will show you a merged list of scripts, both in scriptr.io and in the configured path, under your GitHub account. 

Each item in the view will have a set of icons explaining its state as described below:

IconDescription
This script exists in GitHub but not in scriptr.io, the icon indicates that an update will create (+) it in scriptr.io, while a commit will remove (-) it from GitHub.
This script exists in scriptr.io but not in GitHub, the icon indicates that an update will remove (-) it from scriptr.io, while a commit will create (+) it in GitHub.
This script exists both in scriptr.io and in GitHub, you can commit your latest changes to GitHub or update with the latest committed version.

Automatic Deployment

When you connect to your GitHub account from Settings | GitHub tab, you can enable automatic deployment. Once enabled, a full deployment of your entire GitHub repository will be triggered to your scriptr.io account in the following two scenarios:

  1. When committing a change to GitHub while having the @AUTO-DEPLOY keyword anywhere in the the comment field.
  2. When triggering a GitHub deployment event.

To disable it, go to Settings | GitHub tab and click Disable Automatic Deployment.

Icon

The Purge feature is ON by default, which means that any scriptr.io files that are not in your GitHub repository will get deleted during automatic deployments. However, you can turn OFF the Purge feature at any point from your Settings | GitHub tab.

Icon

Enabling the automatic deployment creates the deployment-execute group and the scriptr_GitHub.com device. You can see them in your Device Directory and delete them at anytime causing your automatic deployment to be disabled. We strongly recommend not deleting these created group and device, and using the Disable Automatic Deployment button under the Settings | GitHub tab when you wish to disable it.

Compare Editor

The compare editor allows you to compare and merge differences between the script version that you have locally on scriptr.io with the one that you have on your GitHub repository. In order to open it:

  1. Go to the Synchronize tab.
  2. Right-click a script name and select Compare.
  3. The compare editor opens showing the working copy on the left side and the GitHub copy on the right side.

Update All

From the Synchronize tree view, you can update the files from the GitHub repository to your scriptr.io account by clicking the Update all icon instead of selecting each file by itself. This action creates a deployment on your GitHub account. Deployments provide the advantage of real-time status tracking which can be obtained from GitHub.

Script Subscription

The publish-subscribe feature in scriptr.io allows a script to subscribe to a channel. Whenever a message gets published to this channel, the subscribed scripts will get triggered, and the message will be available in the request.rawBody property.

There are two ways of subscribing a script to a channel:

  1. Through the Channel tab by clicking the script icon .
  2. Through the subscription dialog by clicking Subscribe which can be accessed from the script editor. The subscription dialog will list all the available channels allowing you to switch the ON/OFF button in order to subscribe/unsubscribe your script.

Note that you can subscribe/unsubscribe scripts via the scripting module pubsub.

Custom Sub-Domain

Scriptr.io provides you with the ability to access your APIs using your own custom sub-domains (e.g., mydomain.scriptrapps.io). This will allow you to call public APIs without passing the anonymous token. For instance you can serve files such as http://mydomain.scriptrapps.io/dashboard.

To add a sub-domain:

  1. Open the Account dialog then switch to the Sub-Domain tab.
  2. Add your custom sub-domain then save.

To delete the sub-domain, you can clear the field then click the save icon.

Icon
Not all sub-domain names are available. Moreover, sub-domain names cannot exceed 64 characters and only accept alphanumeric characters.

Communicating over MQTT and WebSockets

The easiest way to communicate with IoT devices over the MQTT (Message Queue Telemetry Transport) and WebSocket protocols from scriptr.io is by configuring external endpoints then bridging them to channels to which your scripts can subscribe. An external endpoint in scriptr.io is a configuration entry that defines how to connect to a "thing". This includes defining the protocol to use, the URL and port to connect to, in addition to the name of the endpoint and other protocol-specific information such as authentication settings. In order to create an external endpoint, go to Settings, click on the External Endpoints tab, then click on Add External Endpoint Configuration.

Once you configure an external endpoint, all you need to do is go to the Channels tab and bridge it to a channel by clicking on Manage Bridges next to any channel as you can see in the screenshot below. When creating a bridge, which is a connector that connects a "thing", or external endpoint, to a channel, you also need to provide the token to be used by the channel's publishers or subscribers to send/receive messages over it.

Settings

You can manage your account's settings by clicking your username (top-left corner of the workspace) then selecting Settings.

Configuration

CORS

CORS is a mechanism that allows cross-domain communication from HTTP clients by allowing resources on a web page in a given domain to be requested from another domain.

You can edit the field by clicking the pen icon, adding a comma separated list of domains and submitting.

Notification

Scriptr.io provides you with a mean to push notifications to any iOS and Android devices.

From the Configuration section, you can start by creating the appropriate certificates and/or GCM key and save them.

From the Groups section, you can manage groups of iOS and Android device tokens.

Configuration Sub-tab

Currently, scriptr.io provides you with three built-in configurations as listed below:

  1. Development Certificate for iOS
  2. Production Certificate for iOS
  3. GCM API key for Android
iOS Configuration

To attach a production or development iOS certificate, under the iOS Credentials section of the Notification tab, click Add certificate link to upload the certificate and add the relevant password before clicking the Save button.

Note that in order to use your iOS certificate with scriptr.io, make sure to export it to a Personal Information Exchange format (.p12).

Android Configuration

To save a GCM key in your scriptr.io account, under the Android Credentials section of the Notification tab, click Add GCM API Key link, type the key provided by Android and click Save. The same applies to the Default Notification Icon Path which is the path of the icon to be used when the message pushed does not have a payload, in which case, it will be wrapped with a default payload (as described in the push function specs) which requires an icon path to be set. This default notification icon will be read from the configuration.

Once set up, refer to the push function in the Built-in Objects & Functions section above to learn how to send push notifications from your scripts.

Note that you can remove the certificates and GCM key at anytime, however, you will no longer be able to push notifications.

Groups Sub-tab

Scriptr.io gives you the ability to send real-time messages to your mobile device applications. With our group management module, you are able to add iOS and Android device tokens to a group and push notifications in batches by sending to any group.

In order to create a group of mobile device tokens, go to Settings | Notification tab then go to the Groups sub-tab.

Once you click Add Group, a row appears where you can add a unique group ID and select a configuration ID from the drop-down list. Adding and removing mobile device tokens to groups can only be done through the addToGroup and removeFromGroup APIs.

Icon
If you haven't setup your iOS and Android configurations yet, you will not be able to create a group of push tokens. Moreover, if you already have groups created and you deleted your Android and/or iOS configurations, the notifications sent to this group will not be delivered.

GitHub

Under this tab you can connect an GitHub repository to your scriptr.io account in order to benefit from the features described in section GitHub Integration.

Facebook

In order to call the Facebook APIs through scriptr.io, you need to specify the API Key, API Secret and the Access Token of your Facebook app.

To manage the Facebook settings, open the Settings dialog, go to the Facebook tab, fill in the desired fields then click Save.

You can delete the settings at anytime by clicking Clear.

Twitter

In order to call the Twitter APIs through scriptr.io, you need to specify the Consumer Key, Consumer Secret, Access Token and Access Token Secret of your Twitter app.

To manage the Twitter settings, open the Settings dialog, go to the Twitter tab, fill in the desired fields then click Save.

You can delete the settings at anytime by clicking Clear.

Channels

This tab allows you to manage channels to be used for the publish-subscribe feature as described in section Script Subscription. From there you can subscribe/unsubscribe scripts to channels, and bridge/disconnect channels to/from external endpoints.

External Endpoints

As described in the section Communicating over MQTT and Web Sockets, this tab is where you manage your external endpoints in order to connect them to channels.

Device Directory

Controlling access to your scriptr.io application can be achieved by using the Device Directory which provides token and device management capabilities. To do that, click on your username (top-left corner of the workspace) then on Device Directory. A dialog opens showing two tabs - Devices and Groups - that are described below.

Devices

This tab lists all the devices available in your account, such as scriptr.io which is your first device created at registration time.

The token of the scriptr device identifies you as the owner of the application and is used by the system when running and serving scripts and files through the IDE.

The Devices tab allows you to:

  • Add more devices and tokens — to control who has access to your application.
  • Delete devices — to permanently prevent access to your application using their tokens.
  • Edit the description of your devices.
  • Assign or remove devices to/from groups.
  • Suspend or activate devices — upon creation devices are active. Suspending devices will temporarily prevent access to your application using their tokens until you re-activate them.
  • Regenerate devices tokens — regenerating a token will overwrite and invalidate the current one.

Groups

A group is a collection of devices, to whom you might want to grant the same permissions. While access to your application can be granted on a per device basis, the purpose of a group is to make management more convenient when working with a large number of devices.

The Groups tab lists all your groups and allows you to:

  • Add groups — the groups that you create here will appear in the Access Control List dialog.
  • Delete groups — deleting a group will not delete its devices, it will remove them from it and they will lose any permissions that were granted to the group.
  • Edit groups — to update their names. Any devices that were members of the group and any permissions that were granted to it before editing will remain.
  • Manage the members of groups — by assigning or removing devices. The members of a group are granted the group's permissions. When you remove a device from a group it will automatically lose any permissions that were given to that group.

Access Control List

Scriptr.io gives you full control on who can use your application by allowing you to configure an access control list for all your API endpoints.

You can open the Access Control List dialog by clicking the icon  on the top right of any of your editors. It allows you to configure which tokens can be used to run a script or serve a file depending on the type of the API endpoint.

Although you can grant permissions on a per device and per group basis, scriptr.io provides three additional predefined groups:

authenticatedGrants access to all authenticated devices, i.e. any request with a valid token that belongs to any of your scriptr.io devices can execute the API endpoint.
anonymousGrants anonymous access to the specified API endpoint, i.e. anyone can execute the API endpoint without having to pass any tokens by calling it on your sub-domain. However, the Anonymous Token should be passed in the request if it is called on the public domain (https://api.scriptrapps.io/).
nobodyDenies access to the specified API endpoint, i.e. the API endpoint cannot be executed even when using your scriptr token from the IDE.

The Access Control List icon will change according to whether or not access is restricted:

Access to the specified resource is restricted to a list of devices.
Anyone can run or serve the resource.

By default, the ACLs of any new endpoints are configured to be the scriptr device, except for Google Charts and files that are granted anonymous access upon creation.

Icon

When you require a script within another script using the require() statement, its ACL gets ignored and it gets executed with "super user" privileges. For instance, if you have a script with its ACL set to nobody, and you require it inside another script, it will execute normally when its parent script gets executed.

Icon

When you schedule a script, its ACL gets ignored upon execution as it runs with "super user" privileges.

Installing Modules

The Install Modules tool allows you to extend your scriptr.io modules by adding your own. You can either pick from the wide array of modules distributed by scriptr.io or you can easily import your own from GitHub. In the list of modules provided by scriptr.io you will find:

  • Connectors allowing you to integrate and orchestrate different APIs offered by a large range of IoT providers. See the full scriptr.io connector list here.
  • Open source JavaScript libraries modified to work with scriptr.io.

To manage your modules, use the New Script menu, choose Install Module, and you will see the list of available modules.

To install a module from the list, simply click Install and it will be automatically installed in your scripts library under the modules folder.

To import a module that is not in the list, you can import it from GitHub by clicking Add Custom Module from GitHub, fill in the repository details along with the destination folder under which the repository scripts will be installed, and click Install. It will be imported under the destination folder that you specify.

Partners in Cloud Based IDE Scripting Applications

Once installed, you will be able to locate the new modules in the My Scripts tree under the modules folder in case it is provided by scriptr.io, or the user specified folder in case it is custom. It can be used the same as other scriptr.io scripts, i.e. using the require("module_name") built-in function where module_name is the module's folder name including its path.

Scripting Modules for IoT Applications

Terminal

The terminal is a scriptr.io debugging tool that provides a rich set of commands for invoking endpoints using different protocols and options. It can be used to invoke endpoints on different scriptr.io accounts by simply changing the token using the set command. By default, it is set to the hosting account's token.

CommandDescription
aboutDisplays information about the scriptr.io terminal.
clearClears the terminal.
deleteInvokes an endpoint using the DELETE HTTP method.
echoOutputs its argument to the terminal.
getInvokes an endpoint using the GET HTTP method.
helpProvides information about the provided command. If no argument is passed, it lists all available terminal commands.
historyShows the list of recently entered commands.
mapCommand

While you're debugging, you may find that you are invoking an endpoint frequently with a complex sequence of parameters. To save yourself time, assign the sequence of parameters to the ordered arguments to be passed to your endpoints by using the mapCommand command. After doing so you will be able to invoke an endpoint using the POST HTTP method by simply typing its name followed by the ordered list of arguments corresponding to the parameters you previously mapped. Note that this mapping only lasts for the time of the session.

optionInvokes an endpoint using the OPTION HTTP method.
patchInvokes an endpoint using the PATCH HTTP method.
postInvokes an endpoint using the POST HTTP method.
putInvokes an endpoint using the PUT HTTP method.
setSets the token to be used by the terminal when invoking scriptr.io endpoints.
themeChanges the terminal theme and sets it to the passed argument. The argument value can either be white or default.
wsInvokes an endpoint using a WebSocket connection.
<endpoint>

Invokes the <endpoint> using the POST HTTP method. For instance, invoking a script called HelloDevice that takes a parameter called myName can be done as follows:

HelloDevice -d {"myName" : "John"}

For help on using each of the above listed commands, just type "help <command>" in the terminal and it will display its description, list of supported arguments along with an example on how to use it.

To configure your terminal, create a text file on your root folder and call it Autoexec.terminal. Any commands it contains will get automatically executed upon loading the terminal. You can use this feature, for instance, to set your favorite theme, use a specific token or map command arguments.

Built-in Objects & Functions

Below are all the built-in objects and functions that are directly available in your scripts without having to require them.

console

The console logger is a scriptr.io built-in object used to debug your scripts allowing you to output your logs directly to the console.

The available logging functions are error(), warn(), info(), log() and debug() (note that the info and log functions have the same log level). You will also need the setLevel() function that allows you to control the minimum level that will be output to the console. By default, the level is set to DEBUG.

Example
console.setLevel("INFO"); //levels are ERROR | WARN | INFO | DEBUG | OFF
 
console.error("This is the error message of the script");
console.warn("This is the warning message of the script");
console.info("This is the info message of the script");
console.debug("This is the debug message of the script");

facebookPost

The built-in facebookPost function allows you to publish to a Facebook Timeline directly from within a script, by passing the following parameter:

ParameterDescription
messageString representing the message to be posted to a Facebook Timeline using the app's credentials saved in your Settings.

Return value: JSON object containing a Facebook post "id". In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

isGroupInAcl

This built-in function checks if a group is granted permission by a specific ACL.

ParameterDescription
groupIdString representing a group name.
aclString representing an ACL policy, which consists of a semi-colon separated list of users, devices and/or groups.

Returned result: a boolean value specifying whether or not the group is granted permission.

Example
return isGroupInAcl("subscribers", require("pubsub").getChannel("myChannel").result.subscribeACL);

isIdInAcl

This function checks if a device or user is granted permission by a specific ACL.

ParameterDescription
idString representing a user or device identifier.
aclString representing an ACL policy, which consists of a semi-colon separated list of users, devices and/or groups.

Returned result: a boolean value specifying whether or not the resource is granted permission.

Example
var pubsub = require("pubsub");
// Check if the current user has permission to publish messages to the channel called "myChannel"
if (isIdInAcl(request.user.id, pubsub.getChannel("myChannel").result.publishACL)) {
    // publish message to "myChannel"
    pubsub.publish("myChannel", "Hello Device!");
}

jsonToXml

This function converts a JSON object or string to an XML string.

ParameterDescription
jsonA JSON object or string to be converted to an XML string.

Return value: an XML string.

publish

Publishes a message to a specified channel that will be sent to its subscribers.

Parameter
Description
channelName String representing the name that serves as a unique identifier for the channel.
messageJSON, including objects, strings, and numbers, representing the message to be distributed to subscribers.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
return publish("myChannel", "Hello Device!");

push

The built-in push function empowers your scripts to push notifications to iOS and Android devices.

ParameterDescription
devicesArray of device tokens to which you want to send the notification to.
message

String representing the payload containing the notification message to be sent. For iOS payload details, please refer to the The Notification Payload tutorial.

For Android, the payload needs to be sent in the following format '{\"key1\":\"value1\",\"key2\":\"value2\", ...}'.

platformThe targeted platform, i.e. the platform of the devices (iOS or Android).
isProduction

This parameter is ignored if the notification is meant to be sent to some Android devices and will only be taken into consideration for iOS devices. It is a boolean value indicating if the push notification should be sent to your production or development application. Defaults to true. 

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Start by setting up your account and then simply follow these examples:

iOS Example
var message = '{"aps": { "alert" : "The notification you want to send", "badge" : 5, "sound" : "default"}}';
var arrayDevices = ["45866802973125d73b144b6c5d9c17b24fb4b09cf4d7bff855e2dd8e852a49c6","4565656d3423e455b45355c34243f3553f3255b235352c55454dd3255e324b24"];
var deviceType = "ios";

//this is a push to iOS using the development certificate.
var isProduction = "false";
return push(arrayDevices, message, deviceType, isProduction);

//this is a push to iOS using the production certificate.
isProduction = "true";
return push(arrayDevices, message, deviceType, isProduction);
Android Example
var message = '{"Content":"The notification you want to send"}';  
var arrayDevices = ["APA91bHBCTUA8vITavb-yaB2xZlB93xQB1WcquAyzYBjSAJpiEWslvjl-er-1kdvO2VVu52CpgI-ATcMrMs7rKnjInKO2di7pR9njJLJQxd4AK4vpZvGgkxQB2G5fVurKJgiwFKi7Zyyatd0lVy_8GnhieEHUMUbhagURgSTJ7l-dBES00H2eVI"];
var deviceType = "android";
return push(arrayDevices, message, deviceType);

pushToGroup

The built-in pushToGroup function allows you to push notifications directly from within a script to iOS and Android devices, by passing the following parameters:

ParameterDescription
groupIdString representing the identifier for sending push notifications to a particular mobile application.
messageString or JSON representing the message you want to send to the devices through your application.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Icon

For information about how to create a group of mobile device tokens, see section Groups Sub-tab.

request

You can use the request built-in object to retrieve the HTTP request parameters as well as other useful information. 

PropertyDescription
idRequest identifier.
methodName of the HTTP method used for the request.
headers

A map containing the HTTP request headers: "host", "content-length", "accept", "origin", "user-agent", "authorization", "content-type", "referrer", "accept-encoding", "accept-language", "x-forwarded-for", "x-forwarded-scheme", "connection".

rawBodyThe HTTP request body that carries the actual message data.
parametersA map containing the request's parameters.
queryStringQuery string passed to the request.
files

A map containing file objects representing the files sent as request's parameters. Each file object has the following attributes: "paramName", "fileName", "size", "contentType", and "content".

require

The built-in require function allows you to include a module inside your script in order to be able to use its functions and objects. Refer to the modules section for more details.

ParameterDescription
moduleNameThe name of the module to include in the current script.
Icon

When adding a core module to your script, you should require it by name (i.e., require("http")) while requiring your own modules should be done by specifying an absolute path (i.e., require("/myOwnModule")) or the relative path (i.e., require("../../anotherModule") ).

Example
// require the "http" module
var http = require("http");
// After requiring the module "http" you can use its function "request"
var response = http.request({"url": "http://api.openweathermap.org/data/2.5/weather","params": {"q":"london,uk"}});
return response;

response

You can use the response built-in object to intercept the HTTP response stream and manipulate it before it gets sent to the client. However, make sure to set the response CORS headers whenever you call any of the response object's methods.

Example
response.write("hello");
// whenever you manipulate the response object make sure to add your CORS settings to the header
response.addHeaders(configuration.crossDomainHeaders);
response.close();

The response object supports the following methods:

addHeaders

This method allows adding a set of headers to the response. 

ParametersDescription
headers

Map of HTTP response headers represented as a JSON object.

close

This method flushes the data to the stream then closes it. No data can be written to the response after this operation.

flush

This method flushes the output stream and forces any buffered output bytes to be written out.

setHeader

This method allows setting the value of a specified response header. 

ParametersDescription
nameString representing the header name.
valueString representing the header value.

setStatus

This method allows setting the status code of the response. 

ParametersDescription
statusInteger representing the HTTP response status code.

write

This method allows writing a string to the body of the response.

ParametersDescription
bodyString representing the body content of the response.

runAs

By default, everything you do within a script runs with owner privileges. However, if you wish to execute APIs using limited privileges, you can wrap your code inside a function, pass it to runAs() and specify the ID of the device that will be used to invoke that code.

ParameterDescription
functionFunction wrapping the code you need to run using the privileges of the device with the specified id.
idString representing the ID of the device to be used to run the function.

Return value: null.

Example
/* In the following example, executing this script as the scriptr device will succeed. 
 * However, if you use a different device that doesn't have the permission to save a document in the DefaultStore, 
 * the documents.create() function will fail with a PERMISSION_DENIED exception.
 */

var documents = require("document");
var stores = require("store");

// Retrieve the id of the device issuing the request
var userId = request.user.id;

// Update the ACL on the DefaultStore to allow the scriptr device to create documents
stores.update("DefaultStore", {"saveDocumentACL":"scriptr"});

// The code wrapped in the following function will be executed using the privileges of the device issuing the request (userId)
runAs(function(){

// Create a document with the privileges of the device issuing the request
 documents.create({"myfieldName":"value"});

}, userId);

schedule

The built-in function schedule allows you to schedule a script to be executed at a specific date or periodically at fixed dates or intervals.

Parameter
Description
scriptNameString representing the name of the script to execute.
triggerString or Date object indicating when the script will be executed. The script can be scheduled to run at a specific date by passing a Date object or a date string with an ECMA standard ISO date format yyyy-MM-dd'T'HH:mm:ss.SSS'Z' (ex. 2015-09-08T14:28:41.093Z). Alternatively, it can be scheduled to run periodically at fixed dates or intervals by passing a string representing a cron expression.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
schedule("myScript", "2016-09-08T14:28:41.093Z"); // "myScript" will run on the 8th of September 2016 at 14:28 UTC
schedule("myScript", "30 7 ? * MON-FRI"); // "myScript" will run every weekday at 7:30 AM

sendMail

The built-in sendMail function allows you to easily send emails from your scripts by directly calling it using the following parameters:

ParameterDescription
toRecipient's email address.
fromNameSender's name e.g., John Smith.
subjectEmail's subject.
body

Email's body (sent as content type text/html).

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var time = new Date();
var mailBody = "Hello,<br>An intrusion was detected at " + time + "<br>";
mailBody += "<a href='https://api.scriptrapps.io/discard?id=" + request.id + "'>Click here to discard the alert</a>";
var emailConfig = {
  "to": "joe.developer@scriptr.io",
  "fromName": "Joe",
  "subject": "Intrusion alert",
  "body": mailBody
};
return sendMail(emailConfig.to, emailConfig.fromName, emailConfig.subject, emailConfig.body);

storage

script.io provides developers with means to persist data from their scripts using the built-in storage object that exposes two levels of persistence: local and global.

PropertyDescription
localAllows you to store data that is only available to the script that persisted the data.
globalAllows you to store data that is available to all your scripts.

Local Storage

The local storage is accessible through "storage.local". To manipulate data contained in the local store of a script use the following notations:

Example
// we persist (create/update) the "vehicleCount" field
// in the local storage
storage.local.vehicleCount = 100;
// we read the persisted "vehicleCount" field
// from the local storage
var vehicles = storage.local.vehicleCount;
// we delete the "vehicleCount" field
// from the local storage
delete storage.local.vehicleCount;
Example
var vehiclesPerSecond = request.parameters.vehiclesPerSecond;
var lastCount = storage.local.lastCount;
if (lastCount && lastCount < vehiclesPerSecond) {
	storage.local.lightDuration = storage.local.lightDuration - 10;
}
if (lastCount && lastCount > vehiclesPerSecond) {
	storage.local.lightDuration = storage.local.lightDuration + 10;
}
broadcast(storage.local.lightDuration);
storage.local.lastCount = vehiclesPerSecond;
return storage.local.lastCount;

function broadcast(value) {
	// broadcast this value to all traffic lights
}

Global Storage

The global storage is accessible through storage.global. To manipulate global fields within your scripts use the following notations:

Example
// we persist (create/update) the "traffic" field
// in the global storage
storage.global.traffic = new Array();
// we read the persisted "traffic" field
// from the global storage
var traffic = storage.global.traffic;
// we delete the "traffic" field
// from the global storage
delete storage.global.traffic;
Example
var vehiclesPerSecond = request.parameters.vehiclesPerSecond;
var lastCount = storage.local.lastCount;
if (lastCount && lastCount < countOfVehiclesPerSecond) {
  	storage.local.lightDuration = storage.local.lightDuration - 10;
}
if (lastCount && lastCount > countOfVehiclesPerSecond) {
	storage.local.lightDuration = storage.local.lightDuration + 10;
}
broadcast(storage.local.lightDuration);
storage.local.lastCount = vehiclesPerSecond;
// We need to persist the evolution of the traffic as a global field, i.e. shared by all scripts
if (!storage.global.traffic) {
  storage.global.traffic = new Array();
}
var data = {
  "time": new Date().getHours(),
  "vehicles": storage.local.lastCount
}
var traffic = [data].concat(storage.global.traffic);
storage.global.traffic = traffic;
return storage.local.lastCount;

function broadcast(value) {
	// broadcast this value to all traffic lights
}

tweet

The built-in tweet function allows you to tweet directly from within a script by passing the following parameter:

ParameterDescription
tweetStringString representing the new status to post to Twitter using the app's credentials configured in your Settings.

Return value: JSON object containing the result of the tweet. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

xmlToJson

This function converts an XML string to a JSON object.

ParameterDescription
xmlXML string to be converted to a JSON object.

Return value: JSON object.

Modules

script.io is built with modular design in mind. A module is a reusable piece of software that defines variables, functions and/or objects that you can require and use in your own scripts. While some of the modules you will be using are provided by scriptr.io or other third parties, called the core modules, you also have the possibility to create your own modules which are regular scriptr.io scripts. The difference with other scripts is that it should not be directly invoked through HTTP requests and hence, they usually expose fields, functions or classes only.

In order to add a module to your script, i.e., be able to use the functions and/or objects it defines, just use the require("module") instruction.

Definition of the homeAutomation module
function HomeAutomationManager() {
  this.rooms = [
    {"master": {"temperature": 22, "light": false}}, 
    {"kids": {"temperature": 22, "light": false}}, 
    {"living": {"temperature": 22, "light": false}}
  ];
  this.doors = [{"font":false}, {"garage":false}];
}
HomeAutomationManager.prototype.getReport = function() {
  return "Rooms: " + "\n" +  JSON.stringify(this.rooms) + "\nDoors:\n" + JSON.stringify(this.doors);
}   	
Definition of the getReportAPI script that requires the homeAutomation module
var homeAutomation = require("./homeAutomation");
var homeAutomationMgr = new homeAutomation.HomeAutomationManager();
return homeAutomationMgr.getReport();

Note that most scriptr.io functions return a JSON object with the following two properties:

  1. result: containing the actual return result of the function.
  2. metadata: containing the status of the operation and any error details in case of failure.
Example of a Typical Success Response
{
	"result" : {
		"device" : {
			"id" : "AB825CE1520F"
		}
	},
	"metadata" : {
		"status" : "success"
	}
}
Example of a Typical Failure Response
{
	"metadata" : {
		"status" : "failure",
		"statusCode" : 400,
		"errorCode" : "INVALID_PARAMETER_VALUE",
		"errorDetail" : "Invalid value for fieldName [acl]."
	}
}

device Module

The device module allows you to create and manage devices. Each device is associated to the below schema that provides the basic device fields and ACLs. You can modify the schema to meet your needs by updating the apsdb_device system schema.

<!-- 
This is the default device schema. Feel free to modify it to your liking.
This schema follows all rules and restrictions as all other schemas, as do, the documents (devices) created out of it.
However, it imposes the following restrictions of its own:
1. The seven default fields (groups, name, id,token, password, locale and isSuspended) are required.
2. This schema cannot be deleted.

Additionally, since this schema is used for device management, the following ACLs are set by default upon creation of each new device document:
- document.readACL = id, creator
- document.writeACL = id, creator
- required.readACL = nobody
- required.writeACL = nobody
- requiredVisibles.readACL = creator
- requiredVisibles.writeACL = nobody
- requiredEditables.readACL = creator
- requiredEditables.writeACL = creator

You can specify your own ACLs upon device creation by passing them as parameters to the save function of the device module as described in the documentation.
-->
<schema>
  <aclGroups>
    <aclGroup name="required">
      <read>nobody</read>
      <write>nobody</write>
      <fields>
        <field>isSuspended</field>
      </fields>
    </aclGroup>
    <aclGroup name="requiredVisibles">
      <read>creator</read>
      <write>nobody</write>
      <fields>
        <field>id</field>
        <field>groups</field>
        <field>token</field>
      </fields>
    </aclGroup>
    <aclGroup name="requiredEditables">
      <read>creator</read>
      <write>creator</write>
      <fields>
        <field>name</field>
        <field>password</field>
        <field>locale</field>
      </fields>
    </aclGroup>
    <defaultAcl>
      <read>creator</read>
      <write>creator</write>
    </defaultAcl>
    <schemaAcl>
      <read>creator</read>
      <write>creator</write>
      <delete>nobody</delete>
    </schemaAcl>
  </aclGroups>
  <fields>
    <field name="id" type="string" />
    <field name="name" type="string"/>
    <field name="groups" type="string" />
    <field name="password" type="string" />
    <field name="locale" type="string" />
    <field name="isSuspended" type="string" />
    <field name="token" type="string" />
  </fields>
</schema>

save

Saves a device with the provided fields. If the device already exists, it gets updated; otherwise, it gets created.

ParameterDescription
deviceA JSON object containing the device fields.

Return value: JSON object containing the "id" of the device that was successfully created/updated. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The device object properties are as follows:

PropertyDescription
id

String representing the unique identifier of the device. Optional upon device creation, if not provided, a random ID will be generated.

It accepts alphanumeric characters, at signs (@), underscores (_), periods (.), and dashes (-) can have a maximum length of 243 characters.

nameString representing the name of the device. Optional upon update.
passwordString representing the password of the device. Optional upon update.
groups

Represents the group(s) to which this device will be added. It can have any of the following values:

  • a single value.
  • an array of strings to specify multiple groups.
  • a JSON object representing which values should be appended or deleted upon update (e.g. "groups": {"append":["groupB", "groupC"], "delete":"groupA"}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing field.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing field.

Group name accepts alphanumeric characters (a-z A-Z 0-9), dashes (-) and underscores (_), and can have a maximum length of 128 characters.

Note that passing a null or empty value removes the device from all groups.

isSuspended

Boolean value specifying whether or not the device is suspended. Optional, defaults to false.

When set to true, the device will be treated as if it was deleted from the system. It can be reactivated by updating this value to false.

globalDateFormat

String representing the date format to use to parse any date field values passed as string. Optional, if not specified, the formats "yyyy-MM-dd'T'HH:mm:ssZ" (e.g. 2017-01-13T13:01:02+0000) and "yyyy-MM-dd" (e.g. 2017-01-13) only will be accepted.

Refer to this document for the accepted date formats.

meta.types

JSON object containing the list of the document field names to be created/updated along with their corresponding types. The field types can be:

  • string
  • text
  • date
  • numeric
  • geospatial (a pair of longitude and latitude coordinates represented in decimal degrees)

Note that any fields omitted from the meta.types will default to type string, unless otherwise specified in the corresponding device schema.

<fieldName>

Key-value pair representing the name of the field along with its values.

Each value can be:

  • a single value.
  • an array of values for multi-value fields.
  • a JSON object representing which values should be appended or deleted upon update (e.g. "states": {"append":["New Mexico", "Washington"], "delete":["Utah"]}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing field.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing field.

Note that passing a null or empty value deletes the field from the device.

A field of type file should always be defined in the schema first.

Example - Editing the Device Schema
// We need to edit the device schema to allow adding a field called reports for saving files
var newSchemaDefinition = '<schema><aclGroups><aclGroup name="required"><read>nobody</read><write>nobody</write><fields><field>isSuspended</field></fields></aclGroup><aclGroup name="requiredVisibles"><read>creator</read><write>nobody</write><fields><field>id</field><field>groups</field><field>token</field></fields></aclGroup><aclGroup name="requiredEditables"><read>creator</read><write>creator</write><fields><field>name</field><field>password</field><field>locale</field><field>reports</field></fields></aclGroup><defaultAcl><read>creator</read><write>creator</write></defaultAcl><schemaAcl><read>creator</read><write>creator</write><delete>nobody</delete></schemaAcl></aclGroups><fields><field name="id" type="string" /><field name="name" type="string" /><field name="groups" type="string" /><field name="password" type="string" /><field name="locale" type="string" /><field name="isSuspended" type="string" /><field name="token" type="string" /><field name="reports" type="file" /></fields></schema>';

var schema = require("schema");
return schema.update("apsdb_device", newSchemaDefinition);
Example - Saving a Device
var devices = require("device");

var reportA = request.files["reportA"][0];
var reportB = request.files["reportB"][0];

var lastOnline = new Date();

var params = {
	"id" : "AB825CE1520F",
	"password" : "1a2afef9b19c975b429a92ec22e873c8",
	"name" : "deviceA",
	"level" : 9.8,
	"description" : "IoT door monitoring sensor.",
	"firmwareVersion" : "v1.0.972",
	"lastOnline" : lastOnline,
	"location" : "48.8580,2.2951",
	"reports" : [reportA, reportB],
	"meta.types" : {
		"description" : "text",
		"level" : "numeric",
		"lastOnline" : "date",
		"firmwareVersion" : "string",
		"location" : "geospatial"
	}
};

return devices.save(params);
Success Response Example
{   
   "result":{   
      "device":{   
         "id":"AB825CE1520F"
      }
   },
   "metadata":{   
      "status":"success"
   }
}

create

Creates a new device; throws the "DUPLICATE_DEVICE" exception if a device with the same ID already exists, or a "DUPLICATE_USER" exception if a user with the same ID already exists. The create function takes the same parameter as the save function.

update

Updates a device; throws the "INVALID_DEVICE" exception if the device does not exist. The update function takes the same parameter as the save function.

delete

Deletes a device based on the specified ID.

ParameterDescription
idString representing the ID of the device to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

get

Retrieves a device by ID.

ParameterDescription
idString representing the identifier of the device to be retrieved.
includeFieldType

Boolean which, when set to true, will return the meta.types property that contains the list of the device document's fields along with their corresponding field types.

Return value: JSON object containing all the fields of the requested device. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

query

The query function takes the same parameter "filter" as the user module's query function.

getAttachment

Retrieves an attachment from a specific device.

ParameterDescription
idString representing the identifier of the device.
fileNameString representing the name of the requested file attachment.
fieldNameString representing the name of the field under which the requested file is saved.

Return value: JSON object containing the properties and content of the file attachment. In case of a failure the appropriate error code and details will be returned in a metadata property.

generateToken

Generates a token for the specified device. You can only generate one token per device.

The generated token does not expire, therefore, it is called eternal token.

ParameterDescription
idString representing the identifier of the device for which the token should be generated.

Return value: JSON object containing the generated token. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var devices = require("device");

// Generate the eternal token for device "myDevice"
return devices.generateToken("myDevice");
Example of a Success Response
{
    "result": {
        "token": "TjA2QjI2MTc0MTpnZ25EMMMyOjhDNjdENTFFRUVDOTEwBjkxMUE0NEZENDlPRkQ4Q0Iw"
    },
    "metadata": {
        "status": "success"
    }
}

regenerateToken

Regenerates a token for the specified device.

ParameterDescription
idString representing the identifier of the device for which the token should be regenerated.

Return value: JSON object containing the newly generated token. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var devices = require("device");

// Regenerate the eternal token for device "myDevice"
return devices.regenerateToken("myDevice");

revokeToken

Deletes the token of the specified device.

ParameterDescription
idString representing the identifier of the device for which the token should be revoked.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var devices = require("device");

// Revoke the eternal token for device "myDevice"
return devices.revokeToken("myDevice");

document Module

In scriptr.io, data is represented as document entities where each document has a unique key and a collection of fields. Each field consists of a name, multiple values and a type.

As documents are saved in a store in scriptr.io, every instance of the document module is associated with a specific store allowing you to perform actions against that store. When you require the document module inside your script, it will always return the instance associated with the "DefaultStore"; therefore, all calls you make using that instance will be executed on the default store. If you want to manipulate documents on a different store, you can use the getInstance(storeName) method to retrieve an instance of the document module associated with a specific one, and then perform your actions using that instance.

All documents are secured individually with ACLs, allowing developers to specify the Devices and/or Groups that can view, update or delete a documentor more granularly individual fields within that document.

getInstance

Returns an instance of the document module associated with a specific store. All actions performed against this instance, such as saving or deleting documents, will be executed against its associated store.

ParameterDescription
storeNameString representing a store name.

Return value: an instance of the document module.

Example - Retrieve a document from a specific store
// Get an instance of the DefaultStore using the require() function
var defaultStoreDocuments = require("document");
// Get an instance of your custom store called "myStore"
var myStoreDocuments = defaultStoreDocuments.getInstance("myStore");

// Retrieve the document "myDocument" that is saved in "myStore"
return myStoreDocuments.get("myDocument");

save

Saves a document along with its content. If the document already exists, it gets updated; otherwise, it gets created.

ParameterDescription
documentJSON object containing the fields to be persisted in the document.

Return value: JSON object containing the key and the version number of the document. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The document object properties are as follows:

PropertyDescription
keyString representing the unique document identifier. If not provided, it will be generated automatically. Optional upon document creation.
<field>

Key-value pair representing the name of the field along with its values.

Each value can be:

  • a single value.
  • an array of values for multi-value fields.
  • a JSON object representing which values should be appended or deleted upon update (e.g. "states": {"append":["New Mexico", "Washington"], "delete":["Utah"]}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing field.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing field.

Note that passing a null or empty value deletes the field from the document.

attachments  Array of file objects to be attached to a document. Optional.
meta.types

JSON object containing the list of the document field names to be created/updated along with their corresponding types. The field types can be:

  • string
  • text
  • date
  • numeric
  • geospatial (a pair of longitude and latitude coordinates represented in decimal degrees)

Note that any fields omitted from the meta.types will default to type string, unless otherwise specified in the corresponding document schema.

meta.schemaRepresents the name of a preset schema to apply to the document. Optional.
meta.newVersionBoolean specifying whether this call will create a new version of the document (if set to true) instead of updating the existing one (if set to false). Note that versioning can only be used when the document has a schema. Optional.
meta.latestVersionNumeric that indicates the latest version of the document that the user expects to be modifying to manage concurrent updates. If the document has a different latest version number than the one specified, then the update will fail. Note that it can only be sent when a document is versioned. Optional.
meta.ftsFieldsRepresents the name(s) of the field(s) that will be searchable using full-text queries. It accepts either a string or an array of strings. Optional.
Example: Create a document using the save() function
var documents = require("document");

// Retrieve the country flag image file from the request
var countryFlag = request.files["flag"];

// Define the document content
var fields = {
	// set the document key
	"key": "myCountryDocumentKey",
	// add a field containing a string value called name
	"name": "USA",
	// add a field containing a numeric value called totalLandArea
	"totalLandArea": 9147593,
	// add a field containing a date value called independenceDay
	"independenceDay": "1776-07-04",
  	// add a field representing the ID of the device that gathers data related to this document
  	"deviceId": "31afe00925b6a",
  	// add a field representing the device geo-location
  	"deviceLocation": "48.8580,2.2951",
	// add a field containing an array of string value called states
	"states": [
		"New York",
		"California",
		"Chicago",
		"Utah"
	],
	// add a field containing a text value called history
	"history": "The U.S. is a country of 50 states covering a vast swath of North America, with Alaska in the extreme Northwest and Hawaii extending the nation’s presence into the Pacific Ocean. Major cities include New York, a global finance and culture center, and Washington, DC, the capital, both on the Atlantic Coast; Los Angeles, famed for filmmaking, on the Pacific Coast; and the Midwestern metropolis Chicago.",
	// add the country flag image that got retrieved from the request as an attachment to the document
	"attachments": countryFlag,
  	// enable full text-search on the history field
  	"meta.ftsFields":"history",
	// define the types of the fields added above to match their content types
	"meta.types": {
		"name": "string",
		"totalLandArea": "numeric",
		"independenceDay": "date",
		"states": "string",
      	"deviceId": "string",
      	"deviceLocation": "geospatial",
		"history": "text"
	}
};

// Persist the document myCountryDocumentKey
return documents.save(fields);
Example: Update a document using the save() function
var documents = require("document");

// Define the document content to be updated
var fields = {
	// specify the document key
	"key": "myCountryDocumentKey",
	// Update the states field by appending and deleting some values
	"states": {"append":["New Mexico", "Washington"], "delete":["Utah"]},
	// delete the history field by setting it to an empty string
	"history": "",
	// add a new field to the document called connected of type string
	"connected": "true",
    // specify the type of the newly added field
    "meta.types": {
        "connected": "string"
    }
};

return documents.save(fields);
Example of a Success Response
{  
    "result":{  
        "document":{  
            "key":"myCountryDocumentKey",
            "versionNumber":"1.0"
        }
    },
    "metadata":{  
        "status":"success"
    }
}

create

Creates a new document; throws the "DUPLICATE_DOCUMENT_KEY" exception if a document with the same key already exists. The create function takes the same parameter as the save function.

update

Updates a document; throws the "DOCUMENT_NOT_FOUND" exception if the document does not exist. The update function takes the same parameter as the save function.

delete

Deletes a document based on the specified key.

ParameterDescription
keyString representing the key of the document to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var documents = require("document");
 
// Delete the document with key "myCountryDocumentKey"
return documents.delete("myCountryDocumentKey");

query

Queries document data from the current store according to the conditions passed in the provided filter.

ParameterDescription
filterJSON object containing the parameters to be sent along with the query request.

Return value: JSON object containing the array of documents matching the query filter. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The filter object properties are as follows:

PropertyDescription
queryString representing the query condition to execute. Optional.
ftsQueryString used to refine the search after executing the query condition by performing a full-text search on the returned documents. Note that when using the ftsQuery parameter, the sort and aggregateExpression parameters will be ignored.
count

Boolean specifying whether or not to return the total count of documents found. Optional, defaults to false. 

Note that if the ftsQuery parameter is sent in the request, the count will be equal to the number of documents returned in the first page instead of the total number of hits.

fields

String containing a comma separated list of fields that should be returned by the query. Optional if the count property is passed in the filter.

Note that in addition to the user defined fields, you can query on the system fields: creator, lastModifiedDate, lastModifiedBy, creationDate, versionNumber and latest.

In order to return all fields, you can pass the * wildcard.

The query will always return the document key and the versionNumber in addition to the specified fields.

sort

String containing a comma separated list of the fields on which to sort. Optional.

The syntax for sorting fields is: "fieldName<fieldType:sortingOrder>". For instance, to sort a document by name and birthday fields, you could pass in the value “name<string:ASC>, birthday<date:DESC>”.

Note that this parameter is ignored when using the ftsQuery parameter.

resultsPerPageNumeric value that determines the number of documents per page to return. Optional, defaults to 50.
pageNumberNumeric value representing the number of the page to be returned. Optional, defaults to 1.
includeFieldTypeBoolean specifying whether or not to return the meta.types property for each document. The meta.types is a JSON object containing the names and types of the fields returned by the query. Optional, defaults to false.
aggregateExpressionContains the aggregate expression to execute. Note that this parameter is ignored when using the ftsQuery parameter. Optional.
aggregateGroupBy

Groups the aggregate result by one or more fields. Optional.

The syntax for grouping by field is: "fieldName<fieldType>". For instance, to group the results per deviceType and category, you pass in the value “deviceType<String>, category<numeric>”.

aggregatePageSpecifies whether or not the aggregate function will be executed on the documents that are displayed on the current page. Optional, defaults to true.
aggregateGlobalSpecifies whether or not the aggregate function will be executed on all documents returned by the query on all pages. Optional, defaults to false.
saveDocumentACLValue representing the access control list that restricts saving the document. It defaults to nobody.
deleteDocumentACLValue representing the access control list that restricts deleting the document. It defaults to nobody.
getAttachmentACLValue representing the access control list that restricts retrieval of file attachments from the document. It defaults to nobody.
queryACLValue representing the access control list that restricts access to querying the document. It defaults to nobody.
Example 1 - Regular or FTS Queries
var documents = require("document");

var results;
/* Search for the documents where the states field contains "Chicago" and "California",
 * sort by creationDate (ASC) and totalLandArea (DESC),
 * return the states, totalLandArea and creationDate fields.
 */
results = documents.query({"query":'states in ["Chicago", "California"]', "sort":"creationDate<date:ASC>, totalLandArea<numeric:DESC>", "fields":"states, totalLandArea, creationDate"});

// Search for documents having the words "Washington" and "DC" in any of their full-text indexed fields
results = documents.query({"fields":"*", "ftsQuery":"Washington DC"});
Example of a Success Response for Regular or FTS Queries
{
		"result": {
			"documents": [
				{
					"key": "myCountryDocumentKey",
					"versionNumber": "1.0",
					"states": [
						"New York",
						"Chicago",
						"California",
						"New Mexico",
						"Washington"
					],
					"totalLandArea": "9147593.0",
					"creationDate": "2016-11-15T15:59:29+0000"
				}
			]
		},
		"metadata": {
			"status": "success"
		}
}
Example 2 - Aggregate Queries
var documents = require("document");

var results;
// Get the average temperature of all sensors
results = documents.query({"query":'deviceType = "sensor"', "aggregateExpression":"avg($temperature)"}, "fields": "temperature");

// Get the average temperature grouped by device type and category number for the first page and for all pages (global)
results = documents.query({"aggregateExpression":"avg($temperature)", "aggregateGroupBy":"deviceType<String>, category<numeric>", "aggregatePage":true, "aggregateGlobal":true});

// You can similarly use other aggregates such as MIN, MAX, SUM, AVG, or COUNT, in a similar fashion. Another example:
results = documents.query({"aggregateExpression":"max($totalLandArea)", "aggregatePage":true, "aggregateGlobal":true, "fields": "totalLandArea"});

return results;
Example of a Success Response for Aggregate Queries
{
	"result" : {
		"aggregate" : {
			"pageScope" : {
				"value" : "9147593.0"
			},
			"globalScope" : {
				"value" : "9147593.0"
			}
		},
		"documents" : [{
				"key" : "myCountryDocumentKey",
				"versionNumber" : "1.0",
				"totalLandArea" : "9147593.0"
			}, {
				"key" : "anotherCountryDocumentKey",
				"versionNumber" : "1.0",
				"totalLandArea" : "10542.0"
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}
Example 3 - Geospatial Queries
var documents = require("document");

// Search for documents which devices are located within 200 meters of the reference point '48.8588, 2.2965' and return the distance between these devices and the reference point.
return documents.query({
	"query" : 'name<string>="USA" and deviceLocation<geospatial> within (48.8588, 2.2965, 0.200)',
	"includeFieldType" : "true",
	"fields" : "key, deviceLocation, distance(deviceLocation,'48.8588', '2.2965')",
	"sort" : "distance(deviceLocation,48.8588,2.2965)<ASC>"
});
Icon

To query on geospatial fields, the "within" operator should be used. It allows queries to search for geospatial locations that lie within a specified distance from a reference point. Consequently, this operator requires 2 parameters: a geospatial reference point (represented as a pair of latitude/longitude decimal degrees), and a distance value (in kilometers). As an example, the following query condition can be used to find all locations that are 200m away from the Eiffel Tower: location<geospatial> within (48.8580, 2.2951, 0.200).

When returning fields, the distance formula can be expressed in several ways:

  • It can be passed a pair of geospatial points, each represented as a latitude and longitude pair. (Example: distance ('1.0', '2.0', '3.0', '4.0') returns the distance between the geopatial coordinates (1.0, 2.0) and (3.0, 4.0)).
  • It can be passed a pair of geospatial fields. (Example: distance (gpsLocation1, gpsLocation2)).
  • It can be passed a geospatial field and a geospatial point. (Example: distance(gpsLocation, '1.0', '2.0')).

In all cases, the value returned will be the distance in kilometers between the two geospatial locations.

Example of a Success Response for Geospatial Queries
{
	"result" : {
		"documents" : [{
				"key" : "myCountryDocumentKey",
				"versionNumber" : "1.0",
				"deviceLocation" : "48.858,2.2951",
				"_derivedFields" : {
					"distance(deviceLocation,'48.8588', '2.2965')" : "0.1357"
				},
				"meta.types" : {
					"deviceLocation" : "geospatial"
				}
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}

get

Retrieves a document by key.

ParameterDescription
keyString representing the key of the document to be retrieved.
versionNumberNumeric representing the version number of the document. Optional, defaults to 1.

Return value: JSON object containing all the fields of the requested document. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example: Retrieve a document by key
var documents = require("document");
 
// Return the second version of document with key "myCountryDocumentKey"
return documents.get("myCountryDocumentKey", 2);
Example of a Success Response
{  
    "result":{  
        "key":"myCountryDocumentKey",
        "versionNumber":"2.0",
        "independenceDay":"1776-07-04T00:00:00+0000",
        "attachments":"flag.gif",
        "history":"The U.S. is a country of 50 states covering a vast swath of North America, with Alaska in the extreme Northwest and Hawaii extending the nation’s presence into the Pacific Ocean. Major cities include New York, a global finance and culture center, and Washington, DC, the capital, both on the Atlantic Coast; Los Angeles, famed for filmmaking, on the Pacific Coast; and the Midwestern metropolis Chicago.",
        "states":[  
            "New York",
            "Chicago",
            "California",
            "Utah"
        ],
        "name":"USA",
        "totalLandArea":"9147593.0",
        "creator":"scriptr",
        "lastModifiedDate":"2016-08-12T14:29:29+0000",
        "lastModifiedBy":"scriptr",
        "creationDate":"2016-08-12T14:29:29+0000",
        "latest":"1.0",
        "meta.types":{  
            "independenceDay":"date",
            "attachments":"file",
            "history":"text",
            "states":"string",
            "name":"string",
            "totalLandArea":"numeric",
            "creator":"string",
            "lastModifiedDate":"date",
            "lastModifiedBy":"string",
            "creationDate":"date",
            "versionNumber":"numeric",
            "key":"string",
            "latest":"numeric"
        }
    },
    "metadata":{  
        "status":"success"
    }
}

getAttachment

Retrieves an attachment from a specific document.

ParameterDescription
keyString representing the key of the document.
fileNameString representing the name of the requested file attachment.
optionsJSON object containing additional options. Optional.

Return value: JSON object containing the properties and content of the file attachment. In case of a failure the appropriate error code and details will be returned in a metadata property.

The options object properties are as follows:

PropertyDescription
fieldNameString representing the name of the document field that contains the attachment. Optional, defaults to "attachments".
versionNumberNumeric representing the version number of the document from which to retrieve the attachment. Optional, defaults to 1.
Example: Retrieve a document attachment
var documents = require("document");

var getDocument = documents.get("myCountryDocumentKey");

if(getDocument.metadata.status == "success"){
	// Get the name of the file to be retrieved
	var filename = getDocument.result.attachments;

    // Retrieve the attachment
	var result = documents.getAttachment("myCountryDocumentKey", filename, {"fieldName": "attachments", "versionNumber": "1"});

	// As a best practice, always check the status of the previous call 
	if (result.metadata && result.metadata.status == "failure") {
		return result.metadata.errorDetail;
	} else { // write the file to the response
    	
		// you can also choose to trigger the browser's save as/download feature by uncommenting the following line:
		//response.setHeader("content-disposition", "attachment;filename=" + filename);
 
		response.setHeader("content-type","image/png");
		response.setStatus(200);

		// Add the CORS headers
		response.addHeaders(configuration.crossDomainHeaders);

		response.write(result);
	}
}

facebook Module

Scriptr.io provides the facebook module that allows you to interact with Facebook. This module's APIs will use by default the configuration that you have saved in your Settings. However, if you need to use the credentials of a different Facebook app, you can pass them as a parameter to any of the APIs as described below.

ParameterDescription
credentials

Optional parameter of type object, holding the Facebook app's credentials to be used instead of the ones saved in the Settings.

It can contain the following set of key/value pairs:

  • apiKey: key provided by Facebook when creating the application.
  • apiSecret: secret provided by Facebook when creating the application.
  • accessToken*: token identifying the user, obtained as a result of calling getAccessToken and a successful authorization operation.

* not applicable for getAuthorizationUrl and getAccessToken.

post

Publishes a message to the user profile on his behalf.

ParameterDescription
messageString representing the message that is to be posted to Facebook.

Return value: JSON object containing a Facebook post "id". In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
// Require the facebook module to be able to call the post API on it.
var fb = require("facebook");

// In this example, we are posting to Facebook using the configuration saved in Settings.
fb.post("Hello from scriptr.io!");

// In this example, we are posting to Facebook using a different set of configuration than the one saved in Settings.
var credentials = {
   "apiKey": "yourConsumerKey",
   "apiSecret": "yourConsumerSecret",
   "accessToken": "yourAccessToken"
};
return fb.post("Hello from scriptr.io!", credentials);

callApi

Calls any node and edge in the Facebook Graph API and returns the result in a JSON string. 

ParameterDescription
resourceUrl

String representing the URL identifying the API to call.

verbString representing one of the following method: GET, POST or PUT.
parametersObject holding a set of key/value pairs containing API specific parameters.

Return value: JSON object containing the response from the Facebook API call in JSON format. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getApiCall

Calls any node and edge in the Facebook Graph API and returns a URL that will retrieve the result when called. 

ParameterDescription
resourceUrl

String representing the URL identifying the API to call.

verbString representing one of the following method: GET, POST or PUT.
parametersObject holding a set of key/value pairs containing API specific parameters.

Return value: JSON object containing the url/formEncodedParams that needs to be called to get the network's response for the requested API. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getAuthorizationUrl

Requests a link to the login screen URL from Facebook. The login screen will ask the user to authorize the app to perform certain actions as specified in the scope parameter.

ParameterDescription
callbackUrl

String representing the URL that Facebook will redirect to after the user authorizes the application.

Note: Facebook requires that the URL ends with a “/”.

scopeString representing the scope that the user is requesting the token for. The scope defines the set of permissions the application will have.
stateString identifying the current user/request.

Return value: JSON object containing the authorization URL. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getAccessToken

Retrieves the user access token from Facebook that will be sent with all future requests for authentication. 

ParameterDescription
callbackUrl

String representing the callbackUrl specified when calling getAuthorizationUrl. 

Note: Facebook requires this parameter, and it should be the same as the one set when calling getAuthorizationUrl .

oauthVerifierString representing the verifier parameter returned by Facebook in response to an authorization. This verifier will be sent as a parameter when calling the callbackUrl specified when calling getAuthorizationUrl.

Return value: JSON object containing the access token. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

group Module

Scriptr.io allows you to manage the access permissions by organizing users and devices by groups and assigning ACLs to these groups. The users and devices under a specific group will automatically be assigned the ACLs of that group.

create

Creates a new group.

ParameterDescription
nameString representing the name of the group to be created.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

rename

Renames an existing group.

ParameterDescription
nameString representing the name of the group to be renamed.
newNameString representing the new name of the group.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

delete

Deletes an existing group. The devices or users belonging to that group will lose the permissions that were assigned to that group.

ParameterDescription
nameString representing the name of the group to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

list

Retrieves the list of all existing groups.

Return value: JSON object containing the array of the group names. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

http Module

Scriptr.io provides the http module that allows you to easily issue any HTTP request from within a script. All you need to do is to require it and invoke its request(options) function.

request

Issues an HTTP request.

ParameterDescription
optionsJSON object containing the properties of the HTTP request to invoke.

Return value: JSON object containing the HTTP request status, header, body and timeout.

The options object properties are as follows:

PropertyDescription
urlString representing the base URI for the HTTP request. Mandatory.
methodString representing the HTTP method to use when issuing the call to the remote service. The supported methods are POST, GET, PUT, DELETE, PATCH, HEAD and OPTIONS. Defaults to GET. Optional.
paramsJSON object representing the map of HTTP parameters to be sent to the remote service along with the request. Optional.
authCreds

Array containing the username and password in case the request requires HTTP Authentication (e.g., "authCreds": ["username","password"]). Optional.

headersJSON object representing the map of HTTP headers to be sent to the remote service along with the request. Optional.
files

JSON object representing the map of files to be sent to the remote service along with the request. Optional.

Note: If you are trying to send a single file in the HTTP request, you can use one of the following approaches:

  • The file content can be passed by using plain text in the bodyString parameter.
  • The single file can be passed alone into the files parameter.
returnFileRefBoolean value indicating whether or not to return the HTTP response in the value returned from the remote service call. Optional. Defaults to false.
bodyString

String value representing the body to be passed to the HTTP request. Optional.

disableParameterEncodingBoolean value indicating whether or not the request parameters are encoded before being sent in the request. If true, then parameters are not encoded. Optional. Defaults to false.
encodeHeaders

Boolean value indicating whether request headers are encoded before being sent in the request. If true, then headers are encoded. Optional. Defaults to false.

Example
// require the "http" module
var http = require("http");
// build a request. You should at least provide the "url" field
var requestObject = {
	"url" : "http://api.openweathermap.org/data/2.5/weather",
	"params" : {
		"q" : "london,uk"
	},
	"method" : "GET" // optional if GET
}
// send the request by invoking the request function
// of the http module and store the returned response object
var response = http.request(requestObject);
// get the body of the response as a string
var responseBodyStr = response.body;
// check the status of the response
if (response.status == "200") {
	// manipulate the response headers
	if (response.headers["Content-Type"].indexOf("application/json") > -1) {
		return JSON.parse(responseBodyStr);
	}
	return responseBodyStr;
} else {
	return "Remote API returned an error " + response.status;
}
Example of a Success Response
{
"result": {
	"status": "200",
	"headers": {
		"X-Source": "the x-source",
		"Access-Control-Allow-Origin": "the CORS configuration, if any",
		"Transfer-Encoding": "type of transfer encoding",
		"Date": "the response date",
		"Access-Control-Allow-Methods": "allowed HTTP methods",
		"Access-Control-Allow-Credentials": "true/false",
		"Connection": "keep-alive",
		"Content-Type": "the HTTP response content type and allowed charset",
		"Server": "the HTTP server"
	},
	"body": "the response body, as a string. Note that this could be a stringified JSON or could contain an error message sent by the remote service."
	"timeout": true/false
}
Example of a Failure Response
{
	"metadata": {
		"status": "failure",
		"errorCode": "HTTP error code",
		"errorDetail": "HTTP error details"
	}
}

log Module

To facilitate debugging remote calls from hardware, scriptr.io provides an automatic log of all requests, showing how the request got received (parameters, headers, etc.) and the returned response.

In addition, you can generate custom logs which will appear under logs, grouped by request and only logged based on a user-specified log level. Furthermore, this log view page provides the ability to download the logs, filter them by script name and scheduled scripts.

Example
var log = require("log");
log.setLevel("DEBUG"); //levels are ERROR | WARN | INFO | DEBUG | OFF
log.error("This is the error message of the script");
log.warn("This is the warning message of the script");
log.info("This is the info message of the script");
log.debug("This is the debug message of the script");
Icon
  • The default level being OFF, remember to always configure your log level as needed. e.g. log.setLevel("DEBUG");
  • Scriptr.io retains up to two weeks or 2,560 log entries.

mobile-push Module

The mobile-push module offers a mechanism for users to manage their mobile devices' tokens by organizing them into groups.

getGroup

Retrieves a specified mobile push notifications group by ID.

Parameter
Description

id

A unique identifier for the group to retrieve.

Return value: JSON object containing the group properties. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Example
{
	"result" : {
		"group" : {
			"id" : "xxxxx",
			"platform" : "iOS",
			"configurationId" : "xxxxxxx",
			"pushTokens" : [
				"003DAB991FF6C1EFA5854B504D1B7AFAB8F11187BD37B9EA2D82152884B97B91",
				"933C14E952BD20F68AC2F213BDA266CC5F56F10CA795F8139D5AA3965B9AD717"
			],
			"invalidPushTokens" : [
			]
		}
	},
	"metadata" : {
		"status" : "success"
	}
}

listGroups

Retrieves the list of all existing groups. This operation takes no parameters.

Return value: JSON object containing an array that contains all the existing groups along with their details. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Example
{
	"result" : {
		"count" : "2",
		"groups" : [{
				"id" : "xxxxx",
				"platform" : "iOS",
				"configurationId" : "xxxxxxx",
				"pushTokens" : [
					"003DAB991FF6C1EFA5854B504D1B7AFAB8F11187BD37B9EA2D82152884B97B91",
					"933C14E952BD20F68AC2F213BDA266CC5F56F10CA795F8139D5AA3965B9AD717"
				],
				"invalidPushTokens" : [
				],
				"creationTime" : "2015-06-30T07:54:18.416Z",
				"lastModifiedTime" : "2015-06-30T07:55:30.063Z"
			}, {
				"id" : "yyyyy",
				"platform" : "iOS",
				"configurationId" : "xxxxxxx",
				"pushTokens" : [
					"003DAB991FF6C1EFA5854B504D1B7AFAB8F11187BD37B9EA2D82152884B97A91",
					"933C14E952BD20F68AC2F213BDA266CC5F56F10CA795F8139D5AA3965B9AC717"
				],
				"invalidPushTokens" : [
				],
				"creationTime" : "2015-06-30T07:54:18.416Z",
				"lastModifiedTime" : "2015-06-30T07:55:30.063Z"
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}

deleteGroup

Deletes a specified mobile push notifications group by ID.

ParameterDescription
idThe unique identifier of the group to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

addToGroup

Adds push tokens to a group.

ParameterDescription
idThe unique identifier of the group.
pushTokens

An array containing the push notification tokens to be persisted in the created group. This group will later be used to send notifications to all the push notification tokens that it contains.

* Please note that the maximum number of push tokens allowed is 500.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

push

The push function empowers your scripts to push notifications to iOS and Android devices.

ParameterDescription
devicesArray of device tokens to which you want to send the notification to.
message

String representing the payload containing the notification message to be sent. For iOS payload details, please refer to the The Notification Payload tutorial.

For Android, the payload needs to be sent in the following format '{\"key1\":\"value1\",\"key2\":\"value2\", ...}'.

platformThe targeted platform, i.e. the platform of the devices (iOS or Android).
isProduction

Boolean value indicating if the push notification should be sent to your production or development application. This parameter is ignored if the notification is meant to be sent to some Android devices and will only be taken into consideration for iOS devices.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

iOS Example
var mobpush = require("mobile-push");
 
var message = '{"aps": { "alert" : "The notification you want to send", "badge" : 5, "sound" : "default"}}';
var arrayDevices = ["45866802973125d73b144b6c5d9c17b24fb4b09cf4d7bff855e2dd8e852a49c6","4565656d3423e455b45355c34243f3553f3255b235352c55454dd3255e324b24"];
var deviceType = "ios";

//this is a push to iOS using the development certificate.
var isProduction = "false";
return mobpush.push(arrayDevices, message, deviceType, isProduction);

//this is a push to iOS using the production certificate.
isProduction = "true";
return mobpush.push(arrayDevices, message, deviceType, isProduction);
Android Example
var mobpush = require("mobile-push");
 
var message = "The notification you want to send";  
var arrayDevices = ["APA91bHBCTUA8vITavb-yaB2xZlB93xQB1WcquAyzYBjSAJpiEWslvjl-er-1kdvO2VVu52CpgI-ATcMrMs7rKnjInKO2di7pR9njJLJQxd4AK4vpZvGgkxQB2G5fVurKJgiwFKi7Zyyatd0lVy_8GnhieEHUMUbhagURgSTJ7l-dBES00H2eVI"];
var deviceType = "android";
return mobpush.push(arrayDevices, message, deviceType, false);

pushToGroup

The pushToGroup function allows you to push notifications directly from within a script to iOS and Android devices.

ParameterDescription
groupIdString representing the identifier for sending push notifications to a particular mobile application.
messageString or JSON representing the message you want to send to the devices through your application.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Icon

For information about how to create a group of mobile device tokens, see section Groups Sub-tab.

removeFromGroup

Removes push tokens from a group.

ParameterDescription
idThe unique identifier of the group.
pushTokens

An array containing the push notification tokens to be persisted in the created group. This group will later be used to send notifications to all the push notification tokens found in it.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

pubsub Module

Through its publish-subscribe model, scriptr.io provides the 2-way communication that allows devices, scripts and other "things" to relay messages among each other.

publish

Publishes a message to a specified channel that will be sent to its subscribers.

Parameter
Description
channelName String representing the name that serves as a unique identifier for the channel.
messageJSON, including objects, strings, and numbers, representing the message to be distributed to subscribers.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var pubsub = require("pubsub");
return pubsub.publish("myChannel", "Hello Device!");

subscribe

Subscribes a script to a channel in order for it to read all the messages published to that channel. When a message is published to a channel, the subscribed script will get executed and will be able to access the message from the request.rawBody property.

Icon

You cannot subscribe a device to a channel using this API. You can do so using a WebSocket connections (refer to the Real-time Communication section).


Parameter
Description
channelNameString representing the name that serves as a unique identifier for the channel.
scriptNameString representing the script name to be executed.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var pubsub = require("pubsub");
return pubsub.subscribe("myChannel", "myFolder/myScript");

unsubscribe

Unsubscribes a script from a channel in order to stop receiving future messages.

Parameter
Description
channelNameString representing the name that serves as a unique identifier for the channel.
scriptNameString representing the script name.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var pubsub = require("pubsub");
return pubsub.unsubscribe("myChannel", "myFolder/myScript");

createChannel

Creates a channel to exchange messages over it.

Parameter
Description
nameString representing the name that serves as a unique identifier for the channel.
aclsJavaScript object containing the different ACLs that can be set on the channel. Optional.

The acls object properties are as follows:

Property
Description
subscribeACLControls if you want to allow end users / devices to subscribe to the current channel without any authentication. It can be set to either "AUTHENTICATED" or "ANONYMOUS", it defaults to "AUTHENTICATED".
publishACLControls if you want to allow end users / devices to publish to the current channel without any authentication.It can be set to either "AUTHENTICATED" or "ANONYMOUS", it defaults to "AUTHENTICATED".

Return value: JSON object containing the channel name. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var pubsub = require("pubsub");
var options = {
  "subscribeACL": "anonymous",
  "publishACL": "authenticated"
}
return pubsub.createChannel("myChannel", options);
Icon

 For free accounts, the maximum allowed number of channels is 20.

updateChannel

Updates a channel to exchange messages over it.

Parameter
Description
nameString representing the name that serves as a unique identifier for the channel.
aclsOptional JavaScript object containing the different ACLs that can be set on the channel.

The acls object properties are as follows:

Property
Description
subscribeACLControls if you want to allow end users / devices to subscribe to the current channel without any authentication. It can be set to either "AUTHENTICATED" or "ANONYMOUS", it defaults to "AUTHENTICATED".
publishACLControls if you want to allow end users / devices to publish to the current channel without any authentication. It can be set to either "AUTHENTICATED" or "ANONYMOUS", it defaults to "AUTHENTICATED".

Return value: JSON object containing the channel name. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var pubsub = require("pubsub");
var options = {
  "subscribeACL": "anonymous",
  "publishACL": "authenticated"
}
 
return pubsub.updateChannel("myChannel", options);

getChannel

Retrieves a specified channel by name.

ParameterDescription
nameString representing the name that serves as a unique identifier for the channel.

Return value: JSON object containing the channel. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Example
{
	"result" : {
		"name" : "MyChannel",
		"subscribeACL" : "authenticated",
		"publishACL" : "authenticated",
		"creationTime" : "2015-08-17T18:17:49.530Z",
		"lastModifiedTime" : "2015-08-17T18:17:49.530Z"
	},
	"metadata" : {
		"status" : "success"
	}
}

listChannels

Retrieves the list of all existing channels. This operation takes no parameters.

Return value: JSON object containing an array that contains all the existing channels along with their details. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Example
{
	"result" : {
		"count" : "2",
		"channels" : [{
				"name" : "channelX",
				"subscribeACL" : "anonymous",
				"publishACL" : "authenticated",
				"creationTime" : "2015-06-30T07:54:18.416Z",
				"lastModifiedTime" : "2015-06-30T07:55:30.063Z"
			}, {
				"name" : "channelY",
				"subscribeACL" : "anonymous",
				"publishACL" : "authenticated",
				"creationTime" : "2015-06-30T07:54:18.416Z",
				"lastModifiedTime" : "2015-06-30T07:55:30.063Z"
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}

deleteChannel

Deletes a specified channel by name.

ParameterDescription
nameString representing the name that serves as a unique identifier for the channel.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

schema Module

Schemas are used when saving a document to define the kind of data you expect to store for a certain business entity, along with the validation and security rules. For example, you might want to have a vehicle entity in your fleet management application. You can define a schema for that entity, specifying that vehicleId, carType, registrationCertificate, lastServiceDate, fuelPercentage and currentLocation represent the data to be collected for each vehicle. For each of these vehicle attributes, you can associate validation and security rules. Hence, a schema provides a uniform way of dealing with your vehicles. Note that vehicle attributes that are not defined in the schema can still be persisted as part of the vehicle document; however, no specific validation nor security rules can be applied to them.

Scriptr.io does not enforce the use of schemas. Alternatively, you can always persist data without specifying a schema, however, no field-level security nor validation rules can be applied. This "schema-less" mode is meant for prototyping and experimenting purposes. We recommend that business applications be built in a "schema-full" mode.

Please refer to Document Schema Definitions to view the schema syntax (XSD) that you should use to create your schemas. An example of a schema is as follows:

<schema versioning="enabled">
	<aclGroups>
		<aclGroup name="admin">
			<read>userA;group:admin</read>
			<write>group:admin</write>
			<fields>
				<field>vehicleId</field>
				<field>carType</field>
				<field>registrationCertificate</field>				
				<field>lastServiceDate</field>
			</fields>
		</aclGroup>
		<aclGroup name="devices">
			<read>authenticated</read>
			<write>authenticated</write>
			<fields>
				<field>fuelPercentage</field>
				<field>currentLocation</field>
			</fields>
		</aclGroup>
		<defaultAcl>
			<read>authenticated</read>
			<write>authenticated</write>
			<delete>group:admin</delete>
		</defaultAcl>
		<schemaAcl>
			<read>nobody</read>
			<write>nobody</write>
			<delete>nobody</delete>
		</schemaAcl>
	</aclGroups>
	<fields>
		<field searchable="false" name="vehicleId" type="numeric" >
			<validation>
				<cardinality min="1" max="1" />
			</validation>
		</field>
		<field searchable="true" name="carType" type="string" >
			<validation>
				<cardinality min="1" max="1" />
			</validation>
		</field>
		<field searchable="false" name="fuelPercentage" type="numeric">
			<validation>				
				<cardinality min="1" max="1" />
				<range min="0" max="100" />
			</validation>
		</field>		
		<field name="currentLocation" type="geospatial" />
		<field searchable="true" name="registrationCertificate" type="file" />		
		<field name="lastServiceDate" type="date" />
	</fields>
</schema>
Icon

Note that document versioning is only available when using schemas. In order to enable it, set the versioning status at the beginning of the schema. The possible values are "disabled", "enabled", or "forced"; it defaults to "disabled".

create

Creates a schema.

ParameterDescription
nameThe name of the schema to be created.
contentThe XML content of the schema.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var schema = require("schema");
return schema.create("vehicleSchema", '<schema versioning="enabled"><aclGroups><aclGroup name="admin"><read>userA;group:admin</read><write>group:admin</write><fields><field>vehicleId</field><field>carType</field><field>registrationCertificate</field><field>lastServiceDate</field></fields></aclGroup><aclGroup name="devices"><read>authenticated</read><write>authenticated</write><fields><field>fuelPercentage</field><field>currentLocation</field></fields></aclGroup><defaultAcl><read>authenticated</read><write>authenticated</write><delete>group:admin</delete></defaultAcl><schemaAcl><read>nobody</read><write>nobody</write><delete>nobody</delete></schemaAcl></aclGroups><fields><field searchable="false" name="vehicleId" type="numeric" ><validation><cardinality min="1" max="1" /></validation></field><field searchable="true" name="carType" type="string" ><validation><cardinality min="1" max="1" /></validation></field><field searchable="false" name="fuelPercentage" type="numeric"><validation><cardinality min="1" max="1" /><range min="0" max="100" /></validation></field><field name="currentLocation" type="geospatial" /><field searchable="true" name="registrationCertificate" type="file" /><field name="lastServiceDate" type="date" /></fields></schema>');

update

Updates the content of a schema.

ParameterDescription
nameThe name of the schema to be updated.
contentThe new XML content of the schema.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

delete

Deletes an existing schema.

ParameterDescription
nameThe name of the schema to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

rename

Renames a schema. All existing documents with the old schema name will be updated to have the new schema name.

ParameterDescription
nameThe name of the schema to be renamed.
newNameThe new name of the schema.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

list

Retrieves the list of all existing schemas.

Return value: JSON object containing an array of the schema names. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Sample
{		
	"metadata": {
			"status": "success"
		},
	"result": {
		"schemas": [
			{
				"name": "vehicleSchema"
			}
		]
	}
}

get

Retrieves a specific schema by name.

ParameterDescription
nameThe name of the schema to be retrieved.

Return value: JSON object containing the content of the schema. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var schema = require("schema");
return schema.get("vehicleSchema");

store Module

In scriptr.io, data  and digital assets are persisted in a database container called a store. Individual data items persisted in a store are called documents.

All documents saved in a store are secured with store level ACLs, allowing developers to decide which devices, users and/or groups are permitted to save, query, delete documents or retrieve attachments from documents in that store.

The store module allows you to manage stores by offering the below functions. Note that free accounts can only have two stores.

Icon

When you create a scriptr.io account, a store called "DefaultStore" is automatically created for you. It is strongly advised to not delete the "DefaultStore" as you will lose all your triggers for the scheduled scripts and will no longer be able to schedule scripts.

save

Saves a store along with its ACL. If the store already exists, it gets updated; otherwise, it gets created.

ParameterDescription
nameString representing the store name which is a unique identifier.
acl

JSON object containing the access control list of the store determining who can save, delete, query or get attachments from its documents. Optional, defaults to nobody.

Return value: JSON object containing the store name and its ACL. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The acl object properties are as follows:

PropertyDescription
saveDocumentACL

Value representing the access control list that restricts saving documents in the store. It defaults to nobody.

deleteDocumentACL

Value representing the access control list that restricts document deletion from the store. It defaults to nobody.

getAttachmentACLValue representing the access control list that restricts retrieval of file attachments from documents in the store. It defaults to nobody.
queryACL

Value representing the access control list that restricts access to queries on the store. It defaults to nobody.

For each acl property above the value could be any of the following:

  • A single value of type string if the ACL consists only of one device, user or group.
  • An array of strings representing all the devices, users and groups in this ACL.
  • A JSON object representing which values should be appended or deleted upon update (e.g. "saveDocumentACL": {"append":["admins", "editors"], "delete":["nobody"]}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing ACL.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing ACL.
Example
var stores = require("store");

// Create the "myStore" store with the following ACLs
stores.save("myStore", {
	"saveDocumentACL" : "deviceA",
	"deleteDocumentACL" : ["deviceA", "group:firstFloor"],
	"queryACL" : "deviceB",
	"getAttachmentACL" : "deviceB"
});

// Updates the deleteDocumentACL of the store "myStore". Note that the other ACLs will remain untouched if you don't pass them during an update.
return stores.save("myStore", {
	"deleteDocumentACL" : {
		"append" : "deviceB",
		"delete" : ["deviceA", "group:firstFloor"]
	}
});

create

Creates a new store; throws the "DUPLICATE_STORE_NAME" exception if the store already exists. The create function takes the same parameters as the save function.

update

Updates a store; throws the "STORE_NOT_FOUND" exception if the store does not exist. The update function takes the same parameters as the save function.

delete

Deletes a store by name. Deleting a store is a background job and might require some time, the store would be disabled meanwhile. Once done, all the data and digital assets persisted in that store will be deleted.

ParameterDescription
nameString representing the name of the store to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var stores = require("store");
 
// Delete the store with name "myStore"
return stores.delete("myStore");

get

Retrieves a specific store by name.

ParameterDescription
nameString representing the name of the store to be retrieved.

Return value: JSON object containing the name and ACLs of the retrieved store. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Sample
{
	"metadata" : {
		"status" : "success"
	},
	"result" : {
		"saveDocumentACL" : [
			"deviceA"
		],
		"store" : "myStore",
		"deleteDocumentACL" : [
			"deviceA",
			"group:firstFloor"
		],
		"getAttachmentACL" : [
			"deviceB"
		],
		"queryACL" : [
			"deviceB"
		]
	}
}

list

Retrieves all available stores.

Return value: JSON object containing the array of the store names. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Response Sample
{
	"result" : {
		"stores" : [{
				"name" : "DefaultStore"
			}, {
				"name" : "myStore"
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}

twitter Module

Scriptr.io provides the twitter module that allows you to interact with Twitter. This module's APIs will use by default the configuration that you saved in your Settings. However, if you need to use the credentials of a different Twitter app, you can pass them as a parameter to any of the APIs as described below.

ParameterDescription
credentials

Optional parameter of type object, holding the Twitter app's credentials to be used instead of the ones saved in the Settings.

It can contain the following set of key/value pairs:

  • consumerKey: key provided by Twitter when creating the application.
  • consumerSecret: secret provided by Twitter when creating the application.
  • accessToken*: token to be paired with the accessTokenSecret, identifying the user. It is obtained as a result of calling getAccessToken and a successful authorization operation. 
  • accessTokenSecret*: token to be paired with the accessToken, identifying the user. It is obtained as a result of calling getAccessToken and a successful authorization operation. 

* not applicable for getRequestToken and getAccessToken.

tweet

Updates the user's status (i.e., tweets on behalf of the user).

ParameterDescription
tweetStringString representing the new status to post to Twitter.

Return value: JSON object containing the result of the tweet. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
// Require the twitter module in order to be able to call the APIs
var tw = require("twitter");

// In this example, we are tweeting to Twitter using the configuration saved in Settings.
tw.tweet("Hello from scriptr.io!");

// In this example, we are tweeting to Twitter using a different set of configuration than the one saved in Settings.
var credentials= {
   "consumerKey": "yourConsumerKey",
   "consumerSecret": "yourConsumerSecret",
   "accessToken": "yourAccessToken",
   "accessTokenSecret": "yourAccessTokenSecret"
 };
return tw.tweet("Hello from scriptr.io!", credentials);

getHomeTimeLine

Retrieves the most recent tweets/retweets existing on the user's timeline. It uses the default options of Twitter's home_timeline API.

Return value: JSON object containing the home timeline of the user. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getHomeTimeLineUrl

Retrieves a URL that when called, returns the most recent tweets/retweets existing on the user's timeline.

Return value: JSON object containing the URL to call in order to obtain the home time line of the user. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

callApi

Calls any API in the Twitter REST APIs and returns the result in a JSON string.

ParameterDescription
resourceUrlString representing the URL identifying the API to call.
verbString representing one of the following method: GET, POST or PUT.
parametersObject holding a set of key/value pairs containing API specific parameters.

Return value: JSON object containing the response from the Twitter API call in JSON format. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getApiCall

Calls any API in the Twitter REST APIs and returns a URL which, when called, retrieves the result in a JSON string. 

ParameterDescription
resourceUrlString representing the URL identifying the API to call.
verbString representing one of the following method: GET, POST or PUT.
parametersObject holding a set of key/value pairs containing API specific parameters.

Return value: JSON object containing the url/formEncodedParams that needs to be called to get the network's response for the requested API. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getRequestToken

Requests a link to the login screen URL from Twitter.

ParameterDescription
callbackUrlString representing the URL that Twitter will redirect to after the application authorization step.

Return value: JSON object containing the authorization URL and a pair of request token/secret. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

getAccessToken

Retrieves the user access token from Twitter that will be sent with all future requests for authentication purpose. 

ParameterDescription
requestTokenString representing the token identifying the user's request (returned by getRequestToken).
requestTokenSecretString representing the token secret identifying the user's request (returned by getRequestToken).
oAuthVerifierString representing the verifier parameter returned by Twitter in response to an authorization. This verifier will be sent as a parameter when calling the callbackUrl specified when calling getRequestToken.

Return value: JSON object containing a pair of access token/access token secret. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

user Module

The user module allows you to create and manage users. Each user is associated to the below schema that provides the basic user fields and ACLs. You can modify the schema to meet your needs by updating the apsdb_user system schema.

<!--
This is the default user schema. Feel free to modify it to your liking.
This schema follows all rules and restrictions as all other schemas, as do the documents (users) created out of it.
However, it imposes the following restrictions of its own:
1. The six default fields (groups, name, login, password, locale and isSuspended) are required.
2. This schema cannot be deleted.
Additionally, since this schema is used for user management, the following ACLs are set by default upon creation of each new user document:
- document.readACL = login, creator
- document.writeACL = login, creator
- required.readACL = nobody
- required.writeACL = nobody
- requiredVisibles.readACL = creator
- requiredVisibles.writeACL = nobody
- requiredEditables.readACL = creator
- requiredEditables.writeACL = creator
You can specify your own ACLs upon user creation by passing them as parameters to the save() function of the user module as described in the documentation.
-->
<schema>
  <aclGroups>
    <aclGroup name="required">
      <read>nobody</read>
      <write>nobody</write>
      <fields>
        <field>isSuspended</field>
      </fields>
    </aclGroup>
    <aclGroup name="requiredVisibles">
      <read>creator</read>
      <write>nobody</write>
      <fields>
        <field>login</field>
        <field>groups</field>
      </fields>
    </aclGroup>
    <aclGroup name="requiredEditables">
      <read>creator</read>
      <write>creator</write>
      <fields>
        <field>name</field>
        <field>password</field>
        <field>locale</field>
      </fields>
    </aclGroup>
    <defaultAcl>
      <read>creator</read>
      <write>creator</write>
    </defaultAcl>
    <schemaAcl>
      <read>creator</read>
      <write>creator</write>
      <delete>nobody</delete>
    </schemaAcl>
  </aclGroups>
  <fields>
    <field name="login" type="string"/>
    <field name="name" type="string"/>
    <field name="groups" type="string"/>
    <field name="password" type="string" />
    <field name="locale" type="string" />
    <field name="isSuspended" type="string" />
  </fields>
</schema>

save

Saves a user with the provided parameters. If the user already exists, it gets updated; otherwise, it gets created.

ParameterDescription
userA JSON object containing the user fields.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The user object properties are as follows:

PropertyDescription
id

String representing the unique identifier of the user.

It accepts alphanumeric characters, at signs (@), underscores (_), periods (.), and dashes (-) and can have a maximum length of 243 characters.

nameString representing the name of the user. Optional upon update.
passwordString representing the password of the user. Optional upon update.
groups

Represents the group(s) to which this user will be added. It can have any of the following values:

  • a single value.
  • an array of strings to specify multiple groups.
  • a JSON object representing which values should be appended or deleted upon update (e.g. "groups": {"append":["groupB", "groupC"], "delete":"groupA"}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing field.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing field.

Group name accepts alphanumeric characters (a-z A-Z 0-9), dashes (-) and underscores (_), and can have a maximum length of 128 characters.

Note that passing a null or empty value removes the user from all groups.

isSuspended

Boolean value specifying whether or not the user is suspended. Optional, defaults to false.

When set to true, the user will be treated as if it was deleted from the system. It can be reactivated by updating this value to false.

globalDateFormat

String representing the date format to use to parse any date field values passed as string. Optional, if not specified, the formats "yyyy-MM-dd'T'HH:mm:ssZ" (e.g. 2017-01-13T13:01:02+0000) and "yyyy-MM-dd" (e.g. 2017-01-13) only will be accepted.

Refer to this document for the accepted date formats.

meta.types

JSON object containing the list of the document field names to be created/updated along with their corresponding types. The field types can be:

  • string
  • text
  • date
  • numeric
  • geospatial (a pair of longitude and latitude coordinates represented in decimal degrees)

Note that any fields omitted from the meta.types will default to type string, unless otherwise specified in the corresponding user schema.

<fieldName>

Key-value pair representing the name of the field along with its values.

Each value can be:

  • a single value.
  • an array of values for multi-value fields.
  • a JSON object representing which values should be appended or deleted upon update (e.g. "states": {"append":["New Mexico", "Washington"], "delete":["Utah"]}). This JSON object can have the following two properties:
    • "append": the value of the "append" key should be a string or an array containing the values to be added to the existing field.
    • "delete": the value of the "delete" key should be a string or an array containing the values to be deleted from the existing field.

Note that passing a null or empty value deletes the field from the user.

A field of type file should always be defined in the schema first.

Example
var users = require("user");

var params = {
	"id" : "john.doe@example.com",
	"password" : "1a2afef9b19c975b429a92ec22e873c8",
	"name" : "John Doe",
	"description" : "Security services employee",
	"lastOnline" : new Date(),
	"groups" : ["groupA", "groupB"],
	"meta.types" : {
		"description" : "text",
		"lastOnline" : "date"
	}
};

return users.save(params);

create

Creates a new user; throws the "DUPLICATE_USER" exception if a user with the same ID already exists, or a "DUPLICATE_DEVICE" exception if a device with the same ID already exists. The create function takes the same parameter as the save function.

update

Updates a user; throws the "INVALID_USER" exception if the user does not exist. The update function takes the same parameter as the save function.

delete

Deletes a user based on the specified ID.

ParameterDescription
idString representing the ID of the user to be deleted.

Return value: no result is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

get

Retrieves a user by ID.

ParameterDescription
idString representing the identifier of the user to be retrieved.
includeFieldTypeBoolean which, when set to true, will return the meta.types property that contains the list of the user document's fields along with their corresponding field types.

Return value: JSON object containing all the fields of the requested user. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

query

Queries user data according to the conditions passed in the provided filter.

ParameterDescription
filterJSON object containing the parameters to be sent along with the query request.

Return value: JSON object containing array of users matching the query filter. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The filter object properties are as follows:

PropertyDescription
queryString representing the query condition to execute. Optional.
ftsQuery

String used to refine the search after executing the query condition by performing a full-text search on the returned users. Only the fields that are set to "searchable" in the user schema can be searched against using the ftsQuery. Note that when using the ftsQuery parameter, the sort parameter will be ignored.

count

Boolean specifying whether or not to return the total count of users found. Optional, defaults to false. 

Note that if the ftsQuery parameter is sent in the request, the count will be equal to the number of users returned in the first page instead of the total number of hits.

fields

String containing a comma separated list of fields that should be returned by the query. Optional if the count property is passed in the filter.

In order to return all fields, you can pass the * wildcard.

The query will always return the user ID in addition to the specified fields.

Note that in addition to the user defined fields, you can retrieve the system fields: creator, lastModifiedDate, lastModifiedBy, creationDate, versionNumber and latest.

sort

String containing a comma separated list of the fields on which to sort. Optional.

The syntax for sorting fields is: "fieldName<fieldType:sortingOrder>". For instance, to sort a document by name and birthday fields, you could pass in the value “name<string:ASC>, birthday<date:DESC>”.

Note that this parameter is ignored when using the ftsQuery parameter.

resultsPerPageNumeric value that determines the number of documents per page to return. Optional, defaults to 50.
pageNumberNumeric value representing the number of the page to be returned. Optional, defaults to 1.
includeFieldTypeBoolean specifying whether or not to return the meta.types property for each user. The meta.types is a JSON object containing the names and types of the fields returned by the query. Optional, defaults to false.
Example
var users = require("user");

// Look for users in "groupA"
return users.query({"query":'groups in ["groupA"]', "fields":"*", "sort":"name<string:ASC>, lastOnline<date:DESC>"});
// OR
return users.query({"query":'groups = "groupA"', "fields":"*", "sort":"name<string:ASC>, lastOnline<date:DESC>"});
Example of a Success Response
{
	"result" : {
		"users" : [{
				"description" : "Security services employee",
				"groups" : [
					"groupA",
					"groupB"
				],
				"login" : "john.doe@example.com",
				"name" : "John Doe",
				"id" : "john.doe@example.com",
				"creator" : "scriptr@L22826DC91",
				"versionNumber" : "1.0",
				"latest" : "1.0",
				"lastModifiedBy" : "scriptr",
				"creationDate" : "2017-01-10T15:00:20+0000",
				"lastModifiedDate" : "2017-01-10T15:12:59+0000"
			}
		]
	},
	"metadata" : {
		"status" : "success"
	}
}

getAttachment

Retrieves an attachment from a specific user.

ParameterDescription
idString representing the identifier of the user.
fileNameString representing the name of the requested file attachment.
fieldNameString representing the name of the field under which the requested file is saved.

Return value: JSON object containing the properties and content of the file attachment. In case of a failure the appropriate error code and details will be returned in a metadata property.

generateToken

Generates a token for the specified user. You can generate 20 tokens per user.

The generated token expires based on the values that you set.

ParameterDescription
idString representing the identifier of the user for which the token should be generated.
optionsJSON object containing additional options. If not passed, the default values will apply.

Return value: JSON object containing the generated token and its properties. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

The options object properties are as follows:

PropertyDescription
password

String representing the user's password to trigger an additional verification step for performing this operation. If not provided, this security check will be omitted.

expiry

Integer or string representing the relative time, in seconds, after which the token expires and becomes unusable. 

The default expiry is 1800 seconds (30 minutes).

It should always be less or equal to 86400 seconds (24 hours).

lifeTime

Integer or string representing the relative time, in seconds, after which the token cannot be renewed.

The default lifeTime is 7200 seconds (2 hours).

It should always be less or equal to 604800 seconds (1 week).

bindToReferrer

Boolean or string that determines whether or not the tokens will be bound to the issuing request's referrer. It defaults to true.

When a token is bound to a referrer, requests signed by this token can only work with this provided referrer.

Example
var users = require("user");

// Generate a token for user "myUser"
return users.generateToken("myUser", {"password": "password", "expiry": 1800, "lifeTime": 7200, "bindToReferrer": "false"});  
Example of a Success Response
{
    "result": {
        "token": "TjA2QjI2MTc0MTpnZ25EMMMyOjhDNjdENTFFRUVDOTEwBjkxMUE0NEZENDlPRkQ4Q0Iw"
    },
    "metadata": {
        "status": "success"
    }
}

renewToken

Renews a token for the specified user.

ParameterDescription
idString representing the identifier of the user for which the token should be renewed.
tokenString representing the token that needs to be renewed.

Return value: JSON object containing the newly generated token and its properties. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var users = require("user");

// Renew the provided token for user "myUser"
return users.renewToken("myUser", "TjA2QjI2MTc0MTpnZ25EMMMyOjhDNjdENTFFRUVDOTEwBjkxMUE0NEZENDlPRkQ4Q0Iw");

revokeToken

Deletes the token of the specified user.

ParameterDescription
idString representing the identifier of the user for which the token should be revoked.
tokenString representing the token that needs to be revoked.

Return value: no value is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

revokeTokens

Revokes all the tokens of the specified users.

ParameterDescription
idList

Either a string or an array of strings containing the identifiers of the users for which the tokens will be revoked.

Return value: no value is returned. In case of a failure the appropriate error code and details will be returned in the metadata property (refer to common function response).

Example
var users = require("user");

users.revokeTokens(["id1","id2"]);
return users.revokeTokens("id3");

Handling Files

Sending a File to Your Scripts

Scriptr.io handles multi-part requests with binary data and thus, you can easily upload files to your scripts.

The below is the curl instruction to send to your script in order to upload a file. Notice that you need to give a name to your file field (myFile in the example).

curl -X POST -F myFile=@account.png -H 'Authorization: bearer RzM1RkYwQzc4MjpzY3JpcHRyOjQxODBFRDREQTAxQzc2REU4QjcxNTdEMjE4NUZENEUy' 'https://api.scriptrapps.io/multipart'

Retrieving a File from the Request in a Script

All files sent to a script can be retrieved from the files property of the built-in request object. Check the below code to see how easy it is to manipulate files in scriptr.io.

Example
// Retrieve content of the "files" field from the built-in "request" object.
// The "request" object wraps the HTTP request that triggered our script and has a property called "files".
// The "files" property of the "request" object is a map where each file sent to the request is mapped to a field with the same name
var filesInRequest = request.files;
if (request.files) {
   // When we uploaded the file, we associated it to a field called "myFile"
   // this field should end up as a field of the "files" property of the "request" object
   // in the below, we check if "files" contains the "myFile" field and if the latter is not empty
   if (filesInRequest.myFile && filesInRequest.myFile.length > 0) {
     // Do something with the file
   }
}
return "no file";

Send the File to a Remote API using the http Module

In the following, we alter the preceding example by adding a call to a remote API and pass the file that was received in the request.

Example
// Require the http module
var http = require("http");
// Retrieve content of the "files" field from the built-in "request" object
var filesInRequest = request.files;
if (filesInRequest) {
  // When we uploaded the file, we associated it to a field called "myFile"
  // this field should end up as a field of the "files" object
  // in the below, we check if "files" contains the "myFile" field and if the latter is not empty
  if (filesInRequest.myFile && filesInRequest.myFile.length > 0) {
   
    var requestObject = {
  		"url": "https://www.googleapis.com/drive/v1/files",
 		"params": {
  			"kind": "drive#file",
  			"id": "myFile",
  			"title": "someTitle"
        },
      	"files": {"myFile": filesInRequest.myFile},
  		"method": "POST"
	}
	// send the request by invoking the request function of the http module and store the returned response object
	var response = http.request(requestObject);
    return "got a file";
  }
}
return "no file";
Contact us
Ask your question and we'll get back to you shortly.
Send
Message Sent
Support