Code webhook integrations
The following are examples of webhook integrations using code on the receiving server.
When integrating 3rd party server with webhooks, the following actions generally apply:
- Start a web server with en endpoint listening for webhooks.
- Locate and copy the address to the receiving server as this will be used to set up the webhook in XProtect.
- In XProtect Management Client, create and set up the webhook, using the address of the receiving server.
- In XProtect Management Client, create the rule that will trigger the webhook for a given event.
Remember to test your event before deploying your changes.
Example: Receiving events from XProtect in Node.js (with Express)
This example illustrates how to receive events from XProtect in a Node.js Express server using webhooks.
1. Create and start a Node.js Express server
First you must create and start a web server that listens for incoming events.
- Download and install Node.js from https://nodejs.org.
- Create a folder anywhere in your file system and name the folder webhooks.
- Open a terminal and navigate to the webhooks folder you just created.
- Run npm init and use the default values.
- Run npm install express.
- Inside the webhooks folder, create a file and name the file index.js.
- Open the index.js file in a text editor and paste the sample code below into the index.js file.
const express = require('express');
const crypto = require('crypto');
// change SECRET_TOKEN for your own token
// never hard code the token in the code
// we do it only for demonstration purposes
// instead, store it as an environment variable
const SECRET_TOKEN = "32212c72863c01a931609c5ebfe1abc5";
const isSignatureValid = (body, headerSignature, secretToken) => {
const digest = crypto.createHmac("sha256", secretToken).update(body).digest();
const expectedSignature = `sha256=${digest.toString('base64').toString('utf-8')}`;
if (expectedSignature.length !== headerSignature?.length) return false;
return crypto.timingSafeEqual(Buffer.from(headerSignature), Buffer.from(expectedSignature));
}
const app = express();
app.use(express.json());
app.post('/webhooks', (req, res) => {
if (!isSignatureValid(
JSON.stringify(req.body),
req.headers['x-hub-signature-256'],
SECRET_TOKEN)){
console.log('Received event with invalid signature');
return res.status(403).end();
}
console.log('Received event from XProtect through Webhook:');
console.log(req.body);
res.send('');
})
app.listen(5000, () => {
console.log(`Server started...`);
})
- In the terminal, run node -p "require('crypto').randomBytes(64).toString('hex');" to generate your own secret token.
- Copy the token string and paste it in line 8 of index.js replacing the example token.
- Save the index.js file
- Use the terminal to run node index.js. The log message Server started should be displayed.
2. Create a webhook in XProtect
After you have started the server, you must create the webhook in XProtect.
-
In Management Client > Rules and Events > Webhooks, right-click Webhooks and select Add New…
- In Webhook Information:
- Name field: Enter Node integration
- Token (optional) field: Enter the token string you copied into the index.js file.
- Address field: Set the address of the receiving server.
If you created the Node.js server on the same machine as the Event Server, enter http://127.0.0.1:5000/webhooks
If you created the Node.js server on a server with a public IP address, enter https://<IP>:5000/webhooks where <IP> is the IP address of the server with a public address.
For Node.js servers on machines without public addresses, see the section below.
You can use http:// instead of https://, but using http:// through non-secure networks may expose event data in plain text. Using the more secure https:// is strongly recommended.
- Click Save in the toolbar to save the new webhook.
For Node.js servers without public addresses
If you created the Node.js server on a machine on a different network and without a public IP address, for example on a development or testing machine, you can use NGrok for testing purposes.
- Install https://ngrok.com/ in the same machine you installed the Node.js server on.
- On your machine, locate and run ngrok http 5000
- Copy the generated public address and insert the address in the Address field above. The NGrok public address should be something similar to: https://0c60-12-212-221-50.eu.ngrok.io
3. Trigger the webhook with a rule in XProtect
After you have created and set up a webhook, you must create and set up an event to trigger the webhook.
- In Management Client > Rules and Events > Rules, right-click Rules and select Add Rule… to start the Manage Rule wizard at Step 1: Type of rule.
- In Step 1: Type of rule > Name field, enter Send Event High to Node and add an optional description of the rule in the Description field.
- In the Select the rule type you want you create pane, select Perform an action on <event>
- In the Edit the rule description pane, click event and in Events > External Events > User-defined Events, select Event High.
- Click OK to create the event.
- Click Next to go to Step 2: Conditions.
- In Step 2: Conditions, apply any conditions relevant to the event you are creating.
- Click Next to go to Step 3: Actions.
- In Step 3: Actions, scroll down and select Send event info to <Webhook>.
- Click webhook on the Edit the rule description pane
- Add the Node integration webhook and click OK.
- Click Next to go to Step 4: Stop criteria.
- In Step 4: Stop criteria, click Finish to create the rule.
4. Test the webhook from XProtect (Optional)
You should test the event to verify that the event triggers and is recieved in the Express server before utilizing the event and webhook in daily operations.
- Open Management Client > Rules and Events and click User-defined Events.
- Select Event High and click Test Event to test the event.
- Open the console that is running the server. The Received event from XProtect through Webhook log message should be displayed.
5. Troubleshooting (Optional)
If you don’t receive the events in your web server, open the MIP Logs from the Event Server tray icon to troubleshoot any potential errors.
The log of the error can take up to 90 seconds to appear because of the retry policy.
Example: Receiving events from XProtect in Python (with Flask)
This example illustrates how to receive events from XProtect on a Python Flask server using webhooks.
1. Create and start a Python Flask server
First you must create and start a web server that listens for incoming events.
- Download and install the latest version of Python from https://www.python.org/.
- Create a folder anywhere in your file system and name the folder webhooks
- Open a terminal and navigate to the webhooks folder you just created.
- Create a virtual environment inside the folder by using the command python -m venv venv
- Activate the virtual environment by using the command \venv\Scripts\activate
- Install the Flask server by using the command pip install flask
- Inside the webhooks folder, create a file and name the file main.py.
- Open the main.py file in a text editor and paste the sample code below into the main.py file.
from flask import Flask, request
import hashlib
import hmac
import base64
# change SECRET_TOKEN for your own token
# never hard code the token in the code
# we do it only for demonstration purposes
# instead, store it as an environment variable
SECRET_TOKEN = bytes("383b9d27c4a892626881d73b0f70c5b62b213ab89d33c8788ac85bd750dbdf59", 'utf-8')
def is_signature_valid(body: bytes, header_signature: str, secret_token: bytes) -> bool:
digest: bytes = hmac.HMAC(key=secret_token, msg=body, digestmod=hashlib.sha256).digest()
expected_signature: str = f"sha256={base64.b64encode(digest).decode('utf-8')}"
return hmac.compare_digest(header_signature, expected_signature)
app = Flask(__name__)
@app.route('/webhooks', methods=['POST'])
def webhooks():
body = request.data
header_signature = request.headers.get('X-Hub-Signature-256', '')
if not is_signature_valid(body, header_signature, SECRET_TOKEN):
print('Received event with invalid signature')
return '', 403
print("Received event from XProtect through Webhook:")
print(request.json)
return '', 200
app.run(host='127.0.0.1', port=5000)
- In the Python interpreter, run the import secrets; print(secrets.token_hex(32)) command to generate your own secret token string.
- Copy and paste the token string in line 10 of the main.py script file, replacing the dummy token sting of the sample code.
- Save your changes to the main.py script file.
- Use the terminal to run the python main.py command. The * Serving Flask app 'main' log message should be displayed.
2. Create a webhook in XProtect
After you have started the server, you must create the webhook in XProtect.
-
In Management Client > Rules and Events > Webhooks, right-click Webhooks and select Add New…
- In Webhook Information:
- Name field: Enter Python integration
- Token (optional) field: Enter the token string you copied into the main.py file.
- Address field: Set the address of the receiving server.
If you installed Python on the same machine where the Event Server, enter http://127.0.0.1:5000/webhooks
If you installed Python on a server with a public IP address, enter https://<IP>:5000/webhooks where <IP> is the IP address of the server with a public address.
For Python installed on machines without public addresses, see the section below.
You can use http:// instead of https://, but using http:// through non-secure networks may expose event data in plain text. Using the more secure https:// is strongly recommended..
- Click Save in the toolbar to save the new webhook.
For Python on machines without public addresses
If you installed Python on a machine on a different network and without a public IP address, for example on a development or testing machine, you can use NGrok for testing purposes.
- Install https://ngrok.com/ on the same machine you installed Python on.
- On your machine, locate and run ngrok http 5000
- Copy the generated public address and insert the address in the Address field above. The NGrok public address should be something similar to: https://0c60-12-212-221-50.eu.ngrok.io
3. Trigger the webhook with a rule in XProtect
After you have created and set up a webhook, you must create and set up an event to trigger the webhook.
- In Management Client > Rules and Events > Rules, right-click Rules and select Add Rule… to start the Manage Rule wizard at Step 1: Type of rule.
- In Step 1: Type of rule > Name field, enter Send Event High to Python and add an optional description of the rule in the Description field.
- In the Select the rule type you want you create pane, select Perform an action on <event>
- In the Edit the rule description pane, click event and in Events > External Events > User-defined Events, select Event High.
- Click OK to create the event.
- Click Next to go to Step 2: Conditions.
- In Step 2: Conditions, apply any conditions relevant to the event you are creating.
- Click Next to go to Step 3: Actions.
- In Step 3: Actions, scroll down and select Send event info to <Webhook>.
- Click address on the Edit the rule description pane
- Add the Python integration webhook and click OK.
- Click Next to go to Step 4: Stop criteria.
- In Step 4: Stop criteria, click Finish to create the rule.
4. Test the webhook from XProtect (Optional)
You should test the event to verify that the event triggers and is received in the Flask server before utilizing the event and webhook in daily operations.
- Open Management Client > Rules and Events and click User-defined Events.
- Select Event High and click Test Event to test the event.
- Open the console that is running the server. The Received event from XProtect through Webhook log message should be displayed.
5. Troubleshooting (Optional)
If you don’t receive the events in your web server, open the MIP Logs from the Event Server tray icon to troubleshoot any potential errors.
The log of the error can take up to 90 seconds to appear because of the retry policy.