Event Reference
每種 webhook 事件類型,以及 TicketWave 傳送的完整 payload。
Event Reference
每個端點最多可訂閱六種事件類型。每個請求都使用相同的封裝格式 — event、timestamp、guild_id 和 data — 只有 data 物件不同。
| Event | Fires when |
|---|---|
ticket.created | 建立票單時 |
ticket.closed | 票單關閉時 |
ticket.updated | 開啟中的票單有任何其他變更時 |
message.sent | 成員或工作人員在票單中發言時 |
blacklist.added | 成員被加入黑名單時 |
blacklist.removed | 黑名單項目被移除時 |
無法解析的欄位會以 null 傳送,而不是省略掉——因此你可以放心依賴這些 key 一定存在。當 Discord 沒有回傳使用者時,username 會是 null。
Shared fields
每個票單事件都會包含這些欄位:
| Field | Type | Description |
|---|---|---|
ticket_id | string | 依照你的樣板產生的可讀票單 ID,例如 ticket-1042 |
ticket_num_id | number | 票單的流水編號,例如 1042 |
channel_id | string | 票單對應的 Discord 頻道 |
category | string | null | 分類名稱;如果票單沒有分類則為 null |
user | object | null | 票單擁有者,格式為 { id, username } |
ticket.created
在票單頻道建立後立即送出。
{
"event": "ticket.created",
"timestamp": "2026-08-26T08:23:11.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1042",
"ticket_num_id": 1042,
"channel_id": "998877665544332211",
"category": "🤖 Support",
"user": { "id": "987654321098765432", "username": "Luna" },
"created_at": "2026-08-26T08:23:11.000Z"
}
}這會在票單開啟時觸發,也就是成員還沒輸入任何內容之前。如果你需要第一則訊息,也請同時監聽 message.sent。
ticket.closed
{
"event": "ticket.closed",
"timestamp": "2026-08-26T07:45:02.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1041",
"ticket_num_id": 1041,
"channel_id": "998877665544332211",
"category": "💸 Payment",
"user": { "id": "987654321098765432", "username": "Luna" },
"closed_by": { "id": "112233445566778899", "username": "Staff_01" },
"reason": "Issue resolved",
"closed_at": "2026-08-26T07:45:02.000Z"
}
}| Field | Type | Description |
|---|---|---|
closed_by | object | 是誰關閉的。自動關閉會回報 bot |
reason | string | null | 關閉原因;如果沒有提供則為 null |
ticket.updated
用來涵蓋開啟中票單的各種變更。action 會告訴你發生了什麼變更,changes 則包含該動作的詳細內容。
{
"event": "ticket.updated",
"timestamp": "2026-08-26T14:02:19.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1038",
"ticket_num_id": 1038,
"channel_id": "998877665544332211",
"category": "🤖 Support",
"user": { "id": "987654321098765432", "username": "Luna" },
"action": "ticket_priority:add",
"changes": { "priority": "high" },
"reason": null,
"updated_by": { "id": "112233445566778899", "username": "Staff_01" }
}
}Possible action values
action | Meaning | changes contains |
|---|---|---|
ticket_claim:add | 工作人員認領了票單 | (empty) |
ticket_unclaim:add | 取消認領 | (empty) |
ticket_priority:add | 優先級已變更 | priority |
ticket_rename:add | 頻道已重新命名 | new_name |
ticket_remind:add | 已送出提醒 | (empty) |
ticket_feedback:add | 成員為票單評分 | star_count, feedback |
ticket_schedule_close:add | 已排定關閉 | duration, schedule_time |
ticket_request_close:add | 工作人員請成員關閉票單 | duration, request_duration_time |
ticket_request_close_accept:add | 成員已接受 | (empty) |
ticket_request_close_deny:add | 成員已拒絕 | (empty) |
ticket_close_cancel:add | 進行中的關閉已取消 | (empty) |
ticket_additional_access:add | 已將使用者或角色加入票單 | entity_type, entity_id, reason |
ticket_additional_access:remove | 已移除使用者或角色 | entity_type, entity_id, reason |
請把這份清單視為開放式。隨著 TicketWave 成長,新的動作會持續加入,並且一律透過 ticket.updated 傳送。請只針對你在意的 actions 做處理,其他未知值直接忽略,不要因為未知值而拋出錯誤。
回答票單步驟時不會產生事件。否則一張有很多步驟的票單,當成員還在填表時就會把你的端點塞爆。
message.sent
在開啟中的票單內,每一則真人訊息都會送出。來自 bot 的訊息——包含 TicketWave 自己——都會被略過。
{
"event": "message.sent",
"timestamp": "2026-08-26T22:10:55.000Z",
"guild_id": "123456789012345678",
"data": {
"ticket_id": "ticket-1040",
"ticket_num_id": 1040,
"channel_id": "998877665544332211",
"message_id": "1234567890123456789",
"content": "Hello, how can I help you?",
"author": { "id": "112233445566778899", "username": "Staff_01" },
"is_staff": true,
"sent_at": "2026-08-26T22:10:55.000Z"
}
}| Field | Type | Description |
|---|---|---|
content | string | 原始訊息文字。若只有附件則為空 |
author | object | 傳送者的 { id, username } |
is_staff | boolean | 如果傳送者具有已設定的支援角色則為 true |
這是流量最高的事件,遠遠高於其他事件——繁忙的伺服器每則訊息都會產生一個請求。只有在你真的需要訊息層級資料時才訂閱,並確保你的接收端能快速回應。
blacklist.added
這個事件不屬於任何票單,因此這個 payload 沒有 ticket_id。
{
"event": "blacklist.added",
"timestamp": "2026-08-26T18:33:47.000Z",
"guild_id": "123456789012345678",
"data": {
"user": { "id": "111223344556677889", "username": "BadActor" },
"reason": "Spam",
"added_by": { "id": "112233445566778899", "username": "Staff_01" }
}
}blacklist.removed
{
"event": "blacklist.removed",
"timestamp": "2026-08-26T18:40:12.000Z",
"guild_id": "123456789012345678",
"data": {
"user": { "id": "111223344556677889", "username": "BadActor" },
"removed_by": { "id": "112233445566778899", "username": "Staff_01" }
}
}Test events
Send test event 按鈕會送出一個真實、已簽章的請求,而它的 data 只有:
{
"event": "ticket.created",
"timestamp": "2026-08-26T12:00:00.000Z",
"guild_id": "123456789012345678",
"data": { "test": true }
}event 會是該端點訂閱的第一種事件類型。如果你想在正式邏輯中略過測試送達,請檢查 data.test。
Next Steps
- Example Server(在 Express 中處理這些 payload)
- Webhooks(簽章、重試與送達歷史)
How is this guide?
