สร้างฟอร์มและคำตอบ (Form Builder)
ภาพรวม
Form Builder คือเครื่องมือให้แอดมินของ LINE OA สร้างฟอร์มออนไลน์ในลักษณะเดียวกับ Google Form แล้วเผยแพร่เป็นลิงก์ให้ผู้ใช้ LINE เข้ามากรอก จากนั้นกลับมาดูคำตอบ สถิติการส่ง และดาวน์โหลดข้อมูลเป็นไฟล์ CSV ได้จากในระบบ CMS
ฟีเจอร์นี้เหมาะกับทีมการตลาดหรือทีมดูแลลูกค้าที่ต้องการเก็บข้อมูลจากผู้ใช้ LINE เช่น แบบฟอร์มลงทะเบียนกิจกรรม แบบสำรวจความพึงพอใจ ใบสมัครสมาชิก หรือฟอร์มยืนยันตัวตนก่อนรับสิทธิ์ โดยสามารถเชื่อมคำตอบเข้ากับ Member Database และตั้งค่าให้ต้องยืนยันตัวตนด้วย OTP ก่อนส่งฟอร์มได้
ฟีเจอร์แบ่งเป็น 3 หน้าจอหลัก
| หน้าจอ | Route | หน้าที่ |
|---|---|---|
| รายการฟอร์ม | /form-builder | ค้นหา กรอง คัดลอกลิงก์ แก้ไข ดูคำตอบ และลบฟอร์ม |
| ตัวสร้างฟอร์ม | /form-builder/form | แก้ไขฟอร์ม 5 แท็บ พร้อมพรีวิวสดในคอลัมน์ขวา |
| หน้าคำตอบ | /form-builder/response | สถิติ ตารางคำตอบ และส่งออก CSV |
ข้อจำกัดและกติกาสำคัญที่ควรทราบก่อนใช้งาน
| หัวข้อ | รายละเอียด |
|---|---|
| จำนวนคำถาม | สูงสุด 10 ข้อต่อฟอร์ม โดยไม่นับองค์ประกอบจัดหน้า (หัวข้อใหญ่ หัวข้อรอง เส้นคั่น) ซึ่งเพิ่มได้ไม่จำกัด |
| คำถามข้อมูลส่วนบุคคล | ชื่อ นามสกุล อีเมล เบอร์โทร เลขบัตรประชาชน และวันเกิด เพิ่มได้ชนิดละ 1 ข้อเท่านั้น |
| สถานะฟอร์ม | draft / active / inactive เมื่อเผยแพร่เป็น active หรือ inactive แล้วจะย้อนกลับไปเป็น draft ไม่ได้ |
| OTP ระดับฟอร์ม | ตั้งได้ 1 ฟิลด์ต่อฟอร์ม และเปิดใช้ได้เฉพาะเมื่อเปิด Profile Mapping พร้อมเลือก Member Database แล้ว |
| รูปภาพหน้าปก | ไฟล์ JPG หรือ PNG ขนาดไม่เกิน 10MB และกว้างอย่างน้อย 1024px |
โครงสร้างข้อมูลของฟอร์มถูกจัดเก็บเป็นก้อนเดียว ไม่ได้แยกตารางรายคำถาม การบันทึกจึงส่งข้อมูลแบบ multipart ที่ประกอบด้วยชุดคำถาม (questions), ธีมและหน้าปก (theme, coverImage), หน้าขอบคุณ (thankYou), การจับคู่กับ Member Database และ OTP (profileMapping) และการจับคู่คำตอบเข้ากับ custom attribute (fieldAttributeMappings)
ชนิดคำถามที่รองรับ
| กลุ่ม | ชนิดคำถาม |
|---|---|
| ช่องกรอกทั่วไป | ข้อความสั้น ข้อความยาว อีเมล เบอร์โทร ตัวเลข อัปโหลดไฟล์ วันที่ URL |
| ข้อมูลส่วนบุคคล | ชื่อ นามสกุล เลขบัตรประชาชน วันเกิด (กำหนดอายุขั้นต่ำได้) |
| ตัวเลือก | ตัวเลือกเดียว หลายตัวเลือก ดรอปดาวน์ ดรอปดาวน์แบบเลือกหลายค่า |
| พิเศษ | ข้อตกลงและเงื่อนไข (ลิงก์หรือข้อความเต็ม), ช่องกรอกกำหนดเอง (regex หรือรูปแบบตัวอักษร/ตัวเลข พร้อมความยาวขั้นต่ำ-สูงสุด) |
| ตรวจสอบกับฐานข้อมูล | ช่องตรวจสอบระเบียนสมาชิก (db_validation) ใช้ได้เมื่อเปิด Profile Mapping แล้ว |
| จัดหน้า | หัวข้อใหญ่ หัวข้อรอง เส้นคั่น |
ตัวดำเนินการของเงื่อนไขการแสดงคำถาม
ชุดตัวดำเนินการที่เลือกได้ขึ้นอยู่กับชนิดของคำถามแม่ที่อ้างถึง
| ชนิดคำตอบของคำถามแม่ | ตัวดำเนินการที่ใช้ได้ |
|---|---|
| ข้อความ | มีการตอบ, เท่ากับ, ไม่เท่ากับ, มีคำว่า, ไม่มีคำว่า |
| ตัวเลข | มีการตอบ, เท่ากับ, ไม่เท่ากับ, มากกว่า, มากกว่าหรือเท่ากับ, น้อยกว่า, น้อยกว่าหรือเท่ากับ, อยู่ในช่วง, ไม่อยู่ในช่วง |
| วันที่ | มีการตอบ, เท่ากับ, ไม่เท่ากับ, อยู่ในช่วง, ไม่อยู่ในช่วง |
| ตัวเลือกเดียว | เท่ากับ, ไม่เท่ากับ |
| หลายตัวเลือก | มีการตอบ, เท่ากับ, ไม่เท่ากับ, มีคำว่า, ไม่มีคำว่า |
องค์ประกอบจัดหน้าไม่สามารถใช้เป็นคำถามแม่ของเงื่อนไขได้ และเงื่อนไขแบบอยู่ในช่วงจะแสดงช่องกรอกค่าต้นและค่าปลาย
Business Flow
จัดการรายการฟอร์ม
- เข้าหน้ารายการ ระบบตรวจสิทธิ์
VIEWของโมดูลform-builderก่อนแสดงผล - ระบบอ่านเงื่อนไขการกรองล่าสุดจากเซสชัน ถ้ายังไม่เคยกรองจะใช้ค่าเริ่มต้นคือเรียงตามวันที่สร้างจากใหม่ไปเก่า หน้าละ 10 รายการ
- กรองข้อมูลได้จากคำค้นและสถานะฟอร์ม โดยต้องกดปุ่มค้นหาจึงจะมีผล และการค้นหาจะรีเซ็ตกลับไปหน้าแรกเสมอ
- ตารางแสดงชื่อฟอร์ม คำอธิบาย ลิงก์สำหรับเผยแพร่พร้อมปุ่มคัดลอก วันที่สร้าง สถานะ และจำนวนคำตอบที่ได้รับ รองรับการเรียงลำดับเฉพาะคอลัมน์วันที่สร้าง
- แต่ละแถวมีปุ่มแก้ไข ปุ่มดูคำตอบ และปุ่มลบ การลบต้องยืนยันในกล่องข้อความก่อน เมื่อสำเร็จตารางจะรีเฟรชโดยไม่ต้องโหลดหน้าใหม่
สร้างและแก้ไขฟอร์ม
- หน้าตัวสร้างฟอร์มรับพารามิเตอร์เพื่อกำหนดโหมดการทำงาน ได้แก่ สร้างใหม่ แก้ไข ทำสำเนา และดูอย่างเดียว โดยหัวข้อบนหน้าจะเปลี่ยนตามโหมด
- ระบบโหลดข้อมูลตั้งต้นพร้อมกัน 3 ชุด คือ ข้อมูลฟอร์มเดิม (เฉพาะกรณีแก้ไข) กฎการตรวจสอบกลางของแต่ละชนิดคำถาม และรายการ Member Database สำหรับใช้ใน Profile Mapping
- กรณีสร้างใหม่ ระบบล้าง state ทั้งหมดและตั้งสถานะเริ่มต้นเป็น
draftกรณีแก้ไข ระบบเติมค่าคำถาม ธีม หน้าขอบคุณ และการตั้งค่า Profile Mapping กลับเข้าฟอร์ม - กรอกข้อมูลทั่วไปของฟอร์ม ได้แก่ ชื่อฟอร์ม (บังคับ ไม่เกิน 200 ตัวอักษร) คำอธิบาย (ไม่เกิน 250 ตัวอักษร) สวิตช์เปลี่ยนผู้เยี่ยมชมเป็นสมาชิก สวิตช์จำกัดการส่งได้ครั้งเดียวต่อผู้ใช้ และสถานะการเผยแพร่
- เพิ่มคำถามได้จากปุ่มลัดที่แบ่งเป็นกลุ่ม หรือจากดรอปดาวน์รวมทุกชนิด ระบบตั้งชื่อคำถามเริ่มต้นให้ไม่ซ้ำกันโดยอัตโนมัติ และดึงกฎกลางของชนิดนั้นมาใช้ เช่น ชนิดไฟล์แนบจะได้รายการนามสกุลไฟล์ที่อนุญาตมาให้แล้ว
- ปรับแต่งคำถามแต่ละข้อได้ทั้งการเปลี่ยนชนิด กำหนดว่าบังคับกรอกหรือไม่ ทำสำเนา ลบ และลากเปลี่ยนลำดับ
- ตั้งเงื่อนไขการแสดงคำถามได้ โดยเลือกคำถามแม่ ตัวดำเนินการ และค่าที่ใช้เปรียบเทียบ ชุดตัวดำเนินการที่เลือกได้จะเปลี่ยนตามชนิดของคำถามแม่ ส่วนตัวดำเนินการช่วงค่าจะแสดงช่องกรอก 2 ช่อง
- หากลากคำถามลูกไปอยู่ก่อนคำถามแม่ ระบบจะแสดงกล่องยืนยันและตัดความสัมพันธ์ของเงื่อนไขนั้นทิ้งเมื่อผู้ใช้ยืนยัน เพื่อไม่ให้เกิดเงื่อนไขที่อ้างถึงคำถามซึ่งยังไม่ปรากฏ
- คอลัมน์ขวาแสดงพรีวิวสดที่สลับได้ 3 หน้า คือ หน้าฟอร์ม หน้ายืนยัน OTP (แสดงเมื่อเปิด OTP) และหน้าขอบคุณ พรีวิวจะสลับตามแท็บที่กำลังแก้ไขโดยอัตโนมัติ และใช้สีตามธีมที่ตั้งไว้จริง
- เมื่อกดบันทึก ระบบตรวจสอบความถูกต้องฝั่งหน้าจอก่อนส่ง เช่น ต้องมีคำถามอย่างน้อย 1 ข้อและมีข้อที่บังคับกรอกอย่างน้อย 1 ข้อ ทุกคำถามต้องมีชื่อ คำถามแบบตัวเลือกต้องมีตัวเลือกครบ คำถามที่มีเงื่อนไขต้องระบุคำถามแม่และค่าให้ครบ และหน้าขอบคุณแบบกำหนดเองต้องมีข้อความและปุ่มที่ถูกต้อง
- เมื่อผ่านการตรวจสอบ ระบบประกอบข้อมูลทั้งหมดเป็นชุดเดียวแล้วส่งไปสร้างหรืออัปเดต จากนั้นพากลับสู่หน้ารายการ หากเซิร์ฟเวอร์ปฏิเสธจะนำข้อความจาก API มาแสดงให้ผู้ใช้เห็นโดยตรง
- การกดยกเลิกขณะที่กรอกชื่อหรือเพิ่มคำถามไว้แล้ว จะมีกล่องยืนยันก่อนออกจากหน้า
เชื่อมฟอร์มกับ Member Database (Profile Mapping)
- เปิดสวิตช์ Profile Mapping แล้วเลือก Member Database ที่ต้องการเชื่อม
- จับคู่คอลัมน์ของฐานข้อมูลกับคำถามชนิดตรวจสอบระเบียน เพื่อให้ระบบใช้คำตอบเหล่านั้นค้นหาระเบียนสมาชิกที่ตรงกัน สามารถกดเพิ่มช่องกรอกจากหน้าจอนี้ได้โดยตรง
- กำหนดผลลัพธ์เมื่อค้นหาระเบียนพบ ได้แก่ attribute ที่จะใช้บันทึกสถานะการยืนยันและค่าที่จะเขียนลงไป และเลือกได้ว่าจะจำกัดหนึ่งบัญชี LINE ต่อหนึ่งระเบียนหรือไม่ พร้อมข้อความแจ้งเมื่อระเบียนถูกใช้ไปแล้ว
- กำหนดพฤติกรรมเมื่อค้นหาระเบียนไม่พบ ว่าจะปฏิเสธพร้อมข้อความแจ้ง หรือให้ลงทะเบียนเป็นระเบียนใหม่
- ในแท็บ Field Mapping จับคู่คำตอบของแต่ละคำถามเข้ากับ custom attribute ของผู้ใช้ เพื่อให้ข้อมูลไหลกลับไปที่โปรไฟล์สมาชิก
ตั้งค่ายืนยันตัวตนด้วย OTP ระดับฟอร์ม
- แท็บการยืนยันตัวตนจะปรากฏเฉพาะเมื่อผู้ใช้มีสิทธิ์เข้าถึง Member Database
- ระบบอ่านสถานะช่องทาง OTP ของ LINE OA จากหน้าตั้งค่ายืนยัน OTP เพื่อรู้ว่า SMS และอีเมลพร้อมใช้งานแล้วหรือยัง
- สวิตช์เปิดการยืนยันตัวตนจะกดได้เฉพาะเมื่อเปิด Profile Mapping เลือกฐานข้อมูลแล้ว และฐานข้อมูลนั้นมีคอลัมน์อย่างน้อย 1 คอลัมน์ หากเงื่อนไขไม่ครบ ระบบจะอธิบายเหตุผลไว้ในแถบเตือน
- เมื่อเปิดสวิตช์ครั้งแรก ระบบสร้างแถวตั้งค่าให้ 1 แถวโดยเลือกช่องทางที่พร้อมใช้งานให้อัตโนมัติ (เลือก SMS ก่อน ถ้าไม่พร้อมจึงใช้อีเมล) หากยังไม่มีช่องทางใดพร้อม ระบบจะไม่สร้างแถวและปิดปุ่มเพิ่มฟิลด์
- แต่ละแถวคือการเลือกคอลัมน์ของ Member Database ที่จะใช้ส่งรหัส และเลือกช่องทางส่ง จุดสำคัญคือรหัสถูกส่งไปยังค่าในระเบียนที่ค้นหาเจอ ไม่ใช่ค่าที่ผู้ใช้กรอกในฟอร์ม
- ปรับข้อความบนหน้ายืนยันได้ 4 จุด คือ หัวข้อ คำอธิบาย ปุ่มยืนยัน และปุ่มขอรหัสใหม่ ช่องที่เว้นว่างจะใช้ข้อความมาตรฐานแทน โดยคำอธิบายรองรับตัวแปร
{destination}สำหรับแสดงช่องทางติดต่อแบบปิดบังบางส่วน - หากภายหลังช่องทางที่เลือกไว้ถูกปิดที่หน้าตั้งค่า OTP ระดับ OA ฟอร์มจะยังคงการตั้งค่าเดิมไว้แต่แสดงแถบเตือนพร้อมลิงก์ไปแก้ไข ส่วนการปิด OTP อัตโนมัติจะเกิดเฉพาะเมื่อ Profile Mapping หรือฐานข้อมูลที่ผูกไว้หายไป
ดูคำตอบและส่งออกข้อมูล
- เข้าหน้าคำตอบจากปุ่มในตารางรายการฟอร์ม หากเปิดหน้าโดยไม่มีรหัสฟอร์ม ระบบจะพากลับหน้ารายการทันที
- ส่วนบนแสดงการ์ดสถิติ 3 ใบ คือ จำนวนทั้งหมด ส่งครบถ้วน และยังไม่ครบถ้วน กดที่การ์ดเพื่อกรองตารางด้านล่างตามสถานะนั้นได้
- ระบบอ่านโครงคำถามของฟอร์มมาสร้างคอลัมน์ตารางแบบอัตโนมัติ โดยมีคอลัมน์ข้อมูลประกอบตรึงไว้ทางซ้าย 3 คอลัมน์ ได้แก่ เวลาที่ส่ง (เรียงลำดับได้) สถานะการส่ง และรหัสผู้ใช้ LINE ที่คัดลอกได้ ตามด้วยคอลัมน์ของคำถามแต่ละข้อ (ข้ามองค์ประกอบจัดหน้า)
- ค่าคำตอบถูกแสดงตามชนิดคำถาม เช่น ข้อตกลงแสดงเป็นใช่หรือไม่ใช่ URL แสดงเป็นลิงก์เปิดแท็บใหม่ ไฟล์แนบแสดงเป็นลิงก์เปิดหน้าต่างพรีวิว วันที่จัดรูปแบบให้อ่านง่าย และคำตอบแบบหลายตัวเลือกแสดงต่อกันด้วยเครื่องหมายจุลภาค ทุกเซลล์ตัดข้อความบรรทัดเดียวพร้อม tooltip แสดงค่าเต็ม
- ปุ่มส่งออก CSV จะดาวน์โหลดข้อมูลตามเงื่อนไขการกรองที่ใช้อยู่ ระบบตั้งชื่อไฟล์ให้อัตโนมัติโดยอ้างอิงรหัสฟอร์มและเวลาที่ส่งออก
หน้าจอและองค์ประกอบหลัก
หน้ารายการฟอร์ม (/form-builder)
- ส่วนกรองข้อมูล — ช่องค้นหาและตัวเลือกสถานะ พร้อมปุ่มค้นหาและล้างค่า เงื่อนไขล่าสุดถูกจดจำไว้ในเซสชัน
- ตารางรายการ — ชื่อฟอร์ม คำอธิบาย ลิงก์เผยแพร่พร้อมปุ่มคัดลอก วันที่สร้าง สถานะ จำนวนคำตอบ และปุ่มดำเนินการ 3 ปุ่ม
- กล่องยืนยันการลบ — ใช้ชุด modal มาตรฐานของระบบ
ไฟล์อ้างอิงหลัก: src/app/form-builder/page.tsx, src/components/form-builder/list/form-builder.container.tsx, src/components/form-builder/list/form-builder-table.tsx
หน้าตัวสร้างฟอร์ม (/form-builder/form)
หน้าจอแบ่งเป็น 2 คอลัมน์ ฝั่งซ้ายเป็นส่วนแก้ไข ฝั่งขวาเป็นพรีวิวแบบ sticky ส่วนแก้ไขประกอบด้วยข้อมูลทั่วไปของฟอร์ม ส่วน Profile Mapping และชุดแท็บ 5 แท็บ
| แท็บ | เนื้อหา |
|---|---|
| สร้างฟอร์ม | เพิ่ม แก้ไข เรียงลำดับคำถาม ตั้งตัวเลือกและเงื่อนไขการแสดงผล |
| Field Mapping | จับคู่คำตอบกับ custom attribute ของผู้ใช้ |
| ปรับแต่งรูปแบบ | รูปหน้าปก ชุดสี 7 ค่า และรูปแบบปุ่ม |
| การยืนยันตัวตน | ตั้งค่า OTP ระดับฟอร์มและข้อความบนหน้ายืนยัน |
| หน้าขอบคุณ | โหมดมาตรฐานหรือกำหนดเอง ไอคอน ข้อความ ปุ่ม action และการปิดหน้าอัตโนมัติ |
ทุกแท็บถูก render ไว้พร้อมกันและซ่อนด้วย CSS ค่าที่กรอกค้างไว้จึงไม่หายเมื่อสลับแท็บ
แท็บปรับแต่งรูปแบบกำหนดสีได้ 7 ค่า ครอบคลุมพื้นหลังหน้า พื้นหลังฟอร์ม สีข้อความ สีปุ่ม และสีหลัก/สีรองของธีม โดยมีชุดสีเริ่มต้นของระบบเตรียมไว้ให้ ส่วนปุ่ม action ของหน้าขอบคุณเลือกได้ทั้งแบบไม่มีปุ่ม เปิด URL หรือเปลี่ยนริชเมนูของผู้ใช้
องค์ประกอบสำคัญอื่น
- การ์ดคำถาม — มีที่จับสำหรับลาก สวิตช์บังคับกรอก ปุ่มทำสำเนาและปุ่มลบ เนื้อหาภายในการ์ดเปลี่ยนตามชนิดคำถามที่เลือก
- ส่วนตั้งค่าเงื่อนไข — เลือกคำถามแม่ ตัวดำเนินการ และค่าเปรียบเทียบ พร้อมช่องกรอกคู่สำหรับเงื่อนไขแบบช่วงค่า
- ส่วน Profile Mapping — แผงแบบพับได้ 3 ขั้น คือ เลือกฐานข้อมูล จับคู่คอลัมน์ และกำหนดผลลัพธ์
- แผงพรีวิว — ตัวสลับ 3 หน้าจอที่ผูกกับแท็บที่กำลังแก้ไข
ไฟล์อ้างอิงหลัก: src/app/form-builder/form/page.tsx, src/components/form-builder/form/form-builder-form.tsx, src/components/form-builder/form/hooks/useFormBuilder.ts, src/components/form-builder/form/components/FormBuilderTabs.tsx, src/components/form-builder/form/verification/verification-form.tsx
หน้าคำตอบ (/form-builder/response)
- การ์ดสถิติ — จำนวนทั้งหมด ส่งครบถ้วน และยังไม่ครบถ้วน กดเพื่อกรองตาราง
- การ์ดสรุปฟอร์ม — ชื่อ คำอธิบาย วันที่สร้าง สถานะ การเปลี่ยนผู้เยี่ยมชมเป็นสมาชิก และจำนวนคำถาม
- ตารางคำตอบ — คอลัมน์ข้อมูลประกอบตรึงซ้าย ตามด้วยคอลัมน์ของคำถาม ความกว้างคอลัมน์ปรับตามความยาวชื่อคำถาม
- หน้าต่างพรีวิวไฟล์ — เปิดดูไฟล์ที่ผู้ตอบอัปโหลดโดยไม่ต้องออกจากหน้า
- ปุ่มส่งออก CSV — ดาวน์โหลดตามเงื่อนไขการกรองปัจจุบัน
ไฟล์อ้างอิงหลัก: src/app/form-builder/response/page.tsx, src/components/form-builder/response/form-builder-response.container.tsx, src/components/form-builder/response/helpers/column-utils.tsx
บริการฝั่ง API
ฟอร์มใช้ src/services/form-builder.service.ts ส่วนหน้าคำตอบใช้ src/services/form-builder-response.service.ts
| ความสามารถ | Endpoint |
|---|---|
| ดึงรายการฟอร์ม | GET /form-builder |
| ดึงข้อมูลฟอร์มรายตัว | GET /form-builder/{id} |
| สร้างฟอร์มใหม่ | POST /form-builder |
| แก้ไขฟอร์ม | PUT /form-builder/{id} |
| ลบฟอร์ม | DELETE /form-builder/{id} |
| ดึงกฎการตรวจสอบกลาง | GET /form-builder/common-rules |
| ดึงรายการคำตอบ | GET /form-builder/{formHash}/responses |
| ดึงสถิติการส่ง | GET /form-builder/{formHash}/stats |
| ส่งออกคำตอบเป็น CSV | GET /form-builder/{formHash}/export |
การสร้างและแก้ไขฟอร์มส่งข้อมูลแบบ multipart เนื่องจากต้องแนบไฟล์รูปหน้าปกไปพร้อมกับข้อมูลฟอร์ม
จุดเชื่อมต่อกับฟีเจอร์อื่น
- สิทธิ์การใช้งาน — ทุกหน้าถูกควบคุมด้วยสิทธิ์ของโมดูล
form-builderและการเปิดโมดูลนี้จะปลดล็อกหน้าตั้งค่ายืนยัน OTP ไปพร้อมกัน เพราะทั้งสองใช้โมดูลเดียวกัน - Member Database — เป็นเงื่อนไขของส่วน Profile Mapping และแท็บการยืนยันตัวตน หากผู้ใช้ไม่มีสิทธิ์เข้าถึงโมดูลนี้ ทั้งสองส่วนจะไม่แสดงเลย และเป็นแหล่งข้อมูลคอลัมน์ที่ใช้จับคู่และใช้เป็นปลายทางส่ง OTP
- ตั้งค่ายืนยัน OTP — เป็นชั้นล่างที่กำหนดว่า LINE OA ส่ง OTP ได้ทางช่องทางใด แท็บการยืนยันตัวตนอ่านสถานะความพร้อมของแต่ละช่องทางจากที่นี่ และแถบเตือนทุกจุดจะลิงก์กลับไปยังหน้าดังกล่าว
- Attribute Setup และ Template Message — เป็นแหล่งรายการ custom attribute ที่ใช้ในดรอปดาวน์ของ Profile Mapping และ Field Mapping
- Rich Menu Management — เป็นแหล่งรายการริชเมนูสำหรับปุ่ม action ของหน้าขอบคุณ กรณีตั้งค่าให้เปลี่ยนริชเมนูหลังส่งฟอร์มพร้อมกับสวิตช์เปลี่ยนผู้เยี่ยมชมเป็นสมาชิก ผลลัพธ์ที่ประมวลผลทีหลังจะเป็นตัวที่มีผลจริง
- Content Management — หน้าขอบคุณแบบกำหนดเองใช้ตัวแก้ไขข้อความ rich text ชุดเดียวกับโมดูลจัดการเนื้อหา
- โครงสร้างพื้นฐานร่วม — ใช้ระบบยืนยันตัวตนและ HTTP client กลางของ CMS (ออกจากระบบอัตโนมัติเมื่อ token หมดอายุ ทำให้ข้อมูลถูกจำกัดอยู่ที่ LINE OA ที่ล็อกอินอยู่เสมอ) ระบบ breadcrumb และเมนูด้านข้าง ชุด modal มาตรฐาน และการจดจำเงื่อนไขการกรองใน sessionStorage เช่นเดียวกับหน้ารายการอื่นในระบบ
รายละเอียดฝั่ง Backend (CMS API)
โค้ดฝั่ง backend อยู่ที่ internal/modules/formbuilder/ โดยรวม logic ของสามส่วน (ตัวฟอร์ม, กฎของฟอร์ม และคำตอบที่ส่งเข้ามา) ไว้ในบริการเดียว
จุดที่ต้องเข้าใจก่อน — cms-api เป็นเพียงฝั่งสร้างฟอร์มและอ่านคำตอบ เท่านั้น การรับคำตอบจากผู้กรอกจริงเกิดที่ line-management-client-api-go ซึ่งเป็นคนละ service หน้าจอนี้จึงไม่มีทางเห็นข้อผิดพลาดตอนผู้ใช้ส่งฟอร์มโดยตรง
สิทธิ์ที่ต้องมี
- ทุก route ถูกครอบด้วย module gate ของโมดูล
form-builderและโมดูลนี้เป็น ตัวอย่างอ้างอิงของกลไก module gate ทั้งระบบ จึงเป็นจุดที่การบังคับสิทธิ์ระดับโมดูลทำงานจริงและเข้มงวดที่สุด - policy ระดับการกระทำถูกประกาศไว้เฉพาะ การสร้าง (
create) และการแก้ไข (update) เท่านั้น - ข้อสังเกตด้านความปลอดภัย — endpoint กลุ่มอ่าน (รายการ, รายละเอียด, คำตอบ, สถิติ, ส่งออก CSV) และ endpoint ลบฟอร์ม ไม่ได้ประกาศ policy รายการกระทำไว้ การผ่าน module gate จึงเพียงพอที่จะเรียกได้ นั่นหมายความว่าผู้ใช้ที่เข้าถึงโมดูลฟอร์มได้ก็ลบฟอร์มและส่งออกคำตอบทั้งหมดได้ แม้บทบาทจะตั้งใจให้ดูอย่างเดียวก็ตาม
Validation และ Business Rule ที่ backend ตรวจ
- ตอนสร้างฟอร์ม backend เป็นผู้ สร้าง form hash ที่ใช้เป็นตัวอ้างอิงสาธารณะของฟอร์ม ไม่ใช่ค่าที่ผู้ใช้กำหนดเอง — และเป็นค่าที่หน้าคำตอบใช้อ้างถึงฟอร์มแทน id ภายใน
GET /api/form-builder/common-rulesคืนชุดกฎการตรวจสอบมาตรฐานต่อชนิดคำถาม (เช่น นามสกุลไฟล์ที่อนุญาตของคำถามแนบไฟล์) ซึ่งเป็นนิยามจากฝั่ง backend ไม่ใช่ค่าที่ฝังไว้ในหน้าจอ- การสร้างและแก้ไขรับข้อมูลแบบ
multipart/form-dataเพราะรูปหน้าปกและไฟล์ประกอบเดินทางมาพร้อมกับข้อมูลฟอร์ม - โครงสร้างคำถามทั้งชุดถูกเก็บเป็นก้อนเดียว ไม่ได้แตกเป็นตารางรายคำถาม การบันทึกแต่ละครั้งจึงเป็นการเขียนทับทั้งชุด
สิ่งที่บันทึกและผลข้างเคียง (Side Effect)
- ตัวฟอร์มอยู่ในตาราง
form_builderตรรกะเงื่อนไขอยู่ในตารางform_builder_ruleและคำตอบที่ส่งเข้ามาอยู่ในตารางform_submission - เมื่อมีคำตอบใหม่เข้ามา ระบบ publish เหตุการณ์ลงคิว
form_submitted_triggerให้ Trigger Rule และ Workflow นำไปสั่งงานต่อ ฟอร์มจึงเป็นจุดเริ่มของ automation ได้ ไม่ใช่แค่ที่เก็บข้อมูล - คำตอบที่ตั้ง profile mapping ไว้จะถูกเขียนกลับ เข้าไปยัง Member Database และ custom attribute ของผู้ใช้ LINE การส่งฟอร์มหนึ่งครั้งจึงอาจเปลี่ยนข้อมูลโปรไฟล์ของผู้ใช้ไปด้วย
- ความสัมพันธ์ระหว่างฟอร์มกับ Member Database เก็บอยู่ในค่าการตั้งค่า profile mapping ของตัวฟอร์มเอง และเป็นค่าเดียวกับที่หน้า Member Database ค้นย้อนกลับเพื่อแสดงว่า "ฟอร์มใดผูกอยู่"
- ไฟล์แนบที่ผู้ตอบอัปโหลดและไฟล์ CSV ที่ส่งออก อยู่บน object storage
- โมดูลนี้เปิดฟังก์ชันดึงข้อมูลฟอร์มให้โมดูลอื่นเรียกใช้ ซึ่ง Audience Filter เป็นผู้ใช้หลักตอนสร้างเงื่อนไขจากคำถามในฟอร์ม
Edge Case และข้อสังเกตที่ควรรู้
- การลบฟอร์มไม่มีการตรวจการอ้างอิงล่วงหน้า ต่างจาก Quick Reply ที่มี endpoint ตรวจการใช้งาน ทั้งที่ Audience Filter และ Trigger Rule อาจอ้างถึงฟอร์มนั้นอยู่ กฎที่ผูกไว้จึงอาจกลายเป็นกฎที่อ้างถึงฟอร์มที่ไม่มีแล้ว
- เพราะการรับคำตอบเกิดที่ service อื่น การเปลี่ยนโครงสร้างคำถามของฟอร์มที่มีคำตอบเดิมอยู่แล้ว จะทำให้คำตอบเก่ากับคำถามใหม่ไม่ตรงกัน หน้าคำตอบสร้างคอลัมน์จากโครงคำถามปัจจุบันเสมอ
- การตั้งค่า OTP ระดับฟอร์มอ้างอิงการตั้งค่าระดับ LINE OA ที่เก็บในตาราง
otp_configการเปลี่ยนค่าที่ระดับ OA จึงมีผลกับทุกฟอร์มที่เปิด OTP ไว้พร้อมกัน - การส่งออก CSV เป็นการ stream ข้อมูลออกไปตามเงื่อนไขการกรองที่ส่งมา ไม่ได้จำกัดจำนวนแถวไว้ การส่งออกฟอร์มที่มีคำตอบจำนวนมากจึงใช้เวลาอยู่ในคำขอเดียว