enВойти в Senler

Данные сообщений

Ответ из ask, история getMessages, сообщения subscribeDialog и событие messageReceived используют общие данные сообщения. Они подходят для результата рядом с формой и для собственного чата.

Текст и идентификаторы

  • dialogId и eventId определяют диалог и сообщение.
  • text содержит текст, а format указывает plain_text или markdown.
  • attachments содержит вложения, buttons — строки кнопок.

Пустой text не означает ошибку: ответ может содержать только файл. Обычный текст выводите через textContent, а Markdown — через обработчик с очисткой небезопасного HTML. Не вставляйте полученный текст напрямую в innerHTML.

Версии, отправитель и ошибки

ПолеКак использовать
kindmessage — обычное сообщение, error — сохранённая публичная ошибка.
errorПри ошибке может содержать message для посетителя. Внутреннего стека исключения здесь нет.
versionВерсия сообщения: обновляет существующую запись с тем же eventId, включая изменения вложений и кнопок.
timestampВремя сообщения для отображения и сортировки.
sendervisitor, assistant, operator или system. Событие messageReceived ограничено assistant и operator.
senderId, senderName, senderAvatarUrlНеобязательные данные отправителя; URL аватара также может быть null.
sendingStatusНеобязательный статус отправки. Не заменяет итоговый статус запроса ask; учитывайте отсутствие или незнакомое значение.
deletedСообщение удалено: уберите его содержимое или покажите пометку об удалении.

Объединяйте сообщения одного диалога по eventId с учётом version. Экспорт mergeWidgetMessages(previous, incoming) из @senlerio/widget делает это и сортирует результат по времени. Он сохраняет записи с deleted, поэтому их содержимое должен скрывать интерфейс. Не добавляйте ответ второй раз, если он пришёл и через ask, и через подписку. Пример объединения — в инструкции своего чата.

Вложения

Каждое вложение содержит id, type и status. Типом может быть photo, video, document, voice, audio или sticker.

status: "ready" означает готовность файла. Состояния deferred, pending, fetching и uploading относятся к подготовке; quota_pending — к ожиданию доступной квоты, failed — к ошибке. При ошибке может быть указан errorCode. Ссылка не обязана быть доступна сразу.

Дополнительные поля, если они известны:

  • url — файл; previewUrl — изображение для предпросмотра;
  • name, mimeType, size — имя, MIME-тип и размер в байтах;
  • width, height — размеры изображения или видео;
  • durationSeconds — длительность аудио или видео в секундах.

Для отправки файла посетителя используйте отдельный метод uploadFile, а затем передайте результат в ask.

Кнопки

buttons — массив строк вида { buttons: [...] }. У кнопки есть text и action. Действие содержит переход open_url, ответ callback или зарегистрированное действие сайта custom_action.

Дополнительные поля описывают состояние и оформление:

  • instanceId — идентификатор экземпляра кнопки;
  • repeatable — разрешены повторные нажатия; disabled — кнопка выключена;
  • appearance — neutral, primary, positive или negative;
  • pollOption.multiple — вариант опроса с возможностью множественного выбора.

Получение данных кнопки не означает её нажатия или подтверждения действия пользователем. В обработчике нажатия в собственном интерфейсе передайте исходную кнопку в clickButton:

async function clickMessageButton(message, button) {
  if (button.disabled) return;
  await widget.clickButton({
    dialogId: message.dialogId,
    eventId: message.eventId,
    button,
  });
}

widget — готовый экземпляр SDK, message и button — полученные данные. Обрабатывайте ошибку Promise в интерфейсе. Сервер проверяет идентификатор callback-кнопки, права и повторяемость нажатия. Для опроса с несколькими ответами передайте pollSelectedInstanceIds с выбранными instanceId вместе с кнопкой подтверждения. Не вызывайте действие при отрисовке истории.

Для custom_action используйте зарегистрированные обработчики. Завершение clickButton подтверждает выполнение команды, но не ожидание последующего ответа агента: его покажет подписка. Для open_url предпочтительна обычная ссылка <a> с полученным адресом, чтобы сохранить управление с клавиатуры и поведение браузера. У кнопки приветствия до создания диалога отдельный способ отправки.