執行自動化
Webhook
任務結束或手機需要處理時,通知你的伺服器。
新增 Webhook
在控制台:設定 → 連線 → 事件 → Webhook。或透過 API:
訂閱
POST /v1/webhooks
{"url": "https://example.com/clousd", "events": ["run.completed", "run.failed"], "description": "orders bot"}
# → 201 {"webhook": {"id": "wh_3c1a", …}, "secret": "whsec_…"} the secret is shown onceevents 留空表示訂閱全部事件。一組金鑰最多可有十個 Webhook,每個都有自己的簽章密鑰。POST /v1/webhooks/{id}/rotate 產生新的簽章密鑰,/toggle 暫停傳送,/test 立即送出測試事件,GET …/deliveries 列出近期的傳送紀錄,含回應碼和時間。
事件
| 事件 | 觸發時機 |
|---|---|
| run.completed | 任務已完成;主體內含這次執行和它的結果。 |
| run.failed | 任務無法完成;主體會說明原因。 |
| run.cancelled | 任務已被停止。 |
| run.waiting | 任務暫停,等你回答問題或授權。 |
| device.problem | 手機健康檢查未通過。 |
| device.resolved | 問題已排除。 |
驗證簽章
每次傳送都是一個帶 JSON 主體的 POST,標頭為 X-Clousd-Signature: t=<unix time>,v1=<hex>,其中 hex 是以你的 Webhook 簽章密鑰對 "<t>.<raw body>" 計算的 HMAC-SHA256。請拒絕過舊的時間戳記,以防重送攻擊。
Python
import hashlib, hmac, time
def valid(body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t, sig = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > tolerance:
return False
mac = hmac.new(secret.encode(), t.encode() + b"." + body, hashlib.sha256).hexdigest()
return hmac.compare_digest(mac, sig)重試
每個事件最多傳送四次:立即一次,之後在 30 秒、5 分鐘和 30 分鐘後各一次。回應任何 2xx 即表示確認。主體為 {"id", "type", "created", "data"},同一個 id 也會放在 X-Clousd-Event-Id:如果某次成功回應較慢、之後又收到重試,略過已處理過的 id 即可。連續 20 次傳送失敗後,Webhook 會自動暫停;可在控制台或用 /toggle 重新開啟。