Во время веб-звонка (виджет, размещённая страница, ваше приложение) звонящий видит чат рядом с голосом, поэтому агент может не только говорить. У звонящих по телефону этого нет.
Включите Агент → Инструменты → Отправить абоненту (send_to_caller в API агента), и агент сможет выводить на экран звонящего до пяти карточек одновременно: заголовок, строку под ним, описание, картинку, ссылку и до двух кнопок ответа в каждой; он также может предложить до трёх быстрых ответов под вопросом. Ссылки никогда не зачитываются вслух.
Агент может отправлять только те ссылки и картинки, которые были ему даны в этом звонке: его инструкции и приветствие, база знаний (у документа, прочитанного с веб-страницы, есть её адрес), ответы ваших функций и готовые карточки. Кроме того, ссылка должна вести на один из 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 (channel, items с title и url, quickReplies, blocked). За звонок отправка происходит не более 10 раз.
Во время звонка звонящий может также вводить текст (адрес электронной почты, номер заказа) или нажимать кнопку ответа; агент отвечает на это как на речь, предварительно замолчав, если говорил. До 500 символов в сообщении, одно в секунду, 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 }); // for the next call
agent.update('Cart: 2 items, $120', { key: 'cart' }); // during it
agent.registerTool('add_to_cart', async function (args) {
// your code, in the visitor's browser
return { ok: true, checkout: 'https://shop.example.com/checkout' };
});
agent.on('cards', function (cards) {}); // also 'live', 'ended'
});
</script>
setVariables подставляются в {{name}} в инструкциях и приветствии. Они приходят из браузера посетителя, поэтому агенту сообщается, что они не проверены, и они никогда не попадают в ваши функции и начальный запрос.update сообщает агенту, что происходит на странице, не заставляя его отвечать; более новое обновление с тем же key заменяет предыдущее."kind": "page", без url) и зарегистрируйте на своей странице функцию с тем же именем. Агент может вызвать её только в звонках со страницы, которая её зарегистрировала; он ждёт ответа до timeout_sec (1–10, по умолчанию 5), если только wait_for_result не равно false. Она выполняется от имени посетителя, как его собственный клик: запрашивайте подтверждение на своей странице перед всем, что стоит денег или необратимо. Ссылки из её ответа могут отправляться как карточки.Установите Кто может начать звонок в Только с токеном и пусть ваш сервер получает одноразовый токен для вошедшего пользователя:
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, который звонок сохраняет (userId в звонке, user_id для фильтрации звонков). Храните свой API-ключ на сервере.
В собственном приложении отправьте POST { "token": "…", "pageTools": ["add_to_cart"] } на https://evasay.com + web_call_url. В ответе — соединение звонка (адрес WebRTC-предложения или адрес WebSocket с токеном звонка) для клиента RTVI, например клиентского SDK Pipecat; для 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.