Creating Simple Static Integrations

You can create a static package integration by following the steps outlined in this guide. This how-to guide shows how to recreate an already existing static block and present it as an integration package. You can use these steps and remodel them as necessary for your needs.

Setting up this static integration type involves the following steps:

  1. Create a Folder Structure – Define and create a folder structure for the integration. Here is an example:

  • flows

    • integrationName

  • javascript

    • integrationName

  • icons (optional)

An example folder structure
  1. Create a manifest.json file – You need to create the manifest.json file in the main directory of the integration. In it, you can add all dependencies that are used in the package.json file.

{
    "manifest_version": "1.0",
    "name": "TestIntegration",
    "version": "1.0.0",
    "description": "Some description",
    "author": {
        "name": "The name of the creator",
        "email": "test@test.io"
    },
    "dependencies": {
        "ltrim": "^1.0.0"
    },
    "changelog": {
        "1.0.0": "What changed"
    }
}

An example manifest.json
The following parameters can be defined here:

  • manifest_version – the version of the manifest file. You can update the versioning when updating the file to bring awareness of changes.

  • name – The name of the integration package.

  • version – The version of the integration package.

  • description – A description of the integration package.

  • author – you can define the author here. Sub-parameters are the “name” and “email” of the associated author.

  • dependencies – you can define any dependent packages.

  • changelog – Allows you to set changelog entries referencing notes for each integration package.

  1. Place an image in the icons (optional) – You can optionally add an icon to the integration package. They should be small in size and with a transparent background in SVG format.
    The associated icon should be named after the integration name.

  2. Place the JS logic file in the javascript directory – Place the associated file that handles the Javascript logic. It will be called from the static block and contain all execution code. In this example file called lstrip.js, the code will return a promise with resolve (end_result) for success or reject (error_message) for failure.

    'use strict';
    
    const ltrim = require( 'ltrim' );
    
    function lstrip(userId, what) {
    	return new Promise((resolve, reject) => {
    		try {
    			resolve(ltrim(what))
    		} catch (error) {
    			reject(error);
    		}
    	})
    }
    
    module.exports = lstrip;
  3. Create the associated static block – Create the required block containing the base JSON instructions on file handling. Here the flows folder contains the visible blocks in the user interface.

    {
        "platform": "node",
        "language": "js",
        "name": "StringLStripOrAnyNameYouLike",
        "runProcess": "main",
        "processes": [
            {
                "name": "main",
                "entryNode": "logic1",
                "exitNode": "logic2",
                "nodes": [
                    {
                        "name": "logic1",
                        "nodeIsSubProcess": false,
                        "function": "this.moduleAwait('./Salami/lstrip', null, this.i['str']);",
                        "process": null,
                        "processParameters": [],
                        "nextNodes": [
                            "logic2"
                        ],
                        "meta": null
                    },
                    {
                        "name": "logic2",
                        "nodeIsSubProcess": false,
                        "function": "this.i['result'] = this.l['logic1'];",
                        "process": null,
                        "processParameters": [],
                        "nextNodes": [],
                        "meta": null
                    }
                ],
                "variables": [
                    {
                        "name": "str",
                        "level": "INTERMEDIATE",
                        "type": {
                            "type": "string"
                        },
                        "value": "",
                        "isInput": true,
                        "isOutput": false,
                        "required": true,
                        "meta": {
                            "displayName": "String",
                            "description": "Input String"
                        }
                    },
                    {
                        "name": "result",
                        "level": "INTERMEDIATE",
                        "type": {
                            "type": "string"
                        },
                        "isInput": false,
                        "isOutput": true,
                        "meta": {
                            "displayName": "Result",
                            "description": "Result"
                        }
                    }
                ]
            }
        ],
        "meta": {
            "color": "orange",
            "title": "StringLStrip",
            "template": "Process",
            "info": "Strip leading whitespace - this is a description for the block",
            "type": "action"
        }
    }
    

You can define the processes in the "processes" section. The following items are essential parts of the code block:

  • entryNode points towards the node which will be executed first.

  • exitNode points towards the node which will be executed last.

  • nodes contain all the nodes.

  • variables contain all the input and output values.

Nodes define the array of steps that are to be executed in the workflow. The first part of the algorithm starts with entryNode, while each subsequent node has a property called nextNodes containing the instructions on the next steps.

The function param is the actual call to the JS file in javascript folder:
this.moduleAwait('./integrationName/fileToExecute', user_id(nullAtThisMoment), theValueToPass);

Multiple values of different types can be passed after the user_id field.

"nodes": [
    {
        "name": "logic1",
        "nodeIsSubProcess": false,
        "function": "this.moduleAwait('./Salami/lstrip', null, this.i['str']);",
        "process": null,
        "processParameters": [],
        "nextNodes": [
            "logic2"
        ],
        "meta": null
    }
]

Variables also can be defined. There are two elements that are part of the variables array in our example code block. Most fields are easy to understand but the emphasis lies on "isInput" and "isOutput". Each variable can be one of two or both.
An Input variable is data provided by the user. (the str variable)
An Output variable is data used by the user or the return value of a block. (the result variable)

"variables": [
    {
        "name": "str",
        "level": "INTERMEDIATE",
        "type": {
            "type": "string"
        },
        "value": "",
        "isInput": true,
        "isOutput": false,
        "required": true,
        "meta": {
            "displayName": "String",
            "description": "Input String"
        }
    }
]

Adjust the metadata in the relevant section, you can set the title and info variables.

"meta": {
    "color": "orange",
    "title": "StringLStrip",
    "template": "Process",
    "info": "Strip leading whitespace",
    "type": "action"
}
  1. Package the contents in a ZIP file – Once all relevant files are ready, they can be packaged. Create a ZIP package with all files and name them using an appropriate name following this template: integrationName_version.zip.

Note: The zip package must contain the root tree structure itself, do not package the folder holding the files.