Filtered Webhooks
The optional filterExpression
field mentioned in the setup guide allows specifying further conditions that restrict the Webhook applicability.
The filterExpression
field needs to be a valid JMESPath expression and it will be evaluated on the payload
entry of the data about to be sent to the url
(see previous example). If the result is "falsy" (i.e. 0
, ""
, null
, false
or []
) then the Webhook will not be sent.
Only filter conditions referring to the target entity after the event has occurred are acceptable. It is not possible to filter based on the entity state before the event. In other words, filter conditions such as "field X has value Y" are acceptable, but "field X has changed" are not.
We recommend using node queries when using Filtered Webhooks in order to make the JMESPath expression much simpler than it would have to be when using a connection query.
For help testing your filter expressions use the JMESPath playground
Example
The following is an example node
query that is going to be used Filtered "Contact Updated" Webhook:
Example
query {
node(id: "UGVyc29uOjI=") {
id
... on Contact {
personalName {
firstName
lastName
}
emailAddress
}
}
}
The following mutation sets up a Webhook that only triggers when the Contact's email address contains @getadministrate.com
by means of the above query
and a filterExpression
set to contains(node.emailAddress, '@getadministrate.com')
Example
mutation createFilteredContactUpdate {
webhooks {
create(
input: {
name: "Send Contact Updates for Administrate staff"
webhookTypeId: "V2ViaG9va1R5cGU6Y29udGFjdF91cGRhdGVk"
url: "<ENDPOINT_URL>"
query: "query node($objectid: ID!) { node(id: $objectid) { id ... on Contact { personalName { firstName lastName } emailAddress } } }"
notificationEmails: ["an@example.com"]
filterExpression: "contains(node.emailAddress, '@getadministrate.com')"
}
) {
webhook {
id
}
errors {
label
message
value
}
}
}
}
Logs
To inspect the execution of Filtered Webhooks, the logs can be queried for the matchesFilter
field (more on this on our Logs documentation):
Example
query logs{
webhookLogs(filters:[
{field: webhookId, operation: eq, value: "T3V0Ym91bmRIb29rOjYy"}
]){
edges{
node{
id
webhook{
filterExpression
}
matchesFilter
objectId
payload
status
success
triggeredAt
}
}
}
}
The example response below shows that
- the first item was sent to the
url
(status
issuccess
) becausematchesFilter
istrue
, as the payload matched the filter - the second item was not sent to the
url
(status
isnotSent
) becausematchesFilter
isfalse
, as the webhook payload did not match the filter
{
"data": {
"webhookLogs": {
"edges": [
{
"node": {
"id": "T3V0Ym91bmRIb29rc0xvZzozODg=",
"webhook": {
"filterExpression": "contains(node.emailAddress, '@getadministrate.com')"
},
"matchesFilter": true,
"objectId": "UGVyc29uOjI4MQ==",
"payload": "{\"metadata\": {\"user\": {\"email\": null}, \"instance\": \"https://myinstance.administrateapp.com\", \"triggered_at\": \"2023-04-04T11:42:42.000000Z\", \"context\": \"graphql\", \"webhook_id\": \"T3V0Ym91bmRIb29rOjYy\", \"is_retry\": false}, \"payload\": {\"node\": {\"id\": \"UGVyc29uOjI4MQ==\", \"personalName\": {\"firstName\": \"Fiona\", \"lastName\": \"Brown\"}, \"emailAddress\": \"fiona@getadministrate.com\"}}}",
"status": "success",
"success": true,
"triggeredAt": "2023-04-04T11:42:42Z"
}
},
{
"node": {
"id": "T3V0Ym91bmRIb29rc0xvZzozODk=",
"webhook": {
"filterExpression": "contains(node.emailAddress, '@getadministrate.com')"
},
"matchesFilter": false,
"objectId": "UGVyc29uOjM5",
"payload": "{\"metadata\": {\"user\": {\"email\": null}, \"instance\": \"https://myinstance.administrateapp.com\", \"triggered_at\": \"2023-04-04T11:46:03.000000Z\", \"context\": \"graphql\", \"webhook_id\": \"T3V0Ym91bmRIb29rOjYy\", \"is_retry\": false}, \"payload\": {\"node\": {\"id\": \"UGVyc29uOjM5\", \"personalName\": {\"firstName\": \"Fergus\", \"lastName\": \"White\"}, \"emailAddress\": \"fergus@example.com\"}}}",
"status": "notSent",
"success": false,
"triggeredAt": "2023-04-04T11:46:03Z"
}
}
]
}
}
}