Webhook Listeners
Nextcloud supports listening to internal events via webhooks.
Installation
Enable the
webhook_listeners
app that comes bundled with Nextcloud
occ app:enable webhook_listeners
Listening to events
You can use the OCS API to add webhooks for specific events: https://docs.nextcloud.com/server/latest/developer_manual/_static/openapi.html#/operations/webhook_listeners-webhooks-index
Note: When authenticating with the OCS API to register webhooks the account you authenticate as must have administrator rights or delegated administrator rights.
Filters
When registering a webhook listener, you can specify a filter parameter. The value of this parameter must be a JSON object whose properties represent filter conditions. The {}
is an empty query, meaning no specific criteria, so all events are matched.
If you would like to match events fired by a specific user, you can pass { "user.uid": "bob" }
to match all events fired in the context of user "bob"
.
If you would like to enforce multiple criteria, you can simply pass multiple properties { "event.tableId": 42, "event.rowId": 3 }
You can also use additional comparison operators ($eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
) as well as logical operators ($and, $or, $not, $nor
). For example use { "time" : { "$lt": 1711971024 } }
to accept only events prior to April 1st 2024 and { "time" : { "$not": { "$lt": 1711971024 } } }
to accept events after April 1st 2024.
Speeding up webhook dispatch
This app uses background jobs to trigger the registered webhooks. Thus, by default, webhooks will be triggered only every 5 minutes, as the default cron interval is 5 minutes. To trigger webhooks earlier, you can set up a background job worker. The following command will launch a worker for the webhook call background job:
occ background-job:worker "OCA\\WebhookListeners\\BackgroundJobs\\WebhookCall"
It is recommended to restart this worker once a day to make sure code changes are effective and avoid memory leaks, for example by registering it as a systemd service with a daily timer.
Nextcloud Webhook Events
This is an exhaustive list of available events. It features the event ID and the available variables for filtering.
OCA\Forms\Events\FormSubmittedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "form": array{ "id": int, "hash": string, "title": string, "description": string, "ownerId": string, "fileId": string|null, "fileFormat": string|null, "created": int, "access": int, "expires": int, "isAnonymous": bool, "submitMultiple": bool, "showExpiration": bool, "lastUpdated": int, "submissionMessage": string|null, "state": int, }, "submission": array{ "id": int, "formId": int, "userId": string, "timestamp": int, }, } }
OCA\Tables\Event\RowAddedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "tableId": int, "rowId": int, "previousValues": null|array<int, mixed>, "values": null|array<int, mixed> } }
OCA\Tables\Event\RowDeletedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "tableId": int, "rowId": int, "previousValues": null|array<int, mixed>, "values": null|array<int, mixed> } }
OCA\Tables\Event\RowUpdatedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "tableId": int, "rowId": int, "previousValues": null|array<int, mixed>, "values": null|array<int, mixed> } }
OCP\Files\Events\Node\BeforeNodeCreatedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeTouchedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeWrittenEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeReadEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeDeletedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeCreatedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeTouchedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeWrittenEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeReadEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeDeletedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "node": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeCopiedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeRestoredEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }
OCP\Files\Events\Node\NodeRenamedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeCopiedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeRestoredEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }
OCP\Files\Events\Node\BeforeNodeRenamedEvent
array{ "user": array {"uid": string, "displayName": string}, "time": int, "event": array{ "class": string, "source": array{"id": string, "path": string} "target": array{"id": string, "path": string} } }