Use of client.webhookCalls

I could use some guidance on how to use the client.webhookCalls API as documented at: List all webhooks calls - Webhook call - Content Management API

First, if I call buildClient with the environment property, it does not seem to get applied when I call webhookCalls.list() or webhookCalls.rawList(). Is that expected? Is it because webhooks aren’t specific to environments (generally speaking) and thus their artifacts and history aren’t either?

Second, in the Pagination docs (Pagination — DatoCMS), I see an example of passing page[limit] and page[offset] via curl but not via js/ts using listPagedIterator, which is what I think I need to use. What does an example of that look like?

Third, is the filter example as shown in the Pagination docs generally applicable for client.webhookCalls.listPagedIterator()? Can I pass multiple filter criteria? Examples of that?

In general, API access to the webhook call history is underdocumented. Another example of that is that I had to figure out on my own that the “full access” API token must be used. It would be helpful if that documentation could be fleshed out with examples, a list of all the functions and options to the functions on the client.webhookCalls object, etc.

Many thanks.

Another issue… I’m trying to pass a filter to listPagedIterator. I only want webhook calls for a specific environment.

for await (const webhookCall of client.webhookCalls.listPagedIterator({ filter: { request_payload: { environment: 'development' }}})) {
  console.log(webhookCall);
}

The call works - no syntax errors, etc. But the filter isn’t working. Here’s a snippet of the first webhook call that’s returned:

{
  id: '99999999',
  type: 'webhook_call',
  request_url: 'https://my.app.url/webhook/v1/endpoint',
  request_payload: '{\n' +
    '  "environment": "primary-2023-10-19",\n' +   <== WRONG
    '  "entity_type": "item",\n' +
    '  "event_type": "create",\n' +

Note that the request_payload.environment property does not match “development”.

To investigate further, I simplified the filter, closer to the example on the “Pagination” docs:

for await (const webhookCall of client.webhookCalls.listPagedIterator({ filter: { type: 'NOT-webhook_call' }})) {

That still returns the type: 'webhook_call' entries. I would expect with that filter that nothing would be returned from webhookCalls.listPagedIterator(), but it’s still returning entries.

Is filter not implemented for webhookCalls.listPagedIterator()? How about the page[limit] and page[offset] options?

I could really use some guidance. I’m sort of stuck on how to proceed.

Thanks.

Hi @donnie.hale,

Sorry for the confusion here! I’ll try to answer your questions one by one…

  • Webhooks are project-wide, but they can be limited to a specific environment as a trigger condition

  • Webhook calls, both via the API or when you manually look at them in the UI (under “Webhooks activity”, https://yourproje.admin.datocms.com/project_settings/webhook_calls), should show an environment property. Sorry, this was an error in our CMA docs that I’ll update shortly!

  • For pagination, please see List all records - Record - Content Management API under the “Fetching all pages” header for a better example. (Basically, you start with an empty array and use the iterator to push to it one entry at a time). I’ll also update the Pagination docs page with a better example.

  • Sorry, the webcallCalls endpoint/JS method doesn’t support server-side filtering. You can filter it clientside after downloading all of them, with something like:

        const filteredHooks = webhooks.filter(hook => {
            const payload = JSON.parse(hook.request_payload);
            return payload['environment'] === 'main'
        })
    

In general, API access to the webhook call history is underdocumented

Yes, sorry, this is something we’re working through as quickly as we can! We just overhauled the records section recently, and are working our way down the list. Some of it is auto-generated (like the accepted query parameters), so you can look at that part. But we’re trying to add better examples across the board to make it all clearer.

In the meantime, if you ever have a question about something, please feel free to ask and we’ll prioritize answering you :slight_smile: (I know you shouldn’t have to do this, and hopefully soon you won’t, once we can refresh all the docs!)

Yes, unfortunately, that particular endpoint doesn’t support serverside filtering :frowning:

You can see what it does support under “Query parameters”:

(like offset/limit, under page)

That applies to list(), but listPagedIterator() will get you everything, even if you pass it a page parameter – I think that part is a bug (it shouldn’t accept those query parameters because they do nothing). I’ll report it.


TLDR to put this all together, this is how you filter webhook calls by environment:

const webhookCalls = await client.webhookCalls.listPagedIterator();

let allCalls = []

for await (const webhookCall of webhookCalls) {
    allCalls.push(webhookCall);
}

const filteredCalls = allCalls.filter(call => {
    const payload = JSON.parse(call.request_payload);
    return payload['environment'] === 'main'
})

console.log(`There are ${allCalls.length} calls total, and ${filteredCalls.length} of those match the environment.`);
// Returns "There are 4 calls total, and 2 of those match the environment."

Sorry again for the confusion here. We’ll update the docs as soon as we can.

Thanks for the reply. I’ve ended up figuring out much of the above and handling client-side filtering much as you suggested.

Better docs would be great. Enhanced functionality would be better (e.g. server-side filtering). :wink:

But I’m happy to have an API to this at all, so thanks for that.

1 Like