summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoas Schilling <coding@schilljs.com>2023-08-08 23:14:02 +0200
committerJoas Schilling <coding@schilljs.com>2023-08-10 16:25:50 +0200
commit732d9fb1cc4cd9c92239057cc63c764e449e1177 (patch)
tree1c828090b21a0e2699c6fe774b307109477e8625
parentb59c44ff1ffd24b810c3b27cf5cf6a15fed15ede (diff)
feat: Document bots
Signed-off-by: Joas Schilling <coding@schilljs.com>
-rw-r--r--docs/bot-management.md84
-rw-r--r--docs/bots.md171
-rw-r--r--docs/capabilities.md1
-rw-r--r--docs/commands.md6
-rw-r--r--docs/constants.md7
-rw-r--r--mkdocs.yml4
-rw-r--r--src/components/AdminSettings/Commands.vue2
7 files changed, 273 insertions, 2 deletions
diff --git a/docs/bot-management.md b/docs/bot-management.md
new file mode 100644
index 000000000..301f8ba61
--- /dev/null
+++ b/docs/bot-management.md
@@ -0,0 +1,84 @@
+# Setup and management bots
+
+Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: (requires the `bots-v1` capability - available since Nextcloud 27.1)
+
+## Get list of bots installed on the server
+
+Lists the bots that are enabled and can be enabled for the conversation
+
+* Required capability: `bots-v1`
+* Method: `GET`
+* Endpoint: `bot/admin`
+
+* Response:
+ - Status code:
+ + `200 OK`
+ + `403 Forbidden` When the current user is not a moderator/owner
+ + `404 Not Found` When the conversation could not be found for the participant
+ - Data:
+ List of bots, each bot has at least:
+
+| field | type | Description |
+|----------------------|--------|----------------------------------------------------------------------------------------------|
+| `id` | int | Unique numeric identifier of the bot on this server |
+| `name` | string | Display name of the bot shown as author when it posts a message or reaction |
+| `description` | string | A longer description of the bot helping moderators to decide if they want to enable this bot |
+| `url` | string | URL endpoint that is triggered by this bot |
+| `url_hash` | string | Hash of the URL prefixed with `bot-` serves as `actor_id` |
+| `state` | int | One of the [Bot states](constants.md#bot-states) |
+| `error_count` | int | Number of consecutive errors |
+| `last_error_date` | int | UNIX timestamp of the last error |
+| `last_error_message` | string | The last exception message or error response information when trying to reach the bot. |
+
+## Get list of bots for a conversation
+
+Lists the bots that are enabled and can be enabled for the conversation
+
+* Required capability: `bots-v1`
+* Method: `GET`
+* Endpoint: `bot/{token}`
+
+* Response:
+ - Status code:
+ + `200 OK`
+ + `403 Forbidden` When the current user is not a moderator/owner
+ + `404 Not Found` When the conversation could not be found for the participant
+ - Data:
+ List of bots, each bot has at least:
+
+| field | type | Description |
+|-----------------------|--------|----------------------------------------------------------------------------------------------|
+| `id` | int | Unique numeric identifier of the bot on this server |
+| `name` | string | Display name of the bot shown as author when it posts a message or reaction |
+| `description` | string | A longer description of the bot helping moderators to decide if they want to enable this bot |
+| `state` | int | One of the [Bot states](constants.md#bot-states) |
+
+## Enable a bot for a conversation as a moderator
+
+* Required capability: `bots-v1`
+* Method: `POST`
+* Endpoint: `bot/{token}/{botId}`
+
+* Response:
+ - Status code:
+ + `200 OK` When the bot is already enabled in the conversation
+ + `201 Created` When the bot is now enabled in the conversation
+ + `400 Bad Request` When the bot ID is unknown on the server
+ + `400 Bad Request` When the bot is disabled or set to "no-setup" on the server
+ + `403 Forbidden` When the current user is not a moderator/owner
+ + `404 Not Found` When the conversation could not be found for the participant
+
+## Disable a bot for a conversation as a moderator
+
+* Required capability: `bots-v1`
+* Method: `DELETE`
+* Endpoint: `bot/{token}/{botId}`
+
+* Response:
+ - Status code:
+ + `200 OK` When the bot is already enabled in the conversation
+ + `201 Created` When the bot is now enabled in the conversation
+ + `400 Bad Request` When the bot ID is unknown on the server
+ + `400 Bad Request` When the bot is disabled or set to "no-setup" on the server
+ + `403 Forbidden` When the current user is not a moderator/owner
+ + `404 Not Found` When the conversation could not be found for the participant
diff --git a/docs/bots.md b/docs/bots.md
new file mode 100644
index 000000000..573d99968
--- /dev/null
+++ b/docs/bots.md
@@ -0,0 +1,171 @@
+# Bots and Webhooks
+
+Base endpoint is: `/ocs/v2.php/apps/spreed/api/v1`: (requires the `bots-v1` capability - available since Nextcloud 27.1)
+
+Webhook based bots are available with the Nextcloud 27.1 compatible Nextcloud Talk 17.1 release as a first version
+
+!!! note
+
+ For security reasons bots can only be added via the
+ command line. `./occ talk:bot:install --help` gives you
+ a short overview of the required arguments, but they are
+ also explained in the [OCC documentation](occ.md#talkbotinstall).
+
+---
+
+## Receiving chat messages
+
+Messages are signed using the shared secret that is specified when installing a bot on the server.
+Create a HMAC with SHA256 over the request body and the `RANDOM` header using the shared secret.
+Only when the `SIGNATURE` matches the request should be accepted and handled.
+
+**Sample PHP code:**
+
+```php
+$digest = hash_hmac('sha256', $_SERVER['HTTP_X_NEXTCLOUD_TALK_RANDOM'] . file_get_contents('php://input'), $secret);
+
+if (!hash_equals($digest, strtolower($_SERVER['HTTP_X_NEXTCLOUD_TALK_SIGNATURE']))) {
+ exit;
+}
+```
+
+### Headers
+
+| Header | Content type | Description |
+|-----------------------------------|---------------------|------------------------------------------------------|
+| `HTTP_X_NEXTCLOUD_TALK_SIGNATURE` | `[a-f0-9]{64}` | SHA265 signature of the body |
+| `HTTP_X_NEXTCLOUD_TALK_RANDOM` | `[A-Za-z0-9+\]{64}` | Random string used when signing the body |
+| `HTTP_X_NEXTCLOUD_TALK_BACKEND` | URI | Base URL of the Nextcloud server sending the message |
+
+### Content
+
+The content format follows the [ActivityPub](https://www.w3.org/TR/activitypub/) dictionary.
+
+#### Sample chat message
+
+```json
+{
+ "type": "Create",
+ "actor": {
+ "type": "Person",
+ "id": "users/ada-lovelace",
+ "name": "Ada Lovelace"
+ },
+ "object": {
+ "type": "Note",
+ "id": "1567",
+ "name": "message",
+ "content": "{\"message\":\"hi {mention-call1} !\",\"parameters\":{\"mention-call1\":{\"type\":\"call\",\"id\":\"n3xtc10ud\",\"name\":\"world\",\"call-type\":\"group\",\"icon-url\":\"https:\\/\\/nextcloud.local\\/ocs\\/v2.php\\/apps\\/spreed\\/api\\/v1\\/room\\/n3xtc10ud\\/avatar\"}}}",
+ "mediaType": "text/markdown"
+ },
+ "target": {
+ "type": "Collection",
+ "id": "n3xtc10ud",
+ "name": "world"
+ }
+}
+```
+
+#### Explanation
+
+| Path | Description |
+|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| actor.id | One of the known [attendee types](constants.md#attendee-types) followed by the `/` slash character and a unique identifier within the given type. For users it is the Nextcloud user ID, for guests a sha1 value. |
+| actor.name | The display name of the attendee sending the message. |
+| object.id | The message ID of the given message on the origin server. It can be used to react or reply to the given message. |
+| object.name | For normal written messages `message`, otherwise one of the known [system message identifiers](chat.md#system-messages). |
+| object.content | A JSON encoded dictionary with a `message` and `parameters` key. The message can include placeholders and the [Rich Object parameters](https://github.com/nextcloud/server/blob/master/lib/public/RichObjectStrings/Definitions.php) are rendered into it in the chat view. |
+| object.mediaType | `text/markdown` when the message should be interpreted as Markdown. Otherwise `text/plain`. |
+| target.id | The token of the conversation in which the message was posted. It can be used to react or reply to the given message. |
+| target.name | The name of the conversation in which the message was posted. |
+
+## Sending a chat message
+
+Bots can also send message. On the sending process the same signature/verification method is applied.
+
+* Required capability: `bots-v1`
+* Method: `POST`
+* Endpoint: `/bot/{token}/message`
+* Header:
+
+| Name | Description |
+|----------------------------------|-----------------------------------------------------------------|
+| `X-Nextcloud-Talk-Bot-Random` | The random value used when signing the request |
+| `X-Nextcloud-Talk-Bot-Signature` | The signature to validate the request comes from an enabled bot |
+| `OCS-APIRequest` | Needs to be set to `true` to access the ocs/vX.php endpoint |
+
+* Data:
+
+| field | type | Description |
+|--------------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `message` | string | The message the user wants to say |
+| `replyTo` | int | The message ID this message is a reply to (only allowed for messages from the same conversation and when the message type is not `system` or `command`) |
+| `referenceId` | string | A reference string to be able to identify the message again in a "get messages" request, should be a random sha256 |
+| `silent` | bool | If sent silent the message will not create chat notifications even for users |
+
+* Response:
+ - Status code:
+ + `201 Created` When the message was posted successfully
+ + `400 Bad Request` When the provided replyTo parameter is invalid
+ + `401 Unauthenticated` When the bot could not be verified for the conversation
+ + `404 Not Found` When the conversation could not be found
+ + `413 Payload Too Large` When the message was longer than the allowed limit of 32000 characters (or 1000 until Nextcloud 16.0.1, check the `spreed => config => chat => max-length` capability for the limit)
+ + `429 Too Many Requests` When `401 Unauthenticated` was triggered too often
+
+## Reacting to a chat message
+
+Bots can also react to a message. The same signature/verification method is applied.
+
+* Required capability: `bots-v1`
+* Method: `POST`
+* Endpoint: `/bot/{token}/reaction/{messageId}`
+* Header:
+
+| Name | Description |
+|----------------------------------|-----------------------------------------------------------------|
+| `X-Nextcloud-Talk-Bot-Random` | The random value used when signing the request |
+| `X-Nextcloud-Talk-Bot-Signature` | The signature to validate the request comes from an enabled bot |
+| `OCS-APIRequest` | Needs to be set to `true` to access the ocs/vX.php endpoint |
+
+* Data:
+
+| field | type | Description |
+|------------|--------|----------------|
+| `reaction` | string | A single emoji |
+
+* Response:
+ - Status code:
+ + `201 Created` When the reaction was created successfully
+ + `400 Bad Request` When the provided emoji was invalid
+ + `401 Unauthenticated` When the bot could not be verified for the conversation
+ + `404 Not Found` When the conversation or message could not be found
+ + `429 Too Many Requests` When `401 Unauthenticated` was triggered too often
+
+## Delete a reaction
+
+Bots can also remove their previous reaction from amessage. The same signature/verification method is applied.
+
+* Required capability: `bots-v1`
+* Method: `DELETE`
+* Endpoint: `/bot/{token}/reaction/{messageId}`
+* Header:
+
+| Name | Description |
+|----------------------------------|-----------------------------------------------------------------|
+| `X-Nextcloud-Talk-Bot-Random` | The random value used when signing the request |
+| `X-Nextcloud-Talk-Bot-Signature` | The signature to validate the request comes from an enabled bot |
+| `OCS-APIRequest` | Needs to be set to `true` to access the ocs/vX.php endpoint |
+
+* Data:
+
+| field | type | Description |
+|------------|--------|----------------|
+| `reaction` | string | A single emoji |
+
+* Response:
+ - Status code:
+ + `200 OK` When the reaction was deleted successfully
+ + `400 Bad Request` When the provided emoji was invalid
+ + `401 Unauthenticated` When the bot could not be verified for the conversation
+ + `404 Not Found` When the conversation or message could not be found
+ + `429 Too Many Requests` When `401 Unauthenticated` was triggered too often
diff --git a/docs/capabilities.md b/docs/capabilities.md
index 3922b54d5..2fb160374 100644
--- a/docs/capabilities.md
+++ b/docs/capabilities.md
@@ -124,3 +124,4 @@
## 17.1
* `remind-me-later` - Support for "Remind me later" for chat messages exists
+* `bots-v1` - Support of the first version for Bots and Webhooks is available
diff --git a/docs/commands.md b/docs/commands.md
index 3aca4e063..629abb682 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -1,5 +1,11 @@
# Chat commands
+!!! warning
+
+ **Deprecation:** Commands are deprecated in favor of [Bots](bots.md).
+
+---
+
!!! note
For security reasons commands can only be added via the
diff --git a/docs/constants.md b/docs/constants.md
index 729fa33fb..b46977036 100644
--- a/docs/constants.md
+++ b/docs/constants.md
@@ -147,6 +147,13 @@
* `0` - Public: Participants can see the result immediately and also who voted for which option
* `1` - Hidden: The result is hidden until the poll is closed and then only the number of votes for each option are displayed
+## Bots
+
+### Bot states
+* `0` Disabled
+* `1` Enabled
+* `2` No setup - The bot can neither be enabled nor disabled by a moderator
+
## Signaling modes
* `internal` - No external signaling server is used
* `external` - A single external signaling server is used
diff --git a/mkdocs.yml b/mkdocs.yml
index 31f29074e..0c735564b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -23,9 +23,10 @@ nav:
- 'Server system requirements': 'system-requirements.md'
- 'Configuring coTURN': 'TURN.md'
- 'Occ commands': 'occ.md'
- - 'Commands': 'commands.md'
+ - 'Commands (deprecated)': 'commands.md'
- 'Matterbridge integration': 'matterbridge.md'
- 'Developer documentation':
+ - 'Bots and webhooks': 'bots.md'
- 'Constants': 'constants.md'
- 'Capabilities': 'capabilities.md'
- 'PHP events': 'events.md'
@@ -39,6 +40,7 @@ nav:
- 'Reaction management': 'reaction.md'
- 'Poll management': 'poll.md'
- 'Breakout rooms management': 'breakout-rooms.md'
+ - 'Bots management': 'bot-management.md'
- 'Webinar management': 'webinar.md'
- 'Settings': 'settings.md'
- 'Integration by other apps': 'integration.md'
diff --git a/src/components/AdminSettings/Commands.vue b/src/components/AdminSettings/Commands.vue
index dd4167d67..71ac59fe6 100644
--- a/src/components/AdminSettings/Commands.vue
+++ b/src/components/AdminSettings/Commands.vue
@@ -24,7 +24,7 @@
<section id="chat_commands" class="commands section">
<h2>
{{ t('spreed', 'Commands') }}
- <small>{{ t('spreed', 'Beta') }}</small>
+ <small>{{ t('spreed', 'Deprecated') }}</small>
</h2>
<!-- eslint-disable-next-line vue/no-v-html -->