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

Формат уведомления

Обновлено 17 октября 2026

Уведомление — один объект JSON. Он одинаковый в очереди (поле body ответа receiveNotification), в теле вебхука и в доставке подписки. Формат — как у Green API, с полями сверх него: channel, eventId и новые виды уведомлений.

Пример

Мария пишет в личный чат MAX:

{
  "typeWebhook": "incomingMessageReceived",
  "instanceData": {"idInstance": 7100000001, "wid": "79990000001@c.us", "typeInstance": "v3", "channel": "max"},
  "timestamp": 1791823658,
  "idMessage": "117428955282341903",
  "eventId": "msg:8695836:117428955282341903",
  "senderData": {
    "chatId": "8695836", "chatName": "Мария", "chatType": "user",
    "sender": "8695836", "senderName": "Мария", "senderType": "user",
    "senderContactName": "", "senderPhoneNumber": 0
  },
  "messageData": {
    "typeMessage": "textMessage",
    "textMessageData": {"textMessage": "Здравствуйте! Есть места на субботу?"}
  }
}

Общие поля

Поле Тип Описание
typeWebhook string вид уведомления — таблица ниже
instanceData object канал, от которого пришло уведомление
timestamp integer время события, секунды Unix (UTC)
idMessage string id сообщения или события; есть не у всех видов
eventId string ключ события для защиты от повторной обработки; есть не у всех видов
senderData object чат и отправитель — у уведомлений о сообщениях
messageData object содержимое — у уведомлений о сообщениях

Все id — строки, даже если выглядят как числа: id сообщений MAX 64-битные и в JavaScript и PHP числом теряют точность. Числа — только idInstance, timestamp и счётчики.

instanceData

Поле Описание
idInstance номер канала, число
wid аккаунт канала: номер 79990000001@c.us, у почты — адрес ящика. Пустая строка, если площадка номер не сообщила
typeInstance v3 у MAX (как у Green API), telegram, whatsapp, email
channel площадка: max, telegram, whatsapp, email

Ветвитесь по channel: typeInstance нужен для совместимости с Green API.

Виды уведомлений

typeWebhook Что senderData и messageData Статья
incomingMessageReceived сообщение собеседника, его правка, удаление, реакция есть Текст и другие ниже
outgoingMessageReceived своё сообщение с телефона; своя правка, удаление, реакция есть Свои сообщения
outgoingAPIMessageReceived сообщение, отправленное через API есть Свои сообщения
outgoingMessageStatus статус отправленного нет, поля на верхнем уровне outgoingMessageStatus
stateInstanceChanged смена состояния канала нет stateInstanceChanged
incomingCall, outgoingCall звонок нет incomingCall и outgoingCall
callStateChanged ход звонка, который ведёт сервер Gratio нет callStateChanged
groupEvent событие группы нет groupEvent
syncGap после простоя дочитана не вся история нет syncGap

senderData

Поле Личный чат Группа Канал (сообщество)
chatId собеседник группа канал
chatName имя собеседника название группы название канала
chatType user; в Telegram чат с ботом — bot group channel
sender собеседник участник, который написал автор, если площадка его сообщает; в Telegram — сам канал
senderName имя собеседника имя участника имя автора или ""
senderType всегда user user user
senderContactName всегда "" — поле для совместимости с Green API "" ""
senderPhoneNumber всегда 0; номер собеседника WhatsApp — в самом chatId 0 0

chatId — куда отвечать: передайте его в sendMessage. Как выглядят адреса в каждой площадке — в статье Идентификаторы чатов и сообщений.

В своих сообщениях (outgoingMessageReceived, outgoingAPIMessageReceived) chatId — получатель, sender — аккаунт канала.

messageData

Вид содержимого — в messageData.typeMessage:

typeMessage Что Статья
textMessage текст Текст
quotedMessage ответ цитатой Ответ цитатой
extendedTextMessage пересланное, ссылка с превью Ссылка и пересланное
imageMessage, videoMessage, documentMessage, audioMessage, stickerMessage файл, голосовое, альбом Файлы и альбомы
contactMessage контакт Контакт
locationMessage геопозиция Геопозиция
pollMessage опрос Опрос
editedMessage правка Правка
deletedMessage удаление Удаление
reactionMessage реакция Реакция

У писем рядом с содержимым — emailMessageData: тема, цепочка, адресаты. См. Письмо.

Если сообщение отвечает на другое, в messageData есть quotedMessage — и у файла, и у геопозиции. Сообщение вида, который Gratio не разбирает, и служебные сообщения площадки (закреп, вход в чат) уведомлением не приходят. Изменения состава групп — отдельным groupEvent.

idMessage

Уведомление idMessage
сообщение id сообщения на площадке: MAX "117428955282341903", Telegram "4815", WhatsApp "3EB0C767D26A1D5A6F0B", письмо "c62b698304229a98aad3"
правка {id}:edit:{версия} — две правки одного сообщения дают разные id
удаление {id}:delete
реакция {id}:reaction:{автор}:{n} — n растёт при каждой смене и снятии реакции
статус id отправленного сообщения
звонок id звонка или записи о звонке — см. incomingCall и outgoingCall

У правки, удаления и реакции сообщение, к которому относится событие, — в stanzaId внутри messageData.

eventId

eventId — ключ события в Gratio. Одно событие площадки — одно уведомление с одним eventId. Если ваше приложение может получить уведомление дважды (повтор вебхука после тайм-аута, падение до deleteNotification), храните обработанные ключи и пропускайте повторы.

Уведомление Вид eventId
сообщение msg:{chat}:{id}
правка edit:{chat}:{id}:{версия}
удаление del:{chat}:{id}
реакция react:{chat}:{id}:{автор}:{n}
звонок call:{chat}:{id}:{outcome}
событие группы msg:{chat}:{id} или grp:{chat}:{id}
ход звонка callstate:{callId}:{state}
разрыв истории gap:{reason}:{время}:{хеш}

Разбирать eventId не нужно — сравнивайте строку целиком: внутри адрес чата во внутренней форме, без суффиксов WhatsApp.

У outgoingAPIMessageReceived, outgoingMessageStatus и stateInstanceChanged поля eventId нет. Ключ для них — idMessage, пара idMessage + status или хеш тела: повторная доставка приходит тем же телом.

Как разбирать

  • Ветвитесь по typeWebhook, затем по messageData.typeMessage.
  • Незнакомый typeWebhook или typeMessage — пропустите и подтвердите уведомление. Gratio добавляет новые виды и поля, старые не меняет.
  • Поля, которых у площадки нет, приходят пустыми ("", 0, null) или не приходят вовсе. Не полагайтесь на их наличие.

Пример разбора:

def on_notification(body: dict) -> None:
    kind = body["typeWebhook"]
    if kind in ("incomingMessageReceived", "outgoingMessageReceived", "outgoingAPIMessageReceived"):
        data = body["messageData"]
        handlers = {"textMessage": on_text, "editedMessage": on_edit, "reactionMessage": on_reaction}
        handler = handlers.get(data["typeMessage"])
        if handler is not None:
            handler(body)
    elif kind == "outgoingMessageStatus":
        on_status(body["idMessage"], body["status"])
    # остальные виды — пропустить, уведомление всё равно подтвердить

Что дальше

Была ли статья полезна?