ริชเมนู (Default / Custom / Switch)
ภาพรวม
ริชเมนูคือเมนูรูปภาพที่ปักอยู่ด้านล่างหน้าแชทของ LINE OA ฝั่ง CMS ทำหน้าที่ออกแบบเมนู กำหนดว่าใครเห็นเมนูใด และดูสถิติการคลิกย้อนหลัง
โมดูลนี้แบ่งเป็น 3 ประเภท ซึ่งใช้ทั้งเป็นตัวแยกหน้า แยกสิทธิ์ และแยกกฎการทำงาน
| ประเภท | ความหมาย | ข้อกำหนด |
|---|---|---|
| Default | เมนูตั้งต้นของ OA แบ่งย่อยเป็นเมนูสำหรับผู้เยี่ยมชม (guest) และสำหรับสมาชิก (member) | สร้างได้ประเภทละหนึ่งตัว เมื่อครบทั้งสองแล้วปุ่มสร้างใหม่จะถูกซ่อน |
| Custom | เมนูที่ใช้เฉพาะช่วงเวลาที่กำหนด ผูกกับกลุ่มเป้าหมายหนึ่งกลุ่ม หรือทำเครื่องหมายให้ระบบอัตโนมัติเป็นผู้สั่งใช้ | ต้องระบุช่วงวันที่ และระบุกลุ่มเป้าหมายเว้นแต่จะใช้กับระบบอัตโนมัติ |
| Switch | เมนูย่อยที่ผูกกับเมนูหลัก ใช้เป็นปลายทางของการกดเพื่อสลับหน้าเมนู | ต้องมีเมนูหลักอยู่ก่อน และสถานะขึ้นอยู่กับเมนูหลัก |
ทั้งสามประเภทใช้ตัวควบคุมและฟอร์มชุดเดียวกัน แล้วสลับฟิลด์ คอลัมน์ และกฎการตรวจสอบไปตามประเภทที่กำลังทำงานอยู่
Business Flow
1. หน้ารายการ
- แต่ละประเภทมีหน้าของตัวเองและตรวจสิทธิ์แยกกัน
- เงื่อนไขการค้นหาถูกบันทึกลง sessionStorage แยกตามหน้า จึงจำตัวกรองไว้เมื่อผู้ใช้กลับมา
- ระบบดึงรายการเมนูพร้อมกับรายการเมนูหลักสำหรับใช้เป็นตัวเลือกในตัวกรองและในฟอร์ม โดยจัดกลุ่มตัวเลือกเป็นเมนูตั้งต้นกับเมนูกำหนดเอง พร้อมภาพย่อประกอบ
- คอลัมน์ร่วมของทุกประเภทประกอบด้วย ลำดับ ภาพย่อ ชื่อเมนู สถานะ และปุ่มดำเนินการ ส่วนคอลัมน์เพิ่มเติมต่างกันไป
- Default เพิ่มคอลัมน์ประเภทและช่วงเวลา
- Custom เพิ่มคอลัมน์กลุ่มเป้าหมายและช่วงเวลา
- Switch เพิ่มคอลัมน์เมนูหลักและวันที่แก้ไขล่าสุด และไม่แสดงคอลัมน์สถานะ
- เมนูที่ถูกทำเครื่องหมายให้ระบบอัตโนมัติใช้จะมีป้ายกำกับไว้ข้างชื่อ
- ตัวกรองมีเฉพาะประเภท custom (ค้นหา สถานะ และช่วงวันที่) และ switch (ค้นหา เมนูหลัก และช่วงวันที่แก้ไข) ส่วนประเภท default ไม่มีตัวกรอง
- ปุ่มดำเนินการแต่ละแถวมีดูรายละเอียด แก้ไข และลบ (ลบได้เฉพาะประเภท custom และ switch) โดยปุ่มแก้ไขและลบถูกปิดตามกฎธุรกิจ พร้อมข้อความอธิบายเหตุผลเมื่อนำเมาส์ไปวาง
- Custom — แก้ไขได้เมื่อสถานะเป็นใช้งานหรือปิดใช้งาน แต่แก้ไม่ได้เมื่อสิ้นสุดหรือหมดอายุแล้ว หรือเมื่อวันที่เริ่มหรือวันที่สิ้นสุดผ่านไปแล้ว และลบไม่ได้เมื่อสิ้นสุดแล้ว
- Switch — แก้ไขได้เฉพาะเมื่อเมนูหลักอยู่ในสถานะร่างหรือปิดใช้งาน และลบไม่ได้เมื่อตัวเองหรือเมนูหลักสิ้นสุดแล้ว
- การลบต้องยืนยันผ่านกล่องข้อความก่อนเสมอ
2. ออกแบบเมนู
- หน้าฟอร์มใช้ร่วมกันทุกประเภท และตรวจสิทธิ์ด้วยตัวเองตามประเภทที่ระบุใน URL แทนการใช้ตัวครอบหน้ามาตรฐาน
- เลือกเลย์เอาต์ — ระบบมีแม่แบบให้เลือก 15 แบบ แบ่งเป็นสามกลุ่ม คือขนาดใหญ่ ขนาดกะทัดรัด และแบบกำหนดพื้นที่เอง การเปลี่ยนกลุ่มจะเลือกแม่แบบแรกของกลุ่มนั้นให้อัตโนมัติ และการเลือกเลย์เอาต์ใหม่จะล้างรูปภาพกับพื้นที่กดที่ตั้งไว้แล้วสร้างช่องเปล่าตามจำนวนของเลย์เอาต์นั้น
- อัปโหลดรูปภาพ — ระบบตรวจสามชั้นก่อนรับไฟล์ คือต้องเป็นไฟล์ JPEG หรือ PNG ขนาดไฟล์ต้องไม่เกิน 1 เมกะไบต์ และความละเอียดต้องตรงกับชุดขนาดที่กำหนดไว้สำหรับกลุ่มเลย์เอาต์นั้น
- ตั้งค่าการกระทำต่อช่อง — แต่ละช่องมีหัวข้อกำกับเป็น A, B, C ตามลำดับ และเลือกประเภทการกระทำได้ห้าแบบ
- ลิงก์ — กรอก URL พร้อมป้ายกำกับที่จำกัดความยาว 20 ตัวอักษรตามข้อจำกัดของ LINE และเลือกได้ว่าจะเปิดการติดตามการคลิกหรือไม่
- ข้อความ — ส่งข้อความกลับเข้าห้องแชท
- โทรศัพท์ — กรอกหมายเลขโทรศัพท์พร้อมป้ายกำกับ
- สลับริชเมนู — เลือกเมนูปลายทางจากรายการที่จัดกลุ่มเป็นเมนูหลักกับเมนูย่อย พร้อมปุ่มรีเฟรชรายการและปุ่มลัดไปสร้างเมนูย่อยใหม่
- ไม่มีการกระทำ
- กฎการบังคับกรอกจะผ่อนคลายลงเมื่อบันทึกเป็นฉบับร่าง ทำให้เก็บงานที่ยังกรอกไม่ครบไว้ก่อนได้
- เลย์เอาต์แบบกำหนดพื้นที่เอง — ผู้ใช้ลากวาดพื้นที่กดได้บนรูปภาพโดยตรง ปรับตำแหน่งและขนาดได้ด้วยจุดจับที่มุมและขอบ ระบบตรวจไม่ให้พื้นที่ซ้อนทับกันและจำกัดไม่เกิน 20 พื้นที่ หากพบข้อมูลเดิมที่พิกัดไม่ครบ ระบบจะแจ้งเตือนและจัดลำดับใหม่ให้
- สถานะ — กฎการเลือกสถานะเปลี่ยนตามประเภทและโหมดการทำงาน การสร้างเมนูย่อยจะซ่อนตัวเลือกและบังคับเป็นใช้งานทันที ส่วนเมนูกำหนดเองมีการตรวจสอบร่วมกับช่วงวันที่ คือหากตั้งสถานะเป็นใช้งานแต่วันที่เริ่มหรือสิ้นสุดอยู่ในอดีตจะไม่ผ่านการตรวจสอบ
- บันทึก — ต้องมีรูปภาพพื้นหลังก่อนเสมอ ระบบประกอบข้อมูลทั้งหมดรวมถึงไฟล์ภาพ แล้วเปิดกล่องยืนยันก่อนส่ง เมื่อยืนยันจะเรียกสร้างหรือแก้ไขตามโหมด หากเซิร์ฟเวอร์แจ้งข้อผิดพลาดที่ระบุฟิลด์ได้จะแสดงรายฟิลด์ และมีข้อผิดพลาดเฉพาะบางกรณีที่ถูกแปลเป็นข้อความอธิบาย เช่น ริชเมนูยังไม่พร้อมใช้งาน เมนูย่อยยังไม่เปิดใช้งาน หรือมีเมนูอื่นอ้างอิงอยู่
3. ดูสถิติการคลิก
- ในโหมดดูรายละเอียด ระบบแสดงตัวอย่างเมนูแบบอ่านอย่างเดียว พร้อมตารางสถิติการคลิก
- ตารางแสดงตำแหน่งช่อง (แปลงเป็นตัวอักษร A ถึง Z) ข้อมูลของช่องนั้น ประเภทการกระทำ จำนวนคลิกทั้งหมด และจำนวนผู้คลิกที่ไม่ซ้ำ โดยสองคอลัมน์สุดท้ายเรียงลำดับได้
- ช่องที่เป็นลิงก์จะแสดงข้อมูลเป็นลิงก์ที่กดไปยังปลายทางจริงได้
- ปุ่มซิงก์ข้อมูลใหม่จะสั่งให้ระบบเบื้องหลังคำนวณสถิติใหม่จากบันทึกการติดตาม แล้วหน้าจะโหลดข้อมูลใหม่หลังรอสักครู่ ขั้นตอนนี้เป็นงานเบื้องหลัง ไม่ใช่การคำนวณสดในหน้าเว็บ
หน้าจอและองค์ประกอบหลัก
หน้ารายการ
ตัวควบคุมรายการ (src/components/rich-menu/list/rich-menu.container.tsx) รับผิดชอบตาราง ตัวกรอง การลบ และกฎการเปิดปิดปุ่มดำเนินการทั้งหมด โดยมีฟอร์มตัวกรองแยกสำหรับประเภท custom และ switch
หน้าฟอร์ม
ฟอร์มทั้งหมดรวมอยู่ในตัวควบคุมเดียวที่มีขนาดใหญ่ (src/components/rich-menu/form/default/rich-menu-default-form.container.tsx) ครอบคลุมการโหลดข้อมูล การเลือกเลย์เอาต์ การอัปโหลดรูป การตรวจสอบวันที่กับสถานะ การบันทึก และการสั่งซิงก์สถิติใหม่
ตัวเลือกเลย์เอาต์และพื้นที่กด
โฟลเดอร์ src/components/rich-menu/form/template/ รวมสามส่วนเข้าด้วยกัน คือ ตัวเลือกแม่แบบแบบแท็บ ไฟล์นิยามเลย์เอาต์ทั้ง 15 แบบพร้อมจำนวนช่องของแต่ละแบบ และเครื่องมือวาดพื้นที่กดสำหรับเลย์เอาต์แบบกำหนดเอง
การตั้งค่าการกระทำ
การตั้งค่าการกระทำแยกเป็นคอมโพเนนต์แผงพับต่อช่อง กับคอมโพเนนต์ที่วาดฟิลด์ตามประเภทการกระทำพร้อมกฎตรวจสอบเฉพาะของแต่ละประเภท
ปลายทาง API
| การทำงาน | ปลายทาง |
|---|---|
| รายการริชเมนู | GET /rich-menu |
| รายการสำหรับ dropdown | GET /rich-menu/find-all-object |
| ข้อมูลริชเมนูรายตัวพร้อมสถิติ | GET /rich-menu/{id} |
| สร้างริชเมนู | POST /rich-menu |
| แก้ไขริชเมนูหรือเปลี่ยนสถานะ | PUT /rich-menu/{id} |
| ลบริชเมนู | DELETE /rich-menu/{id} |
| สั่งคำนวณสถิติใหม่ | POST /rich-menu/{id}/recalculate-stat |
| รายการกลุ่มเป้าหมาย | GET /audiences |
จุดเชื่อมต่อกับฟีเจอร์อื่น
- กลุ่มเป้าหมาย — เมนูกำหนดเองต้องผูกกับกลุ่มเป้าหมาย เว้นแต่จะทำเครื่องหมายให้ระบบอัตโนมัติเป็นผู้สั่งใช้
- ลำดับการสร้างเมนูย่อย — การกระทำแบบสลับริชเมนูต้องมีเมนูปลายทางอยู่ก่อน จึงต้องสร้างเมนูหลักก่อนแล้วจึงสร้างเมนูย่อย และกฎการแก้ไขหรือลบเมนูย่อยยังอ้างอิงสถานะของเมนูหลักด้วย
- เวิร์กโฟลว์และระบบอัตโนมัติ — เมนูกำหนดเองที่ทำเครื่องหมายไว้จะถูกสั่งใช้จากระบบอัตโนมัติแทนการกำหนดช่วงเวลาเอง
- ระบบติดตามผล — สถิติการคลิกมาจากงานเบื้องหลังที่ประมวลผลบันทึกการติดตาม ไม่ได้คำนวณสดที่หน้าเว็บ หากตัวเลขดูไม่อัปเดต ให้สั่งซิงก์ใหม่แล้วรอสักครู่
- สิทธิ์การเข้าถึง — โมดูล
rich-menuฝั่งเซิร์ฟเวอร์ปลดล็อกทั้งสามประเภทพร้อมกัน โดยเมนูด้านข้างจะแสดงเมนูย่อยตามสิทธิ์ของแต่ละประเภท - จัดการ Rich Message — ใช้โครงสร้างข้อมูลของพื้นที่กดบนรูปภาพร่วมกัน
รายละเอียดฝั่ง Backend (CMS API)
โมดูลริชเมนูเป็นโมดูลที่ซับซ้อนที่สุดตัวหนึ่งของ cms-api เพราะการกดบันทึกหนึ่งครั้งไม่ได้แค่เขียนฐานข้อมูล แต่ไปเปลี่ยนสถานะจริงบน LINE ด้วย
หนึ่งครั้งที่บันทึก backend ทำอะไรบ้าง
- ตรวจชื่อซ้ำก่อน ถ้าซ้ำจะปฏิเสธด้วย error code
RMN_001 - อัปโหลดรูปและสร้างริชเมนูขึ้นบน LINE จริง โดยเรียก LINE ตามลำดับ คือสร้างริชเมนู แล้วอัปโหลดรูปเข้าไปผูกกับริชเมนูนั้น และหากเป็นเมนูที่ต้องมี alias (สำหรับเมนูหลายชั้นหรือแบบแท็บ) จะสร้างหรืออัปเดต alias ต่อ
- แปลงการกระทำที่เป็นลิงก์ให้เป็น URL ติดตามแบบ token ก่อนส่งขึ้น LINE นี่คือกลไกเบื้องหลังตัวเลือก "เปิดการติดตามการคลิก" บนหน้าฟอร์ม และเป็นคนละกลไกกับลิงก์ติดตามในแคมเปญที่ใช้บริการ redirect
- ผูกเมนูกับผู้รับตามที่ระบุ — ถ้าเป็นเมนูของทั้ง OA จะสั่งตั้งเป็นเมนูตั้งต้นบน LINE แต่ถ้าผูกกับกลุ่มเป้าหมาย ระบบจะ อ่านไฟล์ CSV รายชื่อผู้ใช้ของกลุ่มเป้าหมายนั้นจาก object storage แล้วทยอยผูกเมนูให้ผู้ใช้เป็นชุด ๆ พร้อมบันทึกไว้ว่าใครถูกผูกแล้วบ้าง
- เก็บเวอร์ชันเดิมเข้า archive ก่อนถูกแทนที่ จึงมีประวัติของเมนูเวอร์ชันก่อนหน้าไว้
ข้อควรรู้เชิงปฏิบัติ: เพราะขั้นตอนเหล่านี้เรียกระบบภายนอกหลายจังหวะ การบันทึกเมนูที่ผูกกับกลุ่มเป้าหมายขนาดใหญ่จึงใช้เวลานานกว่าการบันทึกทั่วไปมาก และความล้มเหลวกลางทางอาจทำให้สถานะบน LINE กับในฐานข้อมูลไม่ตรงกันชั่วคราว ซึ่งเป็นที่มาของข้อความผิดพลาดเฉพาะกรณีที่หน้าเว็บแปลไว้ เช่น ริชเมนูยังไม่พร้อมใช้งาน
สถิติการคลิกเป็นงานเบื้องหลังจริง ๆ
POST /api/rich-menu/:id/recalculate-stat ไม่ได้คำนวณสถิติในคำขอนั้น แต่ publish งานเข้าคิว calculate_rich_menu_stat_item ให้ worker ไปคำนวณ คำขอจึงตอบกลับทันทีโดยที่ตัวเลขยังไม่เปลี่ยน นี่คือเหตุผลทางเทคนิคที่หน้าเว็บต้องรอสักครู่แล้วค่อยโหลดข้อมูลใหม่ และถ้าตัวเลขยังไม่ขยับ ควรตรวจที่ worker ไม่ใช่ที่ cms-api
การเปลี่ยนเมนูให้ผู้ใช้แบบอัตโนมัติตามเหตุการณ์ก็ทำผ่านคิวเช่นกัน คือคิว line_change_richmenu ซึ่งเป็นช่องทางที่เวิร์กโฟลว์และระบบอัตโนมัติใช้สั่งสลับเมนู
สิทธิ์และการลบ
- ทุกเส้นทางถูกครอบด้วย ModuleGate ของโมดูล
rich-menuซึ่งบังคับใช้จริงกับทั้งสามประเภทพร้อมกัน — ไม่มีการแยก gate ตามประเภท default / custom / switch ที่ระดับ API การแยกสิทธิ์รายประเภทเป็นเรื่องของหน้าเว็บเท่านั้น - ข้อมูลกำกับสิทธิ์รายการกระทำมีอยู่แต่ยังไม่บังคับใช้
GET /api/rich-menu/find-all-objectที่ใช้ทำ dropdown ไม่มีข้อมูลกำกับสิทธิ์เลยDELETE /api/rich-menu/:idเป็น soft delete พร้อมสั่งลบเมนูที่ฝั่ง LINE ไปด้วย ไม่ใช่แค่ซ่อนในฐานข้อมูล ส่วนการลบจริงต้องเป็น super admin และต้องส่งพารามิเตอร์ยืนยัน
ข้อสังเกตทางเทคนิคที่น่าสนใจ
โมดูลนี้อ่านข้อมูล LINE OA ด้วยการ query ตารางตรง ๆ แทนที่จะเรียกผ่านบริการจัดการ LINE OA ตามปกติ เหตุผลคือ ต้องใช้ channel access token ซึ่งบริการนั้นตัดออกจากผลลัพธ์เพื่อความปลอดภัย เป็นการยกเว้นที่ตั้งใจ ไม่ใช่ความไม่เป็นระเบียบของโค้ด