Skip to main content

จัดการ Template Message

ภาพรวม

Template Message คือคลัง LINE Flex Message ที่สร้างขึ้นจากแม่แบบสำเร็จรูป โดยระบบเก็บผลลัพธ์ไว้สองรูปแบบควบคู่กัน

  • ข้อมูลที่ผู้ใช้กรอก — เก็บไว้เพื่อให้กลับมาเปิดแก้ไขด้วยฟอร์มเดิมได้
  • Flex JSON ที่พร้อมส่ง — เก็บไว้ให้โมดูลอื่นดึงไปใช้ส่งได้ทันทีโดยไม่ต้องประกอบใหม่

ฟีเจอร์นี้ออกแบบมาสำหรับทีมคอนเทนต์ที่ต้องการสร้าง Flex Message โดยไม่ต้องเขียน JSON เอง แต่ก็ยังเปิดช่องให้ผู้ที่ถนัดเขียน JSON ทำได้โดยตรง

ทุกฟิลด์ข้อความรองรับ merge tag ในรูปแบบ {{key}} เพื่อแทนค่าข้อมูลของผู้รับแต่ละคนตอนส่งจริง

แม่แบบทั้ง 6 ชนิด

ชนิดโครงสร้างจำนวนบับเบิล
Registerไอคอน หัวเรื่อง คำอธิบาย และปุ่มหนึ่งปุ่ม1
Shoppingรูปภาพ หัวเรื่อง หัวเรื่องรอง และปุ่มสองปุ่ม1
Notificationรูปภาพ ไอคอน หัวเรื่อง คำอธิบาย และปุ่มหนึ่งปุ่ม1
Carouselการ์ดหลายใบเรียงแนวนอน แต่ละใบเป็นรูปเต็มใบพร้อมการกระทำหนึ่งอย่างเริ่มที่ 2 ใบ เพิ่มได้ถึง 6 ใบ
Custom JSONเขียน Flex JSON เองทั้งหมดตามที่ JSON กำหนด
Card Builderเครื่องมือประกอบการ์ดแบบ visual จากบล็อกย่อย แล้วแปลงเป็นบับเบิลอัตโนมัติ1

Card Builder เป็นชนิดเริ่มต้นเมื่อสร้างเทมเพลตใหม่

Business Flow

1. หน้ารายการ

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

ข้อควรทราบ — ตัวเลือกชนิดในตัวกรองยังไม่ครอบคลุมแม่แบบ Card Builder จึงยังกรองหาเทมเพลตชนิดนี้จากตัวกรองไม่ได้

2. โครงการทำงานร่วมของหน้าฟอร์ม

  1. หน้าฟอร์มรองรับสี่โหมด คือ สร้างใหม่ แก้ไข คัดลอก และดูรายละเอียด
  2. เมื่อสร้างใหม่ ระบบตั้งชนิดเป็น Card Builder และเตรียมบล็อกเริ่มต้นให้ชุดหนึ่ง (รูปภาพหลัก ข้อความหัวเรื่อง และปุ่ม)
  3. เมื่อเปิดข้อมูลเดิม ระบบแยกเส้นทางการอ่านข้อมูลตามชนิดแม่แบบ โดยแม่แบบแบบมีโครงสร้างจะแปลงที่อยู่ของรูปภาพกลับเป็นไฟล์เพื่อให้แก้ไขต่อได้
  4. การเปลี่ยนชนิดแม่แบบจะเตือนก่อนเสมอ เพราะข้อมูลเดิมจะถูกแทนที่ด้วยค่าตั้งต้นของชนิดใหม่
  5. เนื้อหาตัวอย่างที่ระบบเตรียมไว้ให้เป็นภาษาอังกฤษโดยตั้งใจ ไม่ได้แปลตามภาษาที่ผู้ใช้เลือก มีเพียงชื่อของชนิดแม่แบบเท่านั้นที่แปล
  1. ระบบแสดงรายการการ์ดที่แก้ไขได้ โดยแม่แบบสามชนิดแรกมีใบเดียว ส่วน Carousel แสดงหัวการ์ดพร้อมปุ่มเลื่อนขึ้นลงและลบ และมีปุ่มเพิ่มการ์ดจนกว่าจะครบหกใบ
  2. ฟิลด์ที่แสดงเปลี่ยนตามชนิด
    • หัวเรื่องแสดงในทุกชนิดยกเว้น Carousel
    • คำอธิบายจำกัดความยาว 200 ตัวอักษร
    • รูปภาพรับไฟล์ JPG, JPEG และ PNG ขนาดไม่เกิน 10 เมกะไบต์
    • ไอคอนรับไฟล์ชนิดเดียวกันแต่ขนาดไม่เกิน 1 เมกะไบต์ และเป็นฟิลด์บังคับในแม่แบบที่มีไอคอน
  3. หากรูปหรือไอคอนยังเป็นภาพตัวอย่างที่ระบบเตรียมไว้ หน้าจอจะขึ้นข้อความแจ้งเตือนให้เปลี่ยนเป็นภาพจริง
  4. ปุ่มในการ์ด เลือกชนิดการกระทำได้สี่แบบ
    • ส่งข้อความ — กรอกป้ายกำกับ (ไม่เกิน 50 ตัวอักษร) และข้อความที่จะส่ง
    • เปิดลิงก์ — กรอกป้ายกำกับ (ไม่เกิน 100 ตัวอักษร) และ URL
    • โทรออก — ใช้ช่องป้ายกำกับเก็บหมายเลขโทรศัพท์โดยตรง ไม่มีช่องป้ายกำกับแยก
    • Postback — กรอกข้อมูลที่จะส่งกลับและข้อความที่แสดง
  5. ในแม่แบบ Carousel ช่องป้ายกำกับถูกซ่อนทั้งหมด เพราะการกระทำผูกกับรูปทั้งใบแทนที่จะเป็นปุ่ม
  6. จำนวนปุ่มต่อการ์ดถูกกำหนดตั้งแต่ค่าตั้งต้นของแม่แบบ ไม่มีปุ่มเพิ่มหรือลบปุ่มในหน้าจอ

4. แม่แบบ Custom JSON

  1. หน้าจอเป็นกล่องข้อความขนาดใหญ่สำหรับพิมพ์ Flex JSON พร้อมตัวช่วยแทรก merge tag ณ ตำแหน่งเคอร์เซอร์
  2. ระบบตรวจว่า JSON แปลงค่าได้จริงเมื่อผู้ใช้ออกจากช่อง และแสดงข้อความผิดพลาดหากไม่ผ่าน
  3. หน้าจอตัวอย่างจะอัปเดตเฉพาะเมื่อ JSON ถูกต้อง หาก JSON ยังไม่สมบูรณ์ ตัวอย่างจะคงค่าเดิมไว้โดยไม่แสดงข้อผิดพลาด

5. แม่แบบ Card Builder

Card Builder เป็นเครื่องมือประกอบการ์ดจากบล็อกย่อย เหมาะกับผู้ใช้ที่ต้องการอิสระในการจัดวางโดยไม่ต้องเขียน JSON

  1. นอกจากบล็อกแล้ว ยังต้องกรอกข้อความสำรอง (alt text) ที่จะปรากฏในรายการแชทและการแจ้งเตือน จำกัดความยาว 400 ตัวอักษร
  2. บล็อกที่เพิ่มได้มี 5 ชนิด
    • รูปภาพหลัก — อัปโหลดรูป เลือกอัตราส่วน (หรือใช้อัตราส่วนจริงของรูป) เลือกวิธีจัดวางระหว่างเต็มกรอบแบบครอบตัด กับแสดงรูปทั้งใบ และกำหนดการกระทำเมื่อกดได้
    • วิดีโอ — วาง URL ของไฟล์ MP4 โดยตรง (ไม่ได้อัปโหลดผ่าน CMS) พร้อมอัปโหลดภาพหน้าปก และเลือกอัตราส่วน หากบล็อกนี้ไม่ได้อยู่ตำแหน่งแรก ระบบจะเตือนว่าจะกลายเป็นภาพนิ่ง เพราะ LINE เล่นวิดีโอได้เฉพาะตำแหน่งบนสุดของการ์ด
    • ข้อความ — ข้อความพร้อมตัวเลือกขนาด ความหนา การจัดวาง สีตัวอักษร และสีพื้นหลัง
    • ปุ่ม — ป้ายกำกับ รูปแบบปุ่ม (ทึบ เส้นขอบ หรือข้อความล้วน) สี ความสูง สีพื้นหลัง และการกระทำ
    • เส้นคั่น — เส้นคั่นพร้อมเลือกสี
  3. การกระทำต่อบล็อกเลือกได้สามแบบ คือ ไม่มีการกระทำ เปิดลิงก์ (ต้องเป็น URL แบบ HTTP หรือ HTTPS) และส่งข้อความ
  4. เรียงลำดับบล็อกได้ทั้งการลากวางและปุ่มลูกศรขึ้นลง และลบได้ทีละบล็อก
  5. รูปภาพในบล็อกถูกอัปโหลดขึ้นเซิร์ฟเวอร์ทันทีที่เลือก แล้วเก็บเฉพาะที่อยู่ของรูปไว้ ทำให้ตอนบันทึกส่งเป็น JSON ล้วนโดยไม่มีไฟล์แนบ
  6. การแปลงบล็อกเป็นบับเบิล ทำที่ฝั่งหน้าเว็บ ตามกฎดังนี้
    • หากบล็อกแรกเป็นรูปภาพหรือวิดีโอ จะถูกยกขึ้นเป็นส่วนหัวของการ์ดแบบเต็มขอบ
    • หากบล็อกแรกไม่ใช่รูปหรือวิดีโอ จะไม่ยกอะไรขึ้นเลย ทุกบล็อกอยู่ในเนื้อการ์ดตามลำดับที่ผู้ใช้จัดไว้ ทำให้รองรับกรณีที่ต้องการหัวเรื่องนำหน้ารูป
    • บล็อกข้อความ ปุ่ม และเส้นคั่นที่ไม่ได้กำหนดสีพื้นหลัง จะถูกจัดกลุ่มไว้ในกรอบที่มีระยะขอบ เพื่อให้อ่านง่าย ส่วนบล็อกที่กำหนดสีพื้นหลังจะแสดงเต็มความกว้าง
    • วิดีโอที่ไม่ได้อยู่ตำแหน่งบนสุดจะถูกลดรูปเป็นภาพหน้าปกแทน
    • ตัวแปลงถูกออกแบบให้ยืดหยุ่น บล็อกที่ยังกรอกไม่ครบจะถูกข้ามไปโดยไม่ทำให้ทั้งกระบวนการล้มเหลว เพื่อให้หน้าจอตัวอย่างยังทำงานต่อได้
  7. เกณฑ์การเปิดปุ่มบันทึกแยกจากตัวแปลงและเข้มงวดกว่า คือต้องมีอย่างน้อยหนึ่งบล็อก ทุกบล็อกต้องกรอกครบ และต้องมีบล็อกที่แสดงเนื้อหาจริง ไม่ใช่มีเพียงเส้นคั่น

6. หน้าจอตัวอย่าง การตรวจสอบ และการบันทึก

  1. หน้าจอตัวอย่างอัปเดตอัตโนมัติแบบหน่วงเวลาเมื่อค่าในฟอร์มเปลี่ยน และแสดงผลด้วยตัวเรนเดอร์ Flex Message จริง
  2. เงื่อนไขการเปิดปุ่มบันทึกแตกต่างกันตามชนิดแม่แบบ
    • Custom JSON — ต้องมีชื่อเทมเพลตและ JSON ที่ถูกต้อง
    • Card Builder — ต้องมีชื่อเทมเพลตและผ่านเกณฑ์ของ Card Builder
    • แม่แบบแบบมีโครงสร้าง — ต้องมีชื่อเทมเพลต มีการ์ดอย่างน้อยหนึ่งใบ ทุกใบต้องมีปุ่มอย่างน้อยหนึ่งปุ่ม กรอกฟิลด์บังคับของชนิดนั้นครบ และทุกปุ่มต้องผ่านกฎของชนิดการกระทำที่เลือก
  3. การสร้างใหม่จะบันทึกทันที ส่วนการแก้ไขจะเปิดกล่องยืนยันก่อน
  4. เมื่อบันทึก ระบบส่งข้อมูลต่างกันตามชนิด โดยแม่แบบแบบมีโครงสร้างส่งไฟล์รูปและข้อมูลของแต่ละการ์ด Custom JSON ส่ง JSON ที่พิมพ์ไว้ และ Card Builder ส่งทั้งโครงบล็อกและ Flex JSON ที่แปลงแล้วขึ้นไปพร้อมกัน
  5. หากเซิร์ฟเวอร์แจ้งข้อผิดพลาดรายฟิลด์ ระบบจะแสดงที่ฟิลด์นั้น มิฉะนั้นจะเปิดกล่องแจ้งข้อผิดพลาดที่รองรับรูปแบบข้อความหลายแบบ

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

หน้ารายการ

ตัวควบคุมรายการ (src/components/template-message/list/template-message.container.tsx) ดูแลตาราง ตัวกรอง การเรียงลำดับ และการลบ

หน้าฟอร์ม

หน้าฟอร์มแบ่งเป็นตัวควบคุมที่ดูแลการโหลดและแปลงข้อมูล การประกอบ JSON สำหรับหน้าจอตัวอย่าง กฎการตรวจสอบ และการบันทึก กับคอมโพเนนต์ฟอร์มขนาดใหญ่ที่รวมส่วนแสดงผลของทุกแม่แบบ การจัดการปุ่ม และการอัปโหลดไฟล์

Card Builder

Card Builder อยู่ในโฟลเดอร์ src/components/template-message/form/flex-card-builder/ แยกความรับผิดชอบเป็นสี่ไฟล์ที่ชัดเจน

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

ตัวช่วย merge tag

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

ปลายทาง API

การทำงานปลายทาง
รายการเทมเพลตGET /template-message
ข้อมูลเทมเพลตรายตัวGET /template-message/{id}
รายการสำหรับ dropdown ของโมดูลอื่นGET /template-message/find-all-object
รายการ merge tagGET /template-message/merge-tags
สร้างเทมเพลตPOST /template-message
อัปโหลดรูปของ Card BuilderPOST /template-message/upload-image
แก้ไขเทมเพลตPUT /template-message/{id}
ลบเทมเพลตDELETE /template-message/{id}

ข้อจำกัดที่กำหนดไว้ตายตัว

Carousel เริ่มที่ 2 ใบและเพิ่มได้ถึง 6 ใบ, รูปภาพไม่เกิน 10 เมกะไบต์, ไอคอนไม่เกิน 1 เมกะไบต์, ชื่อเทมเพลตไม่เกิน 100 ตัวอักษร, คำอธิบายไม่เกิน 200 ตัวอักษร, ป้ายกำกับปุ่มส่งข้อความไม่เกิน 50 ตัวอักษร, ป้ายกำกับปุ่มลิงก์ไม่เกิน 100 ตัวอักษร และข้อความสำรองของ Card Builder ไม่เกิน 400 ตัวอักษร

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

  • จัดการ Rich Message — รายการเนื้อหาชนิดเทมเพลตดึงทั้งรายการและเนื้อหาจากโมดูลนี้
  • กฎทริกเกอร์ การติดตามเพื่อน เวิร์กโฟลว์ และตัวสร้างฟอร์ม — ทั้งหมดเลือกเทมเพลตจากโมดูลนี้ไปใช้กำหนดข้อความที่จะส่ง
  • การส่งจริง — เกิดขึ้นที่โมดูลแคมเปญและตอบกลับอัตโนมัติ ผ่าน Rich Message อีกทอดหนึ่ง
  • ตอบกลับอัตโนมัติ — ช่องข้อความของปุ่มช่วยเติมคำจากคีย์เวิร์ดของโมดูลตอบกลับอัตโนมัติ
  • ริชเมนู — ใช้ชุดค่าคงที่ของชนิดการกระทำร่วมกัน
  • สัญญากับฐานข้อมูล — ระบบเก็บทั้งข้อมูลต้นทางที่ผู้ใช้กรอกและ Flex JSON ที่พร้อมส่งไว้คนละฟิลด์ โดยแม่แบบ Card Builder แปลงที่ฝั่งหน้าเว็บแล้วส่งทั้งสองก้อนขึ้นไปพร้อมกัน
  • สิทธิ์การเข้าถึง — โมดูล template-message ฝั่งเซิร์ฟเวอร์ปลดล็อกทั้งหน้ารายการและหน้าฟอร์มอย่างสอดคล้องกัน

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

โควตาจำนวนเทมเพลต

จุดที่มองจากหน้าเว็บไม่เห็นเลยคือ จำนวนเทมเพลตที่สร้างได้ถูกจำกัดด้วยโควตาระดับองค์กร backend จะตรวจโควตาก่อนสร้างทุกครั้ง ถ้าเต็มแล้วจะปฏิเสธพร้อมข้อความว่าถึงเพดานแพ็กเกจ ค่าเริ่มต้นของแพลตฟอร์มคือ 20 เทมเพลต และผู้ดูแลระดับแพลตฟอร์มปรับค่านี้รายองค์กรได้จากหน้าตั้งค่าโมดูลของ organization

หน้าเว็บไม่ได้ตรวจโควตาไว้ล่วงหน้า ผู้ใช้จึงกรอกฟอร์มจนเสร็จแล้วจึงพบว่าบันทึกไม่ได้ ซึ่งควรทราบเมื่อช่วยผู้ใช้ไล่ปัญหา

merge tag มาจากไหน

GET /api/template-message/merge-tags ไม่ได้คืนรายการที่ hard-code ไว้ แต่ประกอบขึ้นจากสองแหล่ง

  1. tag ระบบ เช่น ชื่อผู้ใช้ และชื่อที่แสดงบน LINE
  2. tag จากแอตทริบิวต์ที่องค์กรกำหนดเอง ของ LINE OA นั้น ๆ ดังนั้นรายการที่เห็นในตัวช่วยเลือก merge tag จะต่างกันไปตาม channel และเปลี่ยนตามการตั้งค่าแอตทริบิวต์

พารามิเตอร์ showSystem เป็นตัวควบคุมว่าจะรวม tag ระบบเข้าไปด้วยหรือไม่

การแทนค่า merge tag ไม่ได้เกิดที่โมดูลนี้ — เทมเพลตเก็บข้อความที่ยังมี merge tag อยู่ตามเดิม การแทนค่าจริงเกิดตอนประกอบข้อความเพื่อส่ง ซึ่งอยู่ในบริการจัดการข้อความของ LINE ที่แคมเปญ ระบบตอบกลับอัตโนมัติ และเวิร์กโฟลว์เรียกใช้ร่วมกัน

กฎอื่นที่ backend ตรวจ

  • ชื่อซ้ำถูกปฏิเสธ ภายในขอบเขตของ OA เดียวกัน
  • ทั้งการสร้างและแก้ไขรับข้อมูลแบบ multipart เพื่อรองรับไฟล์รูปที่แนบมาพร้อมข้อมูลอื่น
  • POST /api/template-message/upload-image เป็นเส้นทางแยกสำหรับรูปของ Card Builder และถูกวางไว้เป็นเส้นทางแบบคงที่โดยเจตนา เพื่อไม่ให้ถูกตีความเป็นรหัสเทมเพลตในการจับคู่เส้นทาง

สิทธิ์

  • ทุกเส้นทางถูกครอบด้วย ModuleGate ของโมดูล template-message ซึ่งบังคับใช้จริง — องค์กรที่ถูกปิดโมดูลนี้จะใช้งานไม่ได้ทั้งชุด
  • ข้อมูลกำกับสิทธิ์รายการกระทำมีอยู่แต่ยังไม่บังคับใช้
  • GET /api/template-message/find-all-object ที่โมดูลอื่นใช้ทำ dropdown ไม่มีข้อมูลกำกับสิทธิ์เลย ตามที่ระบบเวอร์ชันก่อนหน้าเป็น

ผลข้างเคียงและข้อควรรู้

  • Redis cache — backend เก็บ cache ทั้งรายการและรายละเอียดเทมเพลต
  • รูปของ Card Builder ถูกเก็บบน object storage สิ่งที่บันทึกในเทมเพลตคือที่อยู่ของรูป สอดคล้องกับที่หน้าเว็บอัปโหลดรูปทันทีที่เลือกแล้วส่งเฉพาะที่อยู่ตอนบันทึก
  • backend ไม่ได้ตรวจสอบความถูกต้องของ Flex JSON ในโมดูลนี้ ต่างจาก Rich Message ที่ส่งไปให้ LINE ตรวจ ดังนั้น JSON ที่ผิดโครงสร้างอาจบันทึกผ่านที่นี่ แล้วไปพบปัญหาตอนถูกนำไปส่งจริง