วิธี Handle ข้อความที่มามากกว่า 1 ใน Webhook Event เดียว

Jirawatee
LINE Developers Thailand
2 min readAug 30, 2021

--

เริ่มต้นบทความนี้ขอพูดถึง Webhook Event ใน Messaging API ของ LINE กันก่อนว่ามันคือ การที่ผู้ใช้เข้ามามีปฏิสัมพันธ์กับ LINE Chatbot ซึ่งมีมากมายหลายรูปแบบ เช่น การส่งข้อความหา Chatbot ไม่ว่าจะเป็น Text, Image, Sticker หรือการกด Follow ตัว Chatbot, การลาก Chatbot เข้ากลุ่ม, การเข้าไปอยู่ในรัศมีของ LINE Beacon เป็นต้น ทั้งหมดนี้เราจะเรียกมันว่า events โดยหลักการทำงานจะเป็นแบบในรูปด้านล่างนี้

จากรูปขั้นตอนที่ LINE Server ส่ง Webhook events ให้กับ Bot application หรือ API ที่เราไปผูกไว้ใน Messaging API Channel จะมีการส่งข้อมูลในรูปแบบ JSON แนบมาด้วย โดยหน้าตาของข้อมูล Payload จะมีเป็นลักษณะเป็นด้านล่างนี้

ข้อมูลตรงนี้เอง เราสามารถที่จะนำไปใช้ในการประมวลผล จัดเก็บ หรือส่งข้อความกลับหาผู้ใช้ โดยโค้ดที่เราเห็นไม่ว่าจะในภาษาใดๆก็ตาม ตัวอย่างต่างๆในการรับ Webhook events มักจะรับแค่ array ตำแหน่งที่ 0 แบบนี้

// ตัวอย่างใน Node.js
const event = req.body.events[0];

เหตุผลที่โค้ดเป็นเช่นนั้นก็เพราะว่าทุก Webhook events ที่เข้ามา จะมี array ตำแหน่งที่ 0 เสมอ หรือจะด้วยการเขียนโค้ดที่ทำให้เข้าใจง่าย และอีกเหตุผลก็คงเพราะนักพัฒนาหลายท่านยังไม่เคยเจอเหตุการณ์ที่ Webhook เดียวบรรจุหลายๆ events

คำถามคือ มันจะเกิดเหตุการณ์แบบนั้นได้อย่างไร? คำตอบคือ มันจะเกิดขึ้นได้ถ้ามีการปฏิสัมพันธ์หลายๆครั้งในเวลาที่ใกล้ๆกัน เช่น ส่งข้อความถี่ๆ หรือส่งรูปหลายๆรูปพร้อมๆกัน เป็นต้น ดังนั้นเพื่อให้เห็นภาพ ผมจะสร้าง Echo bot ด้วย Cloud Functions for Firebase ให้ตอบสนองข้อความที่เป็น Text และ Image ตามนี้

จากโค้ดด้านบนเราไปทดสอบกันหน่อยว่า ถ้ามีการส่งข้อความที่เป็น Text และ Image พร้อมๆกันจะเป็นอย่างไร

จะเห็นได้ว่าผลลัพธ์คือตัว LINE Chatbot จะไม่ echo ข้อความทุกข้อความกลับมา เนื่องจากข้อความที่ถูกส่งในเวลาไล่เลี่ยกันจะถูกแพ็ครวมอยู่ใน array ชุดเดียวกัน ซึ่งจุดนี้เอง นักพัฒนาหลายคนคงจะเห็นปัญหาที่จะมาในอนาคตแล้ว ว่าระบบของเรามีโอกาสจะพลาดหรือตกหล่นข้อความที่มาจากผู้ใช้นั่นเอง

โชคดีเป็นของคนที่อ่านมาถึงตรงนี้ เพราะผมจะพาทุกคนมาดูวิธีเขียนโค้ดให้ LINE Chatbot ของคุณไม่พลาดในทุกๆ events ที่มากับ Webhook กัน โดยผมจะทำการแก้เฉพาะโค้ดในฟังก์ชันที่ชื่อ Webhook โดยการ for…of เพื่อ loop ทุกสมาชิกใน array ออกมาแบบนี้

หมายเหตุ: สาเหตุที่เลือกใช้ for…of แทน forEach ก็เพราะว่า forEach ไม่เหมาะกับการทำ async, await เนื่องจากมันจะไม่รอให้ promise ทุกตัวที่อยู่ภายใน resolve ให้เสร็จทั้งหมดก่อน ดังนั้นหากเรามีโค้ดที่อยู่ถัดจาก forEach มันก็อาจทำงานขึ้นมาก่อนที่ forEach จะ loop จนครบได้นั่นเอง ที่มา

คราวนี้เราก็ลองพิสูจน์กันหน่อย ว่ามันจะไม่พลาดทุก events ที่เข้ามาแล้วจริงๆใช่ไหม

Ta-Da! ตัว LINE Chatbot ของเราก็สามารถตอบได้ครบทุกข้อความละจ้า

สรุป

เชื่อว่านักพัฒนาหลายๆท่านคงจะถึงบางอ้อ หรือกำลังตลกผลึกอยู่ว่า เอ๊ะ LINE Chatbot ของฉันน่าจะเคยตกหล่นข้อความของผู้ใช้ไปบ้างเหมือนกัน

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

สุดท้ายนี้ ถ้าคุณชอบความนี้ก็ฝาก กดตบมือ เป็นกำลังใจให้ผม หรือถ้าบทความนี้มันใช่สำหรับเพื่อนๆของคุณก็ฝาก กดแชร์ ให้ด้วยนะครับ และถ้าคุณไม่อยากพลาดบทความดีๆในตอนต่อไปก็ฝาก กดติดตาม ตัว Publication ไว้ด้วยนะครับ สำหรับวันนี้ต้องขอตัวลาไปก่อน แล้วพบกันใหม่ตอนหน้า สวัสดีค้าบ

--

--

Jirawatee
LINE Developers Thailand

Technology Evangelist at LINE Thailand / Google Developer Expert in Firebase