ย้อนกลับไปที่ "ข่าวสำหรับผู้พัฒนา"

การจองการนัดหมายด้วย WhatsApp Flows: การสร้างแบ็คเอนด์ Node.js

27 กุมภาพันธ์ 2024โดยGafi G และ Iryna Wagner

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

คู่มือนี้จะแนะนำวิธีสร้างแอพ Node.js ที่ช่วยให้ผู้ใช้สามารถจองการนัดหมายผ่าน WhatsApp Flows คุณจะได้สร้าง Flow บนแพลตฟอร์ม WhatsApp Business แล้วจึงกำหนดค่า Webhook เพื่อรับการตอบกลับของ Flow แล้วทำการจองการนัดหมาย

ข้อกำหนดเบื้องต้น

คุณต้องมีสิ่งต่อไปนี้เพื่อดำเนินการตามบทแนะนำการใช้งาน

การสร้าง WhatsApp Flow

คุณสามารถสร้าง WhatsApp Flow ได้ 2 วิธี ได้แก่ การใช้ Flows Builder ที่สามารถเข้าถึงได้ผ่านตัวจัดการ WhatsApp และ Flows API ซึ่งบทแนะนำการใช้งานนี้ใช้ Flows Builder

สร้าง Flow

ที่เมนูด้านซ้ายของแดชบอร์ดตัวจัดการ WhatsApp ให้เลือก "เครื่องมือบัญชี" จากนั้นคลิก "Flows"

กราฟิกตัวจัดการ WhatsApp

คลิก "สร้าง Flow" ที่มุมขวาบน

กราฟิกการสร้าง Flow

ในกล่องโต้ตอบที่ปรากฏขึ้น ให้กรอกรายละเอียดสำหรับ Flow การนัดหมาย ดังนี้

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

คลิก "ส่ง" เพื่อสร้าง Flow

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

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

การกำหนดค่าปลายทางของ Flow

WhatsApp Flows ช่วยให้คุณสามารถเชื่อมต่อกับปลายทางภายนอก ปลายทางนี้สามารถให้ข้อมูลแบบไดนามิกสำหรับ Flow ของคุณและควบคุมการเลือกเส้นทางได้ นอกจากนี้ ยังทำหน้าที่รับการตอบกลับที่ผู้ใช้ส่งมาจาก Flow อีกด้วย

เพื่อจุดประสงค์ในการทดสอบ บทความนี้จะใช้ Glitch เพื่อโฮสต์ปลายทาง การใช้ Glitch เป็นทางเลือกและไม่จำเป็นต้องใช้ Flows คุณสามารถจำลองโค้ดปลายทางจาก GitHub และเรียกใช้ในสภาพแวดล้อมที่คุณต้องการได้

เข้าถึงโค้ดปลายทางใน Glitch แล้วรีมิกซ์เพื่อรับโดเมนเฉพาะของคุณ ซึ่งทำได้โดยการคลิก "รีมิกซ์" ที่ด้านบนของหน้า โดเมนเฉพาะจะปรากฏเป็นตัวยึดตำแหน่งในองค์ประกอบอินพุตที่ด้านขวาของหน้า Glitch

เรามาดูรายละเอียดโค้ดกันก่อนที่จะดำเนินการต่อ มีไฟล์ JavaScript 4 รายการในไดเรกทอรี src ได้แก่ encryption.js, flow.js, keyGenerator.js และ server.js ไฟล์ข้อมูลเข้าคือ server.js ดังนั้นเราจะมาดูไฟล์นี้เป็นอันดับแรก

server.js

ไฟล์ server.js เริ่มต้นโดยการกำหนดค่าแอพพลิเคชั่น Express เพื่อใช้มิดเดิลแวร์ express.json เพื่อแปลง (Parse) คำขอ JSON ขาเข้า จากนั้นจะโหลดตัวแปรสภาพแวดล้อมที่จำเป็นสำหรับปลายทาง

const { APP_SECRET, PRIVATE_KEY, PASSPHRASE, PORT = "3000" } = process.env;

APP_SECRET ใช้สำหรับตรวจสอบยืนยันลายเซ็น ซึ่งจะช่วยคุณตรวจสอบว่าข้อความถูกส่งผ่าน WhatsApp หรือไม่ เพื่อให้การประมวลผลเป็นไปอย่างปลอดภัย และคุณจะต้องเพิ่มลงในไฟล์ .env

ไปที่แดชบอร์ดในแอพบน Meta for Developers เพื่อเข้าถึง APP_SECRET ในแผงนำทางด้านซ้ายใต้ "การตั้งค่าแอพ" ให้เลือก "พื้นฐาน" คลิก "แสดง" ที่ใต้ "ข้อมูลลับของแอพ" แล้วคัดลอกข้อมูลลับ จากนั้นให้กลับไปที่ Glitch เปิดไฟล์ .env แล้วสร้างตัวแปรที่ชื่อ APP_SECRET โดยมีค่าของข้อมูลลับที่คุณคัดลอกมา

PRIVATE_KEY ช่วยถอดรหัสข้อความที่ได้รับ PASSPHRASE จะช่วยตรวจสอบยืนยันคีย์ส่วนตัว นอกจากคีย์ส่วนตัวแล้ว คุณยังต้องมีคีย์สาธารณะที่สอดคล้องกันด้วย ซึ่งคุณจะได้อัพโหลดในภายหลัง อย่าใช้คีย์ส่วนตัวสำหรับบัญชีที่คุณใช้งานจริงในนี้ ให้สร้างคีย์ส่วนตัวชั่วคราวสำหรับการทดสอบใน Glitch แล้วจึงแทนที่คีย์ชั่วคราวด้วยคีย์ที่ใช้งานจริงในโครงสร้างพื้นฐานของคุณ

สร้างคู่คีย์สาธารณะ-ส่วนตัวด้วยการเรียกใช้คำสั่งด้านล่างในเทอร์มินัล Glitch แทนที่ <your-passphrase> ด้วยวลีรหัสผ่านที่คุณกำหนดเอง เข้าถึงเทอร์มินัล Glitch โดยคลิกที่แท็บ "TERMINAL" ที่ด้านล่างของหน้า

node src/keyGenerator.js <your-passphrase>

คัดลอกวลีรหัสผ่านและคีย์ส่วนตัว แล้ววางในไฟล์ .env คลิกที่ไฟล์ประเภท .env ในแถบด้านซ้าย จากนั้นคลิก "✏️ ข้อความธรรมดา" ที่ด้านบน อย่าแก้ไขโดยตรงจาก UI เนื่องจากจะทำให้การจัดรูปแบบคีย์เสียหาย

เมื่อคุณตั้งค่าตัวแปรสภาพแวดล้อมแล้ว ให้คัดลอกคีย์สาธารณะที่คุณสร้างขึ้น แล้วอัพโหลดคีย์สาธารณะผ่าน Graph API

ไฟล์ server.js ยังประกอบด้วยปลายทาง POST ที่ทำให้เกิดขั้นตอนที่แตกต่างออกไป เช่น

  • ตรวจสอบว่ามีคีย์ส่วนตัวอยู่:
       if (!PRIVATE_KEY) { throw new Error('Private key is empty. Please check your env variable "PRIVATE_KEY".'); }
  • ตรวจสอบลายเซ็นคำขอโดยใช้ฟังก์ชั่น isRequestSignatureValid ที่อยู่ด้านล่างของไฟล์:
if(!isRequestSignatureValid(req)) { // Return status code 432 if request signature does not match. // To learn more about return error codes visit: https://developers.facebook.com/docs/whatsapp/flows/reference/error-codes#endpoint_error_codes return res.status(432).send(); }
  • ถอดรหัสข้อความขาเข้าโดยใช้ฟังก์ชั่น decryptRequest ที่พบในไฟล์ encryption.js:
      let decryptedRequest = null; try { decryptedRequest = decryptRequest(req.body, PRIVATE_KEY, PASSPHRASE); } catch (err) { console.error(err); if (err instanceof FlowEndpointException) { return res.status(err.statusCode).send(); } return res.status(500).send(); } const { aesKeyBuffer, initialVectorBuffer, decryptedBody } = decryptedRequest; console.log("💬 Decrypted Request:", decryptedBody);
  • กำหนดหน้าจอ Flow ที่จะแสดงให้ผู้ใช้เห็น คุณจะได้อ่านรายละเอียดของฟังก์ชั่น getNextScreen ในภายหลัง

const screenResponse = await getNextScreen(decryptedBody);

       console.log("👉 Response to Encrypt:", screenResponse);
  • เข้ารหัสการตอบกลับที่จะส่งไปยังผู้ใช้:
res.send(encryptResponse(screenResponse, aesKeyBuffer, initialVectorBuffer));

encryption.js

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

keyGenerator.js

ไฟล์นี้ช่วยสร้างคีย์ส่วนตัวและสาธารณะตามที่คุณเห็นไปแล้วก่อนหน้านี้ ซึ่งบทแนะนำการใช้งานนี้จะไม่เจาะลึกรายละเอียดของไฟล์ keyGenerator.js เช่นเดียวกับไฟล์ encryption.js

flow.js

ตรรกะการจัดการ Flow อยู่ในไฟล์นี้ ซึ่งเริ่มต้นด้วยอ็อบเจ็กต์ที่มีชื่อว่า SCREEN_RESPONSES อ็อบเจ็กต์นี้ประกอบด้วย ID ของหน้าจอพร้อมรายละเอียดที่เกี่ยวข้อง เช่น ข้อมูลที่กำหนดไว้ล่วงหน้าที่ใช้ในการแลกเปลี่ยนข้อมูล อ็อบเจ็กต์นี้ถูกสร้างขึ้นจาก Flow Builder ที่อยู่ใต้ "..." > "ปลายทาง" > "ส่วนย่อยของโค้ด" > "การตอบกลับ" ในอ็อบเจ็กต์เดียวกันนี้ คุณจะมีอีกหนึ่ง ID นั่นก็คือ SUCCESS ซึ่งจะถูกส่งกลับไปยังอุปกรณ์ไคลเอ็นต์เมื่อ Flow เสร็จสมบูรณ์ ซึ่งเป็นการปิด Flow

ฟังก์ชั่น getNextScreen ประกอบด้วยตรรกะที่แนะนำปลายทางที่ข้อมูล Flow จะแสดงให้ผู้ใช้เห็น ซึ่งเริ่มต้นด้วยการแยกข้อมูลที่จำเป็นมาจากข้อความที่ถูกถอดรหัส

const { screen, data, version, action, flow_token } = decryptedBody;

ปลายทาง WhatsApp Flows มักจะได้รับคำขอ 3 รายการ ได้แก่

คุณสามารถดูรายละเอียดของคำขอเหล่านี้ได้ในเอกสารเกี่ยวกับปลายทาง

ฟังก์ชั่นนี้จะจัดการการตรวจสอบระบบและการแจ้งเตือนข้อผิดพลาดโดยใช้ประโยคคำสั่ง if และการตอบกลับของประโยคคำสั่งนั้น ตามที่แสดงในส่วนย่อยของโค้ดที่ด้านล่างนี้

// handle health check request if (action === "ping") { return { version, data: { status: "active", }, }; } // handle error notification if (data?.error) { console.warn("Received client error:", data); return { version, data: { acknowledged: true, }, }; }
        

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

ตัวอย่างเช่น ดร็อปดาวน์วันที่จะเปิดใช้งานก็ต่อเมื่อมีการกรอกข้อมูลในดร็อปดาวน์สถานที่แล้ว การเปิดและปิดใช้งานช่องข้อมูลจะได้รับการจัดการเมื่อได้รับคำขอ data_exchange

// handle initial request when opening the flow and display APPOINTMENT screen if (action === "INIT") { return { ...SCREEN_RESPONSES.APPOINTMENT, data: { ...SCREEN_RESPONSES.APPOINTMENT.data, // these fields are disabled initially. Each field is enabled when previous fields are selected is_location_enabled: false, is_date_enabled: false, is_time_enabled: false, }, }; }

สำหรับการดำเนินการ data_exchange โครงสร้าง Switch Case จะถูกนำมาใช้เพื่อกำหนดข้อมูลที่จะส่งกลับไปตาม ID ของหน้าจอ หาก ID ของหน้าจอเป็น APPOINTMENT ช่องดร็อปดาวน์จะเปิดใช้งานในกรณีที่มีการเลือกดร็อปดาวน์ก่อนหน้าเท่านั้น

// Each field is enabled only when previous fields are selected is_location_enabled: Boolean(data.department), is_date_enabled: Boolean(data.department) && Boolean(data.location), is_time_enabled: Boolean(data.department) && Boolean(data.location) && Boolean(data.date)

สำหรับหน้าจอ DETAILS ชื่อของคุณสมบัติอ็อบเจ็กต์ข้อมูล เช่น สถานที่และแผนก จะถูกแยกออกมาจากอ็อบเจ็กต์ SCREEN_RESPONSES.APPOINTMENT.data โค้ดนี้จะคาดคะเนว่ามีการจับคู่ที่ถูกต้อง ดังนั้นโปรดทราบว่าอาจมีข้อผิดพลาดหากไม่พบอ็อบเจ็กต์ที่ตรงกัน

ตอนนี้ เราจะมาดูที่อ็อบเจ็กต์สถานที่ การเลือกอ็อบเจ็กต์สถานที่ที่เจาะจงจะถูกกำหนดโดยการจับคู่พร็อพเพอร์ตี้ id ของอ็อบเจ็กต์ในอาร์เรย์ที่มีค่าของ data.location

const departmentName = SCREEN_RESPONSES.APPOINTMENT.data.department.find( (dept) => dept.id === data.department ).title; const locationName = SCREEN_RESPONSES.APPOINTMENT.data.location.find( (loc) => loc.id === data.location ).title; const dateName = SCREEN_RESPONSES.APPOINTMENT.data.date.find( (date) => date.id === data.date

).title;

จากนั้นค่าจะถูกต่อเข้าด้วยกันและส่งกลับเพื่อตอบสนองต่อการแสดงผลหน้าจอ SUMMARY

const appointment = `${departmentName} at ${locationName} ${dateName} at ${data.time}`; const details = `Name: ${data.name} Email: ${data.email} Phone: ${data.phone} "${data.more_details}"`; return { ...SCREEN_RESPONSES.SUMMARY, data: { appointment, details, // return the same fields sent from client back to submit in the next step ...data, }, };
        

เมื่อมีการส่งหน้าจอ SUMMARY จากไคลเอนต์แล้ว การตอบกลับที่สำเร็จจะถูกส่งไปยังอุปกรณ์ไคลเอนต์เพื่อระบุว่า Flow เสร็จสมบูรณ์ flow_token เป็นตัวระบุที่ไม่ซ้ำกัน ซึ่งคุณสามารถตั้งค่าเมื่อส่ง Flow ไปยังผู้ใช้

// send success response to complete and close the flow return { ...SCREEN_RESPONSES.SUCCESS, data: { extension_message_response: { params: { flow_token, }, }, }, };

หน้าจอ TERMS ไม่มีข้อมูลสำหรับแลกเปลี่ยน ดังนั้นปลายทางจะไม่จัดการหน้าจอนี้

เพิ่มปลายทางไปยัง Flow

ที่ด้านขวาบนของหน้า Glitch คุณสามารถคัดลอก URL ด้วยการคลิกที่ไอคอนเมนูจุดแนวตั้งสามจุดแล้วเลือก "คัดลอกลิงก์" คุณยังสามารถรับลิงก์ได้ด้วยการคลิก "แชร์" ที่ด้านขวาบน

กลับไปยัง Flow Editor คลิก "ตั้งค่า" ในแบนเนอร์สีน้ำตาลที่ปรากฏที่ด้านบนของตัวแก้ไข

ป๊อปอัปจะปรากฏขึ้น ซึ่งช่วยให้คุณสามารถกำหนดค่า URI ปลายทาง หมายเลขโทรศัพท์ของธุรกิจ และแอพบน Meta for Developers ได้ เมื่อกำหนดค่าที่จำเป็นเรียบร้อยแล้ว ให้ดำเนินการตรวจสอบระบบ ขั้นแรก เรียกใช้ตัวอย่างแบบอินเทอร์แอคทีฟและตรวจสอบให้แน่ใจว่าคุณเลือก "ส่งคำขอข้อมูล" ที่ใต้ "ส่งคำขอข้อมูลในหน้าจอแรก" ในการตั้งค่าตัวอย่างแบบอินเทอร์แอคทีฟแล้ว การดำเนินการนี้จะส่งคำขอไปยังปลายทางเพื่อดึงข้อมูลสำหรับหน้าจอแรก เพื่อตรวจสอบยืนยันว่าปลายทางสามารถใช้งานได้และคุณได้ดำเนินการตรวจสอบระบบแล้ว

จากนั้น ให้เผยแพร่ Flow โดยคลิกที่เมนูจุดแนวนอนสามจุด (...) แล้วเลือก "เผยแพร่" การดำเนินการนี้จะส่งคำขอตรวจสอบระบบไปยังปลายทางของคุณพร้อมกับ action === "ping" เพื่อตรวจสอบยืนยันว่ามีการตั้งค่าปลายทางก่อนที่จะเผยแพร่

กราฟิกปลายทาง

ทดสอบ Flow

เมื่อคุณกำหนดค่าเรียบร้อยแล้ว ให้เปิดตัวอย่างแบบอินเทอร์แอคทีฟอีกครั้งใน WhatsApp Builder UI เพื่อทดสอบ Flow ในป๊อปอัปที่ปรากฏขึ้น ให้เลือกหมายเลขโทรศัพท์และเลือกตัวเลือก "ส่งคำขอข้อมูล" ที่ใต้ "ส่งคำขอข้อมูลในหน้าจอแรก" ปิด Flow โดยคลิกที่ไอคอน "X" เพื่อเริ่มทดสอบ Flow อีกครั้งจากปุ่ม CTA

เปิดบันทึกข้อมูล Glitch โดยคลิกที่แท็บ "LOGS" คลิก "ล้าง" เพื่อล้างข้อมูล จากนั้นกลับไปยังตัวอย่าง WhatsApp Builder UI คลิก "ดูตัวอย่าง Flow" คุณจะเห็นหน้าจอในลักษณะดังนี้

กราฟิกตัวอย่าง Flow

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

กราฟิกคำขอที่ถูกถอดรหัส

ดำเนินการต่อเพื่อเลือกแผนก ให้สังเกตว่า is_location_enabled ถูกตั้งค่าเป็น true และการดำเนินการเปลี่ยนเป็น data_exchange

กราฟิก data_exchange

ลองใช้ Flow ต่อไปและสังเกตการเปลี่ยนแปลงข้อมูลในบันทึกข้อมูล Glitch บันทึกข้อมูลที่คล้ายกันจะเกิดขึ้นเมื่อผู้ใช้โต้ตอบกับ Flow จากอุปกรณ์มือถือของตน

ในส่วนถัดไป คุณจะได้สร้าง Webhook ที่ส่งข้อความยืนยันไปยังผู้ใช้เมื่อผู้ใช้จองการนัดหมาย

การตั้งค่า Webhook

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

การใช้ Glitch เป็นทางเลือกและไม่จำเป็นต้องใช้ Flows คุณสามารถจำลองโค้ด Webhook จาก GitHub และเรียกใช้ในสภาพแวดล้อมที่คุณต้องการได้

ตั้งค่าตัวแปรสภาพแวดล้อม

เปิดไฟล์ .env บน Glitch เพื่อตั้งค่าตัวแปรสภาพแวดล้อม ตั้งค่า VERIFY_TOKEN ไปยังสตริงตามที่คุณต้องการ FLOW_ID ที่มี ID ของ Flow ของคุณ และ GRAPH_API_TOKEN ไปยังโทเค็นการเข้าถึงของบัญชี WhatsApp Business คุณสามารถรับโทเค็นการเข้าถึงได้จากแดชบอร์ดของแอพบน Meta for Developers เมื่อคุณคลิก "การตั้งค่า API" ที่ใต้ส่วน "WhatsApp" ในแผงการนำทางด้านซ้าย

กราฟิกการตั้งค่า API

ในหน้าที่แสดงผล ให้คลิกปุ่ม "คัดลอก" ที่ใต้การ์ด "โทเค็นการเข้าถึงชั่วคราว" วางคีย์ในไฟล์ .env ของคุณ

ติดตาม Webhook บนแดชบอร์ด Meta

ในบัญชีของคุณบน Meta for Developers ให้คลิกเมนู "การกำหนดค่า" ที่ใต้ "WhatsApp" ในแผงนำทางด้านซ้าย

กราฟิกการกำหนดค่า

คลิก "แก้ไข" ในการ์ด "Webhook" ในกล่องโต้ตอบที่เปิดขึ้น ให้วาง URL Glitch ที่คุณคัดลอกมา แล้วใส่ /webhook ต่อท้ายในช่อง "URL การเรียกกลับ" สำหรับช่อง "ตรวจสอบยืนยันโทเค็น" ให้เพิ่มโทเค็นจากตัวแปร VERIFY_TOKEN ในไฟล์ .env ของคุณ เมื่อเสร็จแล้ว ให้คลิก "ตรวจสอบยืนยันและบันทึก" กล่องโต้ตอบจะปิดลงและกลับไปสู่หน้าจอหลัก คลิก "จัดการ" และตรวจสอบช่อง "ข้อความ" ตอนนี้ Webhook ของคุณพร้อมใช้งานแล้ว

บทสรุปสำหรับโค้ด Webhook

โค้ดประกอบด้วย 2 เส้นทาง ได้แก่ POST /webhook และ GET /webhook เส้นทาง GET จะจัดการคำขอการตรวจสอบยืนยัน Webhook โดยตรวจสอบโทเค็นที่ระบุเทียบกับโทเค็นการตรวจสอบยืนยันที่กำหนดไว้ล่วงหน้า แล้วตอบกลับด้วยโค้ดสถานะที่เหมาะสมและโทเค็น Challenge

const verify_token = process.env.VERIFY_TOKEN; // Parse params from the webhook verification request let mode = req.query["hub.mode"]; let token = req.query["hub.verify_token"]; let challenge = req.query["hub.challenge"]; if (mode && token) { if (mode === "subscribe" && token === verify_token) { console.log("WEBHOOK_VERIFIED"); res.status(200).send(challenge); } else { res.sendStatus(403); } }

เส้นทาง POST /webhook จะประมวลผลการแจ้งเตือน Webhook ขาเข้า คำขอ Webhook สามารถมีเพย์โหลดที่แตกต่างกัน ดังนั้น โค้ดด้านล่างนี้จะอ่านข้อความและหมายเลขโทรศัพท์ของธุรกิจด้วยการเข้าถึงช่องคำขออย่างปลอดภัย ในกรณีที่ไม่ได้กำหนดไว้

const message = req.body.entry?.[0]?.changes[0]?.value?.messages?.[0]; const business_phone_number_id =

req.body.entry?.[0].changes?.[0].value?.metadata?.phone_number_id;

จากนั้นจะดำเนินการตรวจสอบคำขอที่เข้ามาว่าเป็นข้อความประเภท "text" ที่มีคำว่า "การนัดหมาย" (appointment) หรือไม่ หากข้อความมีคำนี้ Flow จะถูกส่งไปยังผู้ใช้ ข้อความ Flow ที่ถูกส่งโดยมี flow_action: "data_exchange," ซึ่งหมายความว่า Flow จะส่งคำขอ INIT ไปยังปลายทางเมื่อมีการเริ่มต้นใช้งาน เพื่อรับหน้าจอและข้อมูลเริ่มต้น

if ( message.type === "text" && // for demo purposes, send the flow message whenever a user sends a message containing "appointment" message.text.body.toLowerCase().includes("appointment") ) { // send flow message as per the docs here https://developers.facebook.com/docs/whatsapp/flows/gettingstarted/sendingaflow#interactive-message-parameters await axios({ method: "POST", url: `https://graph.facebook.com/v18.0/${business_phone_number_id}/messages`, headers: { Authorization: `Bearer ${GRAPH_API_TOKEN}`, }, data: { messaging_product: "whatsapp", to: message.from, type: "interactive", interactive: { type: "flow", header: { type: "text", text: "Hello there 👋", }, body: { text: "Ready to transform your space? Schedule a personalized consultation with our expert team!", }, footer: { text: "Click the button below to proceed", }, action: { name: "flow", parameters: { flow_id: FLOW_ID, flow_message_version: "3", // replace flow_token with a unique identifier for this flow message to track it in your endpoint & webhook flow_token: "<FLOW_TOKEN_PLACEHOLDER>", flow_cta: "Book an appointment", flow_action: "data_exchange", }, }, }, }, }); } ...

หากประเภทข้อความไม่ใช่ "text" โค้ดจะตรวจสอบว่าประเภทข้อความเป็น "interactive." หรือไม่ ประเภทอินเทอร์แอคทีฟ "nfm_reply" จะเป็นตัวบ่งบอกว่าเป็นข้อความขาเข้าเป็นการตอบกลับ Flow จากนั้นระบบจะส่งข้อความ "“You’ve successfully booked an appointment” (คุณจองการนัดหมายสำเร็จแล้ว) กลับไปยังผู้ใช้

... if ( message.type === "interactive" && message.interactive?.type === "nfm_reply" ) { // send confirmation message await axios({ method: "POST", url: `https://graph.facebook.com/v18.0/${business_phone_number_id}/messages`, headers: { Authorization: `Bearer ${GRAPH_API_TOKEN}`, }, data: { messaging_product: "whatsapp", to: message.from, text: { body: "You've successfully booked an appointment" }, }, }); } ...

ระบบจะระบุว่ามีการอ่านข้อความขาเข้าแล้ว ผู้ใช้จึงเห็นเครื่องหมายถูกสีฟ้า

... // mark incoming message as read await axios({ method: "POST", url: `https://graph.facebook.com/v18.0/${business_phone_number_id}/messages`, headers: { Authorization: `Bearer ${GRAPH_API_TOKEN}`, }, data: { messaging_product: "whatsapp", status: "read", message_id: message.id, }, }); ...
        

ประสบการณ์ผู้ใช้

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

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

กราฟิกการส่ง Flow ไปยังผู้ใช้

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

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

การสร้าง WhatsApp Flows นั้นทำได้ง่ายๆ ด้วย Flow Builder UI ทั้งนี้ คุณก็ยังสามารถใช้ API Flow เพื่อสร้าง Flows โดยใช้โปรแกรมได้ด้วยเช่นกัน หากต้องการข้อมูลเพิ่มเติม โปรดดูที่เอกสารประกอบเกี่ยวกับ WhatsApp Flows