Advanced webhook workflow triggers using JSON path queries (JMESPath)

This article references Okta webhook payloads but is not specific to Okta. If you want to test out the examples here, we've provided some sample JSON that matches the structure used in this example. You can find this as an attachment at the bottom of this article.

You can send this JSON to the webhook testing dialog using an app like Postman, or just by using the curl command. e.g.

curl -X POST -H 'Content-Type: application/json' \
  https://app.trelica.com/FlowApi/webhook-test/xxxxxxxx/xxxxxxxxx \
  -d @sample_data.json
You can then easily change the data and quickly repost it when testing.

Payloads with multiple items

Some payloads contain multiple items. For example, if you register for an Okta webhook to notify you when a user is assigned to a group, Okta may send information about multiple assignments to Trelica. If you look at the Okta webhook data structure, the data node contains an array of events.

{
"eventType" : "com.okta.event_hook",
"eventTypeVersion" : "1.0",
"cloudEventsVersion" : "0.1",
"source" : "https://xxxxxx.okta.com/api/v1/eventHooks/acdfhyb3tuqXjPITe4x7",
"eventId" : "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"data" : {
"events" : [{
...
}, {
...
}]
}
}

The easiest way to write and test queries is using the webhook testing dialog. This gives you a URL that you can post data to.

You can then enter a query to match the array of items that you want to process as individual triggers:

The query is written using something called JMESPath. This is a common way of querying JSON data and you can read more about it here: https://jmespath.org/.

JMESPath can do very sophisticated things, but in our example, we can find the array of events by querying for data.events.

Once you've completed your testing, you can then enter this path on the main web request panel:

Mapping field values using a query

The easiest way to reference data in the JSON sent to webhooks is to use simple dot notation.

In our above example, we once we've mapped to the array of events, we can reference data within each event.

A typical event looks like this:

{
    "uuid" : "14a42b00-74e5-11ee-8a5a-69d62fcd0f8b",
    "published" : "2023-10-27T16:22:53.770Z",
    "eventType" : "group.user_membership.add",
    "client" : {
        "userAgent" : {
            "rawUserAgent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
            "os" : "Mac OS X",
            "browser" : "CHROME"
        },
        "device" : "Computer",
        "id" : null,
        ...

If we want to set a field to the browser name, we would enter a field ID of client.userAgent.browser.

However, the Okta event structure is quite complicated. Each event can have multiple targets:

"target" : [{
    "id" : "00ufh423gol2KtaFw4y7",
    "type" : "User",
    "alternateId" : "luca.dasilva@latwerk.com",
    "displayName" : "Luca da Silva",
    "detailEntry" : null
}, {
    "id" : "00g3vcxyryIPX21lL4x7",
    "type" : "UserGroup",
    "alternateId" : "unknown",
    "displayName" : "Devs-App-PagerDuty",
    "detailEntry" : null
}],

How do we identify the name of the user group to which the user was added?

Click Test Webhook again, and post the JSON again.

If you configured Multiple entries in one request as discussed at the start of this article, you will find that the first event will be shown to you.

Now we can try a new JMESPath query. Enter target[?type=='UserGroup'].displayName

This means: In the target array, find the elements where the type attribute has the value UserGroup, and then take the displayName attribute for each match.

You should now see an array containing one element:

Most Trelica fields accept single values, so we need to modify the query slightly to take the first element of the array:

Try using target[?type=='UserGroup'].displayName | [0]

ChatGPT or any LLM is typically very good at helping with generating JMESPath, even when the question is expressed in a very simplistic, results-oriented way e.g.

If you deliberately wanted to concatenate multiple values in the array, you could use target[*].displayName | join(', ', @) which would output "Luca da Silva, Devs-App-PagerDuty"

We can now use this JMESPath query to map to this value in our field:

Re-testing this we get:

Was this article helpful?

0 out of 0 found this helpful

Comments

0 comments

Please sign in to leave a comment.