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); }