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>
2.7 KiB
2.7 KiB
Email-OpenClaw Bridge v1 Design (KISS)
1) Scope & Non-goals
Scope v1
- IMAP ingest -> OpenClaw dispatch -> callback -> SMTP reply.
- Stateful processing with SQLite.
- Thread handling via
thread_id. - Idempotency by
message_id. - Health endpoints:
GET /healthz(liveness)GET /readyz(readiness)
- Retry mechanism:
- OpenClaw dispatch retries: 3 attempts with backoff 1s, 5s, 15s.
- SMTP send retries: 3 attempts with backoff 1s, 5s, 15s.
Non-goals v1
- No rate limiting.
- No DLQ / reprocess UI.
- No advanced metrics stack.
2) State Machine & Schema
Task states
IGNOREDRECEIVEDAI_PROCESSINGCALLBACK_DONESMTP_RETRYINGCOMPLETEDFAILED
Retry rules
- OpenClaw dispatch failure: retry 3 times (1s, 5s, 15s). Exhausted retries ->
FAILED. - SMTP send failure: transition to
SMTP_RETRYING, retry 3 times (1s, 5s, 15s). Exhausted retries ->FAILED. - Persist final failure reason in
last_error.
SQLite schema updates (tasks)
attempt_openclaw INTEGER DEFAULT 0attempt_smtp INTEGER DEFAULT 0last_error TEXT NULLnext_retry_at DATETIME NULL(used only if retry scheduling is asynchronous)
3) API Contracts & Security
OpenClaw callback contract
Required fields:
metadata.task_uuidresult(text)status
Webhook authentication (KISS)
- Bridge requires header
X-Bridge-Tokenon callback requests. - Expected secret is configured in
.env(e.g.,BRIDGE_CALLBACK_TOKEN). - Missing/invalid token ->
401 Unauthorized.
Callback idempotency
- If task already in
COMPLETED, callback handler returns200and skips updates.
Health endpoints behavior
GET /healthz->200 {"status":"ok"}when process is alive.GET /readyzchecks:- DB writable
- required config present (IMAP/SMTP/OpenClaw/token)
- Returns
503on any failed check.
4) Acceptance Criteria
- Valid incoming email eventually reaches
COMPLETEDand reply preserves email thread headers. - OpenClaw/SMTP transient failures retry with exact backoff sequence 1s, 5s, 15s.
- Exhausted retries result in
FAILEDwithlast_errorpopulated. - Anti-loop, whitelist, and idempotency behavior work as defined.
5) Test Matrix (v1)
- Happy path: new mail -> valid callback -> SMTP success ->
COMPLETED. - OpenClaw fails twice then succeeds ->
COMPLETED,attempt_openclaw=3. - SMTP fails all retries ->
FAILED,last_errorpresent. - Callback with invalid token ->
401, no task state change. - Duplicate
message_id-> no new task created. - System sender or non-whitelisted sender ->
IGNORED.
6) Logging (minimum)
Structured logs must include:
task_uuidthread_idmessage_idstatusattempterror(when present)