Skip to content

Commit

Permalink
Merge pull request #12323 from nextcloud/backport/12320/stable30
Browse files Browse the repository at this point in the history
[stable30] Add admin docs for the windmill integration
  • Loading branch information
julien-nc authored Oct 25, 2024
2 parents 2d978af + 2161bcb commit 51c94ab
Show file tree
Hide file tree
Showing 7 changed files with 469 additions and 0 deletions.
1 change: 1 addition & 0 deletions .codespellignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
SME
te
jus
nin
2 changes: 2 additions & 0 deletions admin_manual/contents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Table of contents
office/index
reference/index
ai/index
webhook_listeners/index
windmill_workflows/index
configuration_database/index
configuration_mimetypes/index
maintenance/index
Expand Down
349 changes: 349 additions & 0 deletions admin_manual/webhook_listeners/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
=================
Webhook Listeners
=================

.. _webhook_listeners:

Nextcloud supports listening to internal events via webhooks.

Installation
------------

* Enable the ``webhook_listeners`` app that comes bundled with Nextcloud

.. code-block:: bash
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:

.. code-block:: bash
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\BeforeNodeTouchedEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\BeforeNodeWrittenEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\BeforeNodeReadEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\BeforeNodeDeletedEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeCreatedEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeTouchedEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeWrittenEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeReadEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeDeletedEvent

.. code-block:: text
array{
"user": array {"uid": string, "displayName": string},
"time": int,
"event": array{
"class": string,
"node": array{"id": string, "path": string}
}
}
* OCP\\Files\\Events\\Node\\NodeCopiedEvent

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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

.. code-block:: text
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}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 51c94ab

Please sign in to comment.