웹 통화(위젯, 호스팅된 페이지, 내 앱)에서는 발신자에게 음성 옆에 채팅이 보이므로 에이전트가 말하는 것 이상을 할 수 있습니다. 전화 발신자에게는 해당되지 않습니다.
에이전트 → 지식 및 도구 → 발신자에게 보내기(에이전트 API에서는 send_to_caller)를 켜면 에이전트가 발신자 화면에 한 번에 최대 5장의 카드를 띄울 수 있습니다. 카드마다 제목, 그 아래 한 줄, 설명, 그림, 링크, 최대 2개의 답변 버튼을 넣을 수 있고, 질문 아래 최대 3개의 빠른 답변을 제시할 수도 있습니다. 링크는 소리 내어 읽지 않습니다.
에이전트는 그 통화에서 받은 링크와 그림만 보낼 수 있습니다. 지시문과 인사말, 지식 베이스(웹 페이지에서 읽은 문서에는 그 주소가 붙음), 함수의 답, 미리 만든 카드입니다. 링크는 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)이 전송됩니다. 한 통화에서 최대 10번 보낼 수 있습니다.
통화 중 발신자는 글자를 입력하거나(이메일 주소, 주문 번호) 답변 버튼을 탭할 수도 있습니다. 에이전트는 말한 것처럼 답하며, 말하는 중이었다면 먼저 멈춥니다. 메시지당 최대 500자, 초당 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초 안에 한 통화, 30–3600, 기본 600), agent(슬러그), web_call_url이 있습니다. 위젯 스크립트에 data-token-url="/your/endpoint"를 붙여 토큰을 페이지에 넘기거나(방문자의 쿠키와 함께 그곳에 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를 넘기며 음성을 직접 다룰 수도 있습니다.