Skip to main content

ข้อความตอบกลับด่วน (Quick Reply)

ภาพรวม

Quick Reply คือชุดปุ่ม (chips) ที่ LINE แสดงเหนือช่องพิมพ์ข้อความเมื่อผู้ใช้ได้รับข้อความจาก OA เมื่อผู้ใช้กดปุ่ม ระบบจะทำงานตามชนิดของปุ่มที่ตั้งไว้ เช่น ส่งข้อความกลับเข้าห้องแชท เปิดลิงก์ เปิดกล้อง หรือส่งตำแหน่งที่ตั้ง

ฟีเจอร์นี้ให้แอดมินสร้าง "ชุด quick reply" เก็บไว้เป็นรายการกลาง แล้วให้ Rich Message และ Template Message มาอ้างอิงชุดเดิมซ้ำได้ โดยไม่ต้องตั้งค่าปุ่มใหม่ทุกครั้งที่สร้างข้อความ เหมาะกับทีมที่ต้องส่งข้อความหลายแบบแต่ต้องการชุดปุ่มลัดชุดเดียวกัน

ข้อมูล 1 ชุดประกอบด้วย

ข้อมูลคำอธิบาย
ชื่อชุดชื่อที่ใช้อ้างอิงในตารางและในตัวเลือกของฟีเจอร์อื่น ความยาวไม่เกิน 255 ตัวอักษร
รายการปุ่ม (items)ปุ่มในชุด สูงสุด 13 ปุ่ม แต่ละปุ่มมี label ไม่เกิน 20 ตัวอักษร
สถานะเปิด (active) / ปิด (inactive) ชุดที่ปิดอยู่จะไม่ถูกส่ง chips ออกไป

ชนิดของปุ่มที่เลือกได้จากหน้าจอ

ชนิดข้อมูลที่ต้องกรอกเพิ่มผลเมื่อผู้ใช้กด
ข้อความ (message)ข้อความที่จะส่งส่งข้อความนั้นเข้าห้องแชทแทนผู้ใช้
ลิงก์ (uri)URLเปิดลิงก์ที่กำหนด
เลือกวันที่/เวลา (datetimepicker)ข้อมูลอ้างอิง, โหมด (วันที่ / เวลา / วันที่และเวลา), ค่าเริ่มต้น, ค่าต่ำสุด, ค่าสูงสุดเปิดตัวเลือกวันที่หรือเวลา
กล้อง (camera)-เปิดกล้องถ่ายภาพ
คลังภาพ (cameraRoll)-เปิดคลังภาพในเครื่อง
ตำแหน่งที่ตั้ง (location)-เปิดหน้าจอส่งตำแหน่ง

หมายเหตุ: ชนิด postback ไม่เปิดให้เลือกจากหน้าจอ เพราะฝั่ง API ไม่รองรับ แต่ระบบยังอ่านและแสดงข้อมูลเดิมที่เป็นชนิดนี้ได้

จุดสำคัญที่ต้องทราบ

  • ชุดที่ยังถูกใช้งานอยู่จะถูกป้องกันไว้ หากพยายามปิดหรือลบชุดที่มี Rich Message หรือ Template Message อ้างอิงอยู่ ระบบจะแจ้งเตือนพร้อมแสดงรายการผู้อ้างอิงทั้งหมด
  • กรณี ปิดใช้งาน ผู้ใช้ยืนยันเพื่อดำเนินการต่อได้ (บันทึกซ้ำแบบบังคับ) แต่กรณี ลบ จะทำต่อไม่ได้ ต้องไปแก้ข้อความที่อ้างอิงอยู่ให้เลิกใช้ชุดนี้ก่อน
  • ข้อจำกัดจำนวนปุ่มและความยาว label เป็นข้อกำหนดของ LINE Messaging API ไม่สามารถขยายเกินได้

Business Flow

การจัดการรายการชุด quick reply

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

การสร้างและแก้ไขชุด quick reply

  1. ฟอร์มทำงาน 3 กรณี คือ สร้างใหม่ แก้ไข และดูอย่างเดียว โดยหัวข้อและ breadcrumb เปลี่ยนตามกรณี (ไม่มีโหมดทำสำเนา)
  2. โหมดแก้ไขจะโหลดข้อมูลชุดเดิมและรายการ "ถูกใช้ที่ไหน" พร้อมกัน เพื่อให้เห็นผลกระทบก่อนแก้ไข ส่วนโหมดสร้างใหม่จะตั้งสถานะเริ่มต้นเป็นเปิดใช้งาน
  3. กรอกชื่อชุด แล้วเพิ่มปุ่มทีละรายการ ปุ่มใหม่จะเริ่มต้นเป็นชนิดข้อความเสมอ และปุ่มเพิ่มจะถูกปิดเมื่อครบ 13 รายการ
  4. แต่ละรายการปรับลำดับขึ้น/ลง หรือลบออกได้ ลำดับในหน้าจอคือลำดับที่ chips จะแสดงจริงบน LINE
  5. เมื่อเปลี่ยนชนิดของปุ่ม ระบบจะล้างค่าเฉพาะชนิดเดิมทิ้งและเก็บไว้เฉพาะ label เพื่อไม่ให้ข้อมูลของชนิดเก่าติดค้างไปกับข้อมูลที่บันทึก
  6. คอลัมน์ขวาแสดงตัวอย่าง chips แบบเรียลไทม์ตามที่แก้ไข และในโหมดแก้ไขจะมีการ์ดสรุปว่าชุดนี้ถูกใช้ที่ข้อความใดบ้าง
  7. ก่อนบันทึกระบบตรวจสอบตามลำดับ ได้แก่ ต้องมีอย่างน้อย 1 ปุ่ม ไม่เกิน 13 ปุ่ม ทุกปุ่มต้องมี label ที่ไม่ใช่ช่องว่าง label ไม่เกิน 20 ตัวอักษร และต้องกรอกข้อมูลที่จำเป็นตามชนิดของปุ่มครบ (ข้อความต้องมีข้อความ ลิงก์ต้องมี URL ตัวเลือกวันที่/เวลาต้องมีข้อมูลอ้างอิง)
  8. เมื่อบันทึกสำเร็จ กรณีสร้างใหม่ระบบจะแสดงกล่องแจ้งผลแล้วพากลับหน้ารายการ ส่วนกรณีแก้ไขจะแจ้งผลสั้น ๆ แล้วกลับหน้ารายการทันที
  9. หากการแก้ไขเป็นการปิดใช้งานชุดที่ยังถูกอ้างอิงอยู่ ระบบจะแสดงกล่องยืนยันพร้อมรายการผู้อ้างอิง ยืนยันแล้วจะบันทึกซ้ำแบบบังคับ หากยกเลิกระบบจะคืนค่าสวิตช์สถานะกลับเป็นค่าจริงจากเซิร์ฟเวอร์
  10. หากเซิร์ฟเวอร์ตอบกลับเป็นข้อผิดพลาดรายฟิลด์ ระบบจะแสดงข้อความใต้ฟิลด์นั้นโดยตรง กรณีอื่นจะแสดงเป็นกล่องแจ้งข้อผิดพลาด

การนำชุด quick reply ไปใช้ในข้อความอื่น

  1. ฟอร์มของ Rich Message มีช่องเลือกชุด quick reply ซึ่งโหลดเฉพาะชุดที่เปิดใช้งานอยู่ (สูงสุด 100 รายการ ไม่มีการแบ่งหน้า) และมีตัวเลือก "ไม่ใช้" อยู่หัวรายการ
  2. หากข้อความนั้นผูกกับชุดที่ถูกปิดหรือถูกลบไปแล้ว ระบบจะพยายามดึงข้อมูลชุดนั้นมาแสดงชื่อให้อ่านออก แทนการแสดงรหัสอ้างอิงดิบ
    • ถ้าชุดยังอยู่แต่ปิดใช้งาน จะติดป้ายเตือนว่าชุดที่ปิดอยู่จะไม่ถูกส่ง chips ออกไป
    • ถ้าดึงข้อมูลไม่ได้เลย จะแสดงว่าไม่พบชุดนี้พร้อมข้อความเตือน
  3. เมื่อเลือกชุดแล้ว ระบบจะแสดง label ของปุ่มทั้งหมดใต้ช่องเลือก เพื่อยืนยันว่าเลือกชุดถูกต้อง
  4. หน้าจอพรีวิวแชทของฟีเจอร์ข้อความต่าง ๆ จะแสดง chips ในรูปแบบเดียวกับที่ผู้ใช้เห็นบน LINE

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

หน้ารายการ (/quick-reply)

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

ไฟล์อ้างอิงหลัก: src/app/quick-reply/page.tsx, src/components/quick-reply/list/quick-reply.container.tsx

หน้าฟอร์ม (/quick-reply/form)

  • ช่องชื่อชุด — บังคับกรอก จำกัด 255 ตัวอักษร
  • ตัวแก้ไขรายการปุ่ม — การ์ดต่อ 1 ปุ่ม ประกอบด้วย label ตัวเลือกชนิด ฟิลด์เฉพาะชนิด และปุ่มเลื่อนขึ้น/ลง/ลบ พร้อมตัวนับจำนวนปุ่มที่ใช้ไปเทียบกับเพดาน 13
  • ช่องข้อความของปุ่มชนิดข้อความ — ใช้ช่องกรอกแบบ AutoComplete ที่แนะนำ keyword ของ Auto Response ที่เปิดใช้งานอยู่ เพราะข้อความนี้จะถูกส่งเข้าห้องแชทและอาจไปกระตุ้นกฎ Auto Response
  • สวิตช์สถานะ — กำหนดว่าชุดนี้พร้อมใช้งานหรือไม่
  • แผงพรีวิว chips — ตรึงอยู่กับหน้าจอขณะเลื่อน แสดงผลตามค่าที่กำลังแก้ไขแบบทันที
  • การ์ด "ถูกใช้ที่ไหน" — แสดงเฉพาะโหมดแก้ไข รวมรายการ Rich Message และ Template Message ที่อ้างอิงชุดนี้
  • ในโหมดดูอย่างเดียว ทุกฟิลด์จะถูกปิดการแก้ไขและซ่อนปุ่มบันทึก/ยกเลิก

ไฟล์อ้างอิงหลัก: src/app/quick-reply/form/page.tsx, src/components/quick-reply/form/quick-reply-form.container.tsx, src/components/quick-reply/form/quick-reply-form.tsx, src/components/quick-reply/form/quick-reply-items-editor.tsx

คอมโพเนนต์ร่วม

  • src/components/quick-reply/QuickReplyPicker.tsx — ช่องเลือกชุด quick reply ที่ใช้ในฟอร์ม Rich Message พร้อมกลไกจัดการกรณีชุดที่ผูกไว้ถูกปิดหรือถูกลบ
  • src/components/quick-reply/QuickReplyChipsPreview.tsx — ตัวแสดง chips สไตล์ LINE ใช้ทั้งในฟอร์ม quick reply และในพรีวิวแชทของฟีเจอร์ข้อความอื่น
  • src/components/quick-reply/QuickReplyReferenceList.tsx — ตัวแสดงรายการ "ถูกใช้ที่ไหน" ใช้ร่วมกันทั้งกับข้อมูลที่ดึงมาโดยตรงและกับข้อมูลผู้อ้างอิงที่แนบมากับข้อผิดพลาด

บริการฝั่ง API

รวมอยู่ที่ src/services/quick-reply.service.ts ภายใต้ path หลัก quick-reply

ความสามารถEndpoint
ดึงรายการชุดGET /quick-reply
ดึงข้อมูลชุดรายตัวGET /quick-reply/{id}
ดูรายการผู้อ้างอิงGET /quick-reply/{id}/references
สร้างชุดใหม่POST /quick-reply
แก้ไขชุด (รวมถึงการสลับสถานะ)PUT /quick-reply/{id}
ลบชุดDELETE /quick-reply/{id}

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

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

  • สิทธิ์การใช้งาน — ทั้งหน้ารายการและหน้าฟอร์มถูกควบคุมด้วยสิทธิ์ของโมดูล quick-reply ซึ่งผูกอยู่กับสิทธิ์โมดูลเดียวกับ Auto Response การเปิดสิทธิ์ Auto Response จึงปลดล็อกเมนู Quick Reply ไปพร้อมกัน
  • Rich Message Management — เป็นผู้ใช้หลักของชุด quick reply ผ่านช่องเลือกในฟอร์ม และเป็นสาเหตุหลักที่ทำให้ชุดถูกป้องกันไม่ให้ปิดหรือลบ
  • Template Message — เป็นอีกหนึ่งแหล่งอ้างอิงที่ปรากฏในรายการ "ถูกใช้ที่ไหน"
  • Auto Response — ให้ keyword ที่เปิดใช้งานอยู่มาเป็นคำแนะนำในช่องข้อความของปุ่มชนิดข้อความ เพื่อให้ข้อความที่ปุ่มส่งกลับเข้าแชทตรงกับกฎที่มีอยู่จริง
  • พรีวิวแชทกลาง — คอมโพเนนต์พรีวิวแชทของระบบเรียกใช้ตัวแสดง chips ชุดเดียวกัน ทำให้ภาพตัวอย่างในทุกฟีเจอร์สอดคล้องกัน
  • โครงสร้างพื้นฐานร่วม — ใช้ระบบยืนยันตัวตนและ HTTP client กลางของ CMS (ออกจากระบบอัตโนมัติเมื่อ token หมดอายุ) ระบบ breadcrumb และเมนูด้านข้าง ชุด modal มาตรฐาน และการจดจำเงื่อนไขการกรองใน sessionStorage เช่นเดียวกับหน้ารายการอื่นในระบบ

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

โค้ดฝั่ง backend อยู่ที่โมดูล internal/modules/quickreply/ เป็น โมดูลที่เขียนขึ้นใหม่ ไม่ได้ย้ายมาจากระบบเดิม โครงสร้างจึงอ้างอิงรูปแบบของโมดูลเรียบง่ายที่มีอยู่แล้วในระบบ (เช่น หมวดคอนเทนต์ และ Template Message) จุดที่ต่างจากโมดูลอื่นชัดเจนคือมี endpoint references แยกไว้สำหรับตรวจการอ้างอิงก่อนลบ

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

  • ทุก route ต้องผ่านการยืนยันตัวตนกลาง (JWT) และ token นั้นต้องมีข้อมูล LINE OA ที่เลือกไว้ ถ้าไม่มี request จะไม่ผ่าน
  • ระบบกำหนดชื่อ policy ของโมดูลนี้ให้ตรงกับชื่อโมดูลที่ฝั่ง CMS ใช้ (quick-reply) ไว้ล่วงหน้า เพื่อให้เปิดการบังคับสิทธิ์รายโมดูลได้ในอนาคตโดยไม่ต้องแก้ชื่อ
  • ข้อสังเกตด้านความปลอดภัย — ต่างจาก Auto Response โมดูลนี้ ยังไม่ได้ครอบด้วย module gate และค่า policy ที่ประกาศไว้ยังเป็นเพียงข้อมูลกำกับ (metadata) ที่ยังไม่ถูกบังคับใช้จริง หมายความว่าการซ่อนเมนูตามสิทธิ์เกิดขึ้นที่ฝั่งหน้าจอเป็นหลัก ผู้ใช้ที่ล็อกอินแล้วและเลือก OA แล้วยังเรียก endpoint เหล่านี้ได้โดยตรง จึงไม่ควรถือว่าการซ่อนเมนูเป็นการควบคุมสิทธิ์ที่แท้จริง

Validation และ Business Rule ที่ backend ตรวจ

  • ทุก query ถูก จำกัดขอบเขตตาม LINE OA ที่เลือกอยู่ ข้อมูลของ OA อื่นจะไม่ถูกดึงมาไม่ว่าจะเรียกด้วย id ตรง ๆ ก็ตาม
  • เมื่อขอข้อมูลรายตัวด้วย id ที่ไม่มีอยู่จริง หรือ id ที่เป็นของ OA อื่น backend จะตอบเป็น "ไม่พบข้อมูล" อย่างชัดเจน ไม่ใช่คืนค่าว่างเปล่า ทำให้หน้าจอแยกกรณี "ไม่มีสิทธิ์เห็น" กับ "ข้อมูลผิดพลาด" ได้ถูก
  • GET /api/quick-reply/:id/references เป็น endpoint สำหรับตอบว่าชุดนี้ถูกอ้างอิงอยู่ที่ไหน ซึ่งเป็นข้อมูลที่หน้าจอนำไปแสดงในกล่องเตือนก่อนปิดหรือลบ
  • ไม่มี endpoint แยกสำหรับเปลี่ยนสถานะ การเปิด/ปิดจึงเป็นการเรียก endpoint แก้ไขปกติ (PUT /api/quick-reply/:id) ด้วยข้อมูลทั้งชุด

สิ่งที่บันทึกและผลข้างเคียง (Side Effect)

  • ข้อมูลถูกบันทึกในตาราง quick_reply เพียงตารางเดียว โมดูลนี้ไม่มีการเขียน cache หรือส่งงานเข้าคิวใด ๆ
  • การลบเป็น soft delete โดยประทับเวลาที่ลบไว้ในคอลัมน์ deleted_date แถวข้อมูลยังอยู่ในฐานข้อมูล
  • ชุดปุ่มที่บันทึกไว้จะถูกนำไปแนบกับ payload ที่ส่งเข้า LINE ตอนส่งข้อความจริง ซึ่งเกิดขึ้นในเส้นทางของฟีเจอร์ที่ส่งข้อความ ไม่ใช่ในโมดูลนี้

Edge Case และข้อสังเกตที่ควรรู้

  • โครงสร้างข้อมูลของตารางนี้ไม่ได้ใช้กลไก soft delete อัตโนมัติของ ORM ดังนั้นทุก query ต้องเขียนเงื่อนไข "ยังไม่ถูกลบ" ด้วยตัวเองทุกครั้ง หากมี query ใดลืมใส่เงื่อนไขนี้ ชุดที่ถูกลบไปแล้วจะโผล่กลับมาในผลลัพธ์ เป็นจุดที่ต้องระวังเวลาเพิ่ม query ใหม่ในโมดูลนี้
  • เพราะการลบเป็นแบบ soft delete ชุดที่ผู้ใช้ลบไปแล้วยังถูกอ้างถึงได้จากข้อความที่ผูกไว้เดิม ซึ่งเป็นเหตุผลที่หน้าฟอร์มต้องมีกลไกดึงข้อมูลชุดที่ถูกลบมาแสดงชื่อให้อ่านออก แทนการแสดงรหัสอ้างอิงดิบ
  • การป้องกันไม่ให้ลบชุดที่ยังถูกใช้งาน อาศัยข้อมูลจาก endpoint references ประกอบกับการตรวจฝั่ง backend ตอนลบ การเพิ่มฟีเจอร์ใหม่ที่อ้างอิงชุด quick reply จึงต้องทำให้ endpoint นี้รู้จักแหล่งอ้างอิงใหม่ด้วย ไม่เช่นนั้นการเตือนจะไม่ครบ