1. Service App Webhook Events
  2. Verify incoming webhook event data

1 Service App Webhook Events

Service app utilizes webhooks to notify consumer application about events that occur in a Spaces account. To setup webhook go to event subscription page. In there you must provide callback URL and select at least one trigger event. Once you enter your required data, you must click Save

On the event subscription page, the secret key is hidden by default. It can be revealed by clicking eye icon. To generate new secret key click on refresh icon. You should ensure the new key is updated on your server after changing it, as new requests may not pass verification.

For information how to setup service application, please visit Application using Service Account page.

TriggerDescription
space.createdNotify when a new space was created within a company
space.deletedNotify when a space was deleted within a company
space.call.offerNotify when a digital or Aura call is initiated within a company
space.call.acceptedNotify when a digital or Aura call is answered within a company
space.call.endedNotify when a digital or Aura call is ended within a company
space.call.cancelledNotify when a digital or Aura call is cancelled within a company
space.call.not.answeredNotify when a digital or Aura call has ringing timeout within a company

2 Verify incoming webhook event data

While invoking the callback url configured in the event subscription page, the signature will be signed using the secret key and will be passed in the "X-Spaces-Signature" header.

To verify incoming data into specified callback url given by you, check HTTP headers "X-Spaces-Signature" and "X-Spaces-Request-Timestamp". Use cryptographic algorithm SHA256 to validate signature. See code example bellow.

const crypto = require('crypto');
const bufferEq = require('buffer-equal-constant-time')
const express = require('express');

function verifySignature(string_to_sign, signature, provided_signing_secret) {
  let signing_secret = provided_signing_secret;
  let hmac = crypto.createHmac('sha256', signing_secret);
  let newSignature;

  hmac.update(string_to_sign);
  newSignature = hmac.digest('hex');

  return bufferEq(
      new Buffer.alloc(newSignature.length, newSignature.toString('base64')),
      new Buffer.alloc(signature.length, signature.toString('base64'))
  );
}

function verifySignatureHeaderFromRequest(req, signing_secret) {
  const retrievedSignature = req.get("X-Spaces-Signature");
  const retrievedTimeStamp = req.get('X-Spaces-Request-Timestamp');
  const stringToVerify = 'v0:' + retrievedTimeStamp + ':' + req.body.data;

  return verifySignature(stringToVerify, retrievedSignature, signing_secret);
};

// signing secret on service app events page
const signingSecret = "98ebda579bbc549fe827952fcdc438134c37cfa5";

const app = express();

app.post('/getPostMessageSpaces', (req, res) => {
  console.log("Data received is " + req.body.data);
  if (verifySignatureHeaderFromRequest(req, signingSecret)) {
    console.log('Signature is valid and Webhook called');
  } else {
    console.log("Signature Mismatch");
  }
});