Перейти к содержанию

Обработка состояний вызовов#

Бета-версия

Функциональность находится в режиме бета-версии. Функции могут быть изменены, а также могут работать нестабильно. В будущем за функционал может взиматься дополнительная плата.
Подключение к функционалу можно запросить через техподдержку GREEN-API

CallsConnection — это EventTarget, и весь жизненный цикл звонка виден по его событиям. Стройте интерфейс от состояния, которое приходит в соединении, а не от результатов вызванных вами методов: звонок может закончиться и без вашего участия — например, его примут на другом устройстве того же аккаунта.

Событие state#

Событие state приходит при каждом изменении состояния звонка, а также сразу после подключения и переподключения. Поэтому страница, перезагруженная посреди разговора, сразу покажет верное состояние.

  • event.detail.state — одно из значений: idle (звонка нет), inc-call (поступил входящий вызов), out-call (выполняется исходящий вызов), on-call (звонок установлен);
  • event.detail.info — описание звонка для состояний, в которых звонок есть: id (идентификатор звонка), wid (идентификатор собеседника в WhatsApp) и name (имя, если WhatsApp его передал).
calls.addEventListener('state', (event) => {
  const { state, info } = event.detail;
  console.log('Состояние вызова:', state, info ?? '');

  // например, показать «Звоним...» для 'out-call'
  // и кнопки принять/отклонить для 'inc-call'
});

Текущее состояние можно прочитать и без ожидания события — в calls.state.state. А метод client.getCallState() возвращает состояние звонка по REST, если оно понадобилось вне соединения.

Кто на другой стороне#

Поле wid содержит либо 79991234567@c.us — если у вас есть номер собеседника, либо 1062110180230@lid — если номера нет. Поле info.name заполнено только тогда, когда у WhatsApp есть имя профиля (pushname), а для собеседника, пришедшего с @lid, его обычно нет.

Чтобы показать имя вместо цифр, ищите контакт по обоим адресам: метод getContacts возвращает для одного человека и id, и lid, поэтому контакт находится по любому из них.

Событие end-call#

Событие end-call передаётся после завершения звонка. Поле event.detail.reason говорит, что именно произошло:

  • call-ended — звонок завершён на стороне сервера: собеседник завершил вызов, истёк таймаут или вызов был принят на другом устройстве.
  • connection-lost — во время звонка оборвалось соединение с сервером и восстановить его не удалось.

Для call-ended в событии может быть ещё и поле cause — слово сервера о том, что произошло. Известные значения: hangup, timeout, accepted_elsewhere (вызов приняли на другом устройстве того же аккаунта, например на телефоне), rejected_elsewhere, no-media, connect-timeout, instance-gone, rejected:<причина>. Список открытый, поэтому незнакомое значение лучше показать как есть, а не отбрасывать. Если сервер причину не назвал, поля cause не будет; при connection-lost его не бывает никогда.

calls.addEventListener('end-call', (event) => {
  const { reason, cause } = event.detail;

  if (reason === 'connection-lost') {
    console.log('Вызов завершён: потеряно соединение с сервером.');
  } else if (cause === 'accepted_elsewhere') {
    console.log('Вызов принят на другом устройстве.');
  } else if (cause === 'timeout') {
    console.log('Вызов завершён из-за тайм-аута.');
  } else {
    console.log('Вызов завершён.', cause ? `Причина: ${cause}` : '');
  }

  // Здесь же возвращаем интерфейс в исходное состояние
});

Передачу звука библиотека при завершении звонка выключает сама, см. Передача звука.

Все события соединения#

Событие Что в нём
connect соединение установлено
disconnect соединение потеряно, причина — в detail.reason
error ошибка, текст — в detail.message
state состояние звонка: detail.state и detail.info
incoming-call поступил входящий вызов: detail с полями id, wid, name
local-stream-ready готов поток вашего микрофона
remote-stream-ready готов поток собеседника
end-call звонок закончился: detail.reason и detail.cause