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>
49 lines
1.6 KiB
Markdown
49 lines
1.6 KiB
Markdown
# Checkpoint 004 — Callback Handler
|
|
|
|
**Ngày:** 2026-04-24
|
|
**Trạng thái:** ✅ Hoàn thành
|
|
**Verify:** `go build ./...` thành công
|
|
|
|
---
|
|
|
|
## Việc đã làm
|
|
|
|
### Callback Handler (`internal/api/router.go`)
|
|
|
|
**Endpoint:** `POST /callback`
|
|
|
|
**Xác thực (requirements 5.2):**
|
|
- Middleware `tokenAuthMiddleware` kiểm tra header `X-Bridge-Token`
|
|
- Thiếu hoặc sai token → `401 Unauthorized`
|
|
- Log warning kèm `remote_addr`
|
|
|
|
**Xử lý callback (requirements 4.3 + 5.1):**
|
|
- Parse payload: `metadata.task_uuid` (required), `result` (required), `status`
|
|
- Tìm task theo `task_uuid` → 404 nếu không tìm thấy
|
|
- **Idempotent:** task đã `COMPLETED` → trả `200 {"status":"already_completed"}`, không thay đổi gì
|
|
- Cập nhật `ai_response = result`, `status = CALLBACK_DONE`
|
|
- Gọi async `onDone(task)` sau khi trả response (hook cho SMTP egress)
|
|
|
|
**API Signature thay đổi:**
|
|
- `NewRouter(db, callbackToken, onDone)` — thêm param `OnCallbackDone` callback
|
|
- `main.go` truyền `nil` tạm (sẽ wire SMTP egress ở bước sau)
|
|
|
|
---
|
|
|
|
## Files thay đổi
|
|
|
|
- **Rewrite:** `internal/api/router.go` (thêm callback handler + token auth middleware)
|
|
- **Cập nhật:** `cmd/bridge/main.go` (cập nhật signature `NewRouter`)
|
|
|
|
## Pipeline hiện tại
|
|
|
|
```
|
|
IMAP IDLE → RECEIVED → AI_PROCESSING → (OpenClaw callback) → CALLBACK_DONE → ???
|
|
↓
|
|
[chờ SMTP egress]
|
|
```
|
|
|
|
## Tiếp theo
|
|
|
|
1. **SMTP Egress** — gửi reply email với In-Reply-To/References + retry 3 lần
|