Does Celigo Webhook Listener Support Bearer Token Authentication?

What I’m Trying to Do:

  1. Receive a webhook POST request with a Bearer Token in the header.
  2. Validate the token.
  3. Send the data to NetSuite.

The Solution:

Three ways you could do this without an enhancement (which we should do):

  1. Use a MyAPI – since MyAPIs are behind a bearer token only, this could work if you can give your source system the API token that you generate under resources > API token > custom access to only the MyAPI. From here, the MyAPI can take the request and directly forward it to an IO listener sitting on a flow. Below is a sample script I had made for a different use case, but you should get the gist of how to do it from here. Notice the exports.run call out to the IO listener.

/*
* handleRequest function stub:
*
* The name of the function can be changed to anything you like.
*
* The function will be passed one 'options' argument that has the following fields:
*   'method' - http request method (uppercase string).
*   'headers' - http request headers (object).
*   'queryString' - http request query string (object).
*   'body' - parsed http request body (object, or undefined if unable to parse).
*   'rawBody' - raw http request body (string).
*
* The function needs to return a response object that has the following fields:
*   ‘statusCode’ - http response status code (number).
*   'headers' - http response headers overrides (object, optional).
*   'body' - http response body (string or object).
* Throwing an exception will signal an error.
*/

import {request, integrations, exports, imports, flows, connections} from 'integrator-api';

var productIntegrationId = "65f10eda70ff6d8e69e527db";

function handleRequest (options) {
  
  let responseBody = "";
  if (!options.queryString.validationToken) {
    
    let productIntegrationObj = integrations.get(productIntegrationId);
    
    if (productIntegrationObj && productIntegrationObj.settings && productIntegrationObj.settings.ioWebhookListeners && Array.isArray(productIntegrationObj.settings.ioWebhookListeners) && productIntegrationObj.settings.ioWebhookListeners.length > 0) {
      
      let listenerExportIdsSubscribed = productIntegrationObj.settings.ioWebhookListeners;
      
      for (let e of listenerExportIdsSubscribed) {
        let exportObj = exports.get(e);
        if (exportObj && exportObj.webhook && exportObj.webhook.provider === "integrator-extension") {
          
          options.body.received_at = (new Date()).toISOString();
          
          try {
            exports.run({
              _id: e,
              listenerData: [options.body]
            })
          } catch (e) {
            console.log(JSON.stringify(e));
          }
        }
      }
    }
  } else {
    responseBody = options.queryString.validationToken;
  }
  
  
  return {
    statusCode: 200,
    headers: {"Content-Type":"text/plain"},
    body: responseBody
  }
}

The image shows a software interface where a source is being created, with "Celigo integrator.io" selected from an application search menu. (Captioned by AI)

The image shows a "Create source" interface with options to select an application and choose to listen for real-time data from a source application. (Captioned by AI)

This image shows the "Edit listener" interface of Celigo, where a listener named "Call from MyAPI" is being configured with a public URL and options for securing the listener and generating sample data. (Captioned by AI)

  1. In the March release coming this week, you’ll be able to access request headers and queryParams that are sent to the webhook. So in this scenario, you would set up the webhook as a “secret URL,” then within transformation 2.0, you could compare the token with your correct one. I wouldn’t necessarily recommend this though because you’d be storing the token in plain text as there isn’t somewhere to put an encrypted field setting for webhooks.
  2. You could set up the webhook as a secret URL, then just ignore the authorization header altogether. The fact that the webhook URL is already a secret would be some level of security.

Leave a comment

Your email address will not be published. Required fields are marked *