ข้อมูลอ้างอิงอีเวนต์
ทุกประเภทของอีเวนต์ webhook และ payload ที่แน่นอนที่ TicketWave ส่งมา
ข้อมูลอ้างอิงอีเวนต์
สามารถสมัครรับอีเวนต์ได้ 6 ประเภทต่อหนึ่ง endpoint คำขอทุกครั้งจะใช้ envelope เดียวกัน — event, timestamp, guild_id และ data — โดยมีเพียงอ็อบเจ็กต์ data ที่แตกต่างกัน
| Event | Fires when |
|---|---|
ticket.created | มีการเปิดตั๋ว |
ticket.closed | มีการปิดตั๋ว |
ticket.updated | มีการเปลี่ยนแปลงอย่างอื่นในตั๋วที่เปิดอยู่ |
message.sent | สมาชิกหรือสตาฟเขียนข้อความในตั๋ว |
blacklist.added | มีการเพิ่มสมาชิกเข้าแบล็กลิสต์ |
blacklist.removed | มีการยกเลิกรายการแบล็กลิสต์ |
ฟิลด์ที่ไม่สามารถ resolve ได้จะถูกส่งเป็น null แทนที่จะถูกละไว้ — ดังนั้นคุณจึงมั่นใจได้ว่าคีย์เหล่านี้มีอยู่เสมอ username จะเป็น null เมื่อ Discord ไม่ได้ส่งข้อมูลผู้ใช้กลับมา
ฟิลด์ที่ใช้ร่วมกัน
อีเวนต์ของตั๋วทุกอันจะมีฟิลด์เหล่านี้:
| Field | Type | Description |
|---|---|---|
ticket_id | string | ไอดีตั๋วแบบอ่านได้จากแพตเทิร์นของคุณ เช่น 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 | ใครเป็นผู้ปิดตั๋ว การปิดอัตโนมัติจะรายงานเป็นบอท |
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" }
}
}ค่าที่เป็นไปได้ของ action
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 เติบโต จะมีการเพิ่ม action ใหม่ ๆ และจะส่งมาในรูปแบบ ticket.updated ให้สลับจัดการเฉพาะ action ที่คุณสนใจ และเพิกเฉยรายการอื่นแทนที่จะ throw เมื่อเจอค่าที่ไม่รู้จัก
การตอบคำถามในขั้นตอนของตั๋วจะ ไม่ สร้างอีเวนต์ขึ้นมา เพราะไม่เช่นนั้นตั๋วที่มีหลายขั้นตอนจะส่งคำขอถล่ม endpoint ของคุณในขณะที่สมาชิกยังกรอกฟอร์มอยู่
message.sent
ส่งสำหรับทุกข้อความจากมนุษย์ภายในตั๋วที่เปิดอยู่ ข้อความจากบอท — รวมถึง 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 คือประเภทแรกที่ endpoint สมัครรับไว้ หากต้องการข้ามการส่งทดสอบใน logic ฝั่ง production ให้ตรวจสอบ data.test
ขั้นตอนถัดไป
- Example Server (จัดการ payload เหล่านี้ใน Express)
- Webhooks (การลงลายเซ็น, retries และประวัติการส่ง)
How is this guide?
