Files
thuanleandClaude Opus 4.7 8815c20c13 Initial commit: email-openclaw bridge v1
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>
2026-04-27 18:16:57 +07:00

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 check
  • FindLatestByThreadID — tìm task COMPLETED gần nhất trong thread
  • FindByTaskUUID — lookup cho callback handler
  • ThreadHistory — 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
  • UnilateralDataHandler nhận notification khi có email mới

Xử lý email (đúng 5 bước theo requirements 4.1):

  1. Anti-loop: sender == SYSTEM_EMAILIGNORED
  2. Whitelist: sender không trong danh sách → IGNORED (empty whitelist = cho phép tất cả)
  3. Idempotency: message_id đã tồn tại → skip
  4. Threading: parse In-Reply-To header → tìm parent task → kế thừa thread_id
  5. Save: tạo task status = RECEIVED

Extras:

  • Fetch UNSEEN messages on startup (xử lý email đến trong lúc offline)
  • Mark \Seen sau khi xử lý xong
  • Lưu task IGNORED vào DB cho audit
  • Parse body parts qua go-message để lấy plain text
  • Hook OnReceived cho 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

  1. OpenClaw Dispatch — wire OnReceived → HTTP POST to OpenClaw
  2. Callback handlerPOST /callback + token auth
  3. SMTP Egress — gửi reply với In-Reply-To/References