動作:來自您自己系統的答案
動作讓您的機器人能在對話過程中直接從您自己的系統查詢資訊——訂單在哪裡、何時送達、預約是否已確認。客戶提問,機器人收集所需資訊,呼叫您的 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 時,您放在位址中的值會被填入,其餘的值會加到查詢字串中:
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——機器人會告知客戶,並請他們檢查輸入的內容。
- 其他任何情況,或未及時回覆——機器人會致歉、提供您的聯絡資訊,並為您標記該對話。原因會顯示在「動作」畫面上。
不會跟隨重新導向,超過 256 KB 的回應不會被讀取。
驗證簽章
請求以 Standard Webhooks 的方式簽章,因此您可以使用現有的函式庫。您的簽章密鑰在「動作」畫面上。
手動方式:用英文句點將 id、時間戳記和原始請求內容串接起來,用密鑰(whsec_ 之後的部分,經 base64 解碼)以 HMAC-SHA256 簽章,然後比對。
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 撰寫的其他回覆相同。
在對話中,來自查詢的回答會在下方註明:執行了哪個動作以及結果如何。客戶輸入的值只保留在對話記錄中,不會儲存在其他任何地方。
限制
動作只讀取資訊。不要將動作指向會更改資料的位址——取消訂單或退款需要一個確認步驟,而機器人目前還沒有這一步。