Webhook
ภาพรวม (Overview)
Webhook ช่วยให้ระบบของคุณรับข้อมูลแบบ Real-time เมื่อเกิด Events ต่างๆ ในระบบ Humansoft โดยไม่ต้อง Poll API เป็นระยะ
Webhook จะส่ง HTTP POST request ไปยัง Callback URL ที่คุณกำหนดทุกครั้งที่เกิด Event ที่คุณ subscribe ไว้
การตั้งค่า Webhook
เข้าสู่หน้าตั้งค่า
เข้าสู่ระบบ HumanSoft แล้วไปที่เมนู:
ตั้งค่า → ตั้งค่าการเชื่อมต่อ → Webhook
หรือเข้าผ่านลิงก์โดยตรง: HMS Settings - Webhook
กำหนด Callback URL
ระบุ URL ที่ระบบของคุณจะรับ Webhook events เช่น:
https://your-domain.com/api/webhooks/humansoftข้อกำหนด Callback URL:
- ต้องเป็น HTTPS เท่านั้น
- ต้องสามารถรับ HTTP POST requests ได้
- ควรตอบกลับ HTTP 200 ภายใน 10 วินาที
เก็บ Secret Token
ระบบจะสร้าง Secret Token ให้คุณ ใช้สำหรับ validate ว่า request มาจาก Humansoft จริง
whse********5799สำคัญ: เก็บ Secret Token ไว้เป็นความลับ ห้ามเปิดเผยใน client-side code
เลือก Events ที่ต้องการรับ
เปิดใช้งาน Events ที่ต้องการรับผ่าน Webhook
Events ที่รองรับ
| Event Code | ชื่อ Event | คำอธิบาย |
|---|---|---|
employee.create | สร้างพนักงานใหม่ | เมื่อมีการสร้างข้อมูลพนักงานใหม่ในระบบ |
employee.purge | ลบข้อมูลพนักงาน | เมื่อมีการลบข้อมูลพนักงานออกจากระบบ |
employee.structure.change | พนักงานย้ายแผนก/ปรับตำแหน่ง | เมื่อพนักงานถูกย้ายแผนกหรือเปลี่ยนตำแหน่ง |
employee.terminate | พนักงานลาออก/พ้นสภาพ | เมื่อพนักงานลาออกหรือพ้นสภาพการเป็นพนักงาน |
test.ping | ทดสอบการเชื่อมต่อ | เมื่อกดปุ่มทดสอบในหน้าตั้งค่า |
ดูรายละเอียดและตัวอย่าง Payload ของแต่ละ Event ได้ที่ Webhook Events
Webhook Request Format
HTTP Headers
ทุก Webhook request จะมี Headers ดังนี้:
| Header | คำอธิบาย | ตัวอย่าง |
|---|---|---|
X-Webhook-ID | รหัสเฉพาะของ Webhook request นี้ | wh_abc123def456 |
X-Webhook-Event | ประเภท Event ที่เกิดขึ้น | employee.create |
X-Webhook-Timestamp | Unix timestamp ที่ส่ง request | 1705987200 |
X-Webhook-Signature | Signature สำหรับ validate request | sha256=abc123... |
Request Body
{
"request_id": "req_a90b78b79dadff88",
"event": "employee.create",
"event_occurred_at": "2025-01-23 10:00:00",
"body": {
// ข้อมูลเพิ่มเติมตาม Event
}
}Response Body Fields
| Field | Type | Description |
|---|---|---|
request_id | string | รหัสเฉพาะของ request นี้ |
event | string | ประเภท Event ที่เกิดขึ้น |
event_occurred_at | string | วันเวลาที่เกิด Event (YYYY-MM-DD HH:MM:SS) |
body | object | ข้อมูลรายละเอียดของ Event |
ตัวอย่าง Test Webhook (test.ping)
{
"request_id": "test_a90b78b79dadff88",
"event": "test.ping",
"event_occurred_at": "2025-01-23 12:07:42",
"body": {
"message": "This is a test webhook from HumanSoft API",
"timestamp": "2025-01-23T12:07:42+07:00",
"endpoint": {
"endpoint_id": "20250123FAC4DE16F4FE",
"endpoint_name": "Webhook"
}
}
}ตัวอย่าง Employee Create Event
{
"request_id": "req_b12c34d56e78f901",
"event": "employee.create",
"event_occurred_at": "2025-01-23 09:30:00",
"body": {
"employee_id": "20250123ABC123DEF456",
"employee_code": "EMP001",
"employee_name": "สมชาย ใจดี",
"department": "ฝ่ายทรัพยากรบุคคล",
"position": "พนักงานทั่วไป"
}
}การ Validate Webhook Signature
เพื่อความปลอดภัย คุณควร validate ทุก Webhook request ว่ามาจาก Humansoft จริง โดยใช้ HMAC SHA-256 Signature
วิธีการ Validate
- รับค่า
X-Webhook-Signatureจาก Header - สร้าง signature จาก request body + timestamp โดยใช้ Secret Token
- เปรียบเทียบ signature ที่ได้กับที่ได้รับมา
Algorithm
signature = HMAC-SHA256(
key: SECRET_TOKEN,
message: TIMESTAMP + "." + REQUEST_BODY
)Code Examples
JavaScript
const crypto = require('crypto')
function validateWebhookSignature(req) {
const signature = req.headers['x-webhook-signature']
const timestamp = req.headers['x-webhook-timestamp']
const body = JSON.stringify(req.body)
// ตรวจสอบ timestamp ไม่เก่าเกิน 5 นาที
const currentTime = Math.floor(Date.now() / 1000)
if (currentTime - parseInt(timestamp) > 300) {
throw new Error('Webhook timestamp expired')
}
// สร้าง signature
const payload = `${timestamp}.${body}`
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(payload)
.digest('hex')
// เปรียบเทียบ signature (timing-safe)
if (!crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)) {
throw new Error('Invalid webhook signature')
}
return true
}
// Express.js example
app.post('/api/webhooks/humansoft', (req, res) => {
try {
validateWebhookSignature(req)
const event = req.headers['x-webhook-event']
const data = req.body
switch (event) {
case 'employee.create':
handleEmployeeCreate(data)
break
case 'employee.terminate':
handleEmployeeTerminate(data)
break
// ... handle other events
}
res.status(200).json({ received: true })
} catch (error) {
console.error('Webhook error:', error.message)
res.status(400).json({ error: error.message })
}
})Best Practices
1. ตอบกลับอย่างรวดเร็ว
Webhook request มี timeout 10 วินาที ควรตอบกลับ HTTP 200 ทันที แล้วประมวลผลแบบ async
// ❌ ไม่ดี - ประมวลผลก่อนตอบกลับ
app.post('/webhook', async (req, res) => {
await processWebhook(req.body) // อาจใช้เวลานาน
res.status(200).send('OK')
})
// ✅ ดี - ตอบกลับทันที แล้วประมวลผลทีหลัง
app.post('/webhook', (req, res) => {
res.status(200).send('OK')
processWebhook(req.body) // ประมวลผล async
})2. จัดการ Duplicate Events
Webhook อาจส่งซ้ำในบางกรณี ใช้ X-Webhook-ID เพื่อตรวจสอบ:
const processedWebhooks = new Set()
app.post('/webhook', (req, res) => {
const webhookId = req.headers['x-webhook-id']
if (processedWebhooks.has(webhookId)) {
return res.status(200).json({ message: 'Already processed' })
}
processedWebhooks.add(webhookId)
// Process webhook...
})3. Validate ทุก Request
สำคัญมาก: ตรวจสอบ signature ทุกครั้งเพื่อป้องกัน request ปลอม
4. Log ทุก Webhook
app.post('/webhook', (req, res) => {
console.log({
webhookId: req.headers['x-webhook-id'],
event: req.headers['x-webhook-event'],
timestamp: req.headers['x-webhook-timestamp'],
body: req.body
})
// ...
})Retry Policy
หาก Callback URL ไม่ตอบกลับ HTTP 2xx ระบบจะ retry ตามนโยบายนี้:
| ครั้งที่ | รอ | หมายเหตุ |
|---|---|---|
| 1 | ทันที | Initial request |
| 2 | 1 วินาที | First retry |
| 3 | 2 วินาที | Second retry |
| 4 | 4 วินาที | Third retry |
หลังจาก retry ครบ 4 ครั้งแล้วยังไม่สำเร็จ ระบบจะหยุดส่งและบันทึกเป็น failed delivery
Testing Webhooks
ใช้ Webhook Testing Tools
- webhook.site - รับและดู webhook requests
- ngrok - Expose localhost เป็น public URL
ทดสอบจากหน้าตั้งค่า
ในหน้าตั้งค่า Webhook (ตั้งค่า → ตั้งค่าการเชื่อมต่อ → Webhook) สามารถกดปุ่ม “ทดสอบ” เพื่อส่ง test event (test.ping) ไปยัง Callback URL ของคุณ
Troubleshooting
Webhook ไม่ทำงาน
- ตรวจสอบว่า Callback URL เป็น HTTPS และเข้าถึงได้จาก internet
- ตรวจสอบว่าเปิดใช้งาน Events ที่ต้องการแล้ว
- ตรวจสอบ firewall ว่าอนุญาต incoming requests
Signature Validation Failed
- ตรวจสอบว่าใช้ Secret Token ถูกต้อง
- ตรวจสอบว่า body ไม่ถูก modify ก่อน validate
- ตรวจสอบ timestamp ไม่เก่าเกิน 5 นาที
ได้รับ Duplicate Events
ใช้ X-Webhook-ID header เพื่อ deduplicate ดู Best Practices