Обработка входящих (Webhook)

Webhook служит для обработки входящих событий, ответов на асинхронные запросы и информацию об ошибках. Например, при приеме входящего сообщения в мессенджере, на указанный webhook отправляется POST-запрос:

{
  "id":18,
  "whatsapp_id":"191b80a9238",
  "event_action":"message",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "message": 
    {
       "_id" : "3EB0436AE1E682FF3A37",
       "id":"false_79999999999@c.us_3EB0436AE1E682FF3A37",
       "ack":1,
       "hasMedia":false,
       "mediaKey":"",
       "body":"212",
       "type":"chat",
       "timestamp":1662575377,
       "from":"79991112233@c.us",
       "to":"79999999999@c.us",
       "isForwarded":false
    }
  }
}

Для подтверждения успешного приема события, webhook должен отправить JSON-объект, в котором должен быть указан идентификатор входящего события и статус OK

{
  "result" : "OK",
  "id" : 18
}

Если система не получит в ответ корректного сообщения, то запрос повторится 3 раза, через каждые 20 секунд.

Установка Webhook-a

Для установки ссылки на обработчик Webhook, зайдите в личный кабинет, выберите блок привязанного Whatsapp-месенджера, нажмите 3 точки и выберите редактировать.

В открывшемся окне укажите ссылку на скрипт-обработчик Webhook-a

Нажмите «Сохранить»

Для установления или деактивации WebHook-a по API используйте метод set-hook. Инициируем POST-запрос на адрес:

https://whatsgate.ru/api/v1/set-hook

В теле запроса передается объект:

{
  "WhatsappID": "YOUR_WHATSAPP_ID",
  "callback": "https://callback.my/script.handler"
}
  • WhatsappID - идентификатор Whatsapp в системе
  • callback - URL обработчика обработчика входящих событий

Объект успешного ответа на запрос

{
  "result": "OK"
}

Типы событий

Событие отправляется после авторизации, когда клиент полностью готов к отправке и приему сообщений. Статус сессии изменяется с AUTH на READY. Поле event_action содержит строку «ready» Поле event_data содержит данные об авторизованном аккаунте - его номер и имя.

  • pushname - имя клиента в мессенджере
  • number - номер авторизованного телефона
  • id - whatsapp идентификатор в формате @c.us
{
  "id":19,
  "whatsapp_id" : "191b80a9238",
  "event_action" : "ready",
  "event_date" : "2023-01-24 18:29:37",
  "status_code" : null,
  "event_data" :
  {
    "pushname": "vasya",
    "number" : "79991234567",
    "id" : "79991234567@c.us"
  }
}

Событие отправляется при любом входящем сообщении в чате или группе. Поле event_action содержит строку «message» Поле event_data содержит объект сообщения

{
  "id":18,
  "whatsapp_id":"191b80a9238",
  "event_action":"message",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "message": 
    {
       "_id":"3EB0436AE1E682FF3A37",
       "id":"false_79999999999@c.us_3EB0436AE1E682FF3A37",
       "ack":1,
       "hasMedia":false,
       "mediaKey":"",
       "body":"212",
       "type":"chat",
       "timestamp":1662575377,
       "from":"79991112233@c.us",
       "to":"79999999999@c.us",
       "isForwarded":false
    }
  }
}

Событие отправляется после успешной доставки сообщения, в том случае, если была отправлена асинхронная команда отправки сообщения.

Поле event_action содержит строку «sent» Поле event_data содержит объект сообщения, которое было доставлено

{
  "id":19,
  "whatsapp_id":"191b80a9238",
  "event_action":"sent",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "message": 
    {
       "_id":"3EB0436AE1E682FF3A37",
       "id":"false_79999999999@c.us_3EB0436AE1E682FF3A37",
       "ack":1,
       "hasMedia":false,
       "mediaKey":"",
       "body":"212",
       "type":"chat",
       "timestamp":1662575377,
       "from":"79999999999@c.us",
       "to":"79991112233@c.us",
       "isForwarded":false
    }
  }
}

Событие отправляется при изменении статуса сообщения в чате или группе. Поле event_action содержит строку «ack» Поле event_data содержит объект сообщения, статус которого был изменен. Статус сообщения содержится в объекте сообщения, в поле ack и может принимать следующие значения: 1 - отправлено, 2 - доставлено, 3 - прочитано

{
  "id":19,
  "whatsapp_id":"191b80a9238",
  "event_action":"ack",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "message": 
    {
       "_id":"3EB0436AE1E682FF3A37",
       "id":"false_79999999999@c.us_3EB0436AE1E682FF3A37",
       "ack":1,
       "hasMedia":false,
       "mediaKey":"",
       "body":"212",
       "type":"chat",
       "timestamp":1662575377,
       "from":"79999999999@c.us",
       "to":"79991112233@c.us",
       "isForwarded":false
    }
  }
}

Событие отправляется, когда клиент отсоединяется и закрывается. Это происходит в случаях, когда Вы удаляете клиент из личного кабинета сервиса, или отзываете привязку в приложении Whatsapp на телефоне. Поле event_action содержит строку «disconnect» Поле event_data содержит объект с полем reason, в котором указана причина дисконнекта.

{
  "id":19,
  "whatsapp_id":"191b80a9238",
  "event_action":"disconnect",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "reason": "Client disconnected"
  }
}

Событие отправляется когда происходит какая-либо ошибка. Например, когда Вы пытаетесь асинхронно отправить сообщение не из своего контакт-листа на тарифе Light. Поле event_action содержит строку «error» Поле event_data содержит объект с описанием ошибки.

{
  "id":19,
  "whatsapp_id":"191b80a9238",
  "event_action":"error",
  "event_date":"2022-09-07 18:29:37",
  "status_code":null,
  "event_data":
  {
    "error":"Specified number not in your contact list"
  }
}
{
   "_id":"3EB0436AE1E682FF3A37",
   "id":"false_79999999999@c.us_3EB0436AE1E682FF3A37",
   "ack":1,
   "hasMedia":false,
   "mediaKey":"",
   "body":"212",
   "type":"chat",
   "timestamp":1662575377,
   "from":"79999999999@c.us",
   "to":"79991112233@c.us",
   "isForwarded":false,
   "quoted": {
       "_id": "3EB07621A4D08F9F59E0",
       "from": "79537226631@c.us",
       "type": "chat",
       "body": "Hello!"
   }
}

Поля объекта сообщения:

  • _id - идентификатор сообщения в WhatsApp.
  • id - идентификатор сообщения в Whatsapp, который можно указывать при отправке в поле «quote», для указания того, что сообщение является ответом на указанное сообщение.
  • ack - (int) флаг, показывающий, было ли сообщение просмотрено получателем, принимает следующие значения: 1 - отправлено, 2 - доставлено, 3 - прочитано
  • hasMedia - флаг, указывающий на то, содержит ли сообщение медиа-файл
  • mediaKey - ключ медиа-файла, который необходимо указать в методе get-media для получения media-файла.
  • body - текст сообщения
  • type - тип сообщения
  • timestamp - дата сообщения в формате unix-timestamp
  • from - указывает идентификатор отправителя сообщения
  • to - указывает идентификатор получателя сообщения
  • isForwarded - признак того, было ли сообщение перенаправлено с другого чата
  • quoted - Если данное сообщение цитирует (является ответом на) сообщение, то в поле quoted находится объект, с параметрами цитируемого сообщения.
    • _id - Идентификатор цитируемого сообщения
    • from - Идентификатор автора цитируемого сообщения
    • type - Тип цитируемого сообщения
    • body - Текст цитируемого сообщения
<?php
 
//буферизируем вывод
ob_start();
 
var_dump('----------------------' . date('d.m.Y H:i:s') . '----------------');
 
// вытаскиваем данные запроса
$input = file_get_contents('php://input');
$input_data = json_decode($input, true);
 
var_dump($input_data);
 
if($input_data['event_action'] == 'message') {
    //@TODO обрабатываем входящее сообщение
 
}
 
if($input_data['event_action'] == 'ack') {
 
    //@TODO обрабатываем получение или доставку
 
    if($input_data['event_data']['message']['ack'] == 2) {
        //@TODO доставка
    }
    if($input_data['event_data']['message']['ack'] == 3) {
        //@TODO прочитано
    }
}
 
//сохраняем лог
$fo = fopen('webhook.log', 'a');
fwrite($fo, ob_get_clean());
fclose($fo);
 
//формируем и выводим ответ
$answer_data = [
    'id' => $input_data['id'],
    'result' => 'OK'
];
 
echo json_encode($answer_data);
?>