Plugin Hooks can be used by developers of integrations (also called plugins) to receive real-time events from all Crisp websites that installed the plugin. For instance, you may want to get your plugin notified of messages sent by your website visitors, in real-time.
This guide explains how Plugin Hooks work, and how to get them to work with your integration. Plugin Hooks are available to all integrations created on the Crisp Marketplace.
What do Web Hooks do?
Plugin Hooks can be used to integrate with Crisp, and receive real-time events from Crisp on a custom HTTP endpoint, ie. on your own servers. Your endpoint will receive real-time events for all Crisp websites that installed your plugin.
This can be used in the following scenarios:
- Build a custom chatbot answering to messages
- Connect Crisp to another messaging platform
- Synchronize contacts to a custom CRM platform
- Etc. (you may come up with other scenarios)
How to Setup Plugin Hooks?
Plugin Hooks are configured from the Crisp Marketplace. Before you start, make sure you have an active integration on the Crisp Marketplace. If you do not already have a plugin, follow our guide to create one.
1. Prepare the receiving endpoint
To setup Plugin Hooks, you first need to setup a public HTTP endpoint, handling HTTP POST
payloads. The endpoint can listen on any domain name / URL and can be hosted on your own servers.
Web Hooks delivered to your endpoint will come with a signature header. It is recommended that you use this header to verify that Web Hooks sent to your endpoint are genuine (ie. coming from Crisp), as an attacker may manage to discover your endpoint URL and forge rogue Web Hooks. You can read more about how to verify signatures.
2. Add your endpoint to your plugin
Once the endpoint is ready, create the Plugin Hooks configuration in the Crisp Marketplace:
- Go to the Crisp Marketplace and open navigate to your plugin
- Click on the Settings tab, and scroll down to the Events section
- Paste the URL of your Web Hook endpoint in the Development or Production section (you should use different endpoints for each)
- Hit the Create Web Hook button (a modal will open)
- Pick the event namespaces that you wish to subscribe to (please only pick the ones you expect, and not all of them)
- Copy your signing secret and use it to verify Web Hook signatures (this is not mandatory, but heavily recommended)
- Confirm your changes and finish creating the Web Hook
3. Check your new Web Hook
Now that your Web Hook is created and running, it's time to confirm it works properly.
When Crisp forwards an event to your Web Hook endpoint, it considers any HTTP 200
to HTTP 299
reply as successful. Other status codes are considered as failed (even redirect statuses).
To make it easy for you to debug, Crisp logs the status of the last call to your Web Hook (whether it succeeded or failed). You can check it out by refreshing your plugin settings on the Marketplace (see examples below).
How to Handle Web Hook Events?
Web Hooks events come when a real-time event occurs in your Crisp website. Event payloads have the same data format as the RTM API.
Receiving Web Hook payloads
Web Hook general format
A Web Hook HTTP POST
body is JSON-encoded and formatted as such:
{
"website_id" : "website_id", // The Website ID the event occurred in
"event" : "event", // The event namespace (see list of events below)
"data" : "payload", // The Web Hook payload (format depends on event namespace)
"timestamp" : "timestamp" // The UNIX timestamp of the event (in milliseconds)
}
Web Hook example
For instance, a Web Hook on a visitor text message (message:send
) may come on URL https://endpoint.example.com/crisp/hooks
with body:
{
"website_id": "42286ab3-b29a-4fde-8538-da0ae501d825",
"event": "message:send",
"data": {
"website_id": "42286ab3-b29a-4fde-8538-da0ae501d825",
"session_id": "session_36ba3566-9651-4790-afc8-ffedbccc317f",
"type": "text",
"content": "Hey :)",
"from": "user",
"origin": "chat",
"stamped": true,
"timestamp": 1506985696616,
"fingerprint": 150698569649423,
"user": {
"nickname": "visitor493603",
"user_id": "session_36ba3566-9651-4790-afc8-ffedbccc317f"
}
},
"timestamp": 1506985696616
}
Receiving Web Hooks using a library
The most convenient way to receive Web Hooks is to use a Web Hooks-compatible library that we provide. Read our API Libraries guide to find a library for your programming language.
Let's provide an example on how you can receive Web Hooks in your code.
node-crisp-api
library.1. Import and configure the library
const Crisp = require("crisp-api");
// Create the Crisp client (it lets you access both the REST API and RTM events)
var CrispClient = new Crisp();
// Configure your Crisp authentication tokens ('plugin' token)
CrispClient.authenticateTier("plugin", "<token_identifier>", "<token_key>");
// Set current RTM mode to Web Hooks
CrispClient.setRtmMode(Crisp.RTM_MODES.WebHooks);
2. Start listening for events
// <previous code eluded>
CrispClient.on("message:send", function(message) {
// Filter on text messages
if (message.type === "text") {
console.info(
"Got text message from visitor with content:", message.content
);
}
});
3. Pass Web Hooks coming from HTTP to the library
const express = require("express");
const bodyParser = require("body-parser");
// <previous code eluded>
// Context
const app = express();
const port = 3997;
app.use(bodyParser.json());
// Handlers
app.post("/", (request, response) => {
response.sendStatus(200);
console.log(
`<-- ${request.protocol}://${request.get("host")}${request.originalUrl}\n`,
request.body
);
// -- (you may want to verify the Web Hook signature before accepting it) --
// Receive Web Hook payload
var error = CrispClient.receiveHook(request.body);
if (error !== null) {
console.error("Web Hook processing error", error);
}
});
// Initializers
app.listen(port, () => {
console.log(`Hooks server listening at http://localhost:${port}`);
});
A full working code example can be found at: node-crisp-api/examples/events_webhooks.js.
Verifying if a Web Hook is genuine with its signature
Web Hooks that are receiving by your server should be verified before being processed. Whenever you create a Plugin Hook, you will obtain a secret that you need to keep secure. This secret can be used to verify received Web Hooks.
The verification algorithm is described in the Web Hooks Reference.
Verify using a library
The most convenient way to verify Web Hook signatures is to use a Web Hooks-compatible library that we provide. Read our API Libraries guide to find a library for your programming language.
Let's provide an example on how you can verify Web Hook signatures in your code.
node-crisp-api
library.const express = require("express");
const bodyParser = require("body-parser");
const Crisp = require("crisp-api");
// Configuration
const SECRET = "<your_web_hooks_secret_here>";
// Create the Crisp client (it lets you access both the REST API and RTM events)
var CrispClient = new Crisp();
// Configure your Crisp authentication tokens ('plugin' token)
CrispClient.authenticateTier("plugin", "<token_identifier>", "<token_key>");
// Set current RTM mode to Web Hooks
CrispClient.setRtmMode(Crisp.RTM_MODES.WebHooks);
// -- IMPORTANT: you need to bind to some RTM events here with \
// CrispClient.on(), otherwise the verifyHook() method will always return \
// that signatures do not match! (because you are not even expecting the \
// events that you receive over HTTP) --
// Context
const app = express();
const port = 3997;
app.use(bodyParser.json());
// Handlers
app.post("/", (request, response) => {
response.sendStatus(200);
console.log(
`<-- ${request.protocol}://${request.get("host")}${request.originalUrl}\n`,
request.body
);
let _timestamp = request.headers["x-crisp-request-timestamp"],
_signature = request.headers["x-crisp-signature"];
// Verify signature
let _verified = CrispClient.verifyHook(
SECRET, request.body, _timestamp, _signature
);
console.log(
`${_signature} |remote| <- SIGNATURE -> |local| (hidden)`, _verified
);
});
// Initializers
app.listen(port, () => {
console.log(`Hooks server listening at http://localhost:${port}`);
});
Direct verification (no library)
If you wish to verify a Web Hook request without using a library, please refer to the Web Hooks Reference, which describes the verification algorithm.
Never miss an event with redeliveries
In real-world situations, delivery failures happen. Web Hooks are made reliable by being lenient to failure.
A typical failure case would be a short downtime on your end, as you might be restarting your server or deploying an update to your code.
If a Web Hook delivery attempt gets rejected by your server, then Crisp will try again later, multiple times. It will only drop the event if all delivery attempts failed, or if your server is too slow to respond.
Also, make sure that your server responds with an HTTP 200
success code immediately upon receiving a Web Hook. Endpoints that are too slow to respond might be considered by Crisp as failing, leading to a new delivery attempt. If you already processed the previous delivery attempt, then this would result in duplicates on your end, which is obviously not desired.
200
. In that case, some events will never be received, so make sure that your endpoint is always reliable.Information about the current delivery attempt, and the maximum number of attempts that will be made for a delivery, can be obtained from request headers using the following HTTP headers:
X-Delivery-Attempt-Limit
X-Delivery-Attempt-Count
Which Events Can I Receive?
You can find a list of events that can be handled, as well as examples, in the Web Hooks Reference. Look for Plugin Hooks in the support matrix.
Troubleshooting
If the last call to your Web Hook failed, or if you don't receive Web Hooks events, check the following:
- Is the event namespace that you expect enabled for the Web Hook?
- Is the plugin installed on the website you want to receive the event from?
- Is your SSL/TLS certificate valid? (not expired, and matching the domain name)
- Does the receiving server reply with a
200
status code? - Does the receiving server reply fast enough? (ie. less than 1 second)
Feel free to chat with us if you have any question, or if you cannot solve your issue. We'll gladly help you.