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.goConsumer.HandleLineForwardWebhook
  • internal/line/client.goline.ForwardWebhook(ctx, url, xLineSignature, body)
  • internal/lineoa/service.gogetLineOAByWebhookId() พร้อม 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 และไม่เขียนฐานข้อมูล