แอ็กชัน: คำตอบจากระบบของคุณเอง
แอ็กชันช่วยให้บอทของคุณค้นหาบางอย่างในระบบของคุณเองได้ระหว่างแชท — คำสั่งซื้ออยู่ที่ไหน จะจัดส่งเมื่อไร การจองได้รับการยืนยันหรือไม่ ลูกค้าถาม บอทเก็บข้อมูลที่ต้องใช้ เรียก API ของคุณ แล้วตอบจากสิ่งที่ได้รับกลับมาในภาษาของลูกค้า
ใช้งานได้ทุกที่ที่บอทของคุณทำงาน: วิดเจ็ตบนเว็บไซต์ ลิงก์บอทและ QR code ของคุณ และแอป Android, iOS, React Native, Flutter และ Ionic ไม่ต้องติดตั้งหรืออัปเดตอะไร — การเรียกทำจากเซิร์ฟเวอร์ของเรา ข้อมูลรับรอง API ของคุณจึงไม่ไปถึงเบราว์เซอร์หรือโทรศัพท์เลย
ก่อนเริ่ม: ใครก็สามารถแชทกับบอทของคุณได้
บอทของคุณคือแชทสาธารณะ หากแค่หมายเลขคำสั่งซื้ออย่างเดียวก็ดูคำสั่งซื้อได้ ใครก็สามารถลองพิมพ์หมายเลขไปเรื่อยๆ จนกว่าจะเจอ
บอทช่วยได้สามทาง แต่ไม่มีทางใดแทนที่การตรวจสอบนั้นได้: บอทส่งเฉพาะค่าที่ลูกค้าพิมพ์จริง จำกัดจำนวนครั้งที่แชทหนึ่งหรือที่อยู่หนึ่งค้นหาได้ และคุณเลือกได้ว่าบอทจะเห็นฟิลด์ใดของการตอบกลับบ้าง
ตั้งค่าแอ็กชัน
เปิด แอ็กชัน ในแดชบอร์ดแล้วเลือก แอ็กชันใหม่ เจ้าของและผู้ดูแลระบบสามารถเห็นหน้านี้ได้
- ชื่อ — สำหรับคุณเอง เช่น "สถานะคำสั่งซื้อ"
- บอทควรใช้เมื่อใด? — หนึ่งประโยค เหมือนที่คุณจะบอกเพื่อนร่วมงานใหม่: "ลูกค้าถามว่าคำสั่งซื้ออยู่ที่ไหนหรือจะมาถึงเมื่อไร"
- ที่อยู่ API ของคุณ —
GETหรือPOSTและที่อยู่แบบhttps://เขียน{{order_id}}ตรงตำแหน่งที่ต้องการแทนค่า - สิ่งที่บอทขอจากลูกค้า — สูงสุดหกค่า แต่ละค่ามีป้ายกำกับในแบบคำพูดของคุณ ("หมายเลขคำสั่งซื้อ") ชื่อที่ API ของคุณใช้ (
order_id) และประเภท: ข้อความใดก็ได้ ตัวเลข อีเมล หรือหมายเลขโทรศัพท์ - ส่วนหัว — คีย์ API หรือโทเค็นของคุณ จัดเก็บแบบเข้ารหัสและจะไม่แสดงอีก
- แชร์เฉพาะฟิลด์เหล่านี้กับบอท — ไม่บังคับ ระบุส่วนของการตอบกลับที่บอทใช้ได้ เช่น
status, eta, items[].nameส่วนที่เหลือทั้งหมดจะถูกตัดออกก่อนที่ AI จะเห็น
กด ทดสอบ พิมพ์ค่าตัวอย่าง แล้วคุณจะเห็นคำขอที่ถูกส่งไปและสิ่งที่บอทจะได้รับ จากนั้นลองใช้จริงในหน้า ทดสอบ: "คำสั่งซื้อ 48213 ของฉันอยู่ที่ไหน อีเมลของฉันคือ asha@example.com"
สิ่งที่ API ของคุณได้รับ
หากใช้ GET ค่าที่คุณวางไว้ในที่อยู่จะถูกเติมลงไป และค่าที่เหลือจะถูกเพิ่มใน query string:
GET https://api.yourshop.com/orders/48213?email=asha%40example.comหากใช้ POST ค่าต่างๆ จะอยู่ในเนื้อหา JSON:
POST https://api.yourshop.com/lookup
Content-Type: application/json
{"order_id":"48213","email":"asha@example.com"}ทุกคำขอจะมีส่วนหัวของคุณเองรวมถึงส่วนหัวเหล่านี้ด้วย:
| ส่วนหัว | คืออะไร |
|---|---|
webhook-id | id เฉพาะของคำขอนี้ |
webhook-timestamp | เวลาที่ส่ง เป็นวินาที |
webhook-signature | ลายเซ็น — ดูด้านล่าง |
X-Keyda-Bot | Client ID ของบอทคุณ |
X-Keyda-Action | คีย์ของแอ็กชัน เช่น order_status |
X-Keyda-Conversation | แชทที่เป็นต้นทาง |
สิ่งที่ต้องส่งกลับ
ตอบกลับภายใน 8 วินาทีด้วย JSON หรือข้อความธรรมดาสั้นๆ หนึ่งบรรทัด
- 200 พร้อมข้อมูล — บอทจะตอบจากข้อมูลนั้น ทำให้กระชับและใช้ชื่อฟิลด์ที่เข้าใจง่าย:
{"status":"shipped","eta":"2 October"}ใช้ได้ดีกว่ารหัสภายใน - 404 เมื่อไม่พบข้อมูลที่ตรงกัน — บอทจะแจ้งลูกค้าและขอให้ตรวจสอบสิ่งที่พิมพ์
- กรณีอื่นๆ หรือไม่มีการตอบกลับทันเวลา — บอทจะขอโทษ เสนอข้อมูลติดต่อของคุณ และแชทนั้นจะถูกทำเครื่องหมายไว้ให้คุณ เหตุผลจะแสดงอยู่ที่หน้าแอ็กชัน
ไม่ติดตามการเปลี่ยนเส้นทาง (redirect) และจะไม่อ่านการตอบกลับที่ใหญ่กว่า 256 KB
ตรวจสอบลายเซ็น
คำขอจะถูกลงนามตามแบบ Standard Webhooks คุณจึงใช้ไลบรารีที่มีอยู่แล้วได้ รหัสลับสำหรับลงนามของคุณอยู่ที่หน้าแอ็กชัน
ด้วยตนเอง: นำ id, timestamp และเนื้อหา (body) ที่ตรงกันทุกตัวอักษรมาต่อกันด้วยจุด ลงนามด้วย HMAC-SHA256 โดยใช้รหัสลับ (ส่วนที่อยู่หลัง whsec_ ถอดรหัส base64 แล้ว) จากนั้นเปรียบเทียบ
const crypto = require('crypto');
function isFromKeyda(req, rawBody, secret) {
const id = req.headers['webhook-id'];
const ts = req.headers['webhook-timestamp'];
const given = String(req.headers['webhook-signature'] || '').replace(/^v1,/, '');
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // older than 5 minutes
const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
const want = crypto.createHmac('sha256', key).update(`${id}.${ts}.${rawBody}`).digest('base64');
return given.length === want.length
&& crypto.timingSafeEqual(Buffer.from(given), Buffer.from(want));
}สำหรับคำขอ GET เนื้อหาจะว่างเปล่า ดังนั้นข้อความที่ลงนามจะลงท้ายด้วยจุด ใช้ POST หากต้องการให้ลายเซ็นครอบคลุมตัวค่าด้วย
บอทใช้งานอย่างไร
- บอทจะถามสิ่งที่ยังขาด ทีละหนึ่งคำถามสั้นๆ และจำสิ่งที่ลูกค้าบอกไว้ก่อนหน้านี้ในแชทได้
- บอทไม่เดาค่าเด็ดขาด หากลูกค้าไม่ได้พิมพ์ บอทจะถาม
- ค้นหาได้หนึ่งครั้งต่อข้อความ คำตอบที่บันทึกไว้ของคุณยังมาก่อนเสมอ ดังนั้นคำถามที่คุณตอบไว้เองจะไม่เรียก API ของคุณเลย
- คำตอบจากการค้นหาจะไม่ถูกนำไปใช้ซ้ำกับลูกค้ารายอื่นเด็ดขาด
- การค้นหาหนึ่งครั้งนับเป็นหนึ่งคำตอบ เช่นเดียวกับคำตอบอื่นๆ ที่ AI เขียน
ใน แชท คำตอบที่มาจากการค้นหาจะมีข้อความระบุไว้ด้านล่าง: แอ็กชันใดที่ทำงานและผลลัพธ์เป็นอย่างไร ค่าที่ลูกค้าพิมพ์จะอยู่ในบันทึกการสนทนาเท่านั้น ไม่มีที่อื่น
ขีดจำกัด
แอ็กชันมีไว้อ่านข้อมูล อย่าชี้แอ็กชันไปยังที่อยู่ที่เปลี่ยนแปลงข้อมูล — การยกเลิกคำสั่งซื้อหรือการคืนเงินต้องมีขั้นตอนยืนยันซึ่งบอทยังไม่มี