Change webhooks before they are sent

Write a transformation that reshapes each webhook for its destination, try it on a webhook you received, then save it on a connection.

A transformation is JavaScript on a connection that changes each webhook before it is sent: pick the fields your app needs, rename them, or add headers. The sender keeps sending what it sends, and your app gets the shape it wants.

Write a transformation

A transformation defines a function transform(request), which may be async, and returns the headers and body to send:

function transform(request) {
  const payment = request.body
  return {
    headers: { "x-order-id": payment.reference },
    body: {
      orderId: payment.reference,
      amountTzs: payment.amount,
      phone: payment.msisdn,
      paid: payment.status === "COMPLETED",
    },
  }
}

What it gets

request.methodstring

The method the webhook was received with, such as POST.

request.pathstring

The part of the address after the source’s address, such as /payments/mpesa.

request.querystring

The query string, without the ?.

request.headersobject

The headers, with names in lower case.

request.bodyobject, array, or string

The body parsed as JSON when it is JSON, the text otherwise, or base64 when it is neither.

request.bodyEncodingstring

base64 when body is base64. Left out otherwise.

What it returns

headersobject

The headers to send, at most 100 names and values. They replace the webhook’s headers.

bodyobject, array, or string

The body to send. An object or an array is sent as JSON, with Content-Type: application/json unless you set one. A string is sent as text.

bodyEncodingstring

Set it to base64 to send body, a base64 string, as bytes.

The destination’s authentication and signing headers are added to what it returns, as for any delivery.

Try it first

Run the transformation on a webhook the source received, and see what it would send. Nothing is saved or sent:

curl -X POST "$HOOKS_URL/transformations/try" \
  -H "Authorization: Bearer $HOOKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "function transform(request) { return { body: { orderId: request.body.reference } } }",
    "eventId": "01m3my2b42vahrbx8zt4fw84wc"
  }'

Without eventId, it runs on a sample: a POST with content-type: application/json and the body {"hello":"world"}. The answer has output, what it would send, or error, why it failed, with the lines it wrote with console.log in logs. See Transformations.

In the console, open the connection, write the transformation, and select Validate.

Save it on a connection

Put the code in the connection’s transformation field. Saving refuses code that does not parse, or defines no transform. Send an empty transformation to remove it.

When it runs

  • Filters see the webhook as it was received, before any transformation.
  • It runs on a delivery’s first attempt, and what it returns is kept, so every retry sends the same request. The delivery shows the headers and body it sent in sent.
  • Sending a delivery again runs the connection’s current transformation, so a fixed transformation applies to failed webhooks you send again.

What it can do

A transformation runs for at most 100 milliseconds with at most 128 MB of memory. It cannot fetch, read files, use timers, or import modules. The code is at most 64 KB.

When it fails

A transformation that throws, returns the wrong shape, or runs out of time or memory fails its delivery at once, with the class transformation and the reason in lastError. It is not tried again, and it does not count against the destination. Fix the transformation, then send the failed deliveries again.

Last updated