跳轉到主要內容

Webhook

Webhook 允許外部系統在 Kanera 中的工作變化時做出反應。

當另一個系統應該知道變更而不需要不斷呼叫 API 時,使用 webhook。 常見示例包括:

  • 更新外部儀表板。
  • 同步更改的卡片到另一個系統。
  • 觸發部署或審查工作流程。
  • 在審計系統中記錄 Kanera 活動。

要將卡片活動釋出到團隊聊天通道中,您不需要自己的 webhook。 Kanera 內建了 聊天通知目標 為 Slack, Discord, Telegram, 並 Zulip 當你需要完整的事件目錄、準確的有效載荷和簽名驗證時,可以使用 webhook。

工作區管理員可以從 工作區設定 -> API,在 自定義webhook 單獨的板有相同的 API 整合還可以透過公共 API 或 TypeScript SDK 註冊端點,並且可以在自身的板設定中註冊端點。

顯示 webhook 配置的 Workspace API 設定。

每個 webhook 目標都可以接收所有事件或僅接收選定的事件型別。 Leave eventTypes 空接收每個事件,或提供一個或多個事件型別字串如下所示。

計劃和許可權​

  • 工作區管理員可以檢視和管理該工作區中的每個通用 Webhook 端點。
  • 當端點的使用者是工作區成員時,具有寫入功能的 API 憑證或互動式 OAuth 代理可以在沒有管理員許可權的情況下注冊端點。該端點的範圍僅限於建立連線:只有相同的連線和工作區管理員才能檢視或管理它。讀取範圍的憑據無法管理 Webhook。
  • 網路鉤子需要 Pro 30天 Pro試用。它們在託管 Free 上不可用。
  • 在託管版 Free 套餐中,建立表單會替換為 您的計劃中不提供 Webhook.

撤銷憑據或代理連線還會刪除其連線範圍內的端點。 管理員建立的工作區端點保留,直到管理員刪除它們。

降級時會發生什麼​

當託管組織從 Pro 或試用版遷移到 Free 時,Kanera 會暫停每個啟用的 webhook 端點,而不是刪除任何內容。 它還會撤銷工作區 API 金鑰(私鑰仍然有效 ), 並禁用超出 Free 限制的自動化。

主機上 Free行為
現有終點自動暫停,並且當組織處於 Free 狀態時無法重新啟用它們。
新活動未到達您的端點。
還有什麼正在等待傳送記錄為失敗 webhooks are unavailable on the current plan 而不是遲到。
交付失敗無法手動重試。
配置和歷史記錄保留。 端點、事件選擇、秘密和交付歷史記錄都仍然存在。

升級回 Pro 版本會重新啟用因降級而暫停的端點,並恢復其撤銷的工作區 API 金鑰,因此無需重新構建恢復的整合。

透過程式設計註冊端點​

公共 API 會公開 Workspace 設定所使用的相同通用端點生命週期。

/api/v1/workspaces/{workspaceId}/webhooks
方法路徑使用
GET(基本路徑)列出呼叫者可見的端點。
POST(基本路徑)建立一個端點並返回其簽名秘密一次。
PATCH/{endpointId}更改其名稱、URL、事件過濾器或啟用狀態。
POST/{endpointId}/secret旋轉簽名秘密。
DELETE/{endpointId}刪除端點。
GET/{endpointId}/deliveries閱讀最近的交付嘗試。
POST/{endpointId}/deliveries/{deliveryId}/retry重試一次失敗的交付。

使用 TypeScript SDK,使用 kanera.webhookEndpoints.create(), .list(), .update(), .rotateSecret(), .deliveries(), .retryDelivery(), 和 .delete()。返回的端點有 scope: "workspace" 用於管理員管理的端點或 scope: "connection" 當非管理員憑據註冊它時。 secret 透過建立或旋轉立即返回;後續讀取從不暴露它。

Webhook 事件型別​

公共 API 將當前列表公開於:

https://api.kanera.app/webhook-event-types
面積事件型別
列表list:created, list:updated, list:moved, list:rebalanced, list:deleted
板隔板separator:created, separator:updated, separator:moved, separator:rebalanced, separator:deleted
自定義欄位customField:created, customField:updated, customField:moved, customField:rebalanced, customField:deleted
自定義欄位選項customFieldOption:created, customFieldOption:updated, customFieldOption:moved, customFieldOption:rebalanced, customFieldOption:deleted
卡片card:created, card:updated, card:moved, card:rebalanced, card:deleted
卡片自定義欄位card:customFieldValue:set, card:customFieldValue:cleared
卡片標籤和受讓人card:labels:set, card:assignees:set
卡片附件card:attachment:created, card:attachment:deleted
卡片清單card:checklist:created, card:checklist:updated, card:checklist:moved, card:checklist:rebalanced, card:checklist:deleted
卡清單專案card:checklistItem:created, card:checklistItem:updated, card:checklistItem:moved, card:checklistItem:rebalanced, card:checklistItem:deleted
工作區卡片標籤cardLabel:created, cardLabel:updated, cardLabel:moved, cardLabel:rebalanced, cardLabel:deleted
評論意見comment:created, comment:updated, comment:deleted
評論反應comment:reaction:added, comment:reaction:removed
卡片進給card:feedItem:created, card:feedItem:updated, card:feedItem:deleted
看板board:created, board:updated, board:moved, board:rebalanced, board:deleted
看板成員board:member:added, board:member:removed
工作區workspace:updated, workspace:deleted
工作區成員workspace:member:added, workspace:member:updated, workspace:member:removed
使用者user:profile:updated
筆記note:created, note:updated, note:moved, note:rebalanced, note:deleted, note:locked, note:unlocked
代理執行agentRun:started, agentRun:updated

有效載荷格式​

Kanera 將每個 webhook 作為 JSON 物件傳送,具有穩定的信封和事件特定性 data.

外地意義
id唯一的 webhook 事件 ID。 X-Kanera-Event-Id.
type事件型別,如 card:created.
workspaceId事件發生的工作區。
boardId當事件屬於看板範圍時,事件發生的看板。
cardId當事件有效負載識別出卡時,卡參與事件。
occurredAt事件發生時的 ISO 8601 時間戳。
data形狀取決於: type 並匹配相應的實時事件有效載荷。

代理執行的事件攜帶 { boardId, cardId, run } 在 data, 其中 run 是什麼原因導致了這種情況? agentName, 的 userId 它為什麼會這樣做? status, title, summary, externalUrl,及其 startedAt, heartbeatAt, 和 endedAt 時間戳。 agentRun:updated 對於每一個心跳以及狀態變化都會發射,所以請將您的處理器鍵入 run.status 一個停止心跳的執行作為最後一個步驟到達,而不是將每個交付作為新的工作。 agentRun:updated 與 status: "stalled".

例 子 card:created 有效載荷:

{
"id": "7e5c982a-e6c9-4ea7-9647-b14fe73ed50a",
"type": "card:created",
"workspaceId": "a069fd45-3bb3-4928-bac9-cb574a050d20",
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"cardId": "70c39cef-1aec-44e6-a8f5-f36f765a818d",
"occurredAt": "2026-05-28T12:34:56.000Z",
"data": {
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"card": {
"id": "70c39cef-1aec-44e6-a8f5-f36f765a818d",
"boardId": "48a52a55-763e-4c64-8a76-51ac56247f5c",
"listId": "3bb3c1b3-8fc7-4807-854d-2d5ff62df147",
"title": "Prepare kickoff agenda",
"position": "1000.0000000000"
}
}
}

網路鉤傳送​

Kanera 會以 JSON 形式傳送 webhook 交付,幷包含您可以用來驗證請求的報頭:

頭條意義
X-Kanera-Event-Id唯一事件 ID。
X-Kanera-TimestampUnix 時間戳(秒 ) 。
X-Kanera-Signaturesha256= 加上一個 HMAC-SHA256 簽名。

簽名是根據以下因素計算的:

${timestamp}.${rawBody}

使用 webhook 端點秘密。

當端點返回非 2xx 狀態或無法訪問時,Webhook 交付將重試。 Kanera 記錄交付歷史記錄,以便您可以檢視失敗、重試交付、暫停目標和從工作區 API 設定中輪換秘密。

驗證 webhook 簽名​

在信任有效載荷之前驗證簽名。

該 TypeScript SDK 為你做這件事,並且丟擲而不是返回一個布林值,這樣處理器就不會忘記檢查:

import { parseWebhook } from "@kanera/sdk";

app.post("/kanera/webhook", express.raw({ type: "application/json" }), async (req, res) => {
const event = await parseWebhook({
secret: process.env.KANERA_WEBHOOK_SECRET!,
payload: req.body, // the raw bytes
headers: req.headers,
});
// Handle event.type, event.workspaceId, event.boardId, event.cardId, and event.data.
res.sendStatus(204);
});

要自己驗證,請比較以上的 HMAC {timestamp}.{body} 注意長度檢查: crypto.timingSafeEqual 當兩個緩衝區的長度不同時,攻擊者會控制它們。

import crypto from "node:crypto";
import express from "express";

const app = express();

app.post("/kanera/webhook", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.header("X-Kanera-Timestamp") ?? "";
const signature = req.header("X-Kanera-Signature") ?? "";
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.KANERA_WEBHOOK_SECRET!)
.update(`${timestamp}.${req.body.toString("utf8")}`)
.digest("hex");

const received = Buffer.from(signature);
const digest = Buffer.from(expected);
if (received.length !== digest.length || !crypto.timingSafeEqual(received, digest)) {
return res.status(401).send("invalid signature");
}

const event = JSON.parse(req.body.toString("utf8"));
// Handle event.type, event.workspaceId, event.boardId, event.cardId, and event.data.
res.sendStatus(204);
});

始終根據原始請求正文進行驗證。如果您的框架在驗證之前解析 JSON,則簽名檢查可能會失敗或變得不可靠。

Kanera也傳送 X-Kanera-Timestamp 以及 X-Kanera-Event-Id。拒絕時間戳超出現在幾分鐘時間的交付以繫結重播,並使用事件 ID 使處理程式冪等,因為交付可能會重試。

Webhook 是通用路徑。 針對特定受眾群體,有兩種更狹窄的選項:

路徑觀眾有效載荷設定位置訂閱方案
Webhook另一個系統整個事件目錄中已簽名的 JSON工作區設定 -> APIPro或試用
聊天目的地團隊頻道格式化的訊息,適用於 Slack、Discord、Telegram 或 Zulip工作區設定 -> 整合Pro或試用
個人交付渠道1人ntfy、Gotify 或已簽名的 JSON 用於您自己的通知個人資料設定 -> 通知Pro或試用
MCP 活動訂閱AI代理的主機簽名卡和評論發生到回撥代理人驗證代理透過 MCP 訂閱;無需在 Kanera 中設定每個計劃

聊天目標與 Webhook 端點分開管理,並且不會出現在 Webhook 列表中,因此輪換 Webhook 機密絕不會影響聊天目標。

自動化的 呼叫網路鉤子 行動是有針對性的,而不是基於訂閱。 automation:webhook:called 只對規則中選擇的端點執行,而不管該端點的普通 eventTypes 過濾器,同時保持相同的簽名、重試和遞送歷史記錄行為。 自動化.