Skip to main content

การส่งต่อ Webhook ไปยังระบบภายนอก

ภาพรวม​

ลูกค้าบางรายมีระบบของตนเองที่ต้องการรับ LINE webhook ต่อ เช่น CRM หรือ chatbot เดิมที่ใช้อยู่ แต่ LINE อนุญาตให้ตั้ง webhook URL ได้เพียงที่เดียว ระบบจึงรับ webhook ไว้ก่อนแล้วส่งต่อไปยัง URL ปลายทางที่ตั้งไว้ในโปรไฟล์ OA ผ่านฟิลด์ line_oa.forward_webhook_url

การส่งต่อถูกแยกออกมาเป็นงานในคิวของตัวเอง เพื่อไม่ให้ระบบปลายทางที่ตอบช้าหรือล่มไปถ่วงการประมวลผล webhook หลัก

Business Flow​

  1. รับ payload ที่ประกอบด้วย webhookId, headers และ body ซึ่งมีโครงสร้างเดียวกับคิว line_webhook
  2. getLineOAByWebhookId(webhookId) resolve หา OA ที่เกี่ยวข้อง โดยมี Redis cache ช่วย
  3. หาก OA ไม่ได้ตั้งค่า forward_webhook_url ไว้ ระบบจะบันทึก log ระดับ warning แล้วจบงานพร้อมตอบ ack
  4. อ่านค่า x-line-signature จาก header เดิมที่ได้รับมา
  5. ส่งคำขอ POST โดยแนบ body ดิบทั้งก้อนไปยัง forward_webhook_url พร้อมแนบ x-line-signature ตัวเดิม และตั้ง host header ให้ตรงกับ URL ปลายทาง ทำให้ระบบของลูกค้าตรวจลายเซ็นเองได้เหมือนกับรับ webhook มาจาก LINE โดยตรง
  6. ข้อผิดพลาดที่เกิดขึ้นจะถูกบันทึก log แล้วกลืนไป คือคืนค่า nil เพื่อ ack เสมอ ซึ่งตรงกับพฤติกรรมของระบบเดิม เหตุผลคือระบบปลายทางของลูกค้าที่ล่มไม่ควรทำให้ข้อความค้างอยู่ในคิวหรือไหลลง DLQ

ไฟล์และฟังก์ชันหลัก​

  • internal/lineoa/forward.go
    • Service.SendLineForwardWebhook(ctx, payload) — ครอบคลุมลำดับการทำงานทั้งหมด
    • stringHeader() และ marshalBody() โดยตัวหลัง re-serialize body ให้ได้ผลลัพธ์ตรงกับ JSON.stringify ของ Node เพื่อให้ลายเซ็นยังตรวจสอบได้
  • internal/lineoa/consumer.go — Consumer.HandleLineForwardWebhook
  • internal/line/client.go — line.ForwardWebhook(ctx, url, xLineSignature, body)
  • internal/lineoa/service.go — getLineOAByWebhookId() พร้อม Redis cache กลุ่ม LINE_OA:
  • คิวที่เกี่ยวข้อง: line_forward_webhook (runtime profile main)

จุดเชื่อมต่อกับ Service อื่น​

  • ต้นทางของงาน — line-management-webhook-go ซึ่ง publish งานนี้คู่ขนานไปกับคิว line_webhook
  • ฐานข้อมูล — ตาราง line_oa โดยอ่านฟิลด์ forward_webhook_url และ webhook_id
  • Redis — cache ข้อมูล OA ในกลุ่ม LINE_OA: และ webhook_config:<webhookId> ที่ webhook-go ใช้งาน
  • HTTP ออกสู่ภายนอก — ยิง POST ไปยัง URL ของลูกค้า โดยไม่มีกลไก retry ในระดับแอปพลิเคชัน หากล้มเหลวถือว่าจบ
  • ไม่เรียก LINE API และไม่เขียนฐานข้อมูล