Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bots): Event based bots #14160

Merged
merged 3 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .github/workflows/integration-federation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,12 @@ jobs:
host-spreed-versions: ${{ github.event.pull_request.head.sha }}
host-guests-versions: 'master'
host-circles-versions: 'master'
host-call-summary-bot-versions: 'main'
host-notifications-versions: 'master'
remote-db: 'mysql'
remote-server-versions: 'stable30'
remote-spreed-versions: 'stable30'
remote-guests-versions: 'stable30'
remote-circles-versions: 'stable30'
remote-call-summary-bot-versions: 'main'
remote-notifications-versions: 'stable30'
- test-suite: 'federation'
php-versions: '8.2'
Expand All @@ -74,14 +72,12 @@ jobs:
host-spreed-versions: ${{ github.event.pull_request.head.sha }}
host-guests-versions: 'master'
host-circles-versions: 'master'
host-call-summary-bot-versions: 'main'
host-notifications-versions: 'master'
remote-db: 'mysql'
remote-server-versions: 'stable30'
remote-spreed-versions: 'stable30'
remote-guests-versions: 'stable30'
remote-circles-versions: 'stable30'
remote-call-summary-bot-versions: 'main'
remote-notifications-versions: 'stable30'
- test-suite: 'federation'
php-versions: '8.2'
Expand All @@ -90,14 +86,12 @@ jobs:
host-spreed-versions: 'stable30'
host-guests-versions: 'stable30'
host-circles-versions: 'stable30'
host-call-summary-bot-versions: 'main'
host-notifications-versions: 'stable30'
remote-db: 'mysql'
remote-server-versions: 'master'
remote-spreed-versions: ${{ github.event.pull_request.head.sha }}
remote-guests-versions: 'master'
remote-circles-versions: 'master'
remote-call-summary-bot-versions: 'main'
remote-notifications-versions: 'master'

services:
Expand Down Expand Up @@ -159,13 +153,6 @@ jobs:
path: host/apps/spreed
ref: ${{ matrix.host-spreed-versions }}

- name: Checkout call_summary_bot app - Host
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: host/apps/call_summary_bot
ref: ${{ matrix.host-call-summary-bot-versions }}

- name: Checkout circles app - Host
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -201,13 +188,6 @@ jobs:
path: remote/apps/spreed
ref: ${{ matrix.remote-spreed-versions }}

- name: Checkout call_summary_bot app - Remote
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: remote/apps/call_summary_bot
ref: ${{ matrix.remote-call-summary-bot-versions }}

- name: Checkout circles app - Remote
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -316,7 +296,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand All @@ -329,7 +308,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/integration-mariadb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ jobs:
server-versions: ['master']
guests-versions: ['master']
circles-versions: ['master']
call-summary-bot-versions: ['main']
notifications-versions: ['master']

services:
Expand Down Expand Up @@ -87,13 +86,6 @@ jobs:
with:
path: apps/${{ env.APP_NAME }}

- name: Checkout call_summary_bot app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: apps/call_summary_bot
ref: ${{ matrix.call-summary-bot-versions }}

- name: Checkout circles app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -152,7 +144,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/integration-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ jobs:
server-versions: ['master']
guests-versions: ['master']
circles-versions: ['master']
call-summary-bot-versions: ['main']
notifications-versions: ['master']

services:
Expand Down Expand Up @@ -87,13 +86,6 @@ jobs:
with:
path: apps/${{ env.APP_NAME }}

- name: Checkout call_summary_bot app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: apps/call_summary_bot
ref: ${{ matrix.call-summary-bot-versions }}

- name: Checkout circles app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -152,7 +144,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/integration-oci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ jobs:
server-versions: ['master']
guests-versions: ['master']
circles-versions: ['master']
call-summary-bot-versions: ['main']
notifications-versions: ['master']

services:
Expand Down Expand Up @@ -99,13 +98,6 @@ jobs:
with:
path: apps/${{ env.APP_NAME }}

- name: Checkout call_summary_bot app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: apps/call_summary_bot
ref: ${{ matrix.call-summary-bot-versions }}

- name: Checkout circles app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -159,7 +151,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/integration-pgsql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ jobs:
server-versions: ['master']
guests-versions: ['master']
circles-versions: ['master']
call-summary-bot-versions: ['main']
notifications-versions: ['master']

services:
Expand Down Expand Up @@ -90,13 +89,6 @@ jobs:
with:
path: apps/${{ env.APP_NAME }}

- name: Checkout call_summary_bot app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: apps/call_summary_bot
ref: ${{ matrix.call-summary-bot-versions }}

- name: Checkout circles app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -150,7 +142,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
9 changes: 0 additions & 9 deletions .github/workflows/integration-sqlite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ jobs:
server-versions: ['master']
guests-versions: ['master']
circles-versions: ['master']
call-summary-bot-versions: ['main']
notifications-versions: ['master']

steps:
Expand All @@ -78,13 +77,6 @@ jobs:
with:
path: apps/${{ env.APP_NAME }}

- name: Checkout call_summary_bot app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
repository: nextcloud/call_summary_bot
path: apps/call_summary_bot
ref: ${{ matrix.call-summary-bot-versions }}

- name: Checkout circles app
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
Expand Down Expand Up @@ -138,7 +130,6 @@ jobs:
./occ config:system:set memcache.local --value="\\OC\\Memcache\\APCu"
./occ config:system:set memcache.distributed --value="\\OC\\Memcache\\APCu"
./occ app:enable --force ${{ env.APP_NAME }}
./occ app:enable --force call_summary_bot
./occ app:enable --force circles
./occ app:enable --force guests
./occ app:enable --force notifications
Expand Down
7 changes: 7 additions & 0 deletions docs/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ Sends a request to the bot server, informing it was removed from a chat.
* Event: `OCA\Talk\Events\BotDisabledEvent`
* Since: 20.0.0

### Bot invoke

Sends the request as an event when the bot has the feature `event`

* Event: `OCA\Talk\Events\BotInvokeEvent`
* Since: 21.0.0

## Inbound events to invoke Talk

### Bot install
Expand Down
2 changes: 1 addition & 1 deletion docs/occ.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Install a new bot on the server
|---|---|---|---|---|---|
| `--output` | Output format (plain, json or json_pretty, default is plain) | yes | no | no | `'plain'` |
| `--no-setup` | Prevent moderators from setting up the bot in a conversation | no | no | no | `false` |
| `--feature\|-f` | Specify the list of features for the bot - webhook: The bot receives posted chat messages as webhooks - response: The bot can post messages and reactions as a response - none: When all features should be disabled for the bot | yes | yes | yes | *Required* |
| `--feature\|-f` | Specify the list of features for the bot - webhook: The bot receives posted chat messages as webhooks - response: The bot can post messages and reactions as a response - event: The bot reads posted messages from local events - none: When all features should be disabled for the bot | yes | yes | yes | *Required* |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it also do something with the events? Maybe that can be mentioned in the docs?

Suggested change
| `--feature\|-f` | Specify the list of features for the bot - webhook: The bot receives posted chat messages as webhooks - response: The bot can post messages and reactions as a response - event: The bot reads posted messages from local events - none: When all features should be disabled for the bot | yes | yes | yes | *Required* |
| `--feature\|-f` | Specify the list of features for the bot - webhook: The bot receives posted chat messages as webhooks - response: The bot can post messages and reactions as a response - event: The bot reads posted messages from local events and acts on the predefined triggers (if any) - none: When all features should be disabled for the bot | yes | yes | yes | *Required* |

Something like that maybe?


## talk:bot:list

Expand Down
6 changes: 6 additions & 0 deletions lib/Command/Bot/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ protected function configure(): void {
'Specify the list of features for the bot' . "\n"
. ' - webhook: The bot receives posted chat messages as webhooks' . "\n"
. ' - response: The bot can post messages and reactions as a response' . "\n"
. ' - event: The bot reads posted messages from local events' . "\n"
. ' - none: When all features should be disabled for the bot'
)
;
Expand All @@ -80,6 +81,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if (!empty($input->getOption('feature'))) {
$featureFlags = Bot::featureLabelsToFlags($input->getOption('feature'));
if (str_starts_with($url, 'nextcloudapp://')) {
$featureFlags &= ~Bot::FEATURE_WEBHOOK;
}
} elseif (str_starts_with($url, 'nextcloudapp://')) {
$featureFlags = Bot::FEATURE_EVENT;
} else {
$featureFlags = Bot::FEATURE_WEBHOOK + Bot::FEATURE_RESPONSE;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/BotController.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public function sendMessage(string $token, string $message, string $referenceId
$creationDateTime = $this->timeFactory->getDateTime('now', new \DateTimeZone('UTC'));

try {
$this->chatManager->sendMessage($room, $this->participant, $actorType, $actorId, $message, $creationDateTime, $parent, $referenceId, $silent, rateLimitGuestMentions: false);
$this->chatManager->sendMessage($room, null, $actorType, $actorId, $message, $creationDateTime, $parent, $referenceId, $silent, rateLimitGuestMentions: false);
} catch (MessageTooLongException) {
return new DataResponse(null, Http::STATUS_REQUEST_ENTITY_TOO_LARGE);
} catch (\Exception) {
Expand Down
103 changes: 103 additions & 0 deletions lib/Events/BotInvokeEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Talk\Events;

use OCP\EventDispatcher\Event;

/**
* @psalm-type ChatMessageData = array{
* type: 'Activity'|'Create',
* actor: array{
* type: 'Person',
* id: non-empty-string,
* name: non-empty-string,
* talkParticipantType: non-empty-string,
* },
* object: array{
* type: 'Note',
* id: non-empty-string,
* name: string,
* content: non-empty-string,
* mediaType: 'text/markdown'|'text/plain',
* },
* target: array{
* type: 'Collection',
* id: non-empty-string,
* name: non-empty-string,
* },
* }
* @psalm-type BotManagementData = array{
* type: 'Join'|'Leave',
* actor: array{
* type: 'Application',
* id: non-empty-string,
* name: non-empty-string,
* },
* object: array{
* type: 'Collection',
* id: non-empty-string,
* name: non-empty-string,
* },
* }
* @psalm-type InvocationData = ChatMessageData|BotManagementData
*/
class BotInvokeEvent extends Event {
/** @var list<string> */
protected array $reactions = [];
/** @var list<array{message: string, referenceId: string, reply: bool|int, silent: bool}> */
protected array $answers = [];

/**
* @param InvocationData $message
*/
public function __construct(
protected string $botUrl,
protected array $message,
) {
parent::__construct();
}

public function getBotUrl(): string {
return $this->botUrl;
}

/**
* @return InvocationData
*/
public function getMessage(): array {
return $this->message;
}

public function addReaction(string $emoji): void {
$this->reactions[] = $emoji;
}

/**
* @return list<string>
*/
public function getReactions(): array {
return $this->reactions;
}

public function addAnswer(string $message, bool|int $reply = false, bool $silent = false, string $referenceId = ''): void {
$this->answers[] = [
'message' => $message,
'referenceId' => $referenceId,
'reply' => $reply,
'silent' => $silent,
];
}

/**
* @return list<array{message: string, referenceId: string, reply: bool|int, silent: bool}>
*/
public function getAnswers(): array {
return $this->answers;
}
}
Loading
Loading