Web 通話(ウィジェット、ホストされた通話ページ、あなたのアプリ)では、発信者には音声の横にチャットが表示されるため、エージェントは話す以外のこともできます。電話の発信者にはこれらはありません。
エージェント → ナレッジとツール → 発信者に送る(エージェント API では send_to_caller)を有効にすると、エージェントは発信者の画面に一度に最大 5 枚のカードを表示できます。各カードにはタイトル、その下の一行、説明、画像、リンク、最大 2 つの返答ボタンを付けられます。質問の下に最大 3 つのクイック返信を出すこともできます。リンクが読み上げられることはありません。
エージェントが送れるのは、その通話で与えられたリンクと画像だけです。指示と挨拶、ナレッジベース(Web ページから読み込んだドキュメントにはそのアドレスが付きます)、関数の回答、既製のカードです。さらにリンクは allowed_hosts のいずれかになければなりません(既製カード自身のサイトは常に許可)。エージェントが作り出したリンクや発信者が読み上げたリンクは送られません。エージェントの発言中のそれらのサイトのリンクは、チャットでクリックできます。
"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)が届きます。1 通話につき最大 10 回送信できます。
通話中、発信者は文字を入力したり(メールアドレス、注文番号)、返答ボタンをタップしたりもできます。エージェントは話した言葉と同じように答え、話している最中ならまず止まります。1 メッセージ最大 500 文字、1 秒に 1 件、1 通話 100 件までです。通話記録では、これらのターンは入力またはタップとして示されます。
訪問者は話す代わりに、最初から文字で始めることもできます。ウィジェットとホストページは両方を提供し、Agent → Deploy でどちらか一方だけにすることもできます。文字での会話は音声なしで、メッセージごとに課金されます。自社のサーバーからエージェントとチャットするには Chat API を使います。
ウィジェットはページに evasay オブジェクトを提供します。すべて任意で、通話フレームがページの声を聞くのは、そのページがウィジェットの許可されたサイト(エージェント → デプロイ)にある場合だけです。
<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}} を埋めます。訪問者のブラウザから来るため、エージェントには未検証であることが伝えられ、関数や開始時の照会には決して渡されません。update はページで起きていることをエージェントに伝えますが、返答はさせません。同じ key の新しい更新は古いものを置き換えます。"kind": "page"、url なし)の関数をエージェントに追加し、ページで同名の関数を登録します。エージェントがそれを呼べるのは、登録したページからの通話だけです。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 秒以内に 1 回の通話。30–3600、既定 600)、agent(スラッグ)、web_call_url が含まれます。ウィジェットのスクリプトに data-token-url="/your/endpoint" を付けてトークンをページに渡すか(訪問者の Cookie 付きでそこに POST し、{ "token": "…" } を読み取ります)、agent.setToken(async () => token) を使います。トークンの variables は検証済みです。指示、開始時の照会、関数のテンプレートで使え、user_id も同様です。user_id は通話に保持されます(通話の userId、通話の絞り込みには user_id)。API キーはサーバーに置いてください。
自社アプリでは、{ "token": "…", "pageTools": ["add_to_cart"] } を https://evasay.com + web_call_url に POST します。レスポンスは通話の接続情報(WebRTC offer のアドレスまたは WebSocket のアドレスと通話トークン)で、Pipecat のクライアント SDK などの RTVI クライアントで使います。iOS、Android、React Native はモバイルアプリを参照してください。カード、ページ関数、通知は RTVI の server-message(evasay.cards、evasay.tool、evasay.notice)として届きます。入力した言葉は send-text で、ページの報告と回答は client-message の evasay.context と evasay.tool_result で送ります。または WebSocket による音声 で user_id と page_tools を渡して音声を自分で扱うこともできます。