Skip to main content

รายงานเพื่อนทั้งหมด

ภาพรวม

รายงานเพื่อนทั้งหมด (All Friends Report) คือหน้าฐานข้อมูลผู้ใช้ LINE ทั้งหมดของ OA ใช้สำหรับค้นหาและกรองรายชื่อ ดูรายละเอียดรายบุคคล แก้ไขข้อมูลโปรไฟล์และคุณสมบัติเพิ่มเติม (custom attribute) สั่งซิงก์รายชื่อผู้ติดตามจาก LINE ส่งออกข้อมูลเป็นไฟล์ CSV และนำเข้ารายชื่อ LINE User ID จากไฟล์ CSV

เหมาะกับทีมที่ต้องการภาพรวมของฐานผู้ติดตาม ตรวจสอบข้อมูลรายคนก่อนทำแคมเปญ หรือแก้ไขข้อมูลลูกค้าที่ได้จากช่องทางอื่นให้ตรงกับระบบ

โครงสร้างของโมดูลแบ่งเป็น 3 หน้า ได้แก่ หน้ารายการที่มี 2 แท็บ (รายชื่อในระบบ และประวัติการนำเข้า), หน้ารายละเอียดแบบเต็ม และหน้าฟอร์มนำเข้าไฟล์ CSV

Business Flow

รายชื่อในระบบ

  1. เปิดหน้ารายงาน ระบบตรวจสิทธิ์การเข้าถึงก่อน แล้วจึงโหลดรายชื่อผู้ใช้พร้อมข้อมูลประกอบอีก 2 ชุด คือ สถานะการซิงก์ผู้ติดตามล่าสุด และรายการคุณสมบัติที่ตั้งค่าให้แสดงในรายงานได้
  2. แท็บปัจจุบันอ่านจาก query string ทำให้ผู้ใช้บันทึกหรือแชร์ลิงก์ไปยังแท็บที่ต้องการได้ การสลับแท็บจะรีเซ็ตการแบ่งหน้าเสมอ
  3. ตัวกรองใช้รูปแบบ "กรอกแล้วกดค้นหา" คือค่าที่พิมพ์หรือเลือกจะพักไว้ในตัวตารางก่อน แล้วส่งขึ้นไปยิงคำขอเมื่อกดปุ่มค้นหาหรือกด Enter เท่านั้น จึงไม่ยิงคำขอทุกครั้งที่พิมพ์
  4. ตัวกรองที่ใช้ได้ในแท็บนี้มี 3 ตัว คือ ประเภทผู้ใช้ (สมาชิก / ผู้เยี่ยมชม), สถานะการใช้งาน (ใช้งานอยู่ / ไม่ได้ใช้งาน) และช่วงการใช้งานล่าสุดเป็นจำนวนวัน (7 / 30 / 90 / 180 / 365) ซึ่งระบบจะแปลงเป็นช่วงวันที่ก่อนส่งไปยังเซิร์ฟเวอร์
  5. คอลัมน์มาตรฐานประกอบด้วย ลำดับ, ผู้ใช้ (รูปโปรไฟล์ ชื่อที่แสดง และ user ID แบบย่อที่คัดลอกได้), ประเภท, สถานะ, สถานะการติดตาม, วันที่ใช้งานล่าสุด และวันที่ลงทะเบียน
  6. คอลัมน์คุณสมบัติเพิ่มเติมถูกสร้างขึ้นอัตโนมัติ จากรายการคุณสมบัติที่ถูกตั้งค่าให้แสดงในรายงาน โดยการแสดงผลปรับตามชนิดข้อมูล เช่น ค่าตรรกะแสดงเป็นป้าย ค่าวันที่จัดรูปแบบให้อ่านง่าย ค่าที่เป็นรายการหรือวัตถุแสดงแบบย่อ และค่าว่างแสดงเป็นขีด
  7. ปุ่มท้ายแถวเปิดหน้าต่างรายละเอียดผู้ใช้ ส่วนแถบเครื่องมือด้านขวาแสดงจำนวนเพื่อนทั้งหมด เวลาซิงก์ล่าสุด และปุ่มซิงก์กับปุ่มส่งออก

การซิงก์ผู้ติดตาม

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

การส่งออกข้อมูล

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

รายละเอียดผู้ใช้

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

เส้นทางการใช้งานเว็บไซต์

ดึงข้อมูลพฤติกรรมจาก Google Analytics ของผู้ใช้รายนั้น เลือกช่วงเวลาได้ 7 / 14 / 30 / 90 วัน แล้วแสดงเป็นไทม์ไลน์แยกตาม session พร้อมไอคอนประจำชนิดเหตุการณ์ เช่น การเปิดหน้า การเริ่ม session การเลื่อนหน้า การซื้อ และการคลิก หากยังไม่ได้ตั้งค่า GA ฝั่งเซิร์ฟเวอร์ หน้าจอจะแสดงสถานะว่างพร้อมคำอธิบาย

การนำเข้าไฟล์ CSV

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

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

Route ทั้งสาม — หน้ารายการ (src/app/report/all-friends/page.tsx), หน้ารายละเอียดแบบเต็ม (.../detail/page.tsx) และหน้าฟอร์มนำเข้า (.../form/page.tsx) โดยสองหน้าแรกถูกห่อด้วยตัวตรวจสิทธิ์ ส่วนหน้าฟอร์มไม่ได้ห่อไว้

ตัวควบคุมของรายการ (src/components/report/report-all-friends-table.container.tsx) — รวมตรรกะทั้งหมดของหน้ารายการ ทั้งการสลับแท็บ การกรอง การซิงก์ การส่งออก และการสร้างคอลัมน์คุณสมบัติแบบอัตโนมัติ ส่วนตัวตาราง (report-all-friends-table.tsx) ดูแลแถบเครื่องมือและตัวกรองแบบพักค่า

หน้าต่างรายละเอียด (src/components/report/all-friends-detail-modal.tsx) — เส้นทางหลักในการดูและแก้ไขข้อมูลรายบุคคล รวมถึงการคลี่โครงสร้างคุณสมบัติแบบซ้อนชั้นออกมาแสดง

ไทม์ไลน์ GA (src/components/report/user-ga-journey.tsx) — จัดกลุ่มเหตุการณ์ตาม session และแสดงจุดที่จับคู่ตัวตนบนเว็บกับผู้ใช้ LINE ได้

ตัวควบคุมการนำเข้า (src/components/report/csv-form.container.tsx) — รวมการตรวจไฟล์ทุกชั้นและการจัดการรหัสข้อผิดพลาดจากเซิร์ฟเวอร์ โดยใช้หน้าต่างยืนยันและหน้าต่างสรุปข้อผิดพลาดร่วมกับโมดูลกลุ่มผู้ชม

Endpoint สำคัญ — รายชื่อผู้ใช้และประวัติการนำเข้าอยู่ใต้กลุ่ม /report/* ส่วนข้อมูลรายบุคคล การแก้โปรไฟล์ การแก้คุณสมบัติ การซิงก์ผู้ติดตาม และเส้นทาง GA อยู่ใต้กลุ่ม /line-users/* ซึ่งใช้ร่วมกับโมดูลฐานข้อมูลสมาชิก

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

  • สิทธิ์การเข้าถึง — ใช้ subject report/all-friends ซึ่งแม็ปจากโมดูล report-all-friends ฝั่งหลังบ้าน โดยการกระทำที่ตรวจจริงในหน้าเว็บคือการดูข้อมูล ส่วนการควบคุมสิทธิ์การส่งออกอยู่ที่ฝั่งเซิร์ฟเวอร์
  • ตั้งค่าคุณสมบัติผู้ใช้ (Attribute Master) — เป็นแหล่งของทั้งคอลัมน์แบบอัตโนมัติในตารางและโครงสร้างฟอร์มคุณสมบัติในหน้าต่างรายละเอียด หากยังไม่มีคุณสมบัติใดถูกตั้งให้แสดงในรายงาน ตารางจะไม่มีคอลัมน์เพิ่ม
  • กลุ่มผู้ชม (Audience) — ใช้แปลงรหัสกลุ่มผู้ชมเป็นชื่อในหน้าต่างรายละเอียด และเป็นต้นทางของลิงก์เข้าหน้ารายละเอียดแบบเต็ม นอกจากนี้ยังใช้หน้าต่างประกอบการนำเข้าไฟล์ร่วมกัน
  • Google Analytics — ต้องตั้งค่าฝั่งเซิร์ฟเวอร์ก่อน มิฉะนั้นแท็บเส้นทางการใช้งานเว็บไซต์จะแสดงสถานะว่าง
  • งานเบื้องหลัง — ทั้งการซิงก์ผู้ติดตามและการนำเข้า CSV เป็นงานที่ประมวลผลแบบไม่พร้อมกันที่ฝั่ง worker หน้าเว็บทำหน้าที่สั่งงานแล้วติดตามสถานะผ่านสถานะการซิงก์และตารางประวัติการนำเข้าตามลำดับ
  • ค่ามาตรฐานร่วม — ขนาดหน้าตาราง รูปแบบวันที่ และสไตล์ของ control ในแถบตัวกรอง ใช้ค่ากลางเดียวกับหน้ารายการอื่นของ CMS

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

โมดูลนี้อยู่ที่ internal/modules/report/ ลงทะเบียนใต้กลุ่ม /api/report

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

  • โมดูลนี้มี ModuleGate("report-all-friends") คุมอยู่จริง ต่างจากหลายโมดูลในระบบที่ประกาศ policy ไว้แต่ยังไม่บังคับ กล่าวคือถ้าองค์กรไม่ได้เปิดโมดูล report-all-friends ไว้ คำขอจะถูกปฏิเสธที่ระดับ gate ก่อนถึง handler เลย
  • นอกจาก gate แล้วยังต้องผ่าน JwtAuth ระดับ global
  • การส่งออกใช้สิทธิ์คนละตัวกับการดูGET /api/report/all-friend ประกาศ policy readAll แต่ GET /api/report/all-friend/export ประกาศ policy export แยกต่างหาก เจตนาคือให้ตัดสิทธิ์คนที่ดูรายงานได้แต่ไม่ควรดึงข้อมูลทั้งฐานออกไปได้ (หน้าเว็บตรวจแค่สิทธิ์ "ดูข้อมูล" การแยกจึงเกิดที่ฝั่งเซิร์ฟเวอร์)

เงื่อนไขการกรองมาจากที่เดียวกับหน้าค้นหาเพื่อน

backend นำตัวสร้าง query ของโมดูลจัดการผู้ใช้ LINE มาใช้ซ้ำ ไม่ได้เขียนเงื่อนไขชุดใหม่ ผลที่ได้คือ:

  • ตัวกรองของ GET /api/report/all-friend ตรงกับ GET /api/line-users/search ทุกประการ พฤติกรรมการกรองในสองหน้านี้จึงตรงกัน 100% โดยไม่ต้องดูแลสองที่
  • เมื่อมีการเพิ่มหรือแก้เงื่อนไขกรองในโมดูลผู้ใช้ LINE รายงานนี้จะได้ตามไปด้วยโดยอัตโนมัติ
  • คอลัมน์ attribute ที่แสดงได้มาจาก GET /api/attribute-master/reportable ถ้าไม่มี attribute ใดถูกตั้งให้แสดงในรายงาน ตารางก็จะไม่มีคอลัมน์เพิ่ม

การส่งออก CSV

GET /api/report/all-friend/export ใช้เงื่อนไขกรองชุดเดียวกับการดูรายการ แต่ ไม่มีการแบ่งหน้า และเขียนผลลัพธ์ลง response แบบสตรีมโดยตรง ไม่ได้ประกอบไฟล์ทั้งก้อนไว้ในหน่วยความจำก่อน กลไกเดียวกับการส่งออกของโมดูลกลุ่มผู้ชม ข้อควรรู้:

  • ยิ่งเงื่อนไขกว้าง ไฟล์ยิ่งใหญ่และคำขอยิ่งค้างนาน เพราะปริมาณถูกกำหนดโดยตัวกรองล้วน ๆ
  • เนื่องจากเป็นการสตรีม การล้มเหลวกลางทางอาจได้ไฟล์ที่ไม่สมบูรณ์แทนที่จะเป็นข้อความ error

ประวัติการนำเข้า

GET /api/report/import-history อ่านจาก line_user_import คู่กับ line_user_import_detail จึงเห็นผลของทุกรอบการนำเข้า ไม่ว่าจะสั่งจากหน้าจัดการผู้ใช้ LINE หรือจากหน้านำเข้าแบบจับคู่คอลัมน์ ถ้าอ่านข้อมูลไม่สำเร็จ backend จะตอบเป็นสถานะ 500 พร้อมข้อความว่านำเข้าไม่สำเร็จ ไม่ได้ตอบเป็นรายการว่าง หน้าจอจึงควรแยกแยะระหว่าง "ไม่มีประวัติ" กับ "อ่านประวัติไม่ได้"

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

line_user, line_user_import, line_user_import_detail, attribute_master, system_attribute และ line_oa