Webhook
ภาพรวม (Overview)
Webhook ช่วยให้ระบบของคุณรับข้อมูลแบบ Real-time เมื่อเกิด Events ต่างๆ ในระบบ Humansoft โดยไม่ต้อง Poll API เป็นระยะ
Webhook จะส่ง HTTP POST request ไปยัง Callback URL ที่คุณกำหนดทุกครั้งที่เกิด Event ที่คุณ subscribe ไว้
การตั้งค่า Webhook
เปิดเมนูตั้งค่าการเชื่อมต่อ
ก่อนตั้งค่า Webhook ต้องเปิดเมนู ตั้งค่าการเชื่อมต่อ ให้กับกลุ่มผู้ใช้ที่ต้องการก่อน โดยต้องใช้สิทธิ์ HR หรือ Admin เท่านั้น
ไปที่ ตั้งค่า → ตั้งค่าผู้ใช้ → ตั้งค่ากลุ่มผู้ใช้ จากนั้นติ๊กเปิดสิทธิ์ ตั้งค่าการเชื่อมต่อ → 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