Files
claw-email/docs/specs/2026-04-24-email-openclaw-bridge-design.md
T
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

92 lines
2.7 KiB
Markdown

# 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
- `IGNORED`
- `RECEIVED`
- `AI_PROCESSING`
- `CALLBACK_DONE`
- `SMTP_RETRYING`
- `COMPLETED`
- `FAILED`
### 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 0`
- `attempt_smtp INTEGER DEFAULT 0`
- `last_error TEXT NULL`
- `next_retry_at DATETIME NULL` (used only if retry scheduling is asynchronous)
## 3) API Contracts & Security
### OpenClaw callback contract
Required fields:
- `metadata.task_uuid`
- `result` (text)
- `status`
### Webhook authentication (KISS)
- Bridge requires header `X-Bridge-Token` on 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 returns `200` and skips updates.
### Health endpoints behavior
- `GET /healthz` -> `200 {"status":"ok"}` when process is alive.
- `GET /readyz` checks:
- DB writable
- required config present (IMAP/SMTP/OpenClaw/token)
- Returns `503` on any failed check.
## 4) Acceptance Criteria
1. Valid incoming email eventually reaches `COMPLETED` and reply preserves email thread headers.
2. OpenClaw/SMTP transient failures retry with exact backoff sequence 1s, 5s, 15s.
3. Exhausted retries result in `FAILED` with `last_error` populated.
4. Anti-loop, whitelist, and idempotency behavior work as defined.
## 5) Test Matrix (v1)
1. Happy path: new mail -> valid callback -> SMTP success -> `COMPLETED`.
2. OpenClaw fails twice then succeeds -> `COMPLETED`, `attempt_openclaw=3`.
3. SMTP fails all retries -> `FAILED`, `last_error` present.
4. Callback with invalid token -> `401`, no task state change.
5. Duplicate `message_id` -> no new task created.
6. System sender or non-whitelisted sender -> `IGNORED`.
## 6) Logging (minimum)
Structured logs must include:
- `task_uuid`
- `thread_id`
- `message_id`
- `status`
- `attempt`
- `error` (when present)