Skip to content

Commit 47e2afb

Browse files
author
chaodu-agent
committed
docs: add inbound-attachments.md — unified cross-platform media reference
Covers architecture, platform support matrix, processing pipeline, size limits, storage security, and future HTTP proxy roadmap.
1 parent ec16ae8 commit 47e2afb

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

docs/inbound-attachments.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Inbound Attachments
2+
3+
How OAB handles images, audio, and files sent by users across all platforms.
4+
5+
## Architecture
6+
7+
```
8+
User sends media (photo/voice/file)
9+
→ Platform webhook delivers to Gateway
10+
→ Gateway downloads via platform API (auth stays in Gateway)
11+
→ Image: resize ≤1200px, JPEG compress (GIF passthrough ≤5MB)
12+
→ Store to ~/.openab/media/inbound/<uuid>
13+
→ WS event includes file path in attachments[].path
14+
→ Core reads from disk (zero encoding overhead)
15+
→ Processes: image → LLM, audio → STT, text_file → code block
16+
→ File auto-evicted after 2 minutes
17+
```
18+
19+
## Platform Support Matrix
20+
21+
| Platform | Images | Audio/Voice | Text Files | Video | Binary Files |
22+
|----------|--------|-------------|------------|-------|--------------|
23+
| **Discord** || ✅ (STT) || metadata only | skipped |
24+
| **Telegram** || ✅ (STT) | ✅ (whitelist) | skipped | skipped |
25+
| **Feishu** || ✅ (STT) | ✅ (whitelist) | skipped | skipped |
26+
| **Google Chat** || ✅ (STT) | ✅ (whitelist) | skipped | Drive files skipped |
27+
| **WeCom** ||| ✅ (whitelist) | skipped | skipped |
28+
| **LINE** | planned | planned ||||
29+
| **Slack** || ✅ (STT) ||| skipped |
30+
31+
## Processing Pipeline
32+
33+
### Images
34+
35+
1. Gateway downloads from platform API
36+
2. `resize_and_compress()` — longest side ≤1200px, JPEG quality 75
37+
3. GIFs ≤5MB passed through unchanged (preserves animation)
38+
4. Stored to `~/.openab/media/inbound/<uuid>`
39+
5. Core reads bytes → `ContentBlock::Image` → sent to LLM
40+
41+
### Audio / Voice Messages
42+
43+
1. Gateway downloads raw audio (ogg/m4a/mp3)
44+
2. Stored to filesystem (no transcoding)
45+
3. Core reads bytes → STT transcription (Whisper/Groq) → `[Voice message transcript]: ...`
46+
4. If STT disabled: silently skipped
47+
48+
### Text Files (Documents)
49+
50+
1. Gateway downloads file
51+
2. Extension whitelist check: `.txt`, `.csv`, `.md`, `.json`, `.yaml`, `.rs`, `.py`, `.js`, `.ts`, `.go`, `.java`, `.c`, `.cpp`, `.sh`, `.sql`, `.html`, `.css`, `.toml`, `.xml`, `.ini`, `.cfg`, `.conf`, etc.
52+
3. UTF-8 validation — non-UTF-8 files rejected
53+
4. Stored to filesystem
54+
5. Core reads → wraps in markdown code block: `` ```filename.ext\n<content>\n``` ``
55+
56+
### Unsupported Types
57+
58+
Binary files (zip, pdf, exe, docx), video, and stickers are **silently skipped**. The agent does not receive any notification that a file was sent.
59+
60+
## Size Limits
61+
62+
| Type | Max Size | Enforced By |
63+
|------|----------|-------------|
64+
| Images | 10 MB | Gateway (pre-download Content-Length + post-download bytes) |
65+
| Audio | 20 MB (gateway) / 25 MB (Feishu) | Gateway |
66+
| Text files | 512 KB | Gateway |
67+
| GIF passthrough | 5 MB | `resize_and_compress()` |
68+
| Store (defense-in-depth) | 20 MB | `store_media()` |
69+
70+
## Storage (Colocate Mode)
71+
72+
Media is stored at `~/.openab/media/inbound/<uuid>`:
73+
74+
- **Filenames**: Server-generated UUID v4, no extension (MIME type in event payload)
75+
- **TTL**: 2 minutes — background task evicts expired files every 30 seconds
76+
- **Trust boundary**: Gateway and Core share the same `$HOME` (same pod / sidecar)
77+
- **No auth required**: Core reads directly from filesystem, no HTTP/token needed
78+
79+
### Security
80+
81+
- **Path traversal**: Impossible — filenames are UUID only, never user-supplied
82+
- **Token leakage**: Platform auth tokens (Telegram bot token, LINE access token, Feishu tenant token) stay in Gateway, never reach Core or agent
83+
- **Disk exhaustion**: TTL eviction + size limits prevent unbounded growth
84+
- **No executable content**: Files are raw data, never executed
85+
86+
### Future: HTTP Proxy Mode
87+
88+
For separated deployments (Gateway ≠ Core pod), a future PR will add `GET /media/<uuid>` on the Gateway, allowing Core to fetch via internal HTTP. The `attachments[].path` field will be replaced by `attachments[].url` in that mode.
89+
90+
## Configuration
91+
92+
No additional configuration required. The filesystem store is always active when Gateway is running. Ensure Gateway and Core share the same `$HOME` (default in Helm colocate/sidecar mode).
93+
94+
## Related
95+
96+
- [Telegram](telegram.md) — Telegram-specific behavior and limitations
97+
- [Feishu](feishu.md) — Feishu image/file/audio handling
98+
- [Google Chat](google-chat.md) — Google Chat attachment support
99+
- [STT (Speech-to-Text)](stt.md) — Audio transcription configuration
100+
- [Sending Files (Outbound)](sendfiles.md) — Agent → user file delivery (separate mechanism)

0 commit comments

Comments
 (0)