Skip to content

Commit 8609e14

Browse files
authored
TalkBot docs (#102)
Added small article to documentation about Talk Bots --------- Signed-off-by: Alexander Piskun <bigcat88@icloud.com>
1 parent dba964e commit 8609e14

File tree

6 files changed

+117
-6
lines changed

6 files changed

+117
-6
lines changed

docs/NextcloudApp.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ It's advisable to write these steps as commands in a Makefile for quick use.
7575

7676
Examples for such Makefiles can be found in this repository:
7777
`Skeleton <https://github.com/cloud-py-api/nc_py_api/blob/main/examples/as_app/skeleton/Makefile>`_ ,
78+
`TalkBot <https://github.com/cloud-py-api/nc_py_api/blob/main/examples/as_app/talk_bot/Makefile>`_
7879
`ToGif <https://github.com/cloud-py-api/nc_py_api/blob/main/examples/as_app/to_gif/Makefile>`_ ,
7980
`nc_py_api <https://github.com/cloud-py-api/nc_py_api/blob/main/scripts/dev_register.sh>`_
8081

docs/NextcloudTalkBot.rst

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,75 @@
1-
Nextcloud Talk Bot API in Application
2-
=====================================
1+
Nextcloud Talk Bot API in Applications
2+
======================================
33

4-
to-do
4+
The AppEcosystem is an excellent choice for developing and deploying bots for Nextcloud Talk.
5+
6+
Bots for Nextcloud Talk, in essence, don't differ significantly from regular external applications.
7+
The functionality of an external application can include just the bot or provide additional functionalities as well.
8+
9+
Let's consider a simple example of how to transform the `skeleton` of an external application into a Nextcloud Talk bot.
10+
11+
The first step is to add the **TALK_BOT** and **TALK** scopes to your `info.xml` file:
12+
13+
.. code-block:: xml
14+
15+
<scopes>
16+
<required>
17+
<value>TALK</value>
18+
<value>TALK_BOT</value>
19+
</required>
20+
<optional>
21+
</optional>
22+
</scopes>
23+
24+
The TALK_BOT scope enables your application to register the bot within the Nextcloud system, while the TALK scope permits access to Talk's endpoints.
25+
26+
In the global **enabled_handler**, you should include a call to your bot's enabled_handler, as shown in the bot example:
27+
28+
.. code-block:: python
29+
30+
def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
31+
try:
32+
CURRENCY_BOT.enabled_handler(enabled, nc) # registering/unregistering the bot's stuff.
33+
except Exception as e:
34+
return str(e)
35+
return ""
36+
37+
Afterward, using FastAPI, you can define endpoints that will be invoked by Talk:
38+
39+
.. code-block:: python
40+
41+
@APP.post("/currency_talk_bot")
42+
async def currency_talk_bot(
43+
message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_app)],
44+
background_tasks: BackgroundTasks,
45+
):
46+
return requests.Response()
47+
48+
.. note::
49+
You must include to each endpoint your bot provides the **Depends(talk_bot_app)**.
50+
**message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_app)]**
51+
52+
Depending on **talk_bot_app** serves as an automatic authentication handler for messages from the cloud, which returns the received message from Nextcloud upon successful authentication.
53+
54+
Additionally, if your bot can provide quick and fixed execution times, you may not need to create background tasks.
55+
However, in most cases, it's recommended to segregate functionality and perform operations in the background, while promptly returning an empty response to Nextcloud.
56+
57+
An application can implement multiple bots concurrently, but each bot's endpoints must be unique.
58+
59+
All authentication is facilitated by the Python SDK, ensuring you needn't concern yourself with anything other than writing useful functionality.
60+
61+
Currently, bots have access only to three methods:
62+
63+
* :py:meth:`~nc_py_api.talk_bot.TalkBot.send_message`
64+
* :py:meth:`~nc_py_api.talk_bot.TalkBot.react_to_message`
65+
* :py:meth:`~nc_py_api.talk_bot.TalkBot.delete_reaction`
66+
67+
.. note:: **The usage of system application functionality for user impersonation in bot development is strongly discouraged**.
68+
All bot messages should only be sent using the ``send_message`` method!
69+
70+
All other rules and algorithms remain consistent with regular external applications.
71+
72+
Full source of bot example can be found here:
73+
`TalkBot <https://github.com/cloud-py-api/nc_py_api/blob/main/examples/as_app/talk_bot/src/main.py>`_
74+
75+
Wishing success with your Nextcloud bot integration! May the force be with you!
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
How To Install
2+
==============
3+
4+
Currently, while AppEcosystem hasn't been published on the App Store, and App Store support hasn't been added yet,
5+
installation is a little bit tricky.
6+
7+
Steps to Install:
8+
9+
1. [Install AppEcosystem](https://cloud-py-api.github.io/app_ecosystem_v2/Installation.html)
10+
2. Create a deployment daemon according to the [instructions](https://cloud-py-api.github.io/app_ecosystem_v2/CreationOfDeployDaemon.html#create-deploy-daemon) of the Appecosystem
11+
3. php occ app_ecosystem_v2:app:deploy talk_bot "daemon_deploy_name" \
12+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/talk_bot/appinfo/info.xml
13+
14+
to deploy a docker image with Bot to docker.
15+
16+
4. php occ app_ecosystem_v2:app:register talk_bot "daemon_deploy_name" -e --force-scopes \
17+
--info-xml https://raw.githubusercontent.com/cloud-py-api/nc_py_api/main/examples/as_app/talk_bot/appinfo/info.xml
18+
19+
to call its **enable** handler and accept all required API scopes by default.
20+
21+
22+
In a few months
23+
===============
24+
25+
1. Install AppEcosystem from App Store
26+
2. Configure Deploy Daemon with GUI provided by AppEcosystem
27+
3. Go to External Applications page in Nextcloud UI
28+
4. Find this bot in a list and press "Install" and "Enable" buttons, like with usual Applications.

examples/as_app/talk_bot/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ help:
1111
@echo " "
1212
@echo " deploy deploy example to registered 'docker_dev'"
1313
@echo " "
14-
@echo " run28 install ToGif for Nextcloud 28"
15-
@echo " run27 install ToGif for Nextcloud 27"
14+
@echo " run28 install TalkBot for Nextcloud 28"
15+
@echo " run27 install TalkBot for Nextcloud 27"
1616
@echo " "
1717
@echo " For development of this example use PyCharm run configurations. Development is always set for last Nextcloud."
1818
@echo " First run 'TalkBot' and then 'make manual_register', after that you can use/debug/develop it and easy test."
178 KB
Loading

examples/as_app/talk_bot/src/main.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
from nc_py_api.ex_app import run_app, set_handlers, talk_bot_app
1111

1212
APP = FastAPI()
13+
# We define bot globally, so if no `multiprocessing` module is used, it can be reused by calls.
14+
# All stuff in it works only with local variables, so in the case of multithreading, there should not be problems.
1315
CURRENCY_BOT = talk_bot.TalkBot("/currency_talk_bot", "Currency convertor", "Usage: `@currency convert 100 EUR to USD`")
1416

1517

1618
def convert_currency(amount, from_currency, to_currency):
19+
"""Payload of bot, simplest currency convertor."""
1720
base_url = "https://api.exchangerate-api.com/v4/latest/"
1821

1922
# Fetch latest exchange rates
@@ -37,17 +40,21 @@ def convert_currency(amount, from_currency, to_currency):
3740

3841
def currency_talk_bot_process_request(message: talk_bot.TalkBotMessage):
3942
try:
43+
# Ignore `system` messages
4044
if message.object_name != "message":
4145
return
46+
# We use a wildcard search to only respond to messages sent to us.
4247
r = re.search(
43-
r"@currency\s(convert\s)?(\d*)\s(\w*)\sto\s(\w*)", message.object_content["message"], re.IGNORECASE
48+
r"@currency\s(convert\s)?(\d*)\s(\w*)\sto\s(\w*)\s?", message.object_content["message"], re.IGNORECASE
4449
)
4550
if r is None:
4651
return
4752
converted_amount = convert_currency(int(r.group(2)), r.group(3), r.group(4))
4853
converted_amount = round(converted_amount, 2)
54+
# Send reply to chat
4955
CURRENCY_BOT.send_message(f"{r.group(2)} {r.group(3)} is equal to {converted_amount} {r.group(4)}", message)
5056
except Exception as e:
57+
# In production, it is better to write to log, than in the chat ;)
5158
CURRENCY_BOT.send_message(f"Exception: {str(e)}", message)
5259

5360

@@ -56,19 +63,23 @@ async def currency_talk_bot(
5663
message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_app)],
5764
background_tasks: BackgroundTasks,
5865
):
66+
# As during converting, we do not process converting locally, we perform this in background, in the background task.
5967
background_tasks.add_task(currency_talk_bot_process_request, message)
68+
# Return Response immediately for Nextcloud, that we are ok.
6069
return requests.Response()
6170

6271

6372
def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
6473
print(f"enabled={enabled}")
6574
try:
75+
# `enabled_handler` will install or uninstall bot on the server, depending on ``enabled`` parameter.
6676
CURRENCY_BOT.enabled_handler(enabled, nc)
6777
except Exception as e:
6878
return str(e)
6979
return ""
7080

7181

82+
# The same stuff as for usual External Applications
7283
@APP.on_event("startup")
7384
def initialization():
7485
set_handlers(APP, enabled_handler)

0 commit comments

Comments
 (0)