Anatomy of a Webhook

The following describes the pieces that make up an Alma webhook listener.

Challenge (GET)

When registering a webhook listener as an integration profile, Alma “challenges” the listener. This ensures an active listener is available at the provided URI​. The listener should reply to the GET request with the challenge sent in the querystring​.

Alma sends:

GET /webhook?challenge=1234​

The listener responds:

200 OK​
{“challenge”:”1234”}​

Webhook Event (POST)

For each registered event in the integration profile, Alma sends a POST request to the listener. The request is made up of the following sections:

  • A signature (see below)
  • The webhook details (id, action, time, etc.)
  • Action-specific payload (i.e. Job Instance) in JSON or XML

Alma sends:

POST /webhook​
X-Exl-Signature: g4njfSmb5BqPPh=​
​
{
  "id":"1767426760000561",
  "action":”job_end",
  "time":"2016-09-07T08:48:45Z",
  "job_instance": {
    "id":"1767426760000561",
    "name":"Add set 1767425500000561 to collections: 8182119880000561"
    ...
  }​
  ...​
}

The listener responds:

200 OK

Signature

The signature ensures the message came from Alma and that it was not tampered with​. It is recommended (but not required) that the listener validate the signature​. The signature is a Base64 encoded HMAC SHA256​ hash of the entire body payload and is sent in the X-Exl-Signature header. The shared secret is specified in the webhook integration profile.

Below is an example of how to validate the signature in JavaScript.

function validateSignature(body, secret, signature) {​
  var hash = crypto.createHmac('SHA256', secret)​
     .update(JSON.stringify(body))	​
     .digest('base64');	​
  return (hash === signature);​
}