v0.0.28: BotFather-only registration, per-instance bot toggle, docs update
Security: - Bot registration restricted to BotFather (requires botfather_token) - Direct POST /v1/bot/register without BotFather auth → rejected Deploy: - systemd service reads /home/warzone/server.env for EXTRA_ARGS - deploy/warzone-server.env.mequ: no bots (default) - deploy/warzone-server.env.kh3rad3ree: --enable-bots - setup.sh copies per-hostname env file Docs updated: - LLM_HELP.md: BotFather flow, plaintext bot messaging, E2E option, bridge - LLM_BOT_DEV.md: botfather_token requirement, E2E mode, bridge section - BOT_API.md: full BotFather flow, ownership, numeric IDs, webhook delivery - SERVER.md: --enable-bots flag, per-instance config, bot system section - USAGE.md: bot messaging, BotFather, bridge tool Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,37 +4,45 @@
|
||||
|
||||
featherChat exposes a **Telegram Bot API-compatible** HTTP interface, allowing
|
||||
developers to build bots that interact with featherChat users using familiar
|
||||
patterns. Bots register with the server, receive a token, and communicate via
|
||||
long-polling (webhook support is planned).
|
||||
patterns. Bots are created exclusively through **@botfather**, receive a token,
|
||||
and communicate via long-polling or webhooks.
|
||||
|
||||
Key properties of v1:
|
||||
The server must be started with `--enable-bots` to activate bot functionality.
|
||||
|
||||
Key properties:
|
||||
|
||||
- **BotFather is required** -- only `@botfather` can register bots. It is
|
||||
auto-created on first server start (token printed in server logs).
|
||||
- Bot aliases **must** end with `Bot`, `bot`, or `_bot` (auto-enforced on
|
||||
registration).
|
||||
- Bots receive encrypted user messages as **base64 blobs** (`raw_encrypted`
|
||||
field). Plaintext bot-to-bot messages are delivered with a readable `text`
|
||||
field.
|
||||
- Bot-sent messages are **plaintext** (not E2E encrypted) in v1.
|
||||
- `chat_id` values are hex fingerprints (not numeric Telegram-style IDs).
|
||||
field) unless registered as E2E bots. Plaintext bot-to-bot messages are
|
||||
delivered with a readable `text` field.
|
||||
- Bot-sent messages are **plaintext** (not E2E encrypted) unless the bot is
|
||||
registered in E2E mode.
|
||||
- `chat_id` accepts both hex fingerprints and numeric IDs (Telegram
|
||||
compatibility). Numeric IDs are also returned in `from.id`.
|
||||
- Each bot has an `owner` field linking to the creating user's fingerprint.
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```
|
||||
1. Register your bot:
|
||||
1. Message @botfather to create a bot (or use BotFather token from server logs).
|
||||
BotFather registers the bot via:
|
||||
POST /v1/bot/register
|
||||
{"name": "WeatherBot", "fingerprint": "aabbccdd..."}
|
||||
{"name": "WeatherBot", "fingerprint": "aabbccdd...", "botfather_token": "<bf_token>"}
|
||||
|
||||
2. Extract the token from the response.
|
||||
|
||||
3. Poll for updates:
|
||||
POST /v1/bot/<token>/getUpdates
|
||||
{"timeout": 5}
|
||||
{"timeout": 50}
|
||||
|
||||
4. Send a reply:
|
||||
POST /v1/bot/<token>/sendMessage
|
||||
{"chat_id": "<sender_fingerprint>", "text": "Hello!"}
|
||||
{"chat_id": "<sender_fingerprint_or_numeric_id>", "text": "Hello!"}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -48,21 +56,34 @@ POST /v1/bot/register
|
||||
```
|
||||
|
||||
Creates a new bot, stores it in the server database, and auto-registers an
|
||||
alias.
|
||||
alias. **Only @botfather can call this endpoint** -- a valid `botfather_token`
|
||||
is required.
|
||||
|
||||
**Request:**
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "MyBot",
|
||||
"fingerprint": "aabbccdd1122334455667788aabbccdd"
|
||||
"fingerprint": "aabbccdd1122334455667788aabbccdd",
|
||||
"botfather_token": "<botfather_token>",
|
||||
"owner": "<creator_fingerprint>"
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|---------------|--------|----------------------------------------------|
|
||||
| `name` | string | Display name. Alias suffix auto-added if needed. |
|
||||
| `fingerprint` | string | Hex-encoded public key fingerprint for the bot. |
|
||||
| Field | Type | Description |
|
||||
|--------------------|--------|---------------------------------------------------|
|
||||
| `name` | string | Display name. Alias suffix auto-added if needed. |
|
||||
| `fingerprint` | string | Hex-encoded public key fingerprint for the bot. |
|
||||
| `botfather_token` | string | BotFather authorization token (required). |
|
||||
| `owner` | string | Fingerprint of the user who requested creation. |
|
||||
|
||||
**E2E bot registration** (optional additional fields):
|
||||
|
||||
| Field | Type | Description |
|
||||
|---------------|--------|--------------------------------------------------|
|
||||
| `e2e` | bool | Set to `true` to register as an E2E bot. |
|
||||
| `bundle` | object | Full prekey bundle (identity_key, signed_prekey, signature, one_time_prekeys). |
|
||||
| `eth_address` | string | Ethereum address for the bot. |
|
||||
|
||||
**Response:**
|
||||
|
||||
@@ -73,7 +94,8 @@ alias.
|
||||
"token": "aabbccdd11223344:9f8e7d6c5b4a39281706abcdef012345",
|
||||
"name": "MyBot",
|
||||
"fingerprint": "aabbccdd1122334455667788aabbccdd",
|
||||
"alias": "@mybot_bot"
|
||||
"alias": "@mybot_bot",
|
||||
"owner": "<creator_fingerprint>"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -139,14 +161,17 @@ Returns queued messages for the bot and deletes them from the queue.
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------|------|-----------------------------------------------------|
|
||||
| `timeout` | u64 | Optional. Long-poll wait in seconds. **Capped at 5.** |
|
||||
| Field | Type | Description |
|
||||
|-----------|------|------------------------------------------------------|
|
||||
| `timeout` | u64 | Optional. Long-poll wait in seconds. **Capped at 50.** |
|
||||
|
||||
If the queue is empty and `timeout > 0`, the server waits up to `timeout`
|
||||
seconds (max 5) before returning an empty result, giving new messages a chance
|
||||
seconds (max 50) before returning an empty result, giving new messages a chance
|
||||
to arrive.
|
||||
|
||||
> **Note:** If a webhook is configured via `setWebhook`, updates are delivered
|
||||
> live to the webhook URL via POST instead of being queued for polling.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
@@ -277,13 +302,15 @@ Sends a **plaintext** message to a user or another bot.
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------|--------|--------------------------------------------------|
|
||||
| `chat_id` | string | Recipient fingerprint (hex) or Ethereum address. |
|
||||
| `text` | string | Plaintext message body. |
|
||||
| Field | Type | Description |
|
||||
|--------------|--------|-----------------------------------------------------------|
|
||||
| `chat_id` | string/int | Recipient fingerprint (hex), Ethereum address, or numeric ID. |
|
||||
| `text` | string | Message body. |
|
||||
| `parse_mode` | string | Optional. `"HTML"` renders basic tags (<b>, <i>, <code>, <a>). |
|
||||
|
||||
Non-hex characters in `chat_id` are stripped and the value is lowercased before
|
||||
routing.
|
||||
`chat_id` accepts hex fingerprint strings, Ethereum addresses, or numeric
|
||||
integer IDs (Telegram compatibility). Non-hex characters in string chat_ids are
|
||||
stripped and the value is lowercased before routing.
|
||||
|
||||
**Response:**
|
||||
|
||||
@@ -323,13 +350,15 @@ WebSocket connection (`true`) or queued for later retrieval (`false`).
|
||||
|
||||
| Feature | Telegram | featherChat |
|
||||
|---------|----------|-------------|
|
||||
| `chat_id` type | Numeric integer | Hex fingerprint string |
|
||||
| `getUpdates` timeout | Up to 50s | Capped at **5s** |
|
||||
| Message content | Always plaintext | Encrypted messages arrive as `raw_encrypted` base64; bot must decrypt if it has a session |
|
||||
| Bot-sent messages | Plaintext | Plaintext (not E2E encrypted) in v1 |
|
||||
| Inline keyboards / callback queries | Supported | Not yet (planned) |
|
||||
| `chat_id` type | Numeric integer | Hex fingerprint string or numeric integer (both accepted) |
|
||||
| `getUpdates` timeout | Up to 50s | Capped at **50s** |
|
||||
| Message content | Always plaintext | Encrypted messages arrive as `raw_encrypted` base64; E2E bots can decrypt |
|
||||
| Bot-sent messages | Plaintext | Plaintext by default; E2E mode available |
|
||||
| `from.id` | Numeric integer | Numeric integer (`from.id_str` has hex fingerprint) |
|
||||
| `parse_mode` | Renders HTML/Markdown | HTML rendered (<b>, <i>, <code>, <a>) |
|
||||
| Inline keyboards / callback queries | Supported | Stored + delivered, no popup |
|
||||
| Webhooks (`setWebhook`) | Supported | Implemented -- updates delivered live to webhook URL |
|
||||
| Media groups | Supported | Not yet (planned) |
|
||||
| Webhooks (`setWebhook`) | Supported | Not yet (planned) |
|
||||
| File download (`getFile`) | Supported | Not yet (planned) |
|
||||
|
||||
---
|
||||
@@ -344,7 +373,7 @@ TOKEN = "your_bot_token"
|
||||
API = f"http://localhost:7700/v1/bot/{TOKEN}"
|
||||
|
||||
while True:
|
||||
resp = requests.post(f"{API}/getUpdates", json={"timeout": 5}).json()
|
||||
resp = requests.post(f"{API}/getUpdates", json={"timeout": 50}).json()
|
||||
for update in resp.get("result", []):
|
||||
msg = update.get("message", {})
|
||||
text = msg.get("text") or "[encrypted]"
|
||||
@@ -392,10 +421,20 @@ like a password.**
|
||||
|
||||
---
|
||||
|
||||
## Bot Bridge (`tools/bot-bridge.py`)
|
||||
|
||||
A compatibility layer for existing Telegram bot libraries. Translates between
|
||||
featherChat Bot API and standard TG libraries (python-telegram-bot, aiogram,
|
||||
Telegraf). Handles differences like fingerprint-based chat_id, numeric ID
|
||||
translation, and webhook forwarding.
|
||||
|
||||
```bash
|
||||
python tools/bot-bridge.py --token YOUR_BOT_TOKEN --server http://localhost:7700
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Future Plans
|
||||
|
||||
- **Webhook mode** (`setWebhook`) -- push updates to a URL instead of polling.
|
||||
- **Inline keyboards and callback queries** -- interactive message buttons.
|
||||
- **E2E encrypted bot sessions** -- bots participate in X3DH key exchange.
|
||||
- **File send/receive APIs** -- `sendDocument`, `getFile`.
|
||||
- **Group bot support** -- bots in group chats with sender-key encryption.
|
||||
|
||||
Reference in New Issue
Block a user