← กลับไปหน้าบทความ
ขั้นสูง (MarTech)

ตั้ง LINE Webhook บน Supabase Edge Functions ออกแบบตาราง Event ยังไงให้ไม่พังตอนข้อมูลเยอะ

ทีมบรรณาธิการ linli12 ส.ค. 04:53อัปเดต 12 ส.ค. 04:53อ่าน 6 นาที
ตั้ง LINE Webhook บน Supabase Edge Functions ออกแบบตาราง Event ยังไงให้ไม่พังตอนข้อมูลเยอะ
บทความนี้จัดทำเพื่อความรู้ ชื่อธุรกิจ ตัวเลข หรือบทสนทนาที่ไม่มีแหล่งอ้างอิงกำกับเป็นกรณีตัวอย่างเพื่ออธิบายแนวคิด ดูรายละเอียดที่ นโยบายกองบรรณาธิการ

สรุปสั้น ๆ

ทำ LINE Webhook ด้วย Supabase Edge Functions ได้เปรียบเรื่องเขียนข้อมูลลง Postgres ของ project ตัวเองโดยตรง แต่ต้องออกแบบตาราง event ให้รองรับ event หลายประเภทของ LINE เขียนหลาย event ในหนึ่ง payload ด้วยคำสั่งเดียวแทนการ loop insert ทีละแถว ตอบ reply token ให้ทันก่อนแล้วค่อยเขียนข้อมูลหนักในภายหลัง และอัปเดตสถานะลูกค้าเมื่อมี event unfollow แทนที่จะบันทึกเป็นแค่ log เฉย ๆ

ทีมที่เคยเขียน webhook receiver ทั่วไปเก็บ event ลง Postgres มาก่อน มักคิดว่าการทำ LINE Webhook ด้วย Supabase Edge Functions เป็นแค่การเปลี่ยน source ของ event จากผู้ให้บริการหนึ่งเป็น LINE เท่านั้น เขียนโค้ดตรวจ signature เดิม สร้างตาราง event เดิม แล้วก็คาดว่าจะใช้งานได้เหมือนที่เคยทำมา

แต่พอเริ่มเขียนจริงจะเจอว่า LINE ส่ง event หลายประเภทปนกันมาในโครงสร้างข้อมูลเดียว ทั้ง event ข้อความ event ติดตาม และ event เลิกติดตาม ซึ่งแต่ละแบบมีความหมายทางธุรกิจต่างกันและต้องจัดการต่างกัน ไม่ใช่แค่บันทึกลง log แล้วจบ อีกทั้งยังมีเพดานเวลาของ reply token ที่ต้องแข่งกับเวลาที่ใช้เขียนข้อมูลลงฐานข้อมูล ซึ่งเป็นแรงกดดันที่ webhook ทั่วไปไม่ค่อยเจอ

บทความนี้จะเจาะจุดที่เฉพาะเจาะจงกับการรวม LINE Webhook เข้ากับ Supabase Edge Functions ตั้งแต่ออกแบบตาราง event รองรับ event หลายประเภท เขียนหลาย event ในครั้งเดียว จัดจังหวะระหว่างตอบ reply token กับเขียนฐานข้อมูล ไปจนถึงการอัปเดตสถานะลูกค้าเมื่อมีคนเลิกติดตาม

ทำไม Supabase Edge Functions เหมาะกับ Webhook ของ LINE มากกว่าที่คิด

LINE Webhook มีลักษณะเฉพาะที่ต่างจาก webhook ทั่วไปตรงที่ต้องทำสองอย่างพร้อมกันในเวลาจำกัด คือตอบกลับผู้ใช้ผ่าน reply token ที่มีอายุสั้นมาก และเก็บข้อมูล event ไว้ใช้งานต่อ เช่นวิเคราะห์พฤติกรรม ผูกกับข้อมูลลูกค้า หรือส่งต่อให้ระบบอื่น อ่านรายละเอียดของฝั่ง Cloudflare Workers เพิ่มเติมได้ในบทความ ทำ LINE Webhook ด้วย Cloudflare Workers ซึ่งเน้นเรื่อง signature format และ reply token เป็นหลักโดยไม่ได้ผูกกับการเขียนฐานข้อมูลโดยตรงในโค้ดชุดเดียวกัน

ความต่างของ Edge Functions คืออยู่ใกล้ Postgres ของ project ตัวเองโดยตรง ทำให้ขั้นตอนตรวจ signature แยก event บันทึกลงตาราง และเรียก API ตอบกลับผู้ใช้ ทำได้ในฟังก์ชันเดียวโดยไม่ต้องข้ามไปเรียก service อื่นเพิ่ม ซึ่งช่วยลดจำนวนจุดที่อาจทำให้เวลารวมของ request เกินเพดานที่ reply token มีให้ได้บ้าง

แต่ความสะดวกนี้ไม่ได้แปลว่าออกแบบง่ายกว่าเดิมเสมอไป เพราะการเขียนฐานข้อมูลในเส้นทางเดียวกับที่ต้องตอบ reply token ให้ทัน สร้างแรงกดดันเรื่องเวลาที่ต่างจากการเขียน webhook ทั่วไปที่อธิบายไว้ในบทความ สร้าง Webhook ด้วย Supabase Edge Functions ซึ่งไม่มีเพดานเวลาผูกกับการตอบผู้ใช้ปลายทางแบบเดียวกัน ทีมที่นำแนวทางนั้นมาใช้ตรง ๆ กับ LINE โดยไม่คิดเรื่องลำดับงานใหม่ มีความเสี่ยงที่ reply token จะหมดอายุก่อนเขียนข้อมูลเสร็จ

ออกแบบตาราง Event ให้รองรับประเภท Event ของ LINE ให้ครบ

จุดเริ่มต้นที่สำคัญคือออกแบบตาราง event ให้รองรับความหลากหลายของ event ที่ LINE ส่งมา แทนที่จะสร้างตารางแบบ generic ที่มีแค่ column เก็บ payload ดิบอย่างเดียวเหมือน webhook ทั่วไปบางแบบ เพราะ event แต่ละประเภทของ LINE มีความหมายทางธุรกิจต่างกันมากพอที่ต้องแยกวิเคราะห์และ query แยกกันได้ในภายหลัง

column ที่ควรมีอย่างน้อยคือ identifier เฉพาะตัวของ event ที่ LINE แนบมาให้สำหรับใช้กันซ้ำ, LINE User ID ของผู้ใช้ที่เกี่ยวข้องกับ event นั้น, ประเภทของ event เช่นข้อความ ติดตาม หรือเลิกติดตาม, reply token ในกรณีที่ event นั้นตอบกลับได้, เวลาที่ event เกิดขึ้นตามที่ LINE ระบุ, และ column เก็บ payload ดิบทั้งก้อนไว้สำรองสำหรับกรณีที่ต้องย้อนดูรายละเอียดที่ไม่ได้แยกเก็บเป็น column เฉพาะ

การแยก LINE User ID ออกมาเป็น column ของตัวเองสำคัญมาก เพราะเป็น identifier หลักที่ใช้ผูก event เข้ากับข้อมูลลูกค้าหรือ lead ในระบบอื่นต่อไป ถ้าเก็บไว้แค่ในก้อน payload ดิบเพียงอย่างเดียว การ query หา event ทั้งหมดของผู้ใช้คนใดคนหนึ่งจะทำได้ช้าและซับซ้อนกว่าการมี column แยกที่สร้าง index ได้ตรง ๆ มาก

Columnประเภทข้อมูลจุดประสงค์
line_event_idtext, uniqueกัน event ซ้ำเมื่อ LINE retry payload เดิม
line_user_idtext, indexedผูก event เข้ากับลูกค้าหรือ lead ในระบบ
event_typetextแยกข้อความ ติดตาม เลิกติดตาม postback ฯลฯ
reply_tokentext, nullableเก็บไว้เผื่อ retry การตอบกลับภายในเวลาที่ยังไม่หมดอายุ
raw_payloadjsonbเก็บ payload ดิบทั้งก้อนไว้ตรวจสอบย้อนหลัง

เขียนหลาย Event ใน Payload เดียวลง Postgres ด้วยคำสั่งเดียว ไม่ Loop ทีละแถว

เพราะ LINE รวมหลาย event ที่เกิดใกล้เคียงกันไว้ใน array เดียวของ payload เดียว วิธีที่ตรงไปตรงมาที่สุดที่หลายทีมเขียนตอนแรกคือ loop ผ่านทุก event แล้วสั่ง insert ทีละแถวตามลำดับ ซึ่งทำงานได้จริงแต่มีต้นทุนด้าน latency ที่สะสมขึ้นตามจำนวน event เพราะแต่ละคำสั่ง insert คือ round trip ไปกลับกับฐานข้อมูลหนึ่งครั้ง ถ้า payload หนึ่งครั้งมี event สิบตัว จะกลายเป็นสิบ round trip ที่รันเรียงกันก่อนจะตอบ response กลับได้

แนวทางที่ประหยัดเวลากว่าคือรวม event ทั้งหมดในความทรงจำก่อน แล้วสั่ง insert เป็นชุดเดียวด้วยคำสั่งที่รับหลายแถวพร้อมกัน ร่วมกับ on conflict do nothing ที่ column identifier ของ event เพื่อกัน event ที่เคยบันทึกไปแล้วจาก retry ไม่ให้ถูกเขียนซ้ำ วิธีนี้ลด round trip เหลือครั้งเดียวไม่ว่า payload จะมี event กี่ตัวก็ตาม ซึ่งช่วยประหยัดเวลาที่มีค่ามากในเส้นทางที่ต้องแข่งกับเพดานเวลาของ reply token

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

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

ตอบ Reply Token ให้ทันก่อน แล้วค่อยเขียนข้อมูลหนักด้วย Background Task

ปัญหาที่พบบ่อยเมื่อรวม logic ตอบ reply token เข้ากับการเขียนฐานข้อมูลในฟังก์ชันเดียวกันคือลำดับงานที่ทำให้ reply token หมดอายุก่อนตอบกลับผู้ใช้ได้ทัน ถ้าทีมเขียนโค้ดให้เขียนข้อมูลลง Postgres ให้เสร็จก่อน แล้วค่อยเรียก API ตอบกลับผู้ใช้เป็นลำดับสุดท้าย เวลาที่ใช้ในการเขียนข้อมูล โดยเฉพาะถ้ามี event หลายตัวหรือ table มี trigger ที่ทำงานหนัก อาจกินเวลาจนเกินเพดานของ reply token ไปเลย

แนวทางที่ปลอดภัยกว่าคือสลับลำดับ ให้เรียก API ตอบกลับผู้ใช้ด้วย reply token ก่อนเป็นอันดับแรกทันทีที่ประมวลผลพอรู้ว่าจะตอบอะไร แล้วค่อยเขียนข้อมูลลงฐานข้อมูลเป็นงานที่ทำต่อหลังจากนั้น Edge Functions ของ Supabase รองรับการสั่งงานแบบ background ที่ยังทำงานต่อได้แม้ response หลักถูกส่งกลับไปแล้ว ทำให้แยกงานเขียนฐานข้อมูลที่ไม่จำเป็นต้องเสร็จก่อนตอบผู้ใช้ ออกจากเส้นทางที่ต้องแข่งกับเวลาของ reply token ได้จริง

ข้อควรระวังของแนวทางนี้คืองาน background ที่ทำงานต่อหลังตอบ response แล้ว จะไม่มีโอกาสแจ้งผู้เรียกโดยตรงว่าล้มเหลวหรือสำเร็จ ถ้าการเขียนฐานข้อมูลพลาดหลังจากนั้น ผู้ใช้จะได้รับการตอบกลับปกติทั้งที่ event ของเขาไม่ถูกบันทึกจริง ควรมีระบบ log ความล้มเหลวของงาน background แยกไว้ตรวจสอบ และตั้งการแจ้งเตือนเมื่อ error สะสมผิดปกติ แทนการปล่อยให้เงียบหายไปโดยไม่มีใครรู้

ควรแบ่งให้ชัดว่างานส่วนไหนต้องเสร็จก่อนตอบ reply token และงานส่วนไหนทำทีหลังได้ เช่นการตรวจ signature และแยกประเภท event ต้องทำก่อนเพื่อรู้ว่าจะตอบอะไร ส่วนการเขียน raw payload ลง log หรืออัปเดตสถิติที่ไม่กระทบการตอบกลับผู้ใช้โดยตรง สามารถย้ายไปทำเป็นงาน background ทีหลังได้ทั้งหมด

Follow และ Unfollow ต้องอัปเดตสถานะลูกค้า ไม่ใช่แค่บันทึกเป็น Log เฉย ๆ

event ประเภทติดตามและเลิกติดตามมักถูกมองข้ามว่าเป็นแค่ event เล็ก ๆ ที่บันทึกลง log ไว้เฉย ๆ ก็พอ แต่ในทางปฏิบัติ event สองแบบนี้มีผลต่อข้อมูลลูกค้าที่ผูกกับ LINE User ID โดยตรง เพราะบอกว่าผู้ใช้คนนี้ยังเปิดรับข้อความจากช่องทาง LINE อยู่หรือไม่ในตอนนี้

เมื่อมี event เลิกติดตามเข้ามา ควรอัปเดตสถานะของ record ลูกค้าที่ผูกกับ LINE User ID นั้นให้สะท้อนว่าช่องทาง LINE ของคนนี้ไม่ active แล้ว ไม่ใช่ปล่อยให้ record เดิมดูเหมือนยังติดตามอยู่ตลอดไป เพราะถ้าระบบอื่นที่ต่อกับข้อมูลนี้ยังพยายามส่งข้อความหรือทำงานอื่นกับผู้ใช้ที่เลิกติดตามไปแล้ว จะเป็นการทำงานที่สูญเปล่าและอาจผิดเงื่อนไขการใช้งานของแพลตฟอร์มด้วย

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

การผูก LINE User ID เข้ากับข้อมูลลูกค้าควรทำผ่าน column ที่มี index ชัดเจนตามที่อธิบายไว้ในหัวข้อออกแบบตาราง ไม่ใช่ query ค้นหาจาก payload ดิบทุกครั้งที่ต้องอัปเดตสถานะ เพราะจะช้าลงเรื่อย ๆ เมื่อจำนวน event สะสมมากขึ้นตามเวลา

เก็บ Raw Payload เป็น JSONB คู่กับคอลัมน์ที่ต้อง Query บ่อย

แม้จะแยก column สำคัญอย่าง LINE User ID ประเภท event และ reply token ออกมาแล้ว ยังแนะนำให้เก็บ payload ดิบทั้งก้อนไว้ใน column ประเภท jsonb ควบคู่ไปด้วยเสมอ เพราะ LINE อาจส่งข้อมูลย่อยเพิ่มเติมในบาง event ที่ไม่ได้แยกเป็น column เฉพาะไว้ตั้งแต่ต้น เช่นรายละเอียดของ postback หรือ properties อื่นที่ต่างกันไปตามประเภท event

ข้อดีของการเก็บ jsonb คือความยืดหยุ่นเมื่อ LINE เพิ่มฟิลด์ใหม่ในอนาคต หรือเมื่อทีมพบว่าต้องใช้ข้อมูลบางอย่างที่ไม่ได้คาดไว้ตอนออกแบบตารางครั้งแรก ก็ยังดึงข้อมูลนั้นย้อนกลับมาจาก column jsonb ได้โดยไม่ต้องรอ migration schema ใหม่ก่อน

แต่ข้อเสียคือการ query ข้อมูลที่ซ้อนอยู่ใน jsonb ช้ากว่าการ query column แบบปกติถ้าไม่มี index ช่วย ถ้าพบว่ามีการ query ข้อมูลใน jsonb บ่อยขึ้นเรื่อย ๆ เช่นดึงเฉพาะ field ใดฟิลด์หนึ่งซ้ำ ๆ ควรพิจารณาใช้ index เฉพาะสำหรับ jsonb ที่ Postgres รองรับ หรือย้ายฟิลด์นั้นออกมาเป็น column แยกถ้าใช้งานบ่อยจนคุ้มค่ากับการทำ migration

หลักที่ใช้ได้จริงคือแยก column เฉพาะเท่าที่จำเป็นสำหรับ query หรือ join ที่ใช้บ่อยจริง ส่วนที่เหลือปล่อยให้อยู่ใน jsonb ไปก่อน ไม่ต้องพยายาม normalize ทุกฟิลด์ของ payload ออกมาเป็น column ตั้งแต่วันแรก เพราะจะทำให้ schema ซับซ้อนเกินความจำเป็นและต้อง migrate บ่อยทุกครั้งที่ LINE ปรับโครงสร้าง event เล็กน้อย

ตัวอย่างสมมติ: ลืมอัปเดตสถานะ Unfollow ทำให้ยังพยายามส่งข้อความหาผู้ใช้ที่เลิกติดตามไปแล้ว

ลองดูตัวอย่างสมมติของทีมที่สร้าง Edge Function รับ LINE Webhook แล้วบันทึกทุก event รวมถึง event เลิกติดตามลงตาราง log เดียวกันหมด โดยไม่ได้เขียนโค้ดแยกอัปเดตสถานะของ record ลูกค้าที่ผูกกับ LINE User ID นั้นเมื่อเจอ event เลิกติดตาม (ตัวอย่างสมมติเพื่อประกอบการอธิบาย)

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

ทีมแก้ปัญหาด้วยการเพิ่ม logic เฉพาะสำหรับ event ประเภทเลิกติดตาม ให้อัปเดต column สถานะของ record ลูกค้าที่ผูกกับ LINE User ID นั้นทันทีหลังบันทึก event ลง log เสร็จ แทนที่จะปล่อยให้การบันทึก log กับการอัปเดตสถานะเป็นคนละเรื่องที่แยกออกจากกันโดยไม่มีความเชื่อมโยง บทเรียนจากเคสสมมตินี้คือ event ที่ดูเหมือนเป็นแค่ log เพิ่มเติม อาจมีความหมายทางธุรกิจที่ต้องแปลงเป็นการอัปเดตสถานะจริงในระบบด้วยเสมอ ไม่ใช่แค่บันทึกไว้เฉย ๆ

ทำแบบนี้แล้วพัง เพราะอะไร

ข้อผิดพลาดที่พบบ่อยเมื่อทีมสร้าง LINE Webhook ด้วย Supabase Edge Functions ครั้งแรกโดยยังไม่คุ้นกับจุดเฉพาะของการรวมสองอย่างนี้เข้าด้วยกัน

  • เขียนฐานข้อมูลให้เสร็จก่อนแล้วค่อยตอบ reply token — ทำให้ reply token มีโอกาสหมดอายุก่อนตอบผู้ใช้ทัน โดยเฉพาะเมื่อ payload มีหลาย event
  • loop insert ทีละแถวสำหรับ event หลายตัวใน payload เดียว — เพิ่ม round trip กับฐานข้อมูลโดยไม่จำเป็น กินเวลาที่มีค่าในเส้นทางที่ต้องแข่งกับ reply token
  • บันทึก event เลิกติดตามลง log แต่ไม่อัปเดตสถานะ record ลูกค้า — ทำให้ระบบอื่นยังเห็นผู้ใช้เป็น active อยู่ทั้งที่เลิกติดตามไปแล้ว
  • ไม่แยก column LINE User ID ออกจาก raw payload — ทำให้ query หา event ของผู้ใช้คนใดคนหนึ่งช้าลงเรื่อย ๆ เมื่อข้อมูลสะสมมากขึ้น
  • ไม่มี log แยกสำหรับงาน background ที่ทำหลังตอบ reply token แล้ว — ถ้าการเขียนฐานข้อมูลพลาดหลังจากนั้น จะไม่มีใครรู้เพราะผู้ใช้ได้รับการตอบกลับปกติไปแล้ว

สรุป

การทำ LINE Webhook ด้วย Supabase Edge Functions มีจุดที่ต้องออกแบบเพิ่มเติมจาก webhook ทั่วไปหลายเรื่อง ทั้งตาราง event ที่ต้องรองรับประเภท event หลากหลาย การเขียนหลาย event ในครั้งเดียวแทนการ loop insert ทีละแถว และลำดับงานที่ต้องตอบ reply token ให้ทันก่อนแล้วค่อยเขียนข้อมูลหนักด้วย background task

อีกเรื่องที่มักถูกมองข้ามคือ event ติดตามและเลิกติดตามไม่ใช่แค่ log เฉย ๆ แต่ต้องแปลงเป็นการอัปเดตสถานะลูกค้าที่ผูกกับ LINE User ID จริง เพื่อไม่ให้ระบบอื่นทำงานผิดพลาดกับผู้ใช้ที่เลิกติดตามไปแล้ว

  • ออกแบบตาราง event ให้มี column แยกสำหรับ LINE User ID ประเภท event และ reply token ไม่ใช่เก็บแค่ raw payload อย่างเดียว
  • insert event หลายตัวใน payload เดียวเป็นชุดเดียวด้วย on conflict do nothing แทนการ loop insert ทีละแถว
  • ตอบ reply token ให้ทันก่อน แล้วค่อยเขียนข้อมูลหนักลงฐานข้อมูลเป็นงาน background พร้อม log ความล้มเหลวแยกไว้ตรวจสอบ

คำถามที่พบบ่อย

ควรใช้ Supabase Edge Functions หรือ Cloudflare Workers ทำ LINE Webhook

ขึ้นกับว่าปลายทางหลักของข้อมูลคือ Postgres ของ Supabase หรือไม่ ถ้าใช่ Edge Functions สะดวกกว่าเพราะเขียนข้อมูลตรงได้ในโค้ดชุดเดียว รายละเอียดเฉพาะของ signature และ reply token บน Cloudflare Workers ดูเพิ่มเติมได้ในบทความ LINE Webhook ด้วย Cloudflare Workers

ทำไมต้องเขียน Event หลายตัวใน Payload เดียวเป็นชุดแทนการ Insert ทีละแถว

เพราะการ insert เป็นชุดลด round trip กับฐานข้อมูลเหลือครั้งเดียวไม่ว่าจะมี event กี่ตัว ช่วยประหยัดเวลาที่ต้องแข่งกับเพดานของ reply token ได้มากกว่าการ loop insert ทีละแถว

ควรตอบ Reply Token ก่อนหรือเขียนฐานข้อมูลก่อน

ควรตอบ reply token ก่อนทันทีที่รู้ว่าจะตอบอะไร แล้วค่อยเขียนข้อมูลลงฐานข้อมูลเป็นงาน background ต่อหลังจากนั้น เพื่อไม่ให้เวลาที่ใช้เขียนข้อมูลไปกินเวลาที่ reply token มีให้จนหมดอายุ

Event เลิกติดตามต้องลบข้อมูลลูกค้าออกจากระบบเลยไหม

ไม่จำเป็นต้องลบ แนะนำให้อัปเดตสถานะ record ให้สะท้อนว่าช่องทาง LINE ไม่ active แล้วแทน เพื่อยังเก็บประวัติไว้ใช้งานได้ในอนาคตถ้าผู้ใช้กลับมาติดตามใหม่

เก็บ Raw Payload เป็น JSONB ทั้งก้อนมีข้อเสียไหม

ข้อเสียหลักคือ query ข้อมูลที่ซ้อนอยู่ใน jsonb ช้ากว่า column ปกติถ้าไม่มี index ช่วย ควรแยก column เฉพาะเท่าที่ query บ่อยจริง ส่วนที่เหลือเก็บไว้ใน jsonb ต่อไปได้

ต้องสร้างตารางแยกสำหรับ Event แต่ละประเภทของ LINE ไหม

ไม่จำเป็นเสมอไป ส่วนใหญ่ใช้ตาราง event เดียวที่มี column event_type แยกประเภทได้เพียงพอแล้ว การแยกตารางตามประเภท event เหมาะกับกรณีที่แต่ละประเภทมีข้อมูลเฉพาะเยอะจนรวมกันแล้ว schema ซับซ้อนเกินไป

ลองตรวจด้วยตัวเอง

LINE Webhook Payload Inspector

วาง JSON payload จาก LINE แล้วดูว่าเป็น event ชนิดไหน มี field ครบตาม schema ปัจจุบันหรือไม่

ตรวจ payload ฟรี

ใช้ฟรี ไม่ต้องสมัคร ไม่เก็บข้อมูลที่คุณกรอก

วัด Conversion LINE ทุกแบรนด์ รวมศูนย์ที่เดียว

องค์กรที่มีหลายแบรนด์ หลายสาขา หลาย LINE OA — linli รวม Tracking และส่ง Conversion กลับทุกแพลตฟอร์ม พร้อม Custom Limit เริ่มฟรี 14 วัน

ติดต่อทีม Sales

บทความที่เกี่ยวข้อง

Workers AI กับ AI Search บน Cloudflare เลือกทางไหนตอนสร้าง Chatbot ให้ LINE OA

Workers AI กับ AI Search บน Cloudflare เลือกทางไหนตอนสร้าง Chatbot ให้ LINE OA

ทีมที่จะสร้าง AI Chatbot บน LINE OA ด้วย Cloudflare มักเจอทางแยกว่าจะใช้ Workers AI ที่รันโมเดลในเครือข่ายของ Cloudflare เอง หรือใช้ AI Search ที่จัดการ RAG ให้ทั้งชุด บทความนี้เทียบสองทางนี้ให้เห็นว่าต่างกันตรงไหนและควรเลือกแบบไหนตามลักษณะงาน
เชื่อม MCP กับ LINE OA ให้ AI Agent เรียกดูออเดอร์และสต็อกจริงระหว่างคุยกับลูกค้าได้ยังไง

เชื่อม MCP กับ LINE OA ให้ AI Agent เรียกดูออเดอร์และสต็อกจริงระหว่างคุยกับลูกค้าได้ยังไง

Chatbot ที่ตอบได้แค่จากเอกสารอย่างเดียวไม่พอสำหรับหลายธุรกิจ เพราะลูกค้าอยากรู้สถานะออเดอร์หรือสต็อกจริงตอนนั้น บทความนี้อธิบายว่า MCP หรือ Model Context Protocol เปิดทางให้ AI Agent ที่คุยผ่าน LINE OA เรียกใช้ระบบหลังบ้านจริงได้อย่างไร และมีข้อจำกัดอะไรที่ต้องรู้ก่อนนำไปใช้
ทำไม RAG ที่ทำงานดีตอนทดสอบ ถึงเริ่มตอบผิดเมื่อข้อมูลบริษัทเยอะขึ้น

ทำไม RAG ที่ทำงานดีตอนทดสอบ ถึงเริ่มตอบผิดเมื่อข้อมูลบริษัทเยอะขึ้น

หลายทีมทำ RAG สำหรับ LINE OA แล้วช่วงแรกตอบแม่นดี แต่พอเพิ่มข้อมูลบริษัทเข้าไปมากขึ้นเรื่อยๆ กลับเริ่มตอบผิดหรือดึงข้อมูลไม่ตรงประเด็น บทความนี้ไล่ดูสาเหตุที่แท้จริงและวิธีออกแบบระบบให้ยังแม่นยำแม้ข้อมูลจะโตขึ้นมาก