Skip to main content

ติดตามการเพิ่มเพื่อน

ภาพรวม​

ติดตามการเพิ่มเพื่อน (Friend Track) คือโมดูลสำหรับสร้างแคมเปญวัดผลการชวนเพิ่มเพื่อน แต่ละแคมเปญมี token ประจำตัวที่ใช้เป็นตัวระบุลิงก์ชวนเพิ่มเพื่อน เมื่อผู้ใช้เปิดลิงก์จะถูกนับเป็นการเข้าชม และเมื่อกดเพิ่มเพื่อนสำเร็จจะถูกนับเป็นการติดตาม ระบบจะเก็บข้อมูลทั้งสองส่วนไว้ให้ดูเป็นรายงานอัตราการเปลี่ยนเป็นเพื่อน (conversion) ต่อแคมเปญ

จุดเด่นของโมดูลนี้มี 2 อย่าง

  • เขียนคุณสมบัติให้ผู้ใช้อัตโนมัติ แต่ละแคมเปญกำหนดชุดคู่คีย์-ค่าไว้ได้ ผู้ใช้ที่เข้ามาทางลิงก์นี้จะถูกเขียนค่าเหล่านั้นลงในคุณสมบัติเพิ่มเติมของโปรไฟล์ ทำให้แยกแยะที่มาของผู้ติดตามได้ในภายหลัง
  • ลิงก์รายบุคคล หนึ่งแคมเปญสร้างลิงก์ย่อยได้หลายลิงก์ (เช่น แจกแยกตามพนักงานขายหรือสาขา) โดยอัปโหลดรายการรหัสอ้างอิงเป็นไฟล์ CSV แล้วดาวน์โหลดลิงก์ที่ระบบสร้างให้กลับมาเป็น CSV

โมดูลแบ่งเป็น 3 หน้า คือ หน้ารายการแคมเปญ, หน้าฟอร์มสร้างและแก้ไข และหน้ารายงานผล

Business Flow​

หน้ารายการแคมเปญ​

  1. เปิดหน้ารายการ ระบบตรวจสิทธิ์แล้วโหลดรายการแคมเปญโดยเรียงตามวันที่สร้างล่าสุด
  2. ตัวกรองมี 2 ตัว คือช่องค้นหาที่ยิงคำขอทันทีเมื่อพิมพ์ และตัวเลือกสถานะเปิด/ปิดใช้งาน ทั้งสองตัวจะรีเซ็ตกลับไปหน้าแรกของตารางเสมอ
  3. คอลัมน์ประกอบด้วย ลำดับ, ชื่อแคมเปญ (คลิกเพื่อเข้าไปแก้ไข), token, สถานะ, จำนวนการเข้าชม, จำนวนการติดตาม, อัตราการเปลี่ยนเป็นเพื่อน และวันที่สร้าง
  4. ปุ่มคำสั่งต่อแถวมี 3 ปุ่ม คือ ดูรายงาน, แก้ไข และลบ โดยการลบต้องยืนยันก่อนและแสดงผลลัพธ์ผ่านหน้าต่างสำเร็จหรือหน้าต่างล้มเหลว

หน้าฟอร์มสร้างและแก้ไข​

  1. หน้าฟอร์มแยกโหมดจากพารามิเตอร์ id โดยไม่มี id คือสร้างใหม่ และมี id คือแก้ไข ทั้งสองโหมดใช้ตัวตรวจสิทธิ์ระดับ "ดูข้อมูล" ตัวเดียวกัน
  2. ระบบโหลดข้อมูลประกอบ 2 ชุด คือ รายการ merge tag จากโมดูลข้อความเทมเพลต (ใช้เป็นตัวเลือกคีย์คุณสมบัติ) และข้อมูลแคมเปญเดิมในกรณีแก้ไข
  3. ฟิลด์ในฟอร์มประกอบด้วย
    • ชื่อแคมเปญ (บังคับ)
    • สถานะ เป็นสวิตช์เปิด/ปิด โดยค่าเริ่มต้นในโหมดสร้างคือเปิดใช้งาน
    • token พร้อมปุ่มสร้างให้อัตโนมัติเป็นสตริง 16 ตัวอักษร ถ้าเว้นว่างไว้ระบบหลังบ้านจะสร้างให้เอง
    • คำอธิบาย
    • ตั้งค่าคุณสมบัติ เป็นรายการคู่คีย์-ค่าที่เพิ่มลบได้ โดยคีย์เลือกจากรายการ merge tag
    • คีย์คุณสมบัติอ้างอิง เป็นตัวเลือกจากรายการคุณสมบัติที่ตั้งค่าไว้ ใช้ระบุว่าจะเก็บรหัสอ้างอิงของลิงก์ย่อยไว้ที่ช่องใด
  4. เมื่อกดบันทึก ระบบจะเปิดหน้าต่างยืนยันก่อน จากนั้นจึงประกอบข้อมูลส่ง โดยแปลงรายการคู่คีย์-ค่าเป็นวัตถุเดียว ตัดคำนำหน้า custom. ออกจากคีย์ให้ตรงกับรูปแบบที่ระบบจัดเก็บ และแปลงสวิตช์สถานะเป็นข้อความ
  5. เมื่อเปิดแคมเปญเดิมขึ้นมาแก้ไข ระบบจะแปลงข้อมูลกลับด้านตรงข้าม คือคลี่วัตถุกลับเป็นรายการ และเติมคำนำหน้า custom. คืนให้กับคีย์ที่ไม่ใช่คุณสมบัติมาตรฐานของ LINE
  6. หากบันทึกไม่สำเร็จและเซิร์ฟเวอร์ส่งข้อผิดพลาดรายฟิลด์กลับมา ระบบจะแสดงข้อความใต้ฟิลด์ที่เกี่ยวข้องโดยตรง

รหัสอ้างอิงและลิงก์รายบุคคล​

การ์ดรหัสอ้างอิงจะปรากฏเฉพาะในโหมดแก้ไข เพราะต้องมีรหัสแคมเปญอยู่ก่อน

  1. รูปแบบไฟล์ที่รองรับคือ CSV ที่มีรหัสอ้างอิงหนึ่งรายการต่อหนึ่งแถว หัวตารางจะมีหรือไม่มีก็ได้ โดยหน้าจอแสดงตัวอย่างรูปแบบไว้ให้
  2. ปุ่มดาวน์โหลดเทมเพลตสร้างไฟล์ตัวอย่างขึ้นในเบราว์เซอร์ทันทีโดยไม่ต้องเรียกเซิร์ฟเวอร์
  3. การอัปโหลดส่งไฟล์เข้าสู่ระบบเพื่อประมวลผลเบื้องหลัง เมื่อสำเร็จหน้าจอจะแจ้งสถานะและจำนวนรายการที่บันทึกได้ การตรวจความถูกต้องของเนื้อไฟล์ทำที่ฝั่งเซิร์ฟเวอร์ทั้งหมด
  4. หลังอัปโหลด ระบบจะดึงสถานะงานมาแสดง เมื่อสถานะเป็นเสร็จสิ้นแล้วจึงจะเปิดใช้งานปุ่มดาวน์โหลดลิงก์ พร้อมแสดงจำนวนรายการที่บันทึกสำเร็จและที่ถูกข้าม โดยระบบจะตรวจสถานะเฉพาะตอนเปิดหน้าและหลังอัปโหลด หากงานยังประมวลผลไม่เสร็จผู้ใช้ต้องรีเฟรชหน้าเอง
  5. ปุ่มดาวน์โหลดลิงก์จะดึงไฟล์ CSV ที่มีลิงก์ tracking ของแต่ละรหัสอ้างอิงมาบันทึกลงเครื่อง
  6. ลิงก์จริงที่แจกให้ผู้ใช้ปลายทางถูกประกอบขึ้นที่ฝั่งเซิร์ฟเวอร์ และส่งกลับมาในไฟล์นี้เท่านั้น ต่างจากโมดูลลิงก์รวมเนื้อหาหรือตัวสร้างเมนูที่ประกอบ URL เองในหน้าเว็บ หน้ารายการจึงแสดงเพียง token ไม่ใช่ URL เต็ม

หน้ารายงานผล​

  1. หน้ารายงานอ่านรหัสแคมเปญจาก URL แล้วโหลดข้อมูล 2 ชุด คือข้อมูลแคมเปญ (ใช้ชื่อเป็นหัวข้อหน้า) และข้อมูลรายงานตามช่วงเวลาที่เลือก
  2. ตัวเลือกช่วงเวลาอยู่บนหัวการ์ดกราฟ และควบคุมทั้งกราฟและตารางผู้ใช้พร้อมกัน โดยค่าเริ่มต้นคือดูข้อมูลทั้งช่วง
  3. การ์ดสถิติ 4 ใบ แสดงจำนวนการเข้าชมทั้งหมด, จำนวนการติดตามทั้งหมด, อัตราการเปลี่ยนเป็นเพื่อน และจำนวนการเลิกติดตาม
  4. กราฟเส้นรายวัน วาดจากข้อมูลจริงที่เซิร์ฟเวอร์ส่งมาเป็นชุดข้อมูลตามวันที่ แสดง 2 เส้นคือการเข้าชมและการติดตาม หากไม่มีข้อมูลในช่วงที่เลือกจะแสดงข้อความแจ้งแทน
  5. ตารางผู้ใช้ แสดงรายชื่อผู้ที่เข้ามาผ่านแคมเปญนี้ พร้อมชื่อที่แสดง, LINE user ID, วันที่เข้าชม, วันที่ติดตาม, สถานะ, รหัสอ้างอิงของลิงก์ย่อยที่ผู้ใช้เข้ามา และประเภทผู้ใช้ โดยแบ่งหน้าแยกจากกราฟ

สรุปวงจรการใช้งาน​

  1. ผู้ดูแลสร้างแคมเปญ ได้ token และตั้งค่าคุณสมบัติที่จะเขียนให้ผู้ใช้
  2. หากต้องการลิงก์แยกรายบุคคล ให้กลับเข้าโหมดแก้ไข อัปโหลดรายการรหัสอ้างอิง รอสถานะเสร็จสิ้น แล้วดาวน์โหลดไฟล์ลิงก์ไปแจก
  3. ผู้ใช้ปลายทางเปิดลิงก์ ระบบหลังบ้านบันทึกการเข้าชม และเขียนคุณสมบัติกับรหัสอ้างอิงให้ผู้ที่กดเพิ่มเพื่อน
  4. ผู้ดูแลกลับมาดูผลที่หน้ารายงาน เลือกช่วงวันที่ แล้วอ่านตัวเลขสรุป กราฟ และรายชื่อผู้ใช้
  5. เมื่อจบแคมเปญสามารถปิดใช้งานหรือลบแคมเปญออกได้

หน้าจอและองค์ประกอบหลัก​

Route ทั้งสาม — หน้ารายการ (src/app/friend-track/page.tsx), หน้าฟอร์ม (.../form/page.tsx) และหน้ารายงาน (.../report/page.tsx) ทั้งหมดห่อด้วยตัวตรวจสิทธิ์เดียวกัน

ตัวควบคุมรายการ (src/components/friend-track/list/friend-track-list.container.tsx) — ดูแลการโหลดตาราง ตัวกรอง และการลบพร้อมหน้าต่างแสดงผลลัพธ์

ตัวควบคุมฟอร์ม (src/components/friend-track/form/friend-track-form.container.tsx) — ดูแลการโหลดและบันทึกข้อมูลแคมเปญ รวมถึงการแปลงรูปแบบคุณสมบัติทั้งขาเข้าและขาออก ส่วนตัวฟอร์ม (friend-track-form.tsx) ดูแล UI ทั้งหมดรวมถึงการ์ดรหัสอ้างอิง

ตัวควบคุมรายงาน (src/components/friend-track/report/friend-track-report.container.tsx) — ประกอบการ์ดสถิติ กราฟเส้น และตารางผู้ใช้เข้าด้วยกัน โดยใช้ตัวลงทะเบียนกราฟร่วมกับโมดูลแดชบอร์ด

เซอร์วิสกลาง (src/services/friend-track.service.ts) — ครอบคลุมการอ่านรายการ, อ่านรายตัว, สร้าง, แก้ไข, ลบ, ดึงรายงาน, อัปโหลดรหัสอ้างอิง, ตรวจสถานะงานอัปโหลด และดาวน์โหลดไฟล์ลิงก์

โครงสร้างข้อมูลสำคัญ — ข้อมูลแคมเปญเก็บชื่อ, token, คำอธิบาย, สถานะ, ชุดคุณสมบัติที่จะเขียน, คีย์คุณสมบัติอ้างอิง และตัวเลขสรุป ส่วนข้อมูลรายงานแบ่งเป็น 3 ส่วน คือตัวเลขสรุป, ชุดข้อมูลรายวันสำหรับกราฟ และรายการผู้ใช้พร้อมข้อมูลการแบ่งหน้า

จุดเชื่อมต่อกับฟีเจอร์อื่น​

  • สิทธิ์การเข้าถึง — ใช้ subject friend-track โดยตรวจเฉพาะการกระทำ "ดูข้อมูล" ทุกหน้าใช้ตัวตรวจเดียวกัน รวมถึงหน้าฟอร์มที่สร้าง แก้ไข และอัปโหลดไฟล์ได้
  • ข้อความเทมเพลต (Template Message) — เป็นแหล่งของรายการ merge tag ที่ใช้เป็นตัวเลือกคีย์คุณสมบัติ หากบริการนี้ไม่ตอบสนอง ตัวเลือกจะว่าง
  • ตั้งค่าคุณสมบัติผู้ใช้ (Attribute Master) — เป็นแหล่งของตัวเลือกคีย์คุณสมบัติอ้างอิง โดยต้องสร้างคุณสมบัติไว้ก่อนจึงจะเลือกได้ ซึ่งหน้าจอมีคำแนะนำระบุไว้ชัดเจน
  • ระบบหลังบ้านและ webhook — การนับการเข้าชม การนับการติดตาม และการสร้างลิงก์ต่อรหัสอ้างอิง เป็นงานฝั่งเซิร์ฟเวอร์ทั้งหมด CMS ทำหน้าที่ตั้งค่าและอ่านผลเท่านั้น
  • โมดูลแดชบอร์ด — ใช้ตัวลงทะเบียนไลบรารีกราฟชุดเดียวกัน
  • คอมโพเนนต์ร่วมของ CMS — ส่วนหัวหน้า, หน้าต่างยืนยัน, หน้าต่างผลลัพธ์, สถานะกำลังโหลดแบบเต็มจอ และพื้นที่เลื่อนตาราง ใช้ชุดเดียวกับหน้าอื่นทั้งระบบ

รายละเอียดฝั่ง Backend (CMS API)​

ฟีเจอร์นี้พาดผ่าน 3 ส่วนของ backend คือ โมดูลแคมเปญติดตามเพื่อน (internal/modules/friendtrack/), โมดูลค้นหาผู้ใช้จาก tracking log และกลไกสร้างลิงก์ติดตามที่ไม่มี HTTP route ของตัวเอง

สิทธิ์ที่ต้องมี​

  • ทุก route ของ /api/friend-track ถูกครอบด้วย ModuleGate("friend-track") จริง ถ้าองค์กรไม่ได้เปิดโมดูลนี้ คำขอถูกปฏิเสธก่อนถึง handler
  • policy ที่ประกาศไว้แยกละเอียดกว่าที่หน้าเว็บตรวจ: การอ่านรายการเป็น readAll, การอ่านรายตัว/รายงาน/ดาวน์โหลด/ดูสถานะเป็น read, การสร้างเป็น create, การอัปโหลดรหัสอ้างอิงถูกจัดเป็น update (ไม่ใช่ create) และการลบเป็น delete — หน้าเว็บตรวจแค่การกระทำ "ดูข้อมูล" การแยกจึงมีผลจริงที่ฝั่งเซิร์ฟเวอร์เท่านั้น
  • ข้อสังเกต: policy ของโมดูล friend-track ยังถูกนำไปใช้เป็น metadata ของ GET /api/apps และ PUT /api/apps/:appId ด้วย ซึ่งยกมาตามระบบเดิม จึงเป็นความผูกพันที่ไม่ตรงกับชื่อโมดูลและควรระวังเมื่อจะปรับสิทธิ์

การอัปโหลดรหัสอ้างอิงจำนวนมาก​

  • POST /api/friend-track/:id/refs/upload รับไฟล์แบบ multipart แล้วเขียนลงฐานข้อมูล ด้วยคำสั่ง SQL แบบ batch ที่มีเงื่อนไข "ถ้าซ้ำให้ข้าม" ออกแบบมารองรับ ref หลักพันถึงหลักหมื่นรายการ เช่น ref ต่อพนักงาน ต่อสาขา หรือต่อ QR แต่ละใบ
  • เพราะมีการกันซ้ำในตัว การอัปโหลดไฟล์เดิมซ้ำจึงไม่สร้างรายการซ้ำ และใช้เป็นวิธี "เติม ref เพิ่ม" ได้อย่างปลอดภัย
  • GET /api/friend-track/:id/refs/status ใช้ poll สถานะงานอัปโหลด (กำลังทำ / เสร็จ / ผิดพลาด) เพราะงานไม่ได้เสร็จภายในคำขอเดียว
  • GET /api/friend-track/:id/refs/download สตรีมไฟล์ CSV ของลิงก์และ ref ทั้งหมดลง response โดยตรง ไม่โหลดทั้งก้อนเข้าหน่วยความจำ

รายงานและการนับ​

GET /api/friend-track/:id/report กรองตามช่วงเวลาและ ref ได้ ข้อควรรู้ด้านประสิทธิภาพ: การนับจำนวนผู้ใช้ในรายงานทำโดยดึงแถวทั้งหมดออกมาแล้วนับความยาว ไม่ได้ใช้คำสั่งนับของฐานข้อมูล ซึ่งยกพฤติกรรมมาจากระบบเดิมตรง ๆ ผลคือแคมเปญที่มีผู้ใช้จำนวนมากจะทำให้รายงานหน่วงและกินหน่วยความจำมากกว่าที่ควร

ใครเป็นคนบันทึกว่า "เพื่อนคนนี้มาจาก ref ไหน"​

CMS API ไม่ได้เป็นผู้บันทึกเหตุการณ์นี้ — เมื่อมีคนกดลิงก์แล้วเพิ่มเพื่อน บริการ webhook เป็นฝ่ายรับ event จาก LINE แล้วเขียนลงตาราง friend_track_event โดยผูกกับแคมเปญและ ref ที่ใช้ CMS ทำหน้าที่ตั้งค่าและอ่านผลเท่านั้น ผลที่ตามมาคือถ้าบริการ webhook มีปัญหา ตัวเลขในรายงานจะขาดหายโดยที่หน้า CMS ไม่แสดงความผิดพลาดใด ๆ

ค้นหาผู้ใช้จาก tracking log​

POST /api/tracking-line-users เป็น endpoint เดียวที่ใช้เจาะจากพฤติกรรมกลับมาเป็นรายชื่อคน (เช่น "ใครกดลิงก์นี้บ้าง") โดยรับรายการ tracking key แล้วค้นตาราง tracking_line_users และเชื่อมกลับไปที่ข้อมูลผู้ใช้ LINE

  • ขอบเขตข้อมูลอ่านจาก context ของ request จึงจำกัดอยู่ที่ OA ที่กำลังทำงานอยู่
  • endpoint นี้ผ่านแค่ JwtAuth ระดับ global ไม่มี ModuleGate ต่างจาก /api/friend-track
  • ผลลัพธ์ถูกส่งกลับตามที่ค้นได้โดยไม่แปลงรูป
  • ข้อควรระวัง: ถ้าคำขอไม่ได้ส่งรายการ tracking key มา หรือส่งมาผิดชนิด backend จะตอบเป็นสถานะ 500 พร้อมรหัสข้อผิดพลาดทั่วไป ไม่ใช่ 400 พร้อมข้อความบอกว่าอะไรผิด — พฤติกรรมนี้จงใจคงไว้ให้ตรงกับระบบเดิม ฝั่งเรียกจึงต้องตรวจ payload ให้ครบก่อนส่ง

ลิงก์ติดตามถูกสร้างอย่างไร​

กลไกสร้างลิงก์ติดตามอยู่ในโมดูล internal/modules/tracking/ ซึ่ง ไม่เปิด HTTP route ใด ๆ เลย เป็นเพียงบริการภายในที่โมดูลริชเมนูและโมดูลส่งข้อความเรียกใช้ ประเด็นที่ควรรู้:

  • โหมดการทำงานเลือกด้วยตัวแปรสภาพแวดล้อม TRACKING_REDIRECT_MODE — โหมด builtin ใช้ token ที่ระบบเข้ารหัสเอง ส่วนค่าอื่น (ค่าเริ่มต้นคือโหมดเดิม) จะส่งต่อให้บริการ redirect ภายนอก
  • โหมด builtin ห่อข้อมูลไว้ในตัว token เองด้วยการเข้ารหัสแบบ AES-256-GCM แล้วเข้ารหัสเป็นข้อความ URL-safe ตัว token จึงระบุได้ว่ามาจากริชเมนูหรือจากฟอร์มเก็บข้อมูล โดยไม่ต้องค้นฐานข้อมูลก่อน
  • เมื่อผู้ใช้กดลิงก์ บริการ client-api เป็นฝ่ายถอดรหัส token บันทึกเหตุการณ์ลง tracking_line_users แล้วจึง redirect ไปยังปลายทาง
  • คำเตือนสำคัญ: ตัวเข้ารหัสฝั่ง CMS API กับตัวถอดรหัสฝั่ง client-api ถูกตรึงให้ตรงกัน ถ้าฝั่งใดฝั่งหนึ่งเปลี่ยนรูปแบบ token ลิงก์ที่ส่งออกไปแล้วทั้งหมดจะใช้ไม่ได้ทันที และไม่มีทางกู้คืนนอกจากออกลิงก์ใหม่
  • ลิงก์ของแคมเปญ (campaign) ใช้คนละเส้นทาง คือใช้บริการ redirect ที่ฝั่ง worker ไม่ได้ผ่านกลไก token นี้

ตารางที่เกี่ยวข้อง​

friend_track_campaign, friend_track_event, tracking_token, tracking_line_users, line_user และ line_oa