Перейти к содержимому
AISARAISAR
Сообщения

Сообщения

Новое сообщение

message.created

Отправляется при создании нового сообщения — входящего от контакта или исходящего от оператора либо системы. Для сообщений, начатых из рекламы (WhatsApp Click-to-Message и реклама Instagram с переходом в Direct), payload включает объект referral с данными объявления. Нажатия quick-reply и интерактивных кнопок WhatsApp нормализуются в обычное текстовое сообщение: подпись кнопки попадает в content.text, а payload кнопки — в content.interactive_reply_payload.

HTTP-запрос

AISAR отправляет подписанный POST-запрос на ваш webhook_url:

http
POST {webhook_url}
Content-Type: application/json
X-AISAR-Signature: sha256=...

{
  "event": "message.created",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-22T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message": {
      "id": 123,
      "external_id": "3EB0ABC123456789",
      "conversation_id": 45,
      "thread_id": 67,
      "channel_id": 2,
      "direction": "inbound",
      "type": "text",
      "content": {
        "text": "Hello, I need help"
      },
      "display_content": "Hello, I need help",
      "media": null,
      "reply_to_message_id": null,
      "is_deleted": false,
      "system_notification": false,
      "created_at": "2026-03-22T12:00:00.000000Z"
    },
    "sender": {
      "type": "contact",
      "contact_id": 10,
      "contact_account_id": 15,
      "name": "John Doe",
      "phone": "+77001234567",
      "email": "john@example.com",
      "external_id": "77001234567@s.whatsapp.net"
    },
    "recipient": null,
    "conversation": {
      "id": 45,
      "status": "active",
      "contact_id": 10,
      "deal_id": null,
      "subject": null,
      "is_archived": false,
      "is_group": false
    },
    "channel": {
      "id": 2,
      "type": "whatsapp",
      "name": "Main WhatsApp"
    },
    "is_dialog_assigned": false,
    "referral": null
  }
}

Заголовок X-AISAR-Signature содержит HMAC-SHA256 подпись тела запроса — используйте её, чтобы убедиться, что запрос пришёл от AISAR.

Пример payload

json
{
  "event": "message.created",
  "event_id": "evt_01JXXXXXXXXXXXXXXXXXXXXX",
  "timestamp": "2026-03-22T12:00:00.000000Z",
  "company_id": 1,
  "data": {
    "message": {
      "id": 123,
      "external_id": "3EB0ABC123456789",
      "conversation_id": 45,
      "thread_id": 67,
      "channel_id": 2,
      "direction": "inbound",
      "type": "text",
      "content": {
        "text": "Hello, I need help"
      },
      "display_content": "Hello, I need help",
      "media": null,
      "reply_to_message_id": null,
      "is_deleted": false,
      "system_notification": false,
      "created_at": "2026-03-22T12:00:00.000000Z"
    },
    "sender": {
      "type": "contact",
      "contact_id": 10,
      "contact_account_id": 15,
      "name": "John Doe",
      "phone": "+77001234567",
      "email": "john@example.com",
      "external_id": "77001234567@s.whatsapp.net"
    },
    "recipient": null,
    "conversation": {
      "id": 45,
      "status": "active",
      "contact_id": 10,
      "deal_id": null,
      "subject": null,
      "is_archived": false,
      "is_group": false
    },
    "channel": {
      "id": 2,
      "type": "whatsapp",
      "name": "Main WhatsApp"
    },
    "is_dialog_assigned": false,
    "referral": null
  }
}

Поля payload

ПолеТипОписание
message.idintegerВнутренний ID сообщения
message.external_idstringВнешний ID сообщения (платформенный, например ID сообщения WhatsApp)
message.conversation_idintegerID диалога
message.thread_idintegerID треда
message.channel_idintegerID канала
message.directionstringinbound (от контакта) или outbound (от пользователя/системы)
message.typestringТип сообщения: text, image, video, audio, voice, document, sticker, location, contact, poll, template, ig_post, ig_reel, ig_story, ig_story_reply, story_mention, share, ephemeral, unsupported_type, comment, call, note. voice — голосовое сообщение (записанное аудио, OGG/Opus), audio — обычный аудиофайл. template, ig_post, ig_reel, ig_story, ig_story_reply, story_mention, share, ephemeral, unsupported_type — виды вложений Instagram (карточка generic-шаблона, репост поста/рилса/сторис, ответ на сторис, упоминание в сторис, шеринг поста, самоуничтожающееся и нераспознанное вложение соответственно): для этих типов message.type наследует type первого вложения сообщения (см. message.media[].type ниже), а не выставляется отдельно. comment — комментарий к посту Instagram/Threads (комментарийный тред). call — карточка звонка в таймлайне. note — внутренняя заметка оператора (не покидает AISAR). Нажатия quick-reply / интерактивных кнопок WhatsApp нормализуются в text. Реакции НЕ являются message_type — они доставляются отдельным событием `message.reaction.updated`, а не через `message.created`
message.contentobject|stringСодержимое сообщения. Для текста: {"text": "..."}. Для медиа включает подпись, mime_type и т. п. Для нажатий кнопок дополнительно несёт interactive_reply_payload — payload кнопки / id пункта списка (null, если кнопка шаблона без payload)
message.display_contentstring|nullТекстовое представление содержимого сообщения
message.mediaarray|nullМассив вложений; null, если медиа нет. Каждый элемент несёт только type/url/filename/mime_type/size/duration/playback_url — поле metadata вложения (download_status, media_id, содержимое IG-карточки и т.п.) в вебхук-payload НЕ отдаётся, оно доступно только через REST (GET /messages/{id} или .../attachments)
message.media[].typestringТип вложения (полный набор значений CHECK-constraint message_attachments.type): image, video, audio, voice, document, file, contact, location, sticker, ig_reel, ig_post, ig_story, share, ig_story_reply, story_mention, ephemeral, unsupported_type, template
message.media[].urlstringURL для скачивания
message.media[].filenamestring|nullИсходное имя файла
message.media[].mime_typestring|nullMIME-тип (например, image/jpeg; голосовые сообщения — audio/ogg)
message.media[].sizeinteger|nullРазмер файла в байтах
message.media[].durationinteger|nullДлительность в секундах (аудио / голосовые / видео)
message.media[].playback_urlstring|nullПодписанная ссылка на m4a/AAC-версию голосового вложения (транскодируется лениво из исходного OGG/Opus). Присутствует только для voice-вложений и audio-вложений с mime_type audio/ogg, у которых файл уже скачан локально; иначе null. В вебхуке ссылка временная — действует 7 дней (в REST-версии того же поля, MessageAttachment.playback_url, срок жизни ссылки не ограничен)
message.reply_to_message_idinteger|nullID цитируемого сообщения, если это ответ
message.is_deletedbooleanУдалено ли сообщение
message.system_notificationbooleanЯвляется ли сообщение системным уведомлением
message.created_atstringМетка времени ISO 8601
sender.typestringcontact для входящих сообщений, user для исходящих
sender.contact_idintegerID контакта (для входящих)
sender.contact_account_idintegerID аккаунта контакта (для входящих)
sender.user_idintegerID пользователя (для исходящих)
sender.namestringОтображаемое имя отправителя
sender.phonestring|nullТелефон контакта (для входящих)
sender.emailstring|nullEmail отправителя
sender.external_idstringПлатформенный ID контакта, например 77001234567@s.whatsapp.net (для входящих)
recipientobject|nullТолько для исходящих сообщений: контакт-получатель, та же структура, что у sender с type=contact
conversation.idintegerID диалога
conversation.statusstringactive или closed
conversation.contact_idintegerID контакта
conversation.deal_idinteger|nullID связанной сделки
conversation.subjectstring|nullТема диалога
conversation.is_archivedbooleanАрхивирован ли диалог
conversation.is_groupbooleantrue, если это групповой чат (например, группа WhatsApp), false для личных переписок
channel.idintegerID канала
channel.typestringКлюч типа канала: `whatsapp`, `whatsapp_business`, `instagram`, `instagram_business`, `threads`, `telegram`, `telegram_bot`, `live_chat`
channel.namestringНазвание канала
is_dialog_assignedbooleantrue, если на диалог назначен пользователь, иначе false
referralobject|nullДанные перехода из рекламы; null для обычных сообщений. Заполняется на первом сообщении диалога, начатого из объявления, для каналов `whatsapp`, `whatsapp_business` (Click-to-WhatsApp) и `instagram_business` (реклама с переходом в Direct). Набор полей зависит от канала: WhatsApp отдаёт `source_url`, `ctwa_clid`, `body`, `media_type`; Instagram — `post_id` и `ref`. Общие для обоих: `source_type`, `source_id`, `headline`, `image_url`, `video_url`. Для остальных типов каналов всегда null.
referral.source_urlstringURL объявления или поста; только WhatsApp
referral.source_typestringТип источника: ad или post
referral.source_idstringID объявления или поста (для Instagram — `ad_id`); можно использовать с Meta API для получения данных кампании
referral.headlinestringЗаголовок объявления
referral.bodystringТекст объявления
referral.ctwa_clidstringКлик-ID для точной атрибуции; только WhatsApp
referral.media_typestringТип медиа в объявлении: image или video; только WhatsApp
referral.image_urlstringURL изображения объявления (если есть)
referral.video_urlstringURL видео объявления (если есть)
referral.post_idstringID поста, из которого крутилось объявление; только Instagram
referral.refstringПроизвольная метка из диплинка (`ig.me/...?ref=`), если задана; только Instagram