Tutorial

Make a Plugin

This tutorial help you with the specifics of creating plugins, extending node's behaviour to fit your needs.
If you have not a node up and running yet, follow this guide first.

Step 1: create it

The following code shows a minimal implementation:

  // index.js

module.exports = {
  /**
   * Required. Do something
   * @returns  {Promise}
   */
  run: function() {
    return Promise.resolve(42);
  }
};

Open a terminal and change the working directory to your stormnode installation path, then executes these commands:

  cd storm_modules/custom/
mkdir my-first-plugin
cd my-first-plugin
touch index.js

Copy-paste the previous example into index.js, and you are done!


Step 2: use it

Let's try it for real now, follow the next steps from the dashboard:

  1. refresh the plugins list
  2. add a new plugin command, setting:
    Return: int code
    Command: my-first-plugin
  3. execute it!
    You should see something like this:

Step 3: a more complete example

Now we are going to build a new plugin with more features, a GIT repository with the code is available at this link.

Reopen a terminal and, as before:

  cd storm_modules/custom/
mkdir stormnode-plugin-skeleton
cd stormnode-plugin-skeleton
mkdir src # use an src directory for the source code
touch src/index.js # prepare an entry point
npm init # initialize an npm package, set src/index.js as entry point

Start with the following code. It does nothing for now, just returns an empty object, we will extend its functionalities soon.

  // src/index.js

module.exports = {
  /**
   * Required. Do something
   * @returns  {Promise}
   */
  run: function() {
    return new Promise((resolve, reject) => {
      resolve({});
    });
  }
};

We want our plugin to use some local environment config, and other dynamic arguments.
The dotenv module allow us to use an .env file for local variables.

  npm install dotenv --save
echo MY_SECRET_VAR=42 > .env

Complete src/index.js with the following code.

  // src/index.js

const path = require('path');

// load environment configuration at the first execution
require('dotenv').config({ path: path.dirname(__dirname) + '/.env' });

const defaultArgs = {
  MY_SECRET_VAR: process.env.MY_SECRET_VAR || null,
  SHOULD_REVEAL_SECRET: false
};

module.exports = {
  // optional, needed to receive arguments
  setArguments: function(args) {
    this.args = Object.assign({}, defaultArgs, args);
  },

  // optional, needed to receive node config
  setNodeOptions: function(config) {},

  // required, do something, return a Promise
  run: function() {
    return new Promise((resolve, reject) => {
      const shouldRevealSecret = this.args.SHOULD_REVEAL_SECRET === 'douglas';

      resolve({
        shouldRevealSecret,
        secretVar: shouldRevealSecret ? this.args.MY_SECRET_VAR : 0
      });
    });
  }
};

Now, from the dashboard:

  1. refresh the plugins list
  2. add a new plugin command, setting:
    Return: json
    Command: stormnode-plugin-skeleton
  3. execute it!
    You should see something like this:

Add a custom argument on the plugin command
with key = SHOULD_REVEAL_SECRET, and value = douglas
try executing it again..do you see something different? ;)

Execution via endpoint

First of all, you need to generate an API Token into Profile section.
Edit the plugin command and enable the "Endpoint" switch. Copy its URL. With an HTTP POST request without body, the command will be executed with the specified arguments:

  curl -X POST 'https://storm.dev/api/v1/plugincommand/${example_command_token}/run/${example_profile_token}'
{"return":{"shouldRevealSecret":true,"secretVar":"42"}}
  

Otherwise you can pass any arguments as a JSON object:

  curl -H 'Content-Type: application/json' 'https://storm.dev/api/v1/plugincommand/${example_command_token}/run/${example_profile_token}' -d '{"SHOULD_REVEAL_SECRET":"not_douglas"}'
{"return":{"shouldRevealSecret":false,"secretVar":0}}
  

Congratulations, you wrote your first Storm plugin!