Перейти к содержимому
Wbiztool

Руководства

Вебхуки входящих сообщений (слушатели)

Слушатель связывает один из ваших номеров WhatsApp с Unibox и может отправлять вебхук о входящем сообщении на ваш сервер. На панели управления слушатели настраиваются на странице Входящие триггеры. Как только номер становится слушателем, его чаты синхронизируются во входящие Unibox, а если вы добавите URL вебхука, Wbiztool будет отправлять каждое новое сообщение на ваш сервер. Используйте вебхуки, чтобы записывать переписку в CRM, оповещать команду или создать автоответчик.

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

  • Дополнение Unibox. Оно стоит $20 в месяц или $200 в год за номер WhatsApp, а количество слушателей, которое вы можете создать, равно количеству единиц дополнения. Купите его в разделе Доступные дополнения на странице Биллинг и планы в панели управления. Без него страница Входящие триггеры всё равно открывается, но нажатие Добавить нового слушателя показывает Unibox Add-on Required (Требуется дополнение Unibox) с кнопкой Subscribe to Unibox Add-on (Подписаться на дополнение Unibox).
  • Подключённый номер WhatsApp в настройках WhatsApp. Добавить можно только подключённые номера, которые ещё не являются слушателями.
  • Вы должны быть владельцем или редактором рабочего пространства.
  • Для вебхуков: публичный URL (используйте https) длиной не более 100 символов, который принимает запросы POST с телом в формате JSON.

Добавление слушателя#

  1. Откройте «Входящие триггеры»

    В боковом меню откройте Unibox и нажмите Входящие триггеры или перейдите на страницу Входящие триггеры.

  2. Создайте нового слушателя

    Нажмите на карточку Добавить нового слушателя.

  3. Выберите номер

    Выберите номер в поле Выберите номер WhatsApp. Если в списке написано Нет доступных номеров WhatsApp, значит, все подключённые номера уже являются слушателями или ни один номер не подключён.

  4. Добавьте вебхук (необязательно)

    Введите URL вебхука (Опционально). Как только вы введёте URL, появится раздел Webhook Events (События вебхука): оставьте отмеченными Incoming Messages (Входящие сообщения), Outgoing Messages (Исходящие сообщения) или оба варианта. URL можно добавить или изменить позже.

  5. Сохраните

    Нажмите Добавить слушателя. Слушатель появится в виде карточки со статусом Active (Активен). Если вы указали URL, для него создаётся секрет вебхука.

Управление слушателями#

На каждой карточке указаны номер, его статус, URL вебхука: (или Не настроено), Последняя активность: (когда номер в последний раз проверялся на наличие сообщений, или Никогда) и Секрет вебхука:, который скрыт, пока вы не нажмёте кнопку с глазом.

Откройте меню на карточке, чтобы выполнить действие:

ДействиеЧто происходит
РедактироватьИзменение URL вебхука, событий вебхука или секрета. Номер изменить нельзя.
Отключить / ВключитьОтключение переводит слушателя в статус Inactive (Неактивен): номер перестаёт синхронизироваться с почтовым ящиком, и вебхуки не отправляются. Включение снова делает его Active.
УдалитьУдаляет слушателя после подтверждения. Беседы, которые уже есть в почтовом ящике, остаются. Если позже снова добавить тот же номер, слушатель восстанавливается. Если при повторном добавлении указать URL вебхука, слушатель сохраняет прежний секрет вебхука (если он был), а не получает новый.

Статусы слушателей#

СтатусЗначение
Active (Активен)Сообщения синхронизируются, и вебхуки отправляются, пока номер подключён.
Pending (Ожидание)Номер не был подключён, когда создавался слушатель, например через Zapier. Нажмите Включить, когда номер будет подключён.
Inactive (Неактивен)Отключён. Ничего не синхронизируется, и вебхуки не отправляются.

Статистика#

КарточкаЧто показывает
Активные слушателиВсе слушатели на странице, включая отключённых.
Доступные номераПодключённые номера, которые ещё не являются слушателями. Номера, слушатель которых вы удалили, здесь по-прежнему считаются использованными, поэтому значение может быть меньше, чем вы на самом деле можете добавить.
Общий лимитСколько слушателей позволяет ваше дополнение Unibox.
Сообщений сегодняПока не отслеживается; всегда показывает 0.

Изменение URL или событий вебхука#

  1. Откройте слушателя

    Нажмите на карточке, затем Редактировать.

  2. Обновите настройки

    Измените Webhook URL (Optional) (URL вебхука, необязательно) и Webhook Events. Очистите URL, чтобы прекратить отправку вебхуков для этого номера: его секрет тоже удаляется, а если снова добавить URL, будет создан новый.

  3. Сохраните

    Нажмите Update Listener (Обновить слушателя).

Повторная генерация секрета#

В окне Edit Listener (Редактирование слушателя) нажмите кнопку обновления рядом с Webhook Secret (Секрет вебхука) и подтвердите. Новый секрет сохраняется сразу, даже если после этого закрыть окно, не нажимая Update Listener, и с этого момента запросы подписываются им. Немедленно обновите секрет на своём сервере.

Как доставляются вебхуки#

Wbiztool отправляет на ваш URL один запрос POST для каждого нового сообщения, найденного при синхронизации номера. Синхронизация происходит каждые несколько минут, пока номер подключён и не занят отправкой сообщений.

  • События: message_received — для сообщений, которые люди присылают на ваш номер, и message_sent — для сообщений, отправленных с него (с телефона, из кампаний или через API). Отправляются только события, отмеченные в Webhook Events.
  • Ответы из входящих Unibox обычно не вызывают message_sent, потому что к моменту синхронизации они уже есть в почтовом ящике.
  • Ответ: ответьте HTTP 200 в течение 8 секунд. Любой другой ответ или тайм-аут считается неудачной доставкой.
  • Без повторных попыток: каждое сообщение отправляется один раз. Если ваш сервер недоступен, этот вебхук теряется.
  • Порядок: запросы отправляются независимо друг от друга и могут приходить не по порядку. Если порядок важен, сортируйте по message.timestamp.

Заголовки#

ЗаголовокЗначение
Content-Typeapplication/json
X-Wbiztool-Eventmessage_received или message_sent
X-Wbiztool-TimestampВремя отправки вебхука в формате ISO 8601 UTC. Совпадает с timestamp в теле.
X-Wbiztool-Webhook-IdID слушателя. Совпадает с webhook_id в теле.
X-Wbiztool-Signaturesha256=, за которым следует подпись. Отправляется всегда, когда у слушателя есть секрет, а он есть всегда, если задан URL.

Полезная нагрузка#

Примеры тела вебхука
{
  "event": "message_received",
  "timestamp": "2026-09-16T10:31:12.482913+00:00",
  "webhook_id": 42,
  "whatsapp_client_id": "678",
  "whatsapp_phone": "919812345678",
  "message": {
    "id": "[email protected]_3EB0C1A2B3D4E5F60718",
    "type": "chat",
    "content": "Hi, is my order #4821 out for delivery?",
    "from": "919876543210",
    "from_name": "Aman",
    "to": "919812345678",
    "timestamp": "2026-09-16T10:29:58+00:00",
    "whatsapp_timestamp": 1789554598,
    "direction": "incoming",
    "status": "pending",
    "is_forwarded": false,
    "forwarding_score": 0
  },
  "contact": {
    "whatsapp_id": "[email protected]",
    "phone": "919876543210",
    "name": "Aman",
    "is_group": false,
    "is_business": false
  },
  "organisation": {
    "id": "10314",
    "name": "Acme Stores"
  }
}

Номера, ID и имена выше приведены для примера.

Поля верхнего уровня#

ПолеТипОписание
eventstringmessage_received или message_sent.
timestampstringВремя отправки вебхука (ISO 8601, UTC).
webhook_idintegerID слушателя.
whatsapp_client_idstringID вашего номера WhatsApp, как в настройках WhatsApp.
whatsapp_phonestringВаш номер WhatsApp.
messageobjectСообщение. См. ниже.
contactobjectЧеловек или группа, с которыми ведётся беседа. См. ниже.
organisationobjectid (string) и name вашего рабочего пространства.
groupobjectТолько для групповых чатов: name — название группы.

Поля message#

ПолеТипОписание
idstringID сообщения в WhatsApp. Используйте его, чтобы отбрасывать дубликаты.
typestringchat для текста. В остальных случаях — тип WhatsApp, например image, video, audio, ptt (голосовое сообщение), document, sticker или location.
contentstringТекст для сообщений chat. Для медиафайлов вместо него метка: 📸 Image, 🎥 Video, 🎵 Audio, 🎤 Voice Message, 😊 Sticker, Document: с текстом документа (Document, если текста нет) или название типа с заглавной буквы для всего остального, например Location. Подписи не включаются.
fromstringВсегда номер контакта (или ID группы) — в обоих направлениях.
from_namestringИмя контакта или название группы. Может быть пустым.
tostringВсегда ваш номер WhatsApp — в обоих направлениях.
timestampstringКогда сообщение было отправлено в WhatsApp (ISO 8601, UTC).
whatsapp_timestampintegerТо же время в виде Unix-метки в секундах.
directionstringincoming или outgoing. Определяйте направление по этому полю, а не по from и to.
statusstringСейчас всегда pending. Не полагайтесь на него для определения статуса доставки или прочтения.
is_forwardedbooleanБыло ли сообщение переслано.
forwarding_scoreintegerСколько раз сообщение пересылалось.
mediaobjectДля медиасообщений, если данные доступны: filename, mimetype и size в байтах. Сам файл не включается.
quoted_message_idstringТолько если сообщение является ответом на другое сообщение.

Поля contact#

ПолеТипОписание
whatsapp_idstringWhatsApp ID, например [email protected] для человека или …@g.us для группы.
phonestringНомер без + или, для групп, ID группы.
namestringИмя контакта, известное Wbiztool, или название группы. Может быть пустым.
is_groupbooleantrue для групповых чатов.
is_businessbooleantrue для аккаунтов WhatsApp Business, если это известно.

Проверка подписи#

Каждый запрос подписывается секретом вашего слушателя с помощью HMAC-SHA256. Подпись вычисляется по необработанному телу запроса в точности в том виде, в каком оно получено, и передаётся в X-Wbiztool-Signature как sha256= плюс шестнадцатеричный дайджест в нижнем регистре.

Всегда вычисляйте подпись по необработанным байтам до разбора JSON. Разбор и повторное кодирование меняют тело (например, символы, отличные от английских, и эмодзи приходят экранированными как \uXXXX), и подпись не совпадёт.

// Express: keep the raw body for this route
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.WBIZTOOL_WEBHOOK_SECRET;

app.post("/wbiztool/webhook", express.raw({ type: "application/json" }), (req, res) => {
  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.body).digest("hex");
  const received = req.get("X-Wbiztool-Signature") || "";

  const valid =
    received.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
  if (!valid) return res.status(401).send("Invalid signature");

  const data = JSON.parse(req.body.toString("utf8"));
  if (data.event === "message_received") {
    console.log(`New message from ${data.contact.phone}: ${data.message.content}`);
  }
  res.sendStatus(200); // reply quickly; do slow work in the background
});

app.listen(3000);

Подпись не охватывает заголовок с меткой времени, поэтому не защищает от повторной отправки перехваченного запроса. Если это важно, сохраняйте каждый обработанный message.id и игнорируйте повторы.

Устранение неполадок#

Сообщение или проблемаЧто делать
Unibox Add-on Required (Требуется дополнение Unibox) при нажатии Добавить нового слушателяУ вашего рабочего пространства нет дополнения Unibox. Купите его в разделе Доступные дополнения на странице Биллинг и планы в панели управления.
You have reached your unibox numbers limitУдалите слушателя, который вам больше не нужен, или увеличьте количество единиц дополнения.
Нет доступных номеров WhatsAppПодключите ещё один номер — или нужный номер уже является слушателем.
This WhatsApp number is already a listenerВместо этого отредактируйте существующую карточку.
Invalid WhatsApp clientНомер отключился. Подключите его заново в настройках WhatsApp и перезагрузите страницу.
Ошибка с упоминанием value too long при сохраненииURL вебхука длиннее 100 символов. Используйте более короткий URL.
Вебхуки не приходятПроверьте, что слушатель в статусе Active, номер подключён, тип события отмечен, а ваш URL — публичный https с действительным сертификатом. Сообщения отправляются только после следующей синхронизации, через несколько минут.
Некоторые вебхуки пропадаютВаш сервер вернул ответ, отличный от 200, отвечал дольше 8 секунд или был недоступен. Неудачные доставки не повторяются.
Подпись не совпадаетИспользуйте необработанное тело, а не повторно закодированный JSON, и текущий секрет. Повторная генерация секрета или подключение Zapier заменяет его.
Последняя активность: показывает НикогдаНомер ещё не проверялся. Он должен быть подключён и не занят отправкой сообщений.

Связанные материалы#