網頁通話(掛件、代管通話頁、你的 App)中,來電者在語音旁邊還會看到聊天介面,所以 Agent 能做的不只是說話。電話來電者沒有這些。
開啟 Agent → 知識庫與工具 → 傳給客戶(Agent API 中為 send_to_caller),Agent 就能在來電者畫面上一次顯示最多五張卡片:每張可有標題、標題下一行字、描述、圖片、連結和最多兩個回覆按鈕;也可以在問題下方提供最多三個快速回覆。連結永遠不會念出來。
Agent 只能傳送這通電話中給過它的連結和圖片:它的指令和開場白、知識庫(從網頁讀入的文件帶有網址)、你的函式回傳的結果,以及預設卡片。連結也必須在 allowed_hosts 之一(預設卡片自己的網站一律允許)。Agent 自己編的連結或來電者念出的連結都不會傳送。Agent 話語中這些網站的連結,在聊天裡可以點擊。
"send_to_caller": {
"enabled": true,
"allowed_hosts": ["shop.example.com", "*.cdn.example.com"],
"presets": [
{ "name": "hours", "when": "asked when we open", "title": "Opening hours",
"description": "Mon–Sat 9:00–18:00", "url": "https://shop.example.com/stores", "image_url": "" }
]
}
每次傳送都會以 call.message_sent Webhook 通知你(channel、帶 title 和 url 的 items、quickReplies、blocked)。一通電話最多傳送 10 次。
通話中來電者也可以打字(電子郵件、訂單編號)或點回覆按鈕;Agent 像聽到說話一樣回答,正在說話時會先停下。每則最多 500 字,每秒 1 則,每通電話 100 則。通話紀錄會標出這一輪是打字還是點按鈕。
訪客也可以一開始就打字,而不是說話:網頁掛件和託管頁同時提供兩種方式,也可以在 Agent → 部署 裡只提供其中一種。打字對話不出聲音,按則計費。要從你自己的伺服器和 Agent 對話,請用 Chat API。
掛件會在你的網頁上提供一個 evasay 物件。全部可選;只有當網頁在掛件允許的網站中(Agent → 部署),通話視窗才會接收網頁的訊息:
<script src="https://evasay.com/voice-widget.js" data-agent="AGENT_SLUG" async></script>
<script>
window.evasay = window.evasay || [];
evasay.push(function (agent) {
agent.setVariables({ plan: 'pro', page: location.pathname }); // 給下一通電話
agent.update('Cart: 2 items, $120', { key: 'cart' }); // 通話中
agent.registerTool('add_to_cart', async function (args) {
// 你的程式碼,在訪客的瀏覽器裡執行
return { ok: true, checkout: 'https://shop.example.com/checkout' };
});
agent.on('cards', function (cards) {}); // 還有 'live'、'ended'
});
</script>
setVariables 的值會填入指令和開場白裡的 {{name}}。它們來自訪客的瀏覽器,所以會告訴 Agent 這些值未經驗證,而且永遠不會傳給你的函式或開場查詢。update 告訴 Agent 網頁上發生了什麼,但不要求它回答;同一個 key 的新更新會取代舊的。"kind": "page",沒有 url)的函式,並在網頁上註冊同名函式。Agent 只能在來自已註冊該函式的網頁的通話中呼叫它;除非 wait_for_result 為 false,否則最多等 timeout_sec(1–10,預設 5)秒取得結果。它以訪客的登入身分執行,就像訪客自己點了一下:任何會花錢或無法復原的動作前,請在你自己的網頁上要求確認。結果中的連結可以用卡片傳送。把 誰可以發起通話 設為 只允許帶權杖,再由你的伺服器為已登入使用者取得一次性權杖:
curl https://evasay.com/api/v1/voice/web-calls \
-X POST \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{ "agent_id": "AGENT_ID", "user_id": "u_42", "variables": { "name": "Ann" }, "expires_in": 600 }'
回應包含 token(expires_in 秒內可用一次,30–3600,預設 600)、agent(slug)和 web_call_url。在掛件的 script 上加 data-token-url="/your/endpoint" 把權杖交給網頁(它會帶著訪客的 Cookie POST 到那裡,讀取 { "token": "…" }),或使用 agent.setToken(async () => token)。權杖裡的 variables 是經過驗證的:指令、開場查詢和你的函式範本都可以使用,user_id 也一樣,並會保留在通話上(通話的 userId,篩選通話用 user_id)。API 金鑰請留在你的伺服器上。
在你自己的 App 裡,把 { "token": "…", "pageTools": ["add_to_cart"] } POST 到 https://evasay.com + web_call_url,得到這通電話的連線資訊(WebRTC offer 網址或 WebSocket 網址,帶通話權杖),用 RTVI 用戶端連線,例如 Pipecat 的用戶端 SDK;iOS、Android 和 React Native 見行動 App。卡片、頁面函式和提示以 RTVI server-message 傳來(evasay.cards、evasay.tool、evasay.notice);打的字用 send-text 傳送,網頁回報和函式結果用 client-message 的 evasay.context、evasay.tool_result 傳送。也可以用音訊 WebSocket 自己傳音訊,帶上 user_id 和 page_tools。