Asana 出站 Webhook
將 Webhook 視為基礎設施:專案/團隊資源綁定到一個穩定 https:// 主機名(僅網關對外),換 Xcode 或擴節點不改 URL。
- 步驟 1. 在 Asana 開發者應用建立 Webhook,
POST目標指向網關專用路徑(單獨 location、合理本文大小上限)。 - 步驟 2. 完成握手:依文件將請求中的
X-Hook-Secret原樣帶回回應標頭並回200/204,再把該值持久化為後續X-Hook-Signature所用金鑰。 - 步驟 3. 在設定檔過濾事件:僅在任務進入約定欄位/區段或自訂欄位符合時入佇列;其餘在驗簽通過後快速
200略過。
簽名驗證
先驗簽、再解析。X-Hook-Signature 為原始本文之 HMAC-SHA256 十六進位;先 JSON.parse 再 stringify 常在負載下弄壞摘要。
- 步驟 1. 緩衝完整原始位元組,以握手所得密鑰計算 HMAC,與標頭常數時間比對。
- 步驟 2. 不符回
401,日誌只留 delivery id、路由、位元組長度等去識別欄位。 - 步驟 3. 解析後以
resource.gid + action + 時間窗或平台 delivery id 做冪等;僅在入佇列已持久化後回200,重試語意可對齊 任務佇列重試步驟。
OpenClaw 網關路由
路由表把「Asana 說了什麼」對應成池內任一台 Mac 可執行的正規化任務(含 task_gid、儲存庫、ref、idempotency_key)。僅網關持密;工作者只 dequeue 與回報完成事件。拓撲與 TLS 分工見 多節點部署指南。
- 步驟 1. 推入共享佇列時附
correlation_id;為 Webhook 預留併發與連線上限,避免尖峰餓死其他回呼(可一併參考 網關限流與工作階段併發)。 - 步驟 2. 完成後由節點附
mesh_node_id發內部事件,網關統一對外廣播,避免每機各發一則聊天訊息。
多節點通知模板
由網關單一模板組裝 JSON 或聊天 Webhook 載荷,欄位固定便於去重:build_id、task_gid、標題、mesh_node_id、status(queued/running/succeeded/failed)、duration_ms、exit_code、截斷的 log_tail。失敗時網關另組執行摘要(首行結果、次行可能原因、日誌連結),以 Asana REST 寫入任務留言;細日誌進物件儲存或日誌棧,不必貼進 Asana。
401/429 排錯 FAQ
- 呼叫網關 URL 得到 401
- 屬入站簽章:密鑰與握手時不一致、WAF 改寫本文、或 gzip/Unicode 正規化改變位元組。對 staging 擷取失敗請求,比對 raw 長度與簽章輸入。
- 只有回寫留言時 401
- 屬出站 API:權杖過期、工作區不符、或缺少建立故事權限。修正後再重試,勿無限重試 401。
- Asana REST 或聊天 Webhook 回 429
- 遵守
Retry-After,否則指數退避加抖動並設上限;多節點同時紅燈時由網關集中出站,同一build_id結果去重,避免蜂擁。
要訣:單一對外 URL、raw body 驗簽、持久化後才 200、網關統一模板與摘要回寫、401/429 分流入站/出站治理。