Using Webhooks
Webhooks in Paradym provide a powerful way to listen to system events and trigger actions. Webhooks can be used with different events.
Setting up Webhooks
To start receiving webhooks, some configuration is needed in the dashboard.
Go to Webhooks
To configure a webhook listener, go to the Webhooks tab (opens in a new tab) in the dashboard.
Create webhook endpoint
Enter the URL on which you want to receive the webhook events, and give it a unique name.
You can use a site such as Webhook.site (opens in a new tab) or Request Baskets (opens in a new tab) to get a temporary endpoint to receive events and play around with.
Note that webhook events contain sensitive information, and these services do not verify the HMAC of the events. You should not use these services for production webhooks.
Save webhook secret
Make sure to copy and save the webhook secret as it won't be displayed again. See Security for more information on how to secure your webhook endpoint.
From now on, all events are sent to the created webhook endpoint. You can create multiple webhook endpoints, but be aware that all events are sent to all configured webhook endpoints.
When creating a webhook using the Webhook API (opens in a new tab) you can configure specific event types for the webhook. When configured, only events matching one of the eventTypes
configured on the webhook will be sent to the webhook endpoint. This allows you to have different handlers for different event types, or filter out webhook events you're not interested in.
Webhook Events
The following webhook events are currently emitted:
workflowExecution.started
workflowExecution.actionExecuted
workflowExecution.completed
workflowExecution.waitingForTrigger
workflowExecution.canceled
workflowExecution.failed
All workflowExecution
events contain an workflowExecutionId
in the payload that can be used to retrieve an execution Using the API.
workflowExecution.started
Event dispatched when a workflow execution is started.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.started",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
}
}
workflowExecution.actionExecuted
Event dispatched when a workflow action is executed.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.actionExecuted",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
"workflowActionId": "workflow-action-id",
}
}
workflowExecution.completed
Event dispatched when a workflow finishes its execution successfully.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.completed",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
}
}
workflowExecution.waitingForTrigger
Event dispatched when a workflow is waiting for an external trigger to resume its execution.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.waitingForTrigger",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
"workflowActionId": "workflow-action-id",
}
}
workflowExecution.canceled
Event dispatched when a workflow execution is manually canceled.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.canceled",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
}
}
workflowExecution.failed
Event dispatched when a workflow fails during its execution.
Example:
{
"webhookId": "webhook-id",
"webhookPublishedAt": "time-of-publication",
"projectId": "project-id",
"eventType": "workflowExecution.failed",
"payload": {
"workflowId": "workflow-id",
"workflowExecutionId": "workflow-execution-id",
"workflowActionId": "workflow-action-id", // optional
"error": {
"message": "error-message",
"code": "error-code",
"details": "error-details"
}
}
}
Timeouts and retries
Webhooks are subject to a 5 second timeout. If your server does not respond with a 200 OK
HTTP status code within 5 seconds, the webhook will be considered failed and will not be retried.
Security
If you choose not to use the secret, your webhook becomes vulnerable to unauthorized events. Anybody who knows the webhook URL would be able to send events to it.
To prevent events not sent by Paradym from being sent to your webhook endpoint, Paradym employs a security measure using SHA256 HMAC. The X-Paradym-HMAC-SHA-256
header is included in each webhook HTTP request.
Here's a basic example of how to verify the request using Node.js and the crypto
standard library:
const express = require('express')
const crypto = require('crypto')
const bodyParser = require('body-parser')
const PORT = 3000
const SECRET = 'your-webhook-secret'
const app = express()
// middleware to get the raw request body
app.use(
bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf.toString()
},
})
)
app.post('/webhook', (req, res) => {
const hmac = req.get('X-Paradym-HMAC-SHA-256')
const computedHmac = crypto.createHmac('sha256', SECRET).update(req.rawBody, 'utf8').digest('hex')
if (computedHmac !== hmac) {
console.log('HMAC is invalid!')
res.sendStatus(401)
return
}
console.log('HMAC is valid!')
// process the webhook event
console.log(req.body)
res.sendStatus(200)
})
app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`)
})
In this example, the code computes the HMAC digest of the incoming request payload with your secret and compares it to the request's X-Paradym-HMAC-SHA-256
. This allows you to confirm that the webhook was sent by Paradym, preventing any spoofing attempts. The secret should be securely stored on your server and is not included in the webhook requests.