Implement External -Adapters

For the demo purpose, we will setup our external adapter to pull the data from weather API. Follow along the following tutorial to understand how it works.

Setting up external initiator requires the following steps to be performed

  • Git clone the repository

  • cd & npm install

  • Include the API endpoint & Parse the payload

  • Run the server

Step 1 -

git clone https://github.com/GoPlugin/external-adapter-template.git

Step 2 -

cd weather_adapter

Step 3 -

npm install

Step 4 -

map the api endpoint

Requesting Data

When an external adapter receives a request from the Plugin node, the JSON payload will include the following objects:

  • data (Guaranteed to be present but may be empty)

  • meta (Optional, depends on job type)

  • responseURL (Optional, will be supplied if job supports asynchronous callbacks)

  • id (Optional, can be nice to use for EA logging to help debug job runs)

Returning Data

When the external adapter wants to return data immediately, it must include data in the returned JSON.

An example of the response data can look like this:

{
  "data": {
    "result": "20.04"
  }
}

Note - The external adapter that you are running, should be the same URL endpoint mapped in Bridge.

const { Requester } = require('@goplugin/external-adapter')
require("dotenv").config();

const customError = (data) => {
  if (data.Response === 'Error') return true
  return false
}

const customParams = {
  endpoint: ['endpoint']
}

const createRequest = (input, callback) => {

  const url = `http://<host>/api/${input.data.endpoint}`

  const config = {
    url
  }

  if (process.env.API_KEY) {
    config.headers = {
      Authorization: process.env.API_KEY
    }
  }
  Requester.request(config, customError)
    .then(response => {

      if (input.data.envCheck == "WindDirection") {
        var resultData = response.data[0]['windDirection'];
      } else if (input.data.envCheck == "Temperature") {
        var resultData = response.data[0]['tempC'];
      } else if (input.data.envCheck == "WindChill") {
        var resultData = response.data[0]['windChillC'];
      }
      response.data.result = resultData.toString();
      
      const res = {
        data: {
          "result": response.data.result.toString()
        }
      }
      callback(response.status, Requester.success(input.id, res));
    })
    .catch(error => {
      callback(500, Requester.errored(input.id, error))
    })
}

module.exports.createRequest = createRequest

Let's see what's in "index.js"

  • We are importing 'external-adapter' from goplugin npm using importing methods such as Requester

  • Importing "dotenv" module to access the .env file for sensitive info (API_KEY).

  • "customError" is a function to return either true or false if an error occurs.

  • "customParams" is a variable to declare parameters to pass on in URL - this can be customized accordingly.

  • "createRequest" is the method actually doing the heavy lifting.

    • URL is getting defined since for the weather node the endpoint is getting passed via smart contract the "endpoint" is accessed via "input.data.endpoint".

    • <host> to be replaced with a respective domain name or IP address where we are fetching the data

    • api -> router name. Again for our weather node, we have API as rrouter name for your case it can be a different

    • config -> variable name to have url parm

    • Next, we are checking APIKEY if exists in env parm, else it will not be applied. For authenticated API, you have to pass APIKEY

    • Requester.request will scan for the payload from the API endpoint and customize the output .. In this example, we are checking "input.data.envCheck".

      • Note that, envCheck is a parameter we are passing via smart contract(Check weather node)

      • Based on envCheck, the loop iterates and scans the value from the output payload

      • Finally we are constructing the response and return

When you run PM2 Start server.js, the server will by default run in port 5001 and just make sure the bridge is correctly pointed out to this port number. For instance, this should be http://localhost:5001/

Last updated