Webhooks
Webhooks make it possible for your application to be notified of important system events, as soon as these take place within Bponi Storeopen in new window.
While you are generally able to create as many webhook entries as you'd like, remember that a single webhook always targets a single trigger. The following triggers are available:
ID | Name | Description | Includes | Limitations |
---|---|---|---|---|
0 | taskStarted | Task started by worker. | taskId, data.task | None |
1 | taskEta | Worker ETA less than or equal to threshold value provided, in seconds. | taskId, data.task, etaSeconds | Limit of 10 webhooks. Each will fire once per task, at most once every 30 seconds, when threshold is met. |
2 | taskArrival | Worker arriving, at or closer than threshold value provided, in meters. | taskId, data.task, distance | Limit of 10 webhooks. Each will fire once per task, at most once every 30 seconds, when threshold is met. |
3 | taskCompleted | Task completed by worker. | taskId, data.task | None |
4 | taskFailed | Task failed. | taskId, data.task | None |
5 | workerDuty | Worker status changed (0 for off-duty, 1 for on-duty). | workerId, status, data.worker | None |
6 | taskCreated | New task created. | taskId, data.task | Does not include tasks created via task import from the Bponi Storeopen in new window dashboard. |
7 | taskUpdated | Task updated | taskId, data.task | None |
8 | taskDeleted | Task deleted. | taskId, data.task | None |
9 | taskAssigned | Task assigned to worker. | taskId, data.task | None |
10 | taskUnassigned | Task unassigned from worker. | taskId, data.task | None |
12 | taskDelayed | Task is delay time is greater than or equal to threshold value provided, in seconds. | taskId, data.task, delay | Limit of 10 webhooks, applies only to active tasks, will only fire once. |
13 | taskCloned | Task cloned via dashboard or API. Note that the taskCreated trigger will not fire when a task is cloned. | taskId, data.task | None |
14 | smsRecipientResponseMissed | Recipient responds to a notification via SMS, but the organization is unable to handle it at that time. | from, to, body | None |
15 | workerCreated | A new worker has been created. | adminId, workerId, actionContext , triggerId,triggerName, taskId,data.worker, time | None |
16 | workerDeleted | A worker has been deleted. | adminId, workerId, actionContext , triggerId,triggerName, taskId,data.worker, time | None. |
17 | SMSRecipientOptOut | When a recipient replied "STOP" to opt out of SMS communications | recipient, timestamp, SMS, triggerId, triggerName,time | None |
Webhooks can be maintained via dashboard or API. All standard, non-validation requests from Bponi Storeopen in new window to you are made via POST.
In addition to the properties from the Includes column above, the JSON body we will POST to your url will include a time property along with triggerId and triggerName so you may overload the same url on your application as required. In addition, full objects will be provided in the data property, as relevant. Note that all other properties not relevant to the trigger may be provided as null.
Quick Start
Bponi Storeopen in new window offers a webhook developer tool in our open-source developer repository. The webhook tool serves up a Python Flask application that acts as your webhook server and allows you to test out different webhooks. The tool includes an endpoint for each Bponi Storeopen in new window webhook trigger, validates the webhook, and prints the payload to screen.
Webhook Validation
All URLs are validated through a simple token exchange mechanism so we may trust that you actually control the target server. Note that validation happens right at webhook creation, meaning that we will issue a request to you before successfully registering the webhook. The validation will send a GET request to your url with a query string of check=<random_string>
, your webhook server should respond back with the <random_string>
to be validated.
Webhook Authentication
Bponi Storeopen in new window uses HMAC (hash-based message authentication code) with the SHA-512 hash function for additional authentication. By using the webhook secret obtained on the Bponi Storeopen in new window dashboard, your webhook server should verify that the source of webhook requests are indeed coming from Bponi Storeopen in new window and is associated with your organization.
Each webhook request contains a signature from Bponi Storeopen in new window in X-Bponi-Signature
header. To authenticate the webhook request received on your webhook server, you will need to validate against this header.
To validate against X-Bponi-Signature
, you will need to compare its value with an HMAC you have generated using the hexadecimal format of your webhook secrets and the full body of the webhook POST request in raw bytes. We have provided some coding examples in Python and NodeJS.
import hashlib, hmac, binascii
hash = hmac.new(binascii.a2b_hex(secret), body, 'sha512').hexdigest()
# Compare hash with the received X-Bponi-Signature in raw bytes
2
3
4
5
const crypto = require('crypto')
const secret_in_hex = Buffer.from(secret, 'hex');
const hash = crypto.createHmac('sha512', secret_in_hex)
.update(body)
.digest('hex')
// Compare hash with the received X-Bponi-Signature in raw bytes
2
3
4
5
6
7
8
Retry
Any failed requests will be retried in 30-minute cycles, up to one full day. A failed request is any non-200 response that a webhook request gets from your application. If there are more than 300 consecutive failures, the webhook will be automatically disabled.
Testing
You may find a tool like ngrokopen in new window useful to test your webhook integrations, however in order to pass the initial validation step, you will need to ensure that your tool of choice allows you to respond to our validation request, unless it has been automatically validated.
Use Bponi Storeopen in new window developer tools for webhook testing, learn more here.
Create webhook
Body parameters
Name | Type | Description |
---|---|---|
url | string | The URL that Bponi Storeopen in new window should issue a request against as soon as the trigger condition is met. It must be HTTPS and have a valid certificate. |
name | string | A name for the webhook for identification. |
trigger | number | The number corresponding to the trigger condition on which the webhook should fire. |
threshold | number | Optional. For trigger 1, the time threshold in seconds; for trigger 2, the distance threshold in meters. |
The url value provided will receive a GET request from our servers, with a check query parameter. You need to respond to our validation request with exactly this value, untouched, as a simple string response.
In a Node.js/CoffeeScript environment, the following would suffice:
server.get '/bponi-store/taskStart', (req, res, next) ->
res.send req.params.check
return next()
2
3
To create a new webhook, provide a verifiable url and trigger.
curl -X POST "https://store.bponi.com/api/v2/webhooks" \
-u "cd3b3de84cc1ee040bf06512d233719c:" \
-d '{"url":"https://11ec4a02.ngrok.com/bponi-store/taskStart","trigger":0}'
2
3
{
"id": "9zqMxI79mRcHpXE111nILiPn",
"count": 0,
"url": "https://11ec4a02.ngrok.com/bponi-store/taskStart",
"trigger": 0
}
2
3
4
5
6
As previously mentioned, you will need to respond to our validation request with the check query parameter value, as a simple string response in order to avoid validation failures. This applies if you're not using the automatic validation from Zapier
and Requestbin
.
List webhooks
count provides a total number of successful requests made for a webhook. If a webhook failed consecutively for 300 times or more, the isEnabled parameter will be turned to false.
curl -X GET "https://store.bponi.com/api/v2/webhooks" \
-u "cd3b3de84cc1ee040bf06512d233719c:"
2
[
{
"id": "ZnVRY8rdfUwNPjHQy2QthtxZ",
"name": "Webhook 1 - Driver Nearby",
"count": 7,
"url": "https://11ec4a02.ngrok.com/bponi-store/driverNearby",
"trigger": 2,
"isEnabled": true
},
{
"id": "9zqMxI79mRcHpXE111nILiPn",
"name": "Webhook 2 - TaskStarted",
"count": 3,
"url": "https://11ec4a02.ngrok.com/bponi-store/taskStart",
"trigger": 0,
"isEnabled": true
},
{
"id": "8KD3PcIMsG*bC0imJ~EjR9GX",
"name": "Webhook 3 - TaskCompleted on Zapier",
"count": 6,
"url": "https://hooks.zapier.com/hooks/catch/4212020/0z5pha/",
"trigger": 3,
"isEnabled": true
}
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Delete webhook
curl -i -X DELETE "https://store.bponi.com/api/v2/webhooks/ZnVRY8rdfUwNPjHQy2QthtxZ" \
-u "cd3b3de84cc1ee040bf06512d233719c:"
2
HTTP/1.1 200 OK