การส่งต่อ Webhook ไปยังระบบภายนอก
ภาพรวม
ลูกค้าบางรายมีระบบของตนเองที่ต้องการรับ LINE webhook ต่อ เช่น CRM หรือ chatbot เดิมที่ใช้อยู่ แต่ LINE อนุญาตให้ตั้ง webhook URL ได้เพียงที่เดียว ระบบจึงรับ webhook ไว้ก่อนแล้วส่งต่อไปยัง URL ปลายทางที่ตั้งไว้ในโปรไฟล์ OA ผ่านฟิลด์ line_oa.forward_webhook_url
การส่งต่อถูกแยกออกมาเป็นงานในคิวของตัวเอง เพื่อไม่ให้ระบบปลายทางที่ตอบช้าหรือล่มไปถ่วงการประมวลผล webhook หลัก
Business Flow
- รับ payload ที่ประกอบด้วย
webhookId,headersและbodyซึ่งมีโครงสร้างเดียวกับคิวline_webhook getLineOAByWebhookId(webhookId)resolve หา OA ที่เกี่ยวข้อง โดยมี Redis cache ช่วย- หาก OA ไม่ได้ตั้งค่า
forward_webhook_urlไว้ ระบบจะบันทึก log ระดับ warning แล้วจบงานพร้อมตอบ ack - อ่านค่า
x-line-signatureจาก header เดิมที่ได้รับมา - ส่งคำขอ
POSTโดยแนบ body ดิบทั้งก้อนไปยังforward_webhook_urlพร้อมแนบx-line-signatureตัวเดิม และตั้ง host header ให้ตรงกับ URL ปลายทาง ทำให้ระบบของลูกค้าตรวจลายเซ็นเองได้เหมือนกับรับ webhook มาจาก LINE โดยตรง - ข้อผิดพลาดที่เกิดขึ้นจะถูกบันทึก log แล้วกลืนไป คือคืนค่า nil เพื่อ ack เสมอ ซึ่งตรงกับพฤติกรรมของระบบเดิม เหตุผลคือระบบปลายทางของลูกค้าที่ล่มไม่ควรทำให้ข้อความค้างอยู่ในคิวหรือไหลลง DLQ
ไฟล์และฟังก์ชันหลัก
internal/lineoa/forward.goService.SendLineForwardWebhook(ctx, payload)— ครอบคลุมลำดับการทำงานทั้งหมดstringHeader()และmarshalBody()โดยตัวหลัง re-serialize body ให้ได้ผลลัพธ์ตรงกับJSON.stringifyของ Node เพื่อให้ลายเซ็นยังตรวจสอบได้
internal/lineoa/consumer.go—Consumer.HandleLineForwardWebhookinternal/line/client.go—line.ForwardWebhook(ctx, url, xLineSignature, body)internal/lineoa/service.go—getLineOAByWebhookId()พร้อม Redis cache กลุ่มLINE_OA:- คิวที่เกี่ยวข้อง:
line_forward_webhook(runtime profilemain)
จุดเชื่อมต่อกับ 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 และไม่เขียนฐานข้อมูล