docs: update docs for Teams integration

- USAGE.md: Teams Integration section (config, setup, compat matrix)
- CHEATSHEET.md: Teams config snippet
- API.md: TeamsBot and TeamsMessage reference
- README.md: Teams in features list
- ROADMAP.md: v2.1.0 milestone
- TODO.md/TASKS.md: Teams items

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-21 19:52:39 +01:00
parent 014b609686
commit 4a165e8b28
7 changed files with 221 additions and 2 deletions

View File

@@ -1301,3 +1301,102 @@ timeout = 10 # HTTP fetch timeout
max_urls = 3 # max URLs to preview per message
ignore_hosts = [] # additional hostnames to skip
```
## Teams Integration
Connect derp to Microsoft Teams via outgoing webhooks. The bot runs an HTTP
server that receives messages from Teams and replies inline. No Microsoft SDK
required -- raw asyncio HTTP, same pattern as the webhook plugin.
### How It Works
1. **Outgoing webhook** (Teams -> bot): Teams POSTs an Activity JSON to the
bot's HTTP endpoint when a user @mentions the bot. The bot dispatches the
command through the shared plugin registry and returns the reply as the
HTTP response body.
2. **Incoming webhook** (bot -> Teams, optional): For proactive messages
(alerts, subscriptions), the bot POSTs to a Teams incoming webhook URL.
### Configuration
```toml
[teams]
enabled = true
bot_name = "derp" # outgoing webhook display name
bind = "127.0.0.1" # HTTP listen address
port = 8081 # HTTP listen port
webhook_secret = "" # HMAC-SHA256 secret from Teams
incoming_webhook_url = "" # for proactive messages (optional)
admins = [] # AAD object IDs (UUID format)
operators = [] # AAD object IDs
trusted = [] # AAD object IDs
```
### Teams Setup
1. **Create an outgoing webhook** in a Teams channel:
- Channel settings -> Connectors -> Outgoing Webhook
- Set the callback URL to your bot's endpoint (e.g.
`https://derp.example.com/api/messages`)
- Copy the HMAC secret and set `webhook_secret` in config
2. **Expose the bot** via Cloudflare Tunnel or reverse proxy:
```bash
cloudflared tunnel --url http://127.0.0.1:8081
```
3. **Configure permissions** using AAD object IDs from the Activity JSON.
The AAD object ID is sent in `from.aadObjectId` on every message. Use
`!whoami` to discover your ID.
### Permission Tiers
Same 4-tier model as IRC, but matches exact AAD object IDs instead of
fnmatch hostmask patterns:
```toml
[teams]
admins = ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
operators = ["yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"]
trusted = ["zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"]
```
### Plugin Compatibility
~90% of plugins work on Teams without modification -- any plugin that uses
only `bot.send()`, `bot.reply()`, `bot.state`, `message.text`, `.nick`,
and `.target`.
| Feature | IRC | Teams |
|---------|-----|-------|
| `bot.reply()` | Sends PRIVMSG | Appends to HTTP response |
| `bot.send()` | Sends PRIVMSG | POSTs to incoming webhook |
| `bot.action()` | CTCP ACTION | Italic text via incoming webhook |
| `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 AAD object IDs |
| Passive monitoring | All channel messages | @mention only |
### HMAC Verification
Teams outgoing webhooks sign requests with HMAC-SHA256. The secret is
base64-encoded when you create the webhook. The `Authorization` header
format is `HMAC <base64(hmac-sha256(b64decode(secret), body))>`.
If `webhook_secret` is empty, no authentication is performed (useful for
development but not recommended for production).
### Endpoint
Single endpoint: `POST /api/messages`
The bot returns a JSON response:
```json
{"type": "message", "text": "reply text here"}
```
Multiple reply lines are joined with `\n`.