Callback URL
For long-running actions, clients need to maintain a polling to track the action's status periodically. When the action is finished, the client will have access to the response url
to get the response data. Sometimes this is not a convenient process.
The Callback URL
feature makes our server send back the response data actively to a prepared callbackUrl
when it finishes the action. The callbackUrl
is an endpoint prepared and maintained by client that must be able to receive and process our server's request message.
Usage
Request
The client attaches a value for the callbackUrl
field into the request data. This callbackUrl
field is optional.
{
"callbackUrl": "https://bespokify.com/callbackUrl"
}
WARNING
The client must prepare the endpoint for callbackUrl
to handle POST messages from our server.
Response data
When server finishes processing, it connects to the callbackUrl
and sends a POST message with resource data that includes:
Parameter | Type | Description |
---|---|---|
id | string | Resource id |
type | string | Resource type |
url | string | Resource url |
data | object | Resource data. it is instant response data at the time of completion. (The client can also retrieve this data by accessing the response url ). |
The response is sent along with the X-Bespokify-Signature
header, which is generated using a shared secret
(this will be provided).
Verification
To verify that the request came from Bespokify, compute the HMAC digest according to the following algorithm and compare it to the value in the X-Bespokify-Signature
header. If they match, you can be sure that the request was sent from Bespokify and the data has not been compromised.
Below is a simple example in NodeJS with Express framework:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const crypto = require('crypto');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
/**
*
* @param {object} data
* @param {hmacHeader} string
*/
function verifyWebhook({ data, hmacHeader }) {
const secretToken = 'YOUR_SECRET_TOKEN';
const calculatedHmac = crypto
.createHmac('sha256', secretToken)
.update(JSON.stringify(data))
.digest('hex');
return calculatedHmac === hmacHeader;
}
app.post('/', (req, res) => {
const hmacHeader = req.headers['X-Bespokify-Signature'];
const data = req.body;
const verified = verifyWebhook({ data, hmacHeader });
res.send(`Webhook verified: ${verified}`);
});
Example
In this case, the client has prepared the callback URL at: https://bespokify.com/callbackUrl
.
The following is the request data for the export
function:
{
"draftId": "e02bc2c6-ff09-4f71-9b31-062f5ef7e751",
"callbackUrl": "https://bespokify.com/callbackUrl",
"fileType": "dxf",
"config": {
"format": "aama",
"driver": "generic",
"singleInstance": true,
"materialGroup": false,
"singleFile": false
},
"nesting": {
"sheetWidth": 140,
"preNestRotation": 45,
"partRotation": 0,
"partMargin": 1,
"sheetLength": 3000,
"sheetEdgeMargin": 10
},
"objects": ["ShirtFront", "ShirtBack"]
}
WARNING
Currently, the callbackUrl
feature is supported only for the draft
, export
, and batch
functions (which need long execution times).
After the server prepares the export file, it posts the response data to https://bespokify.com/callbackUrl
:
{
"id": "467b7a82-ecb6-4591-af37-bc775baffdb3",
"type": "export",
"url": "https://api.bespokify.com/v2/exports/467b7a82-ecb6-4591-af37-bc775baffdb3",
"data": {
"id": "467b7a82-ecb6-4591-af37-bc775baffdb3",
"draftId": "e02bc2c6-ff09-4f71-9b31-062f5ef7e751",
"fileType": "dxf",
"config": {
"format": "aama",
"driver": "generic",
"singleInstance": true,
"materialGroup": false,
"singleFile": false
},
"nesting": {
"sheetWidth": 140,
"preNestRotation": 45,
"partRotation": 0,
"partMargin": 1,
"sheetLength": 3000,
"sheetEdgeMargin": 10
},
"objects": ["ShirtFront", "ShirtBack"],
"createdAt": "2018-08-04T07:37:02.278Z",
"status": "completed",
"files": [
{
"filename": "output.dxf",
"url": "https://path/to/output.dxf"
}
]
}
}