Stryke Docs - 1.9.0

Stryke Docs - 1.9.0

›Actions Definition

Overview

  • Overview
  • Quick Start Guide
  • The Playground app

Changelog

  • Stryke Changelog

Developing an App

  • Users Overview
  • Create a new App
  • Entity Definition
  • Actions Definition

    • Actions Definition
    • Scripts and source code
    • Triggers
    • Templates and views
  • Where is your app's data stored?
  • Synchronising app instances

Using an App

  • Stryke App UI
  • Working with your app's data
  • End users
  • Access Control
  • Files

API

  • Stryke API
  • Stryke queries

Developer Tools

  • Tools

Stryke Library

  • Stryke Library Reference

Scripts and source code

Stryke allows you to write your app's business logic in the form of simple scripts. These scripts are written in Javascript (ES2017). Your scripts run in a sandboxed Node environment and can benefit from many of the features that Node provides.

You can create and edit your scripts through the Stryke's web interface but we recommend you to Download Visual Studio Code and install our extention: Stryke Code. This provides a more complete experience and allows you to work with your scripts from your local environment.

Scripts can contain anything, the only requirement for a script to work is that it must be ended by either a call to the resolve or error methods.

// the most basic Stryke script!
stryke.resolve('Hello World!');

These methods are part of the Stryke Library.

Stryke Library

The Stryke Library provides ways to interact with Stryke from your scripts. It includes functions that can be called to query data, create and modify records, but also getting information about the execution context of the script, such as: the user that is executing the script, or the record from which an execution was triggered, and much more.

Below are examples of how to use the functions and properties provided by the Stryke Library.

For more details be sure to check out the Stryke Library Reference

Script Functionality

Resolve and Error

All scripts must be ended with a call to either resolve or error.

resolve ends the execution of a script much like a return statement in a function. The resolve function accepts an optional parameter, which is the value that will be returned to Stryke and ultimately shown on your app's UI or the response to an API request. The value returned through the resolve function must match the datatype that the parent action is expected to return. For example, if the action's return type is: object the resolve function should be passed a JS object.

resolve comes in handy when your code contains asynchronous calls. By placing the resolve call in the right place you can ensure that the execution of the script will wait for your promises or callbacks to finish before ending the script execution.

myAsyncFunc((result) => {
    // the script will end only when the callback is called!
    stryke.resolve(result);
});

error is similar to resolve in the fact that it also ends script execution as soon as it is reached. The only difference is that the script will be terminated with an error. The error function can accept a message, which will be returned and shown in the app's UI or API response. Calling error is the correct way to handle error conditions inside your scripts.

myPromise.then((result) => {    
    stryke.resolve(result);
})
.catch((err) => {
    // the script will be ended with an error response containing the message from 'err'
    stryke.error(err.message);
});

Create and Update functions

The Stryke Library provides functions to create and update data in your app. These functions are asynchronous and will callback to your script with the result of the operation. Create and update can work in one of two ways:

  1. accepting a callback function which is called when the operation is completed (with or without an error)
  2. if no callback function is provided they will return a promise which is resolved or rejected with the result or error from the operation.

Create

Below is an example of how to use the create function with a callback:

const receiptToCreate = { amount: 65.50, type: '8cd87440-06dd-454d-9346-6de44a6360f2' }

stryke.create('receipt', receiptToCreate, (err, savedRecord) => {
    // if there is an error, terminate with it!
    if (err) {
        stryke.error(err.message);
    }
    console.log('saved: ' + savedRecord.alias);

    stryke.resolve();
});

Alternatively, the same code can be implemented using a promise:

const receiptToCreate = { amount: 65.50, type: '8cd87440-06dd-454d-9346-6de44a6360f2' }

stryke.create('receipt', receiptToCreate).then((savedRecord) => {
    
    console.log('saved: ' + savedRecord.alias);
    stryke.resolve();
})
.catch((err) => {
    // if there is an error, terminate with it!    
    stryke.error(err.message);
});

Since Stryke supports ES2017, we can make use of async/await to make this tidier:

const receiptToCreate = { amount: 65.50, type: '8cd87440-06dd-454d-9346-6de44a6360f2' }

try {
    const savedRecord = await stryke.create('receipt', receiptToCreate);
    
    console.log('saved: ' + savedRecord.alias);
    stryke.resolve();
}
catch(err) {
    // if there is an error, terminate with it!    
    stryke.error(err.message);
}

Update

Below is an example of how to use the update function with a callback:

const receiptToUpdate = { amount: 50.50, type: '8cd87440-06dd-454d-9346-6de44a6360f2' }

stryke.update(idOfReceiptToUpdate, receiptToUpdate, (err, updatedReceipt) => {
    if (err) {
        stryke.error(err.message); 
    }
        
    console.log('updated: ' + updatedReceipt.alias);
    stryke.resolve(updatedReceipt);
});

Here is the same functionality as above, but implemented using a promise.

const receiptToUpdate = { amount: 50.50, type: '8cd87440-06dd-454d-9346-6de44a6360f2' }

stryke.update(idOfReceiptToUpdate, receiptToUpdate).then((updatedReceipt) => {
    console.log('updated: ' + updatedReceipt.alias);
    stryke.resolve(updatedReceipt);    
})
.catch((err) => {
    stryke.error(err.message);     
});

Find, FindOne, and Query

Scripts can leverage Stryke's GraphQL API to perform advanced queries on the data. The Stryke Library offers three functions to query data.

Find

The stryke.find() function accepts a GraphQL query string (this query can leverage all features and operators of the Stryke query) and returns a promise, which will resolve with an array of records containing the query result.

stryke.find() should be the default function to use to query data. For additional functionality see the stryke.findOne() and stryke.query() functions below.

// A GraphQL query to retrieve all receipts where the amount is greater than 50.
// This query leverages Stryke's custom query engine through the 'filter' parameter.
const queryForReceipts = 
    `{ 
        Receipt (filter: { 
            amount: { gt: 50 } 
        }) {
            alias, amount, date, type
        }
    }`;

stryke.find(queryForReceipts).then(result) => {    
    stryke.resolve(`${result.length} receipts with amount > 50`);
}

FindOne

The stryke.findOne() function provides a convenience function that wraps the stryke.find() function and returns a single object instead of an array for queries that are expected to return a single value (example: query by ID). Note that this function will throw an error is the result contains more that 1 record.

// A GraphQL query to retrieve a single receipts record by ID
const queryForSingleReceipt = 
    `{ 
        Receipt (id: "f3b94767-07ad-4d28-aa47-6266e88ea6c1") {
            alias, amount, date, type
        }
    }`;

stryke.find(queryForReceipts).then(receipt) => {    
    stryke.resolve(`receipt: ${receipt.alias} with amount: ${receipt.amount}`);
}

Query

For more advanced query cases, the stryke.query() function can be used instead of stryke.find() or stryke.findOne(). stryke.query() accepts more arguments than other query functions to provide more control over the query operation.

The result generated by the stryke.query() function is more verbose than the format returned by stryke.find() and follows the standard GraphQL format

stryke.query() accepts a second argument to control whether access control should be applied when executing the query. Access control is always applied when using stryke.find() or stryke.findOne(). For scenarios in which it is necessary to retrieve data beyond what the current user has access to, the stryke.query() function can be called passing false as the second argument.

// Executes 2 queries in a single statement and returns a result in the standard GraphQL format.
const queryForReceipts = 
    `{ 
        Receipt (filter: { 
            amount: { gt: 50 } 
        }) {
            alias, amount, date, type
        }
        Type {
            id, alias
        }
    }`;

stryke.query(queryForReceipts, true).then(result) => {
    console.log('GraphQL errors: ' + result.errors);    
    stryke.resolve(`There are ${result.data.Receipt.length} receipts and ${result.data.Type.length} types`);
}
            

NOTE: It is possible to execute multiple query statements in a single query call using the stryke.find() function too. In such cases the result returned by the stryke.find() function will be the same as the one returned by stryke.query().

Execution Data

The Stryke Library offers access to ExecutionData. ExecutionData contains data that is relevant for a specific script execution.

As an example, when a script is triggered via a button on the app's UI, you can retrieve that record via stryke.data.record.

stryke.data and its content is provided to scripts as read-only. This means that objects like stryke.data.record cannot be modified directly.

record

The record in context for this script execution. This is the record from which an script was triggered to run.

recordBefore

When running trigger scripts, recordBefore holds the data of the record that cause the trigger to run, before the update, create or delete actions were executed.

recordAfter

When running trigger scripts, recordAfter holds the data of the record that cause the trigger to run, after the update, create or delete actions were executed.

requestPayload

Any data that was passed as payload (ie the body of the HTTP request) to the original script or action execution request. This can be used to pass request specific arguments to the script being executed. The payload must be in valid JSON format.

User Info

UserInfo contains information about the app user that is executing the script. This allows retrieving the user's information via: stryke.user.

Console

Scripts can use console functions like any other JS code. The output of console.log statements can be seen under Visual Studio Code, when executing a script via Stryke Code. Additionally they are stored by Stryke for auditing.

Supported Node Modules

Scripts runs in a sandboxed environment that guarantees security and data isolation. Not all

builtin

  • util

external modules

  • node-fetch
  • axios
  • moment
  • @slack/bolt

Script examples

Callout to a 3rd party service

Scripts can use node modules to perform requests to external services. This allows retrieving data as well as posting information. Here is a simple example illustrating a callout performed from a script.

Using axios

const axios = require('axios');

axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
  .then((response) => {
    // return the parsed JSON response
    stryke.resolve(JSON.stringify(response.data));    
  })
  .catch((error) => {
    // handle errors
    stryke.error('Callout failed: ' + error.message);
  });

Using fetch

const fetch = require('node-fetch');

fetch('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
    .then(res => res.json())
    .then(json => stryke.resolve(JSON.stringify(json)))    
    .catch(error => stryke.error('Callout failed: ' + error.message));

Use Moment to work with dates

Moment is a very powerful module to work with dates and times in JS.

Below is a simple example that calculates the difference between two dates and returns a formatted message to the user.

const moment = require('moment');

// we are assuming that this action has a record in context (eg: a button clicked from 
// a record), and that the record has a startDate and endDate date-time fields. 
const momentStart = moment(stryke.data.record.startdate);
const momentEnd = moment(stryke.data.record.enddate);

const timeDifferenceInMinutes = momentEnd.diff(momentStart, 'minutes');

const formattedStart = momentStart.format('YYYY-MM-DD HH:mm');
const formattedEnd = momentEnd.format('YYYY-MM-DD HH:mm');

const formattedResult = `There are ${timeDifferenceInMinutes} minutes between ${formattedEnd} and ${formattedStart}`;

stryke.resolve(formattedResult);

Integrate with Slack

Slack provides a library called Bolt that provides ways to build Slack apps and interact with your Slack workspace.

For the full documentation on Bolt, check out Slack's official docs

The example below will post a message on the channel with the specified ID. In order for the script below to work you will need to create an app in your Slack workspace.

const { App } = require('@slack/bolt');

const SLACK_SIGNING_SECRET = 'set your signing secret here';
const SLACK_BOT_TOKEN = 'set your bolt token here';
const SLACK_CHANNEL_ID = 'set the channel id of the channel where you want to post the message';

// Initialize app
const app = new App({
    signingSecret: SLACK_SIGNING_SECRET,
    token: SLACK_BOT_TOKEN
});

// Slack error handler
app.error((error) => {
    console.error(error);
    stryke.error('failed: ' + error.message);
});

// post a message on your Slack channel
try {
    app.client.chat.postMessage({
        token: SLACK_BOT_TOKEN,
        channel: SLACK_CHANNEL_ID,
        text: 'Hello Slack!',
        link_names: true
    });
    stryke.resolve('message posted on Slack!');    
} catch (error) {
    console.error(error);
    stryke.error('failed: ' + error.message);
}
← Actions DefinitionTriggers →
  • Stryke Library
  • Script Functionality
    • Resolve and Error
    • Create and Update functions
    • Find, FindOne, and Query
    • Execution Data
    • User Info
  • Console
  • Supported Node Modules
    • builtin
    • external modules
  • Script examples
    • Callout to a 3rd party service
    • Use Moment to work with dates
    • Integrate with Slack
Stryke Docs - 1.9.0
Docs
Docs HomeAPI DocsStryke Tools
Community
Stryke HomeTwitterGithub
Contact Us
support@stryke.io
Copyright © 2021 Viroppa