Full pipeline: IMAP ingress -> OpenClaw dispatch -> callback -> SMTP reply. SQLite stateful storage with idempotency, threading, and retry logic. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3.0 KiB
3.0 KiB
Checkpoint 002 — IMAP Ingress
Ngày: 2026-04-24
Trạng thái: ✅ Hoàn thành
Verify: go build ./... thành công
Việc đã làm
1. Task Repository (internal/database/repository.go)
Thêm các helper function cho CRUD operations:
FindByMessageID— lookup cho idempotency checkFindLatestByThreadID— tìm task COMPLETED gần nhất trong threadFindByTaskUUID— lookup cho callback handlerThreadHistory— lấy toàn bộ history thread (cho OpenClaw context)CreateTask,UpdateTask— CRUD cơ bản
2. IMAP Watcher (internal/mail/imap.go)
Module chính cho Ingress, bao gồm:
Kết nối & IDLE:
DialTLS→ Login → Select INBOX- IDLE loop với timer 28 phút (RFC recommends < 29 min)
- Auto-reconnect sau 10s khi mất kết nối
- Graceful shutdown qua
context.Context UnilateralDataHandlernhận notification khi có email mới
Xử lý email (đúng 5 bước theo requirements 4.1):
- Anti-loop: sender ==
SYSTEM_EMAIL→IGNORED - Whitelist: sender không trong danh sách →
IGNORED(empty whitelist = cho phép tất cả) - Idempotency:
message_idđã tồn tại → skip - Threading: parse
In-Reply-Toheader → tìm parent task → kế thừathread_id - Save: tạo task
status = RECEIVED
Extras:
- Fetch UNSEEN messages on startup (xử lý email đến trong lúc offline)
- Mark
\Seensau khi xử lý xong - Lưu task IGNORED vào DB cho audit
- Parse body parts qua
go-messageđể lấy plain text - Hook
OnReceivedcho dispatch (chưa wire)
3. Entrypoint (cmd/bridge/main.go)
- Chạy IMAP watcher + HTTP server concurrently
- Graceful shutdown qua SIGINT/SIGTERM
sync.WaitGroupđợi cả hai goroutine
Dependencies mới
github.com/emersion/go-imap/v2 v2.0.0-beta.8
github.com/emersion/go-message v0.18.2
github.com/google/uuid (for task_uuid generation)
Quyết định thiết kế
| Quyết định | Lý do |
|---|---|
| go-imap v2 thay vì v1 | IDLE tích hợp sẵn, API hiện đại hơn, dự án mới nên dùng v2 |
| IDLE timer 28 min | RFC recommends < 29 min, close + reopen IDLE để tránh server timeout |
| Fetch UNSEEN on startup | Xử lý email đến lúc bridge offline |
| Empty whitelist = allow all | UX tốt hơn: không cấu hình whitelist thì mặc định chấp nhận mọi sender |
| Lưu IGNORED vào DB | Auditability: biết email nào bị bỏ qua và lý do |
UnilateralDataHandler |
Nhận notification realtime khi mailbox thay đổi (không cần polling) |
Files thay đổi
- Mới:
internal/database/repository.go - Mới:
internal/mail/imap.go - Cập nhật:
cmd/bridge/main.go(IMAP watcher + graceful shutdown) - Xóa:
internal/mail/mail.go(stub cũ)
Tiếp theo
- OpenClaw Dispatch — wire
OnReceived→ HTTP POST to OpenClaw - Callback handler —
POST /callback+ token auth - SMTP Egress — gửi reply với In-Reply-To/References