Skip to Content
操作指南自動化

建立 callback 驅動的自動化

這條流程把資料契約、after-commit automation 與 external write 串在一起:先以 rules 保護資料,再設定 trigger actions,mint 最小權限 callback token,讓外部系統寫入,最後以 trigger run 確認 downstream 結果。

1. 先發布 rules

至少為外部 natural key 建立 unique,再加上欄位格式或跨欄位契約:

{ "rules": [ { "type": "unique", "name": "ERP event ID 不可重複", "columns": ["ERP event ID"], "case_insensitive": false }, { "type": "check", "name": "數量不可為負", "column": "數量", "op": "gte", "value": 0 } ] }

依序呼叫 rules.get、rules.preview、rules.set。PUT 是 full replace;每張表最多 10 條。把 rules.get 的 rules_digest 當作 expected_rules_digest 送回,並行的修改就會回 409 rules_changed,而不是被覆寫。

2. 設定 after-commit trigger

{ "triggers": [ { "name": "同步已送出訂單", "on": "created", "when": [ { "column": "狀態", "op": "eq", "value": "已送出" } ], "actions": [ { "type": "api_call", "method": "POST", "url": "https://fulfillment.example/orders/$row.ERP event ID", "body": { "quantity": "$row.數量", "source": "custom-table" } } ] } ] }

請把 fulfillment.example 換成真正的公開 endpoint:api_call 的 host 會在儲存 trigger 時做 DNS 解析,且只能解析到公開位址,否則儲存會回 400 api_call url rejected: …。

以表格 moderator 身分先 triggers.get——trigger 設定只限 moderator 讀取——再以 triggers.set 發布完整清單,並保留每個 trigger 與 action 的 id。讀回這個 action 時會看到 "source": "__SECRET__":每個 api_call body 常值都是唯寫機密 slot,"$row.數量" 則仍然可見。回應中的 secrets 清單會依 trigger、action 與位置列出每個這種 slot。把佔位符送回會保留已儲存的值,省略 slot 也一樣,所以要移除時請送 null;若 action 的 scheme、host 或 port 改變了,保留會以 400 trigger_secret_keep_refused 被拒絕。Action 在來源 commit 後執行,失敗不會回滾 record;外部 endpoint 應能安全處理同一事件的重送。

Warning channel SCP table 不能設定 trigger,而 public callback 也沒有 acting room。這個架構可搭配 invariant,不能用在需要 per-room channel binding 的表。

3. Mint callback token

curl -X POST \ "$BASE_URL/private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/callback-tokens" \ -H "Authorization: Bearer $MODERATOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "ERP importer", "allowed_ops": "create", "valid_until": "2026-12-31T23:59:59" }'

External producer 只需新增時就選 "create",不要給 "create,update"。Secret 只出現一次,立即存入 secret manager;token 會以 minting moderator 作 write actor。細節見 callback token lifecycle。

4. External system 寫入

curl -X POST \ "$BASE_URL/public/module/custom_tables/callback/33333333-3333-4333-8333-333333333333" \ -H "Authorization: Bearer $CALLBACK_SECRET" \ -H "Content-Type: application/json" \ -d '{ "op": "create", "data": { "ERP event ID": "erp-1042", "狀態": "已送出", "數量": 3 }, "idempotency_key": "erp-1042" }'

保留同一 external event 的 idempotency_key;receipt 視窗(預設 24 小時)內重送會回原 accepted result,相同 key 搭配不同 body 則是 409 idempotency_key_reuse。Body 不可超過 65,536 bytes,每 token 每分鐘 60 requests。423 / transient 429 可在退避後用同一 key 重試;validation/unique error 必須修資料。

檢查 response 的 status:created 表示 record 已落地;held_for_approval / already_pending 是 2xx terminal outcomes,但 record 尚未落地。若另有 require_approval,trigger 要等 approved apply 真正 commit 後才會產生 run。

5. 觀察 trigger run

用 callback response 的 record_id 關聯 runs。Run 列表只能以 status、skip 與 limit 篩選,所以請逐頁讀取,並在用戶端比對每個 run 的 record_id:

curl \ "$BASE_URL/private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/trigger-runs?skip=0&limit=50" \ -H "Authorization: Bearer $MODERATOR_TOKEN"

狀態流程是 pending → running → done,或進入 failed。?status=stuck 是列表篩選條件——failed run,加上最後更新超過 300 秒仍在 running 的 run——不是儲存的狀態。保留 run.id、record_id、chain_id、attempts、error 與逐 action action_results 做可觀測性。單一 failed run 經確認後可呼叫 triggerRuns.retry;它會略過已成功 actions 並 resume。

6. 收尾與輪替

在 dashboard 追蹤 callback 4xx/423/429、run failed/stuck 與 downstream latency。輪替 token 時先部署新 token、驗證新流量,再 callbackTokens.revoke 舊 token。不要透過反覆 mint tokens 規避 rate limit。

要逐步走過 rules、triggers、callback mint 與 run observation,最後請開啟流程精靈。

Last updated on