พจนานุกรมปูพื้นฐานเรื่อง Webhook & Callback (Webhook Dictionary)
ปูพื้นฐานคำศัพท์เฉพาะทางเกี่ยวกับการส่งสัญญาณแจ้งเตือนเหตุการณ์ให้แจ่มแจ้งกันก่อน:
การตั้งระบบรอรับข่าวสารที่เซิร์ฟเวอร์ปลายทางเป็นคนยิงข้อความมาหาเราเองเมื่อมีเหตุการณ์สำคัญเกิดขึ้น (เปรียบเหมือนบริการส่งอาหาร Delivery ที่ไรเดอร์โทรหาเมื่อถึงบ้าน)
การเขียนโค้ดลูปสั่งให้แอปพลิเคชันของคุณวิ่งไปถามเซิร์ฟเวอร์ย้ำๆ ทุกๆ 3-5 วินาทีว่างานเสร็จหรือยัง ซึ่งสิ้นเปลืองเน็ตและทรัพยากรเบราว์เซอร์มาก
สถานการณ์จำเพาะเจาะจงที่เกิดขึ้น เช่น ลูกค้าสแกนจ่ายเงินเสร็จเรียบร้อย, มีคนพิมพ์แชท LINE หาบอท หรือโปรแกรมเมอร์เซฟอัปเดตไฟล์โค้ดใหม่
โค้ดรหัสลับเข้ารหัสที่ยิงพ่วงมาใน Header เพื่อใช้ยืนยันกับโค้ดหลังบ้านของเราว่าข้อมูลที่ทักมานั้นส่งมาจากผู้ให้บริการจริง ไม่ใช่มีคนแฮกมาส่งข้อความปลอม
1ทำไม API ปกติถึงไม่ตอบโจทย์ทุกอย่าง?
ในบทเรียนที่แล้ว เราใช้ API ปกติ (REST API) เพื่อดึงข้อมูลสภาพอากาศ ซึ่งเซิร์ฟเวอร์สามารถตอบได้ทันทีในเสี้ยววินาที แต่ในโลกแห่งความเป็นจริง มีหลายงานที่ "ไม่สามารถเสร็จได้ในทันที" ตัวอย่างเช่น:
- การให้ AI ประมวลผลวิดีโอความยาว 1 ชั่วโมง (อาจใช้เวลา 20 นาที)
- การสั่งพิมพ์เสื้อยืดจากโรงงาน (อาจใช้เวลา 3 วัน)
- การตัดบัตรเครดิตที่ต้องรอให้ธนาคารส่ง OTP เข้ามือถือลูกค้า (อาจใช้เวลา 1-5 นาที)
วิธีแก้แบบกำปั้นทุบดิน (Polling)
สมัยก่อน โปรแกรมเมอร์แก้ปัญหาด้วยการใช้วิธี Polling (การถามย้ำๆ) คือการเขียนลูป (Loop) ให้แอปของเราวิ่งไปถามเซิร์ฟเวอร์ทุกๆ 5 วินาที
(ผ่านไป 5 วินาที)
เรา: "เสร็จยังอะ?" → ธนาคาร: "ยังจ้า"
(ผ่านไป 5 วินาที)
เรา: "ตอนนี้ล่ะ?" → ธนาคาร: "เออ เสร็จละ!"
ลองคิดดูว่าถ้าแอปคุณมีผู้ใช้งาน 100,000 คนพร้อมกัน เซิร์ฟเวอร์ธนาคารจะต้องรับคำขอ (Request) เป็นล้านๆ ครั้งต่อนาที นี่คือการกระทำที่สิ้นเปลืองทรัพยากร เปลืองแบนด์วิดท์ และทำให้เซิร์ฟเวอร์พัง (Crash) ได้ง่ายที่สุดเลย!
เปรียบเทียบการทำงาน (Interactive Simulator)
ลองกดดูความแตกต่างระหว่างแบบเก่าที่ต้องส่งคำถามรัวๆ (ภาระหนัก) กับแบบใหม่ที่ทำงานแบบปล่อยวางได้เลย
ระบบแบบ Polling ทำให้เซิร์ฟเวอร์ต้องรับภาระหนัก เพราะเราต้องส่งคำขอไปถามรัวๆ เปลืองอินเทอร์เน็ต
2กำเนิด Webhook (การให้เขาทักมาเอง)
เพื่อแก้ปัญหานี้ วงการพัฒนาซอฟต์แวร์จึงสร้างคอนเซปต์ใหม่ที่เรียกว่า Webhook (เว็บฮุค) หรือ URL Callback ขึ้นมา คอนเซปต์ของมันคือคำพังเพยที่ว่า "Don't call us, we'll call you." (ไม่ต้องโทรมาถามหรอก เดี๋ยวทำเสร็จแล้วเราจะโทรกลับไปเอง)
มันทำงานอย่างไร?
คุณแค่สร้าง "ช่องทางรับข่าวสาร" ขึ้นมา 1 ช่องทางบนเซิร์ฟเวอร์ของคุณเอง (สร้าง Endpoint API ของคุณขึ้นมา เช่น https://your-shop.com/api/payment-success) และเมื่อคุณส่งคำสั่งให้ธนาคารตัดเงิน คุณก็ "แนบ" ลิงก์นี้ไปด้วย บอกธนาคารว่า:
ผลลัพธ์คือ ระบบของคุณจะได้ไปทำงานอย่างอื่นอย่างสบายใจ (ไม่ต้องทำลูปถามย้ำๆ) และเมื่อธนาคารตัดเงินสำเร็จ เซิร์ฟเวอร์ของธนาคารจะเปลี่ยนร่างเป็น Client ชั่วคราว แล้วยิงข้อมูล (POST Request) มาที่ลิงก์ของคุณทันที!
3เมื่อธนาคารทักมา ข้อมูลหน้าตาเป็นอย่างไร?
เวลาที่ระบบภายนอก (เช่น ธนาคาร, LINE, Facebook) ยิง Webhook กลับมาหาเซิร์ฟเวอร์เรา เขาจะแพ็คข้อมูลสถานะล่าสุดมาให้ในรูปแบบ JSON เสมอ เพื่อให้ระบบของเราเอาไปอัปเดตฐานข้อมูลต่อได้ ตัวอย่างเช่น ถ้านี่คือ Webhook จากบริษัทชำระเงิน Stripe เมื่อมีการจ่ายเงินสำเร็จ:
POST Request -> https://your-shop.com/api/webhook{ "id": "evt_1MqwQ4LkdIwHu7ix", "object": "event", "type": "payment_intent.succeeded", "created": 1679012345, "data": { "object": { "id": "pi_1Mqw...", "amount": 250000, "currency": "thb", "status": "succeeded", "customer_email": "[email protected]" } } }
เมื่อโค้ดฝั่งหลังบ้านของคุณได้รับก้อนข้อมูลนี้ มันก็จะอ่านค่า type === "payment_intent.succeeded"และรู้ทันทีว่าการสั่งซื้อเสร็จสมบูรณ์ ระบบของคุณก็จะสามารถส่งอีเมลใบเสร็จ หรือเปิดคอร์สเรียนให้ลูกค้าได้เลยโดยอัตโนมัติ
4ความท้าทาย: เรื่องน่าปวดหัวของ Webhook
แม้ Webhook จะยอดเยี่ยมและประหยัดทรัพยากรมาก แต่มันก็มาพร้อมกับ "ความรับผิดชอบอันใหญ่ยิ่ง" ที่โปรแกรมเมอร์ต้องระวังให้ดี:
ถ้า URL Webhook ของคุณหลุดไป แฮกเกอร์อาจจะเขียนโค้ดยิงข้อมูลปลอมๆ เข้ามาหลอกเซิร์ฟเวอร์คุณว่า "ฉันจ่ายเงินล้านนึงแล้วนะ!" วิธีแก้คือ: ธนาคารจะส่ง "ลายเซ็นดิจิทัล" (Secret Signature) แนบมาใน Header ด้วยเสมอ เซิร์ฟเวอร์ของคุณต้องเขียนโค้ดเช็คลายเซ็นนี้ก่อน ถึงจะเชื่อว่าเป็นข้อมูลจากธนาคารจริงๆ
สมมติจังหวะที่ธนาคารทักมา แต่เน็ตออฟฟิศคุณตัดพอดี! ข้อมูลการจ่ายเงินก็หายสิ? ไม่ต้องห่วง ระบบ Webhook ที่ดี (เช่น Stripe หรือ LINE) จะมี Retry Policy ถ้ามันยิงมาแล้วเราไม่ตอบรหัส 200 OK กลับไป มันจะพยายามยิงมาใหม่ในอีก 1 นาที, 1 ชั่วโมง, และ 1 วันถัดไป จนกว่าเราจะรับทราบ
5ตัวอย่างการเขียนโค้ดเพื่อ "รอรับ" Webhook
ในมุมของโปรแกรมเมอร์ การใช้ Webhook หมายความว่าเราต้อง "สร้าง API" ขึ้นมาเอง นี่คือตัวอย่างโค้ด JavaScript หลังบ้าน (Node.js/Express) ที่รอรับข้อมูลเมื่อมีคนโอนเงิน:
server.js// 1. สร้าง Endpoint API ของเราเตรียมไว้ให้เขามาทัก (POST) app.post('/api/webhook/payment', (req, res) => { // 2. รับข้อมูล JSON ที่ระบบธนาคารแพ็คส่งมาให้ const event = req.body; // 3. เช็คว่ามันคือเหตุการณ์ (Event) อะไร? if (event.type === 'payment.success') { const amount = event.data.amount; const user_id = event.data.user_id; // 4. เขียนโค้ดอัปเดตฐานข้อมูลของเรา console.log(`เย้! ลูกค้าหมายเลข ${user_id} จ่ายเงินมา ${amount} บาทแล้ว`); database.updateUserStatus(user_id, 'PAID'); } // 5. **สำคัญมาก** ต้องตอบกลับ 200 OK ให้ธนาคารรู้ว่า "เราได้รับข้อความแล้วนะ ไม่ต้องส่งซ้ำ!" res.status(200).send('Webhook received successfully'); });
6คุณเจอ Webhook อยู่ทุกวันโดยไม่รู้ตัว
LINE Bot / Chatbot
เวลาคุณพิมพ์ข้อความหาแชทบอท LINE ของร้านค้า... เซิร์ฟเวอร์ของ LINE จะเอาข้อความคุณ ยิงเป็น Webhook วิ่งเข้าไปหาเซิร์ฟเวอร์ของร้านค้านั้น เพื่อไปดึงโค้ดอัตโนมัติมาตอบแชทคุณนั่นเอง (เราเรียกสิ่งนี้ว่า Messaging API)
ระบบจ่ายเงิน (Omise / Stripe)
การสแกนจ่าย QR Code หรือจ่ายบัตรเครดิต เซิร์ฟเวอร์อีคอมเมิร์ซจะไม่เคยยืนรอผลลัพธ์เลย แต่มันจะตั้ง Webhook ทิ้งไว้ พอคุณโอนเงินเสร็จ ธนาคารจะยิงมาบอกแอปให้เปลี่ยนหน้าจอเป็นรูป "จ่ายเงินสำเร็จ" ให้คุณเห็น
GitHub Auto Deploy
เวลาโปรแกรมเมอร์กดบันทึกโค้ด (Push) ขึ้น GitHub... GitHub จะยิง Webhook ไปบอกเซิร์ฟเวอร์ฝั่งหน้าบ้าน (เช่น Vercel) ว่า "มีโค้ดชุดใหม่มาแล้วนะ ช่วยดึงไปแสดงผลบนเว็บไซต์จริงให้หน่อย!" นี่คือเคล็ดลับที่เว็บอัปเดตเองได้อัตโนมัติ
