การส่ง Campaign แบบ Multicast / เจาะกลุ่มเป้าหมาย
ภาพรวม
Multicast คือการส่ง campaign ไปยัง กลุ่มผู้รับที่ระบุไว้ (audience) หรือถึงสมาชิกทั้งหมดของ OA เท่าที่มีอยู่ในฐานข้อมูล ต่างจาก broadcast ตรงที่ต้องรู้ lineUserId ของผู้รับทุกคน แต่แลกมาด้วยความสามารถในการใช้ merge tag เพื่อใส่ชื่อผู้รับลงในข้อความ และสร้าง tracking link รายบุคคล ได้
นี่คือเส้นทางที่หนักที่สุดในระบบ เพราะจำนวนผู้รับอาจมีตั้งแต่หลักแสนถึงหลายล้านคน จึงต้องมีกลไก concurrency, resume, dry-run และรองรับการเลือกใช้ LINE API ได้ 2 รูปแบบ
Business Flow
-
รับ payload ที่ประกอบด้วย
campaignId,audienceId,organizationIdและlineOaIdพร้อมเปิด claim heartbeat ที่อัปเดตทุก 5 นาที -
Resolve OA และ validate campaign ด้วยเงื่อนไขเดียวกับ broadcast จากนั้นโหลด quick reply ล่วงหน้าเพียงครั้งเดียว หากโหลดไม่สำเร็จระบบจะส่งข้อความต่อไปโดยไม่มี quick reply แทนที่จะล้มทั้ง campaign
-
หารายชื่อผู้รับ แยกออกเป็น 3 กรณี
- มี
audienceIdและ audience มีไฟล์ CSV ระบุไว้ที่info.lineUserIdsPathFilename— อ่านไฟล์ CSV จาก S3 แบบแบ่งหน้า ครั้งละ 10,000 รายชื่อจนครบ - มี
audienceIdแต่ไม่มี CSV ซึ่งหมายถึง automated audience — query จากตารางline_userโดยกรองด้วยเงื่อนไขaudience_ids @> to_jsonb($1::int)และline_oa_id - ไม่มี
audienceId— เรียกFindAllMemberUIDเพื่อดึงสมาชิกทั้งหมดของคู่lineOaIdและorganizationId
- มี
-
ตรวจว่าเนื้อหามี merge tag หรือไม่ โดยดูจาก
campaign.has_merge_tagsหรือสแกนเนื้อหาโดยตรง แล้วเลือกเส้นทางส่งเส้นทาง A — LINE Multicast API ใช้เมื่อ ไม่มี merge tag และเปิด
MULTICAST_USE_BATCH_API- สร้าง redirect mapping แบบ shared เพียงครั้งเดียว และ transform message เพียงครั้งเดียว
- ยิงทีละ batch ขนาด 500 คน โดยใช้ retry key รูปแบบ
campaign:<id>:multicast:<batchNo> - เป็นเส้นทางที่เร็วและประหยัดจำนวน API call มากที่สุด
เส้นทาง B — Push Message รายคน เป็นค่าเริ่มต้น และถูกบังคับใช้เมื่อมี merge tag
- แบ่งผู้รับเป็น batch แล้วในแต่ละ batch จะ bulk-fetch ข้อมูลผู้ใช้ เช่น
display_name,firstname,email,custom_attributeเฉพาะกรณีที่มี merge tag เท่านั้น - กระจายงานให้ worker ทำงานพร้อมกันตามค่า
MULTICAST_CONCURRENCY(ค่าเริ่มต้น 200) - สำหรับผู้ใช้แต่ละคน ระบบจะ resolve merge tag → สร้าง tracking link ที่ผูกกับ
lineUserId→ transform message → แนบ quick reply → เรียก push message - ผู้ใช้ที่หาข้อมูลสำหรับ merge tag ไม่เจอจะถูก skip โดยนับไว้ใน
skippedCountและเก็บ 100 รายแรกไว้ใน log ตามค่าตั้งในcampaign.skip_merge_tag_missing
-
รองรับการ resume — บันทึกผู้รับที่ส่งสำเร็จลง Redis set แยกตาม campaign หาก message ถูก redeliver ระหว่างการส่ง คนที่ส่งไปแล้วจะถูกข้ามไปโดยอัตโนมัติ หาก Redis ล่มก็ไม่ block การส่ง
-
Dry-run — เมื่อเปิด
MULTICAST_DRY_RUNระบบจะทำทุกขั้นตอนตามปกติยกเว้นการยิง LINE API จริง -
จบงาน — อัปเดตตาราง
campaignด้วยline_message_object,template_tracking,rich_message_content,end_tracking_date,total_recipientและตั้งสถานะเป็นsentหรือหากล้มเหลวจะเข้าmulticastFailedซึ่งคืนเนื้อหาต้นฉบับ ตั้งสถานะเป็นfailedพร้อมบันทึกreason
ไฟล์และฟังก์ชันหลัก
internal/linemessageapi/multicast.goMulticastService.HandleLineMulticastRichMessage(ctx, payload)— flow ทั้งหมดของ feature นี้- struct
MulticastTogglesซึ่งเก็บค่าDryRun,UseBatchAPIและConcurrency sentSetKey(),isAlreadySent(),markSent()— กลไก resume ผ่าน RedismulticastFailed()
internal/linemessageapi/consumer.go—Consumer.HandleLineMulticastRichMessageและwithClaimHeartbeatinternal/linemessageapi/mergetag.go—ResolveMergeTags(),extractMergeTagKeys(),hasMergeTags()internal/linemessageapi/extend.go—createRedirectMappings()ในโหมดรายผู้ใช้internal/csvaudience/csvaudience.go— อ่านไฟล์ CSV ของ audience จาก S3 ผ่านCountและPagecmd/worker/integration.go— adapteraudienceForLineMessageApiและlineUserRepoForLineMessageApi- Queue:
line_multicast_rich_messageบน profilemain
จุดเชื่อมต่อกับ Service อื่น
- แหล่งที่มาของงาน — scanner ของ queue
process_campaignหรือ cms-api-go กรณีสั่งส่งทันที - ตารางที่เกี่ยวข้อง —
campaign,rich_message,audience(อ่านinfo.lineUserIdsPathFilename),line_user(รายชื่อผู้รับและข้อมูลสำหรับ merge tag),line_oaและกลุ่มตาราง quick reply - S3 — เก็บไฟล์ CSV รายชื่อ audience
- Redis — เก็บ sent-set สำหรับกลไก resume
- LINE API —
POST /v2/bot/message/multicastสำหรับเส้นทาง A และPOST /v2/bot/message/pushสำหรับเส้นทาง B - Environment variable ที่ปรับพฤติกรรมได้ —
MULTICAST_DRY_RUN,MULTICAST_USE_BATCH_API,MULTICAST_CONCURRENCY - มีเอกสารออกแบบ chunked delivery สำหรับอนาคต ซึ่งจะเพิ่ม queue
line_campaign_delivery_batchและตารางcampaign_delivery_batchอยู่ที่docs/campaign-delivery-tracking-redesign.mdใน repository ของ worker