การจัดการ Rich Menu
ภาพรวม
Rich Menu คือเมนูรูปภาพที่แสดงอยู่ด้านล่างหน้าจอแชท LINE ระบบรองรับเมนูหลายประเภท
(default, member, guest, custom) และสามารถผูกเมนูคนละแบบให้ผู้ใช้แต่ละคนได้
งานนี้เป็น consumer ที่รับคำสั่งเปลี่ยน ผูก และลบ rich menu แล้วไปเรียก LINE Rich Menu API จริง
โดยใช้ queue เดียวคือ line_change_richmenu ซึ่งรองรับคำสั่งได้ 6 รูปแบบ แยกกันด้วยฟิลด์ type
ใน payload
Business Flow
Handler จะอ่านฟิลด์ type แล้วแตกไปยังสาขาการทำงานที่เกี่ยวข้อง
ค่า type | การทำงาน |
|---|---|
member | changeRichMenuFromWebhookId — กรณีผู้ใช้พิมพ์คำว่า "member" ในแชท ระบบจะ resolve OA จาก webhookId ค้นหา line_user เปลี่ยน user_type เป็น MEMBER แล้วผูก rich menu ประเภท member ให้ผู้ใช้รายนั้นผ่าน LINE API |
setRichMenuMember | setRichMenuMemberByLineOaId — ผูก rich menu ประเภท member ให้สมาชิกทุกคนของ OA โดยทำงานเป็นชุด (chunk) และสร้าง CLS context ใหม่ต่อหนึ่ง message |
setRichMenuMemberByLineUserId | ผูก rich menu ให้ผู้ใช้ที่ระบุเป็นรายบุคคล |
setRichMenuByTriggerRule | ผูก rich menu ตามผลลัพธ์ของ trigger rule ซึ่งถูกสั่งมาจาก action switch_rich_menu |
cronSetRichMenuCustom | ค้นหา rich menu ประเภท custom ที่มี status=active, complete_link_user=false และอยู่ในช่วงเวลา start_date <= now < end_date แล้วทยอยผูกให้สมาชิกกลุ่มเป้าหมาย เมื่อครบทุกคนจะ mark complete_link_user=true |
delete | deleteRichMenu — unlink ผู้ใช้ทั้งหมด ลบ rich menu บน LINE แล้ว cascade สถานะไปยัง alias rich menu |
หลักการที่ใช้ร่วมกันในทุกสาขา:
- resolve
channel_access_tokenผ่านLineOAResolver(คือlineoa.Serviceที่ทำหน้าที่ verify และ refresh token ให้) จากนั้นสร้าง LINE client แยกต่อ OA - การผูกผู้ใช้จำนวนมากจะถูกแบ่งเป็น chunk ด้วย
chunkStringsเพื่อไม่ให้ยิง API รวดเดียว - ล้าง Redis cache ที่เกี่ยวข้องหลังการเปลี่ยนแปลงทุกครั้งด้วย
delRedisAllCacheRelate - payload ที่ decode ไม่ได้จะคืน
mq.Permanentเพื่อเข้า DLQ ทันที ส่วนtypeที่ไม่รู้จักจะ return nil (ack เงียบ ๆ โดยไม่ retry)
ไฟล์และฟังก์ชันหลัก
internal/richmenu/consumer.go—Consumer.HandleLineChangeRichMenu()ทำหน้าที่ dispatch ตามค่าtypeและRegister()internal/richmenu/richmenu.go—Service,NewService(), enumtypeOfRichMenuDefault/Member/Guest/Custom,chunkStrings(),delRedisAllCacheRelate()internal/richmenu/service_methods.go—changeRichMenuFromWebhookId(),setRichMenuMemberByLineOaId(),setRichMenuMemberByLineUserId(),setRichMenuByTriggerRule(),deleteRichMenu()internal/richmenu/service_cron.go—cronSetRichMenuCustom(),cronDeleteRichMenuCustom(),findRichMenuMemberLineUserIds(),cascadeStatusToAliasRichMenus()internal/line/richmenu.go— LINE Rich Menu API clientcmd/worker/integration.go— จุด wiring ของlineOaForRichMenuและlineUserForRichMenu- Queue:
line_change_richmenu(profilemain)
จุดเชื่อมต่อกับ Service อื่น
- รับ job จาก: handler ของ
line_webhook(กรณีผู้ใช้พิมพ์ "member"), cms-api-go โดเมน rich menu และ action executor ผ่าน actionswitch_rich_menu - ตารางที่เกี่ยวข้อง:
rich_menu,rich_menu_action,rich_menu_archive,line_user(คอลัมน์rich_menu_idและuser_type) และline_oa - Redis: cache ของโดเมน rich menu โดยใช้ prefix ตามค่า
MODULE_NAME - LINE API: create/delete rich menu, การ link ผ่าน
POST /v2/bot/user/:userId/richmenu/:richMenuId, การ unlink และการจัดการ rich menu alias - สถิติการคลิกเมนูอยู่ในเอกสาร การคำนวณสถิติ Rich Menu