commsuite-bot 1.0.40__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- commsuite_bot-1.0.40/PKG-INFO +96 -0
- commsuite_bot-1.0.40/README.md +81 -0
- commsuite_bot-1.0.40/commsuite_bot.egg-info/PKG-INFO +96 -0
- commsuite_bot-1.0.40/commsuite_bot.egg-info/SOURCES.txt +7 -0
- commsuite_bot-1.0.40/commsuite_bot.egg-info/dependency_links.txt +1 -0
- commsuite_bot-1.0.40/commsuite_bot.egg-info/top_level.txt +1 -0
- commsuite_bot-1.0.40/commsuite_bot.py +86 -0
- commsuite_bot-1.0.40/pyproject.toml +26 -0
- commsuite_bot-1.0.40/setup.cfg +4 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: commsuite-bot
|
|
3
|
+
Version: 1.0.40
|
|
4
|
+
Summary: Standard-library Python client for the Commsuite Bot API
|
|
5
|
+
Author: Aleksey Shvarts
|
|
6
|
+
Project-URL: Homepage, https://github.com/AlekseyShvartsGD/commsuite
|
|
7
|
+
Project-URL: Source, https://github.com/AlekseyShvartsGD/commsuite/tree/main/server/bot_api
|
|
8
|
+
Project-URL: Releases, https://github.com/AlekseyShvartsGD/commsuite/releases
|
|
9
|
+
Keywords: commsuite,bot,chat,api,messenger
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Communications :: Chat
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# Commsuite Bot API
|
|
17
|
+
|
|
18
|
+
Bots are real Commsuite accounts (`role = 'bot'`). They appear in People, can
|
|
19
|
+
be added to groups, and cannot sign in with a password. Each bot has an API
|
|
20
|
+
token that lets your own program act as that account.
|
|
21
|
+
|
|
22
|
+
Create a bot in **Settings → Developer tools**, then open **API** on the bot
|
|
23
|
+
card to copy its token. The same dialog contains a ready-to-run Python example.
|
|
24
|
+
|
|
25
|
+
## Endpoints
|
|
26
|
+
|
|
27
|
+
All requests use `Authorization: Bearer cmsb_…`.
|
|
28
|
+
|
|
29
|
+
| Method | Path | Purpose |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| GET | `/api/bot/me` | Bot identity |
|
|
32
|
+
| GET | `/api/bot/updates?offset=0&timeout=30&limit=100` | Long-poll incoming messages |
|
|
33
|
+
| POST | `/api/bot/sendMessage` | Send a message |
|
|
34
|
+
|
|
35
|
+
`sendMessage` body:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{ "conversationId": "…", "text": "hello", "replyTo": "optional-message-id" }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`updates` response:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"updates": [
|
|
46
|
+
{
|
|
47
|
+
"updateId": 42,
|
|
48
|
+
"conversationId": "…",
|
|
49
|
+
"message": { "id": "…", "senderId": "…", "body": "hi", "…": "…" }
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Pass the last `updateId` as `offset` on the next request; acknowledged updates
|
|
56
|
+
are deleted. `timeout` keeps the request open while the bot is idle (maximum
|
|
57
|
+
50 seconds). A paused bot rejects its token with `401`.
|
|
58
|
+
|
|
59
|
+
A bot can also call the regular user API (`/api/conversations`,
|
|
60
|
+
`/api/conversations/:id/messages`, …) with the same token.
|
|
61
|
+
|
|
62
|
+
## Python
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install commsuite-bot
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from commsuite_bot import CommsuiteBot
|
|
70
|
+
|
|
71
|
+
bot = CommsuiteBot("http://localhost:3000", "cmsb_…")
|
|
72
|
+
|
|
73
|
+
def handle(update):
|
|
74
|
+
message = update["message"]
|
|
75
|
+
bot.send_message(update["conversationId"], "echo: " + message["body"])
|
|
76
|
+
|
|
77
|
+
bot.run(handle)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The package is a single standard-library module, so it also works by copying
|
|
81
|
+
`commsuite_bot.py` next to your script. See `example_echo_bot.py` for a complete
|
|
82
|
+
echo bot. Only Python 3.8+ is required; there are no external dependencies.
|
|
83
|
+
|
|
84
|
+
Publishing a new version (maintainers): `python -m build` then
|
|
85
|
+
`twine upload dist/*` from this folder, with `TWINE_USERNAME=__token__` and
|
|
86
|
+
`TWINE_PASSWORD` set to a PyPI API token.
|
|
87
|
+
|
|
88
|
+
## Built-in replies and mini-apps
|
|
89
|
+
|
|
90
|
+
Bots without an external program can still use keyword replies and one
|
|
91
|
+
mini-app (JSON formatter, Base64, or UUID generator). Both are managed from the
|
|
92
|
+
bot card in Developer tools. `send /help` to a bot to discover its commands.
|
|
93
|
+
|
|
94
|
+
External programs receive updates for every message sent to the bot by a
|
|
95
|
+
human account. Messages sent by other bots are not queued, which prevents
|
|
96
|
+
runaway loops between automated accounts.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Commsuite Bot API
|
|
2
|
+
|
|
3
|
+
Bots are real Commsuite accounts (`role = 'bot'`). They appear in People, can
|
|
4
|
+
be added to groups, and cannot sign in with a password. Each bot has an API
|
|
5
|
+
token that lets your own program act as that account.
|
|
6
|
+
|
|
7
|
+
Create a bot in **Settings → Developer tools**, then open **API** on the bot
|
|
8
|
+
card to copy its token. The same dialog contains a ready-to-run Python example.
|
|
9
|
+
|
|
10
|
+
## Endpoints
|
|
11
|
+
|
|
12
|
+
All requests use `Authorization: Bearer cmsb_…`.
|
|
13
|
+
|
|
14
|
+
| Method | Path | Purpose |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| GET | `/api/bot/me` | Bot identity |
|
|
17
|
+
| GET | `/api/bot/updates?offset=0&timeout=30&limit=100` | Long-poll incoming messages |
|
|
18
|
+
| POST | `/api/bot/sendMessage` | Send a message |
|
|
19
|
+
|
|
20
|
+
`sendMessage` body:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{ "conversationId": "…", "text": "hello", "replyTo": "optional-message-id" }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`updates` response:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"updates": [
|
|
31
|
+
{
|
|
32
|
+
"updateId": 42,
|
|
33
|
+
"conversationId": "…",
|
|
34
|
+
"message": { "id": "…", "senderId": "…", "body": "hi", "…": "…" }
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Pass the last `updateId` as `offset` on the next request; acknowledged updates
|
|
41
|
+
are deleted. `timeout` keeps the request open while the bot is idle (maximum
|
|
42
|
+
50 seconds). A paused bot rejects its token with `401`.
|
|
43
|
+
|
|
44
|
+
A bot can also call the regular user API (`/api/conversations`,
|
|
45
|
+
`/api/conversations/:id/messages`, …) with the same token.
|
|
46
|
+
|
|
47
|
+
## Python
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install commsuite-bot
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from commsuite_bot import CommsuiteBot
|
|
55
|
+
|
|
56
|
+
bot = CommsuiteBot("http://localhost:3000", "cmsb_…")
|
|
57
|
+
|
|
58
|
+
def handle(update):
|
|
59
|
+
message = update["message"]
|
|
60
|
+
bot.send_message(update["conversationId"], "echo: " + message["body"])
|
|
61
|
+
|
|
62
|
+
bot.run(handle)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The package is a single standard-library module, so it also works by copying
|
|
66
|
+
`commsuite_bot.py` next to your script. See `example_echo_bot.py` for a complete
|
|
67
|
+
echo bot. Only Python 3.8+ is required; there are no external dependencies.
|
|
68
|
+
|
|
69
|
+
Publishing a new version (maintainers): `python -m build` then
|
|
70
|
+
`twine upload dist/*` from this folder, with `TWINE_USERNAME=__token__` and
|
|
71
|
+
`TWINE_PASSWORD` set to a PyPI API token.
|
|
72
|
+
|
|
73
|
+
## Built-in replies and mini-apps
|
|
74
|
+
|
|
75
|
+
Bots without an external program can still use keyword replies and one
|
|
76
|
+
mini-app (JSON formatter, Base64, or UUID generator). Both are managed from the
|
|
77
|
+
bot card in Developer tools. `send /help` to a bot to discover its commands.
|
|
78
|
+
|
|
79
|
+
External programs receive updates for every message sent to the bot by a
|
|
80
|
+
human account. Messages sent by other bots are not queued, which prevents
|
|
81
|
+
runaway loops between automated accounts.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: commsuite-bot
|
|
3
|
+
Version: 1.0.40
|
|
4
|
+
Summary: Standard-library Python client for the Commsuite Bot API
|
|
5
|
+
Author: Aleksey Shvarts
|
|
6
|
+
Project-URL: Homepage, https://github.com/AlekseyShvartsGD/commsuite
|
|
7
|
+
Project-URL: Source, https://github.com/AlekseyShvartsGD/commsuite/tree/main/server/bot_api
|
|
8
|
+
Project-URL: Releases, https://github.com/AlekseyShvartsGD/commsuite/releases
|
|
9
|
+
Keywords: commsuite,bot,chat,api,messenger
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Topic :: Communications :: Chat
|
|
13
|
+
Requires-Python: >=3.8
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# Commsuite Bot API
|
|
17
|
+
|
|
18
|
+
Bots are real Commsuite accounts (`role = 'bot'`). They appear in People, can
|
|
19
|
+
be added to groups, and cannot sign in with a password. Each bot has an API
|
|
20
|
+
token that lets your own program act as that account.
|
|
21
|
+
|
|
22
|
+
Create a bot in **Settings → Developer tools**, then open **API** on the bot
|
|
23
|
+
card to copy its token. The same dialog contains a ready-to-run Python example.
|
|
24
|
+
|
|
25
|
+
## Endpoints
|
|
26
|
+
|
|
27
|
+
All requests use `Authorization: Bearer cmsb_…`.
|
|
28
|
+
|
|
29
|
+
| Method | Path | Purpose |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| GET | `/api/bot/me` | Bot identity |
|
|
32
|
+
| GET | `/api/bot/updates?offset=0&timeout=30&limit=100` | Long-poll incoming messages |
|
|
33
|
+
| POST | `/api/bot/sendMessage` | Send a message |
|
|
34
|
+
|
|
35
|
+
`sendMessage` body:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{ "conversationId": "…", "text": "hello", "replyTo": "optional-message-id" }
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`updates` response:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"updates": [
|
|
46
|
+
{
|
|
47
|
+
"updateId": 42,
|
|
48
|
+
"conversationId": "…",
|
|
49
|
+
"message": { "id": "…", "senderId": "…", "body": "hi", "…": "…" }
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Pass the last `updateId` as `offset` on the next request; acknowledged updates
|
|
56
|
+
are deleted. `timeout` keeps the request open while the bot is idle (maximum
|
|
57
|
+
50 seconds). A paused bot rejects its token with `401`.
|
|
58
|
+
|
|
59
|
+
A bot can also call the regular user API (`/api/conversations`,
|
|
60
|
+
`/api/conversations/:id/messages`, …) with the same token.
|
|
61
|
+
|
|
62
|
+
## Python
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install commsuite-bot
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from commsuite_bot import CommsuiteBot
|
|
70
|
+
|
|
71
|
+
bot = CommsuiteBot("http://localhost:3000", "cmsb_…")
|
|
72
|
+
|
|
73
|
+
def handle(update):
|
|
74
|
+
message = update["message"]
|
|
75
|
+
bot.send_message(update["conversationId"], "echo: " + message["body"])
|
|
76
|
+
|
|
77
|
+
bot.run(handle)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The package is a single standard-library module, so it also works by copying
|
|
81
|
+
`commsuite_bot.py` next to your script. See `example_echo_bot.py` for a complete
|
|
82
|
+
echo bot. Only Python 3.8+ is required; there are no external dependencies.
|
|
83
|
+
|
|
84
|
+
Publishing a new version (maintainers): `python -m build` then
|
|
85
|
+
`twine upload dist/*` from this folder, with `TWINE_USERNAME=__token__` and
|
|
86
|
+
`TWINE_PASSWORD` set to a PyPI API token.
|
|
87
|
+
|
|
88
|
+
## Built-in replies and mini-apps
|
|
89
|
+
|
|
90
|
+
Bots without an external program can still use keyword replies and one
|
|
91
|
+
mini-app (JSON formatter, Base64, or UUID generator). Both are managed from the
|
|
92
|
+
bot card in Developer tools. `send /help` to a bot to discover its commands.
|
|
93
|
+
|
|
94
|
+
External programs receive updates for every message sent to the bot by a
|
|
95
|
+
human account. Messages sent by other bots are not queued, which prevents
|
|
96
|
+
runaway loops between automated accounts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
commsuite_bot
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Tiny standard-library client for the Commsuite Bot API.
|
|
2
|
+
|
|
3
|
+
Create a bot in Commsuite → Settings → Developer tools, open its API dialog,
|
|
4
|
+
copy the token, and pass it here. No third-party packages are required.
|
|
5
|
+
|
|
6
|
+
from commsuite_bot import CommsuiteBot
|
|
7
|
+
|
|
8
|
+
bot = CommsuiteBot("http://localhost:3000", "cmsb_...")
|
|
9
|
+
print(bot.me())
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
import urllib.error
|
|
14
|
+
import urllib.request
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CommsuiteError(RuntimeError):
|
|
18
|
+
def __init__(self, status, message):
|
|
19
|
+
super().__init__(f"{status}: {message}")
|
|
20
|
+
self.status = status
|
|
21
|
+
self.message = message
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CommsuiteBot:
|
|
25
|
+
def __init__(self, base_url, token, request_timeout=60):
|
|
26
|
+
self.api_base = base_url.rstrip("/") + "/api"
|
|
27
|
+
self.token = token
|
|
28
|
+
self.request_timeout = request_timeout
|
|
29
|
+
|
|
30
|
+
def _request(self, method, path, data=None, timeout=None):
|
|
31
|
+
body = None if data is None else json.dumps(data).encode("utf-8")
|
|
32
|
+
request = urllib.request.Request(
|
|
33
|
+
self.api_base + path,
|
|
34
|
+
data=body,
|
|
35
|
+
method=method,
|
|
36
|
+
headers={
|
|
37
|
+
"Authorization": f"Bearer {self.token}",
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
},
|
|
40
|
+
)
|
|
41
|
+
try:
|
|
42
|
+
with urllib.request.urlopen(
|
|
43
|
+
request, timeout=timeout or self.request_timeout
|
|
44
|
+
) as response:
|
|
45
|
+
return json.load(response)
|
|
46
|
+
except urllib.error.HTTPError as error:
|
|
47
|
+
try:
|
|
48
|
+
payload = json.load(error)
|
|
49
|
+
message = payload.get("error", error.reason)
|
|
50
|
+
except Exception:
|
|
51
|
+
message = error.reason
|
|
52
|
+
raise CommsuiteError(error.code, message) from None
|
|
53
|
+
|
|
54
|
+
def me(self):
|
|
55
|
+
return self._request("GET", "/bot/me")
|
|
56
|
+
|
|
57
|
+
def get_updates(self, offset=0, timeout=30, limit=100):
|
|
58
|
+
"""Long-polls for messages. Pass the last updateId back as offset."""
|
|
59
|
+
query = f"?offset={int(offset)}&timeout={int(timeout)}&limit={int(limit)}"
|
|
60
|
+
return self._request(
|
|
61
|
+
"GET", "/bot/updates" + query, timeout=timeout + 10
|
|
62
|
+
)["updates"]
|
|
63
|
+
|
|
64
|
+
def send_message(self, conversation_id, text, reply_to=None):
|
|
65
|
+
payload = {"conversationId": conversation_id, "text": text}
|
|
66
|
+
if reply_to:
|
|
67
|
+
payload["replyTo"] = reply_to
|
|
68
|
+
return self._request("POST", "/bot/sendMessage", payload)["message"]
|
|
69
|
+
|
|
70
|
+
# The regular API is available too, e.g. conversations() to discover id's.
|
|
71
|
+
def conversations(self):
|
|
72
|
+
return self._request("GET", "/conversations")["conversations"]
|
|
73
|
+
|
|
74
|
+
def messages(self, conversation_id, limit=50):
|
|
75
|
+
return self._request(
|
|
76
|
+
"GET", f"/conversations/{conversation_id}/messages?limit={int(limit)}"
|
|
77
|
+
)["messages"]
|
|
78
|
+
|
|
79
|
+
def run(self, handler, poll_timeout=30):
|
|
80
|
+
"""Calls handler(update) forever, acknowledging each batch."""
|
|
81
|
+
offset = 0
|
|
82
|
+
while True:
|
|
83
|
+
updates = self.get_updates(offset=offset, timeout=poll_timeout)
|
|
84
|
+
for update in updates:
|
|
85
|
+
offset = update["updateId"]
|
|
86
|
+
handler(update)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "commsuite-bot"
|
|
7
|
+
version = "1.0.40"
|
|
8
|
+
description = "Standard-library Python client for the Commsuite Bot API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
authors = [{ name = "Aleksey Shvarts" }]
|
|
12
|
+
keywords = ["commsuite", "bot", "chat", "api", "messenger"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Topic :: Communications :: Chat",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/AlekseyShvartsGD/commsuite"
|
|
21
|
+
Source = "https://github.com/AlekseyShvartsGD/commsuite/tree/main/server/bot_api"
|
|
22
|
+
Releases = "https://github.com/AlekseyShvartsGD/commsuite/releases"
|
|
23
|
+
|
|
24
|
+
# Ship the single stdlib module; example_echo_bot.py stays in the repo only.
|
|
25
|
+
[tool.setuptools]
|
|
26
|
+
py-modules = ["commsuite_bot"]
|