Webhook transformations
Overview
By default every webhook call:
- uses the
POSTHTTP method - has the
Content-Typeheader set toapplication/vnd.contentful.management.v1+json - does not have the
Content-Lengthheader set - sends a predefined body depending on the triggering event (as described above)
If you control the code of your webhook receiver you can respond to the default webhook call appropriately by implementing a custom logic in your receiver. The situation is different if you try to call an API you don't control with a webhook: most likely the default webhook payload won't adhere to the format expected by the API.
The transformation property of a webhook definition allows you to define:
- a custom HTTP method
- a custom
Content-Typeheader - if automatically computed, a
Content-Lengthheader should be included. - a custom webhook call body that may or may not make use of the default webhook body.
transformation property is an optional object containing the following properties. None of these properties are required.
transformation.method can be one of:
POST(default)GETPUTPATCHDELETE
transformation.contentType can be one of:
application/vnd.contentful.management.v1+json(default)application/vnd.contentful.management.v1+json; charset=utf-8application/jsonapplication/json; charset=utf-8application/x-www-form-urlencodedapplication/x-www-form-urlencoded; charset=utf-8
Using the last two options will convert the JSON body to URL encoded form data.
transformation.includeContentLength can be either true or false. If true the Content-Length header will be present with its value set to automatically computed byte length of the request body.
transformation.body can be any arbitrary JSON data structure. It will be used as the webhook call body.
It's possible to use values from the original webhook payload in the transformed body. This can be achieved by JSON pointers in the body JSON. Depending on the referenced data either whole values or strings are resolved.
URL transformation
Webhook URLs can contain JSON pointers that are resolved to values from the original payload. The value resolution always follows the string template resolution logic. For example, a webhook defined as follows will result in a call to https://my-webhook-endpoint.com/my-entry-1 for an entity with ID my-entry-1.
{
"name": "Dynamic URL",
"url": "https://my-webhook-endpoint.com/{ /payload/sys/id }"
}
Header transformation
Custom header values can contain JSON pointers as described below. This is achieved by JSON pointers that are resolved using the string template resolution logic.
The following header definition
{
...,
"headers": [
{ "key": "X-CTFL-Entity-ID", "value": "{ /payload/sys/id }" },
{ "key": "X-CTFL-Entity-Type", "value": "{ /payload/sys/type }" }
]
}
will result in two headers on the actual webhook call if the webhook was triggered by a change of entry 42:
X-CTFL-Entity-ID: 42
X-CTFL-Entity-Type: Entry
Secret and HTTP Basic Auth headers are not transformed. Also, the header keys are not transformed.
Resolution strategies
Resolving a whole value
- In your data structure, introduce a string value that starts with
{and ends with}in a place you want to resolve the original value - In between curly braces put an absolute JSON pointer to the property you want to resolve; the original webhook body is stored in the
payloadtop-level namespace - The string value containing a pointer will be replaced with the resolved value
For example, given the following original payload:
{
"sys" {
"id": "entry-id"
"type": "Entry"
},
"fields": {
"title": {
"en-US": "hello world"
}
}
}
And the following body transformation:
{
"entryId": "{ /payload/sys/id }",
"title": "{ /payload/fields/title }"
}
Your webhook will be called with:
{
"entryId": "entry-id",
"title": {
"en-US": "hello world"
}
}
Using string templates
- In your data structure, introduce a string value that contains an absolute JSON pointer to the property you want to resolve, wrapped with
{and} - The original webhook body is stored in the
payloadtop-level namespace - JSON pointers will be replaced with resolved values
- All values, including complex ones, will be stringified
For example, given the following original payload:
{
"sys": {
"id": "entry-id",
"type": "Entry"
},
"fields": {
"title": {
"en-US": "hello world"
}
}
}
And the following body transformation:
{
"entityInfo": "Entity of type { /payload/sys/type } with ID { /payload/sys/id }",
"title": "Entity title is { /payload/fields/title/en-US }",
"stringified": "Let's try to stringify an object: { /payload/fields/title }"
}
Your webhook will be called with:
{
"entityInfo": "Entity of type Entry with ID entry-id",
"title": "Entity title is hello world",
"stringified": "Let's try to stringify an object: {\"en-US\":\"hello world\"}"
}
Helpers
In some cases, there can be a need for trimming or slightly modifying certain fields before delivering them to the webhook target. Contentful provides numerous helpers that can be used at the transformation level. For example:
{
"content": "{ first-paragraphs 2 /payload/fields/content/en-US }",
}
Above-mentioned example limits the content field with first two paragraphs. If the content field has more than two paragraphs, the rest of the text gets trimmed. In addition to
trimming content, helpers are useful in modifying or refining content. Following is another transformation, using the strip-stop-words helper:
{
"keywords": "{ strip-stop-words /payload/fields/content }",
}
The above transform filters out stop words and delivers only the keywords in the content field. For example:
Art is the expression or application of human creative skill and imagination
becomes:
art expression application human creative skill imagination
Refer to the table below to see the full list of available functions:
| Helper name | Parameter | Description |
|---|---|---|
| first-chars | Number | Selects first n characters of the field. Example: { first-chars 6 /payload/fields/content/en-US } |
| first-words | Number | Selects first n words of the field. Example: { first-words 12 /payload/fields/content/en-US } |
| first-paragraphs | Number | Selects first n paragraphs of the field. Example: { first-paragraphs 3 /payload/fields/content/en-US } |
| strip-stop-words | - | Strip out stop words (only English is supported). Example: { strip-stop-words /payload/fields/content/en-US } |
| strip-markdown | - | Strip out Markdown markup. Example: { strip-markdown /payload/fields/content/en-US } |
| stringify | - | Stringify the value pointed to. Example: { stringify /payload/fields } |
Transformation context
When transforming request body, URL, and headers, JSON pointers are used to resolve values. Values are resolved from a context object. Currently the context object has the following properties:
payloadcontains the original webhook payloadtopicis a string containing the webhook topicuseris a stripped-down version of aUserentity for the user who executed action triggering the webhook call; the only available pointer is{ /user/sys/id }