From 86ad4e6d25d5716f70ad10b5da09d6157aa82c4e Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 Aug 2025 10:30:28 -0400 Subject: [PATCH] Add plugin dev documentation for webhook callbacks --- docs/plugins/development/webhooks.md | 63 ++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 64 insertions(+) create mode 100644 docs/plugins/development/webhooks.md diff --git a/docs/plugins/development/webhooks.md b/docs/plugins/development/webhooks.md new file mode 100644 index 000000000..42a515aca --- /dev/null +++ b/docs/plugins/development/webhooks.md @@ -0,0 +1,63 @@ +# Webhooks + +NetBox supports the configuration of outbound [webhooks](../../integrations/webhooks.md) which can be triggered by custom [event rules](../../features/event-rules.md). By default, a webhook's payload will contain a serialized representation of the object, before & after snapshots (if applicable), and some metadata. + +## Callback Registration + +Plugins can register callback functions to supplement a webhook's payload with their own data. For example, it might be desirable for a plugin to attach information about the status of some objects at the time a change was made. + +This can be accomplished by defining a function which accepts a defined set of keyword arguments and registering it as a webhook callback. Whenever a new webhook is generated, the function will be called, and any data it returns will be attached to the webhook's payload under the `context` key. + +### Example + +```python +from extras.webhooks import register_webhook_callback +from my_plugin.utilities import get_foo_status + +@register_webhook_callback +def set_foo_status(object_type, event_type, data, request): + if status := get_foo_status(): + return { + 'foo': status + } +``` + +The resulting webhook payload will look like the following: + +```json +{ + "event": "updated", + "timestamp": "2025-08-07T14:24:30.627321+00:00", + "object_type": "dcim.site", + "username": "admin", + "request_id": "49e3e39e-7333-4b9c-a9af-19f0dc1e7dc9", + "data": { + "id": 2, + "url": "/api/dcim/sites/2/", + ... + }, + "snapshots": {...}, + "context": { + "foo": 123 + } +} +``` + +### Callback Function Arguments + +| Name | Type | Description | +|---------------|-------------------|-------------------------------------------------------------------| +| `object_type` | ObjectType | The ObjectType which represents the triggering object | +| `event_type` | String | The type of event which triggered the webhook (see `core.events`) | +| `data` | Dictionary | The serialized representation of the object | +| `request` | NetBoxFakeRequest | A copy of the request (if any) which resulted in the change | + +## Where to Define Callbacks + +Webhook callbacks can be defined anywhere within a plugin, but must be imported during plugin initialization. If you wish to keep them in a separate module, you can import that module under the PluginConfig's `ready()` method: + +```python +def ready(self): + super().ready() + from my_plugin import webhook_callbacks +``` diff --git a/mkdocs.yml b/mkdocs.yml index 4e5f484c7..8f98fe38c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -144,6 +144,7 @@ nav: - Search: 'plugins/development/search.md' - Event Types: 'plugins/development/event-types.md' - Data Backends: 'plugins/development/data-backends.md' + - Webhooks: 'plugins/development/webhooks.md' - REST API: 'plugins/development/rest-api.md' - GraphQL API: 'plugins/development/graphql-api.md' - Background Jobs: 'plugins/development/background-jobs.md'