Skip to main content

Что это такое

YCloud WhatsApp Calling API управляет сигнализацией голосовых вызовов между пользователем WhatsApp и бизнес-номером телефона. Ваше приложение обменивается данными SDP через YCloud, в то время как ваша реализация WebRTC управляет аудиосоединением. Звонки могут инициироваться в обоих направлениях:
  • Инициированные пользователем: Пользователь WhatsApp звонит вашей компании. Ваше приложение получает offer и принимает или отклоняет вызов.
  • Инициированные компанией: Ваше приложение создает offer и запрашивает у YCloud звонок пользователю WhatsApp.
Calling API обрабатывает сигнализацию вызова, а не медиастек WebRTC. Ваше приложение отвечает за настройку peer connection, захват и воспроизведение звука, генерацию SDP и освобождение ресурсов WebRTC.

Карта API

API Calling и события Webhook следуют одному и тому же жизненному циклу, но не образуют единую последовательность, применимую к каждому звонку. Выполните общую настройку, а затем следуйте процессу для вызовов, инициированных пользователем или компанией. Используйте ID звонка, wacid, для сопоставления каждой операции и события.

Общая настройка

Звонки, инициированные пользователем

Звонки, инициированные компанией

Общее завершение звонка

Необязательная обработка медиа

В этих таблицах описан рабочий процесс приложения. Они не гарантируют, что Webhook будут доставлены в том же порядке, что и строки. Сопоставляйте события по wacid и обрабатывайте повторную доставку идемпотентно.

Перед началом работы

Перед отправкой запроса к Calling подготовьте следующее:
  1. API-ключ аккаунта YCloud. Передавайте его в заголовке X-API-Key. См. раздел Аутентификация.
  2. WhatsApp Business Account и бизнес-номер телефона, зарегистрированный в YCloud.
  3. Включенная функция Calling для этого номера телефона.
  4. Реализация аудио WebRTC, которая может создавать и применять SDP-предложения и ответы.
  5. Эндпоинт Webhook YCloud, подписанный на события Calling, используемые вашей интеграцией. См. раздел Настройка Webhook.
  6. Разрешение пользователя на вызовы, если оно требуется для исходящего вызова от имени компании.
Свяжитесь с представителем YCloud, чтобы включить доступ к Calling API. Для исходящих вызовов соблюдайте актуальные требования Calling, включая уровень обмена сообщениями Business Portfolio на 2 000 клиентов и поддерживаемые страны для бизнес-номеров. Прежний порог в 1 000 переписок заменен текущими требованиями. В примерах ниже используются следующие переменные окружения:
Храните API-ключ на своем сервере. Не добавляйте его в код браузерных или мобильных приложений.

Как это работает

Сначала настройте рабочий номер телефона компании. Затем выполните обмен SDP в соответствии с направлением вызова. Ответы API подтверждают отдельные операции сигнализации, а события webhook сообщают об изменениях состояния и конечном результате. Если включена фиксация, отдельные события сообщают о готовности записи или расшифровки к скачиванию.

Запрос

Настройка рабочего номера телефона компании

Настройки вызовов и записи привязаны к конкретному бизнес-номеру телефона WhatsApp. Настройте их перед началом обработки вызовов.

Чтение настроек Calling

Используйте GET /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings, чтобы проверить, включены ли вызовы и виден ли значок вызова:
Если опустить type, YCloud вернет ответ с настройками Calling.

Включение Calling

Сохраните настройки Calling с помощью POST /whatsapp/phoneNumbers/{wabaId}/{phoneNumber}/settings, прежде чем начинать принимать или совершать вызовы:
Ответ содержит сохраненный объект calling. Перед обработкой реальных вызовов завершите настройку Webhook и сессий WebRTC.

Настройка записи и расшифровки

Параметры фиксации применяются к новым вызовам, созданным через API. Вы можете включить запись, расшифровку или обе эти функции.
Чтобы прочитать параметры фиксации, используйте type=capture:
Вы можете включить calling и capture в один запрос POST. После проверки доступа к номеру телефона YCloud попытается сохранить каждый раздел независимо. В случае ошибки при сохранении одного раздела второй уже может быть сохранен. Прочитайте обе настройки после ошибки и повторите попытку только для того раздела, который все еще требует обновления.

Обработка вызова, инициированного пользователем

Последовательность вызова, инициированного пользователем При вызове, инициированном пользователем, WhatsApp отправляет SDP-предложение. Ваше приложение отвечает на этот offer, а затем принимает или отклоняет вызов.

1. Получение события подключения

Подпишитесь на whatsapp.call.connect. В событии, инициированном пользователем, direction имеет значение USER_INITIATED и содержит SDP offer.
Сохраните callingConnect.wacid и callingConnect.phoneId вместе. Примените полученный SDP-предложение к вашему пиринговому соединению WebRTC и создайте SDP-ответ.

2. Предварительный прием вызова (pre-accept)

Вызовите pre-accept после создания SDP-ответ, но до того, как оператор примет вызов. Это подготовит медиатракт и позволит избежать прерываний звука в момент ответа на вызов. Эндпоинт: POST /whatsapp/calls/preAccept
После успешного предварительного принятия удерживайте звонок в состоянии вызова или готовности. Предварительное принятие не означает ответ на звонок со стороны пользователя.

3. Примите вызов

Когда оператор отвечает, отправьте те же phoneId, wacid, тип SDP и ответ SDP на эндпоинт принятия вызова. Эндпоинт: POST /whatsapp/calls/accept
Поля запроса и формат ответа такие же, как и при предварительном принятии. После успешного ответа используйте состояние подключения WebRTC для оценки готовности медиаданных и дождитесь события whatsapp.call.terminate, чтобы узнать окончательный результат вызова. Документированное окно для принятия входящего вызова составляет около 30–60 секунд после Webhook-события connect. Примите вызов без задержки: неотвеченный звонок завершается со стороны пользователя уведомлением Not Answered и Webhook-событием terminate. Даже если подключение WebRTC уже установлено, запускайте аудио только после того, как запрос на принятие вернет HTTP 200. Более ранний запуск может привести к обрезке первых слов, а слишком поздний — к тишине.

Отклонение вместо принятия

Если оператор не может принять входящий звонок, отклоните его вместо создания активной сессии. Эндпоинт: POST /whatsapp/calls/reject
Ответ возвращается в стандартном формате Calling response. Освободите локальное пиринговое соединение после запроса и все равно обработайте последующее событие завершения для этого wacid, если оно поступит.

Инициирование звонка со стороны бизнеса

При звонке, инициированном бизнесом, ваше приложение создает SDP-предложение (offer) и отправляет его в YCloud.

Получение разрешения на звонок

Перед совершением вызова необходимо получить разрешение пользователя на звонок. Интерактивный запрос разрешения можно отправить в течение активного окна клиентской поддержки:
Отправьте это тело запроса на POST /v2/whatsapp/messages/sendDirectly или поставьте его в очередь с помощью POST /v2/whatsapp/messages. Вы также можете создать шаблон разрешения на звонки. Например, отправьте это тело на POST /v2/whatsapp/templates, а затем дождитесь одобрения:
Отправьте одобренный шаблон с соответствующим параметром тела:
Когда параметр callback_permission_status включен в настройках вызовов телефонного номера, звонок от пользователя может предоставить разрешение на обратный вызов. Пользователь также может предоставить постоянное разрешение на звонки в профиле компании. Ответы с разрешениями приходят в виде событий whatsapp.inbound_message.received. Проверяйте объект interactive.call_permission_reply, а не просто факт доставки сообщения с запросом разрешения:
Не инициируйте звонок после отказа или по истечении срока действия разрешения. Ошибка Meta 138006 означает, что у бизнес-номера нет необходимого разрешения на совершение звонков. Подробности об ошибках провайдера см. в разделе Ошибки Calling от Meta.

1. Создайте SDP-предложение (offer)

Создайте локальное WebRTC пиринговое соединение и добавьте аудиотрек. Сгенерируйте SDP-предложение (offer), установите его в качестве локального описания (local description) и дождитесь завершения этой операции перед отправкой предложения в YCloud.

2. Установите соединение для вызова

Эндпоинт: POST /whatsapp/calls/connect Укажите как минимум одно из полей: to или recipient. Если переданы оба, YCloud использует to и проигнорирует recipient.
Сразу сохраните возвращенный wacid. Статус success: true означает, что операция подключения принята в обработку; это не означает, что пользователь ответил на звонок.

3. Примените ответ и отслеживайте попытку

YCloud отправляет whatsapp.call.connect для вызова. Для исходящего звонка, инициированного бизнесом, событие имеет direction: BUSINESS_INITIATED и содержит удаленный SDP answer. Примените этот ответ в качестве удаленного описания (remote description) для того же peer connection. Подпишитесь на whatsapp.call.status.updated, чтобы отслеживать попытку:
Сделайте обработку событий идемпотентной, чтобы повторная доставка не дублировала действия оператора, списание средств или очистку ресурсов.

Завершение активного вызова

Вызывайте terminate, когда вашему приложению необходимо завершить активный входящий или исходящий вызов. Эндпоинт: POST /whatsapp/calls/terminate
Поля запроса совпадают с запросом на отклонение (reject). Успешный ответ подтверждает, что YCloud обработал операцию завершения. Сохраняйте запись вызова открытой до получения окончательного события завершения или до тех пор, пока ее не закроет ваша собственная политика восстановления.

Ответ

Все пять эндпоинтов сигналинга возвращают ответ одинаковой структуры:
wacid идентифицирует вызов, связанный с операцией. success: true подтверждает, что операция сигналинга прошла успешно; это не подтверждает, что другой участник ответил или что вызов завершен. Для этих результатов используйте состояние WebRTC и события Webhook вызовов.

Обработка финального события вызова

whatsapp.call.terminate — это терминальное событие жизненного цикла вызова.
При получении этого события завершите запись вызова и освободите оставшиеся ресурсы WebRTC. Более ранний ответ API не подтверждает, что вызов завершен.

Получение записей и транскрипций

Если запись включена, обработка медиа продолжается после завершения жизненного цикла вызова. Запись и транскрипция имеют отдельные финальные события: В следующем примере показана доступная запись:
Оба свойства полезной нагрузки используют одинаковые поля:

Скачивание доступного ресурса

Вызывайте медиа-эндпоинт только после того, как соответствующее событие сообщит AVAILABLE. Эндпоинт: GET /whatsapp/calls/media/{mediaAssetId}
Эндпоинт возвращает файл целиком в виде вложения и не поддерживает скачивание по диапазонам байтов (byte-range). Записи используют .ogg; транскрипции используют .json. Скачать ресурс может только владеющий им тенант YCloud. Ресурс остается доступным в течение 30 дней с момента создания. Отсутствующие, недоступные, истекшие или чужие ресурсы возвращают HTTP 404.

Создание надежного приемника Webhook

Подпишите ваш эндпоинт на события, необходимые для вашей интеграции:
Для каждого запроса:
  1. Сохраняйте исходное тело запроса (raw body) и проверяйте YCloud-Signature, прежде чем доверять событию.
  2. Сохраняйте событие в постоянное хранилище или помещайте надежную задачу в очередь.
  3. Своевременно возвращайте успешный ответ 2xx.
  4. Выполняйте дедупликацию по id верхнего уровня события.
  5. Сопоставляйте данные вызова по wacid; сохраняйте phoneId вместе с ними для последующих операций.
  6. Обрабатывайте связанные события, поступающие с небольшим интервалом, и учитывайте возможность повторной доставки.
Сведения о создании эндпоинтов, проверке подписи и механизмах доставки приведены в разделе Настройка Webhook. Полные сгенерированные примеры можно найти на странице Примеры полезной нагрузки Webhook.

Обработка ошибок и восстановление

Эндпоинты для звонков используют стандартный формат ответа об ошибке YCloud API. Структуру ответа и рекомендации по повторным попыткам см. в разделе Обработка ошибок. Используйте эти проверки при типичных сбоях Calling: Тайм-аут запроса не означает сбой операции сигнализации. Перед повторной попыткой сопоставьте запрос с событиями Webhook и текущим локальным состоянием звонка. Действие уже могло достичь WhatsApp.

Чек-лист интеграции

  • Включите функцию Calling для нужного корпоративного номера телефона.
  • Настройте и протестируйте все необходимые подписки на Webhook для звонков.
  • Проверяйте подписи Webhook и выполняйте дедупликацию событий.
  • Храните wacid, phoneId, направление и текущее состояние вместе.
  • Интерпретируйте API success как принятие операции в обработку, а не как финальный результат звонка.
  • Используйте preAccept только для подготовки; вызывайте accept для ответа.
  • Завершайте вызовы по событию whatsapp.call.terminate.
  • Загружайте записанные медиафайлы только после события AVAILABLE и в течение 30 дней.
  • Освобождайте ресурсы WebRTC при отклонении, завершении, ошибке или локальном тайм-ауте.
  • Не записывайте API-ключи, полные SDP или идентификаторы участников в общие журналы приложения.

Справочник по Calling API

Ознакомьтесь с точными схемами запросов и ответов для каждого эндпоинта Calling.

Примеры полезной нагрузки Webhook

Ознакомьтесь с полными примерами событий Calling, сгенерированными на основе спецификации Webhook.