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

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

  • 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)