Inline Slack NodeJS Lambda

Objective

At Galactic Fog we needed a way to funnel our web sales notifications from our website to a private Slack channel. However, we had no desire to build a stand alone web service and deal with its inherit complexities. Normally, we would write a simple nodejs server, host, maintain and integrate the process into our CI pipeline. The server would always be running, requiring additional resources and monitoring. This is a perfect task for a lambda function!

Requirements

  • Implement App As Serverless Solution
  • Expose publicly for our website
  • Obfuscate any potentially sensitive information from the client
  • Provide some sort of thottling

Pre Requisites

  • You are authenticated and authorized to Gestalt Platform
  • You have already defined a Hierarchy (Org, Workspace, Environment)
  • You have already defined an API in Gestalt Platform
  • You have configured a slack web hook

Create an API for posting messages to a slack channel

Define the Lambda

Since this is an Inline Lambda we will need to use the core NodeJS https API so we can make REST request. In a future tutorial, we'll show you how roll your own Packaged Lambda with the 3rd party libraries of your choice.

  1. Navigate to your desired Environment and on the Create Menu Click Create Lambda
  2. Select the desired Lambda Provider and Name
  3. Select the a NodeJS Runtime and select Inline Code Type
  4. Specify the **Handler as run
  5. Paste the source code below into the editor. Notice the exports.run where .run is the Handler i.e. the function main we want to invoke when the lambda is called
var exports = module.exports = {};
exports.run = function(payload, context, callback) {
  const https = require('https');
  const host = process.env.SLACK_HOST;
  const path = process.env.SLACK_PATH;
  const options = { method: 'POST', host, path, payload };

  // https request POST method
  const request = (options) => {
    const postOptions = Object.assign({
      headers: {
        'Content-Type': 'application/json',      
        'Content-Length': Buffer.byteLength(payload),
      },
      json: true,
    }, options);

    const req = https.request(postOptions, (res) => {
      res.on('end', () => callback(null, 'SUCCESS'));
    });

    req.on('error', (e) => callback(e.message, 'ERROR'));
    req.write(payload);
    req.end();       
  };

  request(options);
};

Configure Environment Variables

Environment Variables that are defined on the Lamnda are passed to nodeJS lambdas via process.ENV Here you will need the information that weas generated when you configured your webhook with slack

  1. Define two variables in the Environment Variables
  2. SLACK_HOST: hooks.slack.com
  3. SLACK_PATH: /services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
  4. Click Create

Expose an API Endpoint

Now that we've created our Slack Lambda we need to expose an api endoint.

  1. On the same Lambda screen, in the Public Endpoints section click Add Endpoint
  2. Select an API and click Next
  3. Enter a Relative Path e.g /send
  4. Check only the POST Allowed HTTP Method
  5. Check the Rate Limit and enter 60 (the number of requests allowed per minute)
  6. Click Finish
  7. Click or copy the Public URL which you will use to make your REST API call

Using your favority REST client you can post the following message format using the following settings:

  • URL: The public URL that ws generated when you created the endpoint:
  • Headers: Content-Type: application/json Accept: application/json
  • Method POST
  • Body:
{
"text": "Hello Slack!" 
}

You should see a message in your slack channel!!!