Skip to main content

จัดการแคมเปญส่งข้อความ (Campaign)

ภาพรวม

Campaign คือการส่งข้อความ (rich message) ออกไปหาเพื่อน LINE ตามกลุ่มเป้าหมายที่กำหนด และตั้งเวลาส่งล่วงหน้าได้ โมดูลนี้ดูแลตั้งแต่การสร้างแคมเปญ การเลือกผู้รับ ไม่ว่าจะเป็นทั้ง OA หรือเฉพาะ audience ไปจนถึงการดูรายงานติดตามผลว่าใครเปิดหรือกดลิงก์ใดบ้าง

การส่งจริงไม่ได้เกิดขึ้นใน API นี้ โดย API ทำหน้าที่เพียงบันทึกข้อมูลและ publish งานลง RabbitMQ ให้ worker เป็นผู้ส่ง ทำให้ request ตอบกลับได้เร็วและรองรับการส่งจำนวนมาก

Business Flow

การสร้างและส่ง

  1. GET /api/campaign/recipients-dropdown ให้ cms-web แสดงตัวเลือกผู้รับ เช่น audience ที่มีอยู่

  2. POST /api/campaign รับเป็น multipart/form-data เพื่อบันทึกแคมเปญ ประกอบด้วยชื่อแคมเปญ rich message ที่จะส่ง ประเภทผู้รับ (broadcast ทั้ง OA หรือ multicast ตาม audience) และเวลาส่ง

  3. service ตรวจว่าข้อความมี merge tag เช่น {{name}} หรือไม่ ด้วยฟังก์ชัน hasMergeTags เนื่องจากข้อความที่มี merge tag ต้องส่งแบบ personalize ทีละคน

  4. ระบบ publish งานลง RabbitMQ ตามเงื่อนไข

    • ไม่ระบุ audience จะลงคิว line_broadcast_rich_message
    • ระบุ audience จะลงคิว line_multicast_rich_message
    • งานที่ตั้งเวลาหรือประมวลผลรวมจะลงคิว process_campaign

    payload ถูกสร้างให้ byte-identical กับระบบ TypeScript เดิม โดยคงลำดับ key ไว้เหมือนเดิม เพราะ worker ตัวเดิมยังเป็นผู้อ่านอยู่

  5. worker ดึงงานไปยิง LINE Messaging API

การติดตามผล

  1. GET /api/campaign/campaign-tracking/:id สรุปยอดการส่ง เปิด และคลิก โดยคำนวณด้วย raw SQL aggregation
  2. GET /api/campaign/campaign-tracking/:id/users เจาะดูรายชื่อผู้ที่ทำ action นั้น รองรับ query actionType, originalUrl, richMessageIndex, page และ limit
  3. ลิงก์ในแคมเปญถูกแปลงเป็น URL ติดตามผ่าน RedirectService ฝั่ง worker ซึ่งต่างจาก rich menu ที่ใช้กลไก token-based

การจัดการทั่วไป

  1. GET /api/campaign แสดงรายการแบบแบ่งหน้า โดย repository จะ spread ค่า target ของ audience เข้าไปในผลลัพธ์
  2. GET /api/campaign/:id และ PUT /api/campaign/:id ใช้ดูและแก้ไข ส่วน DELETE /api/campaign/:id เป็น soft delete
  3. DELETE /api/campaign/:id/hard?confirm=true ลบข้อมูลจริง เฉพาะ super admin เท่านั้น

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

โค้ดอยู่ที่ internal/modules/campaign/ ประกอบด้วย controller.go, service.go, tracking.go และ dto.go

MethodRouteHandlerPolicy (metadata)
GET/api/campaignct.findAllreadAll campaign
GET/api/campaign/recipients-dropdownct.recipientsDropdownreadAll campaign
GET/api/campaign/:idct.findByIDread campaign
GET/api/campaign/campaign-tracking/:idct.trackingByIDread campaign
GET/api/campaign/campaign-tracking/:id/usersct.trackingUsersByIDread campaign
POST/api/campaignct.createcreate campaign
PUT/api/campaign/:idct.updateupdate campaign
DELETE/api/campaign/:idct.deletedelete campaign
DELETE/api/campaign/:id/hardct.hardDeleteauth.SuperAdmin()

ทุก route ครอบด้วย modulegate.ModuleGate(d, "campaign")

ฟังก์ชันที่ควรทราบคือ hasMergeTags ซึ่งใช้ regex /\{\{[^}]+\}\}/ แบบเดียวกับ JavaScript กล่าวคือต้องมีวงเล็บปีกกาปิดสองตัวติดกันจริงจึงจะ match

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

  • PermissionModuleGate("campaign") เป็นตัวบังคับจริง ส่วน PolicyModuleCampaign เป็นเพียง metadata และ hard delete ต้องผ่าน auth.SuperAdmin()
  • ตารางที่เกี่ยวข้องcampaign, rich_message, audience, line_user, tracking_line_users, line_oa
  • RabbitMQ — คิว process_campaign, line_broadcast_rich_message, line_multicast_rich_message และ campaign_click_trigger
  • Redis — cache ทั้งรายการและรายละเอียด
  • Cross-modulelinemessageapi สำหรับ validate และ format ข้อความ รวมถึง richmessage และ audience
  • โมดูลที่เกี่ยวข้อง — ข้อความริช, การจัดการ audience และ trigger rule ซึ่งใช้การคลิกในแคมเปญเป็น trigger source