docs: update docs for Telegram integration
This commit is contained in:
69
docs/API.md
69
docs/API.md
@@ -288,6 +288,75 @@ Same stable attributes and methods as `Bot`:
|
||||
|
||||
---
|
||||
|
||||
## `derp.telegram` -- Telegram Adapter
|
||||
|
||||
Alternative bot adapter for Telegram via long-polling (`getUpdates`).
|
||||
All HTTP routed through SOCKS5 proxy. Exposes the same plugin API as
|
||||
`derp.bot.Bot` so protocol-agnostic plugins work without modification.
|
||||
|
||||
### `TelegramMessage` dataclass
|
||||
|
||||
Duck-typed compatible with IRC `Message`:
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `raw` | `dict` | Original Telegram Update |
|
||||
| `nick` | `str \| None` | Sender first_name (or username fallback) |
|
||||
| `prefix` | `str \| None` | Sender user_id as string (for ACL) |
|
||||
| `text` | `str \| None` | Message body (stripped of @bot suffix) |
|
||||
| `target` | `str \| None` | chat_id as string |
|
||||
| `is_channel` | `bool` | `True` for groups, `False` for DMs |
|
||||
| `command` | `str` | Always `"PRIVMSG"` (compat shim) |
|
||||
| `params` | `list[str]` | `[target, text]` |
|
||||
| `tags` | `dict[str, str]` | Empty dict (no IRCv3 tags) |
|
||||
|
||||
### `TelegramBot`
|
||||
|
||||
Same stable attributes and methods as `Bot`:
|
||||
|
||||
| Attribute | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| `name` | `str` | Always `"telegram"` |
|
||||
| `config` | `dict` | Merged TOML configuration |
|
||||
| `nick` | `str` | Bot display name (from `getMe`) |
|
||||
| `prefix` | `str` | Command prefix (from `[telegram]` or `[bot]`) |
|
||||
| `state` | `StateStore` | Persistent key-value storage |
|
||||
| `registry` | `PluginRegistry` | Shared command and event registry |
|
||||
|
||||
**Sending messages** -- same signatures, Telegram API transport:
|
||||
|
||||
| Method | Behaviour |
|
||||
|--------|-----------|
|
||||
| `send(target, text)` | `sendMessage` API call (proxied, rate-limited) |
|
||||
| `reply(msg, text)` | `send(msg.target, text)` |
|
||||
| `long_reply(msg, lines, *, label="")` | Paste overflow, same logic as IRC |
|
||||
| `action(target, text)` | Italic Markdown text via `sendMessage` |
|
||||
| `shorten_url(url)` | Same FlaskPaste integration |
|
||||
|
||||
**Message splitting**: messages > 4096 chars split at line boundaries.
|
||||
|
||||
**IRC no-ops** (debug log, no error):
|
||||
|
||||
`join`, `part`, `kick`, `mode`, `set_topic`
|
||||
|
||||
**Plugin management** -- delegates to shared registry:
|
||||
|
||||
`load_plugins`, `load_plugin`, `reload_plugin`, `unload_plugin`
|
||||
|
||||
**Permission tiers** -- same model, exact user_id string matching:
|
||||
|
||||
`_get_tier(msg)`, `_is_admin(msg)`
|
||||
|
||||
### Helper Functions
|
||||
|
||||
| Function | Signature | Description |
|
||||
|----------|-----------|-------------|
|
||||
| `_strip_bot_suffix` | `(text: str, bot_username: str) -> str` | Strip `@username` from command text |
|
||||
| `_build_telegram_message` | `(update: dict, bot_username: str) -> TelegramMessage \| None` | Parse Telegram Update into message |
|
||||
| `_split_message` | `(text: str, max_len: int = 4096) -> list[str]` | Split long text at line boundaries |
|
||||
|
||||
---
|
||||
|
||||
## Handler Signatures
|
||||
|
||||
All command and event handlers are async functions receiving `bot` and
|
||||
|
||||
@@ -504,6 +504,23 @@ Teams endpoint: `POST /api/messages`. HMAC-SHA256 auth via `Authorization: HMAC
|
||||
Replies returned as JSON in HTTP response. IRC-only commands (kick, ban, topic) are no-ops.
|
||||
~90% of plugins work without modification.
|
||||
|
||||
## Telegram Integration
|
||||
|
||||
```toml
|
||||
# config/derp.toml
|
||||
[telegram]
|
||||
enabled = true
|
||||
bot_token = "123456:ABC-DEF..." # from @BotFather
|
||||
poll_timeout = 30 # long-poll seconds
|
||||
admins = [123456789] # Telegram user IDs
|
||||
operators = []
|
||||
trusted = []
|
||||
```
|
||||
|
||||
Long-polling via `getUpdates` -- no public endpoint needed. All HTTP
|
||||
through SOCKS5 proxy. Strips `@botusername` suffix in groups. Messages
|
||||
split at 4096 chars. IRC-only commands are no-ops. ~90% of plugins work.
|
||||
|
||||
## Plugin Template
|
||||
|
||||
```python
|
||||
|
||||
@@ -1400,3 +1400,77 @@ The bot returns a JSON response:
|
||||
```
|
||||
|
||||
Multiple reply lines are joined with `\n`.
|
||||
|
||||
## Telegram Integration
|
||||
|
||||
Connect derp to Telegram via long-polling (`getUpdates`). All outbound HTTP
|
||||
is routed through the SOCKS5 proxy. No public endpoint required, no Telegram
|
||||
SDK dependency.
|
||||
|
||||
### How It Works
|
||||
|
||||
The bot calls `getUpdates` in a loop with a long-poll timeout (default 30s).
|
||||
When a message arrives with the configured prefix, it is dispatched through
|
||||
the shared plugin registry. Replies are sent immediately via `sendMessage`.
|
||||
|
||||
### Configuration
|
||||
|
||||
```toml
|
||||
[telegram]
|
||||
enabled = true
|
||||
bot_token = "123456:ABC-DEF..." # from @BotFather
|
||||
poll_timeout = 30 # long-poll timeout in seconds
|
||||
admins = [123456789] # Telegram user IDs (numeric)
|
||||
operators = [] # Telegram user IDs
|
||||
trusted = [] # Telegram user IDs
|
||||
```
|
||||
|
||||
### Telegram Setup
|
||||
|
||||
1. **Create a bot** via [@BotFather](https://t.me/BotFather):
|
||||
- `/newbot` and follow the prompts
|
||||
- Copy the bot token and set `bot_token` in config
|
||||
|
||||
2. **Add the bot** to a group or send it a DM
|
||||
|
||||
3. **Configure permissions** using Telegram user IDs. Use `!whoami` to
|
||||
discover your numeric user ID.
|
||||
|
||||
### Permission Tiers
|
||||
|
||||
Same 4-tier model as IRC, but matches exact Telegram user IDs (numeric
|
||||
strings) instead of fnmatch hostmask patterns:
|
||||
|
||||
```toml
|
||||
[telegram]
|
||||
admins = [123456789]
|
||||
operators = [987654321]
|
||||
trusted = [111222333]
|
||||
```
|
||||
|
||||
### Plugin Compatibility
|
||||
|
||||
Same compatibility as Teams -- ~90% of plugins work without modification.
|
||||
|
||||
| Feature | IRC | Telegram |
|
||||
|---------|-----|----------|
|
||||
| `bot.reply()` | Sends PRIVMSG | `sendMessage` API call |
|
||||
| `bot.send()` | Sends PRIVMSG | `sendMessage` API call |
|
||||
| `bot.action()` | CTCP ACTION | Italic Markdown text |
|
||||
| `bot.long_reply()` | Paste overflow | Paste overflow (same logic) |
|
||||
| `bot.state` | Per-server SQLite | Per-server SQLite |
|
||||
| `bot.join/part/kick/mode` | IRC commands | No-op (logged at debug) |
|
||||
| Event handlers (JOIN, etc.) | Fired on IRC events | Not triggered |
|
||||
| Hostmask ACL | fnmatch patterns | Exact user IDs |
|
||||
| Message limit | 512 bytes (IRC) | 4096 chars (Telegram) |
|
||||
|
||||
### Group Commands
|
||||
|
||||
In groups, Telegram appends `@botusername` to commands. The bot strips
|
||||
this automatically: `!help@mybot` becomes `!help`.
|
||||
|
||||
### Transport
|
||||
|
||||
All HTTP traffic (API calls, long-polling) routes through the SOCKS5
|
||||
proxy at `127.0.0.1:1080` via `derp.http.urlopen`. No direct outbound
|
||||
connections are made.
|
||||
|
||||
Reference in New Issue
Block a user