Диалог
Виджет / Диалог

Диалог с оператором

Privacy, реакции, inline-клавиатуры, system cards, кнопка «Закрыть тикет», лайтбокс для фото.

Как устроен диалог

Диалог — это самая «живая» часть виджета. Сверху hero-блок с приветствием («Добро пожаловать!» + время ответа), под ним — скроллируемая лента сообщений, внизу — композер.

Что выводится в ленте:

  • Bubble посетителя — справа, акцентного цвета.
  • Bubble оператора — слева, с аватаркой (своя или fallback на лого workspace) и именем.
  • System card — серая центрированная плашка для событий тикета: оператор назначен, тикет передан в отдел, отложен/возобновлён, закрыт.
  • Inline keyboard — кнопки под bubble оператора, если он их прикрепил (URL, deeplink, callback).

Privacy

SettingsWidget BuilderConversationPrivacy — три флага, которые управляют видимостью индикаторов.

conversation.privacy.typing_enabled
Тип: booleanПо умолчанию: true
Показывать визитёру индикатор «оператор печатает». Когда выключено — оператор печатает «в тишине», визитёр узнаёт о сообщении только когда оно отправилось.
conversation.privacy.read_receipts_enabled
Тип: booleanПо умолчанию: true
Галочки ✓✓ под исходящими сообщениями посетителя. Если выключено, посетитель не видит, прочитан ли его пост.
conversation.privacy.operator_seen_enabled
Тип: booleanПо умолчанию: true
Подпись «✓✓ прочитано» под последним сообщением посетителя после того, как оператор открыл тикет. Backend дедуплицирует событие — отправит один раз на каждое новое сообщение визитёра, не на каждый refresh.

SettingsWidget BuilderConversationCookie domain — поле conversation.cookie_domain. По умолчанию пустое: visitor-session cookie scoped по host, и виджет на example.com и app.example.com создаёт два разных контакта.

Задайте .example.com (с точкой!) — visitor cookie станет cross-subdomain, посетитель сохранит одну беседу при переходе между поддоменами. Точка обязательна; без неё cookie ставится только на указанный хост.

То же самое можно задать через data-cookie-domain атрибут в <script>-теге — атрибут выигрывает у конфига (удобно если стейдж и прод на разных доменах). Подробности про multi-tier storage — в справочнике для разработчиков.

Реакции

Long-press 350ms (на тачах) или hover 600ms (на мышке) по сообщению оператора → всплывает панель из 4 эмодзи. Клик ставит реакцию, счётчик появляется чипом под bubble.

conversation.reactions_enabled
Тип: booleanПо умолчанию: true
Master-выключатель. Если false, панель эмодзи не всплывает, чипы не рендерятся.
brand.emoji_pack_id
Тип: stringПо умолчанию:
Свой набор эмодзи через запятую: ❤️,🔥,👍,🎉. По умолчанию ❤️ 👍 👎 🎉. Подробнее — в разделе «Бренд».

Когда визитёр нажимает реакцию, она моментально появляется у него (optimistic update). Параллельно бэкенд бродкастит событие — message.reaction.added — операторам и другим визитёрам этого тикета (multi-tab support). При получении другие открытые табы ре-фетчат полные счётчики через GET, чтобы порядок добавления/снятия не разъезжался.

Inline keyboards

Оператор может прикрепить под своё сообщение 2D-матрицу кнопок — например, выбор языка, типы запроса, ссылки на документацию. Каждая кнопка — это:

  • url — открывает ссылку в новой вкладке (window.open(...));
  • deeplink — то же, но для нативных приложений (tg://..., mailto:...);
  • callback — отсылает событие на бэкенд: POST /api/webhooks/widget/{ws}/messages/{id}/inline-callback с {target}. Бэк создаёт служебное internal message в тикете «Нажата кнопка: target» и шлёт операторам toast с уведомлением.
conversation.inline_keyboard_enabled
Тип: booleanПо умолчанию: true
Глобально выключить рендеринг inline-keyboard'ов. Сами сообщения остаются, кнопки исчезают.

System cards

Серые центрированные плашки в ленте для событий тикета. Текст можно переопределить в SettingsWidget BuilderSystem Messages — все поля поддерживают шаблонные подстановки {operator}, {department}, {time}.

ticket_confirmation_text
Тип: stringПо умолчанию: "Тикет создан"
Появляется сразу после первого сообщения визитёра.
assigned
Тип: { enabled, text }По умолчанию: "Оператор {operator} с вами"
Когда тикет назначен оператору. Backend подставляет имя оператора в {operator}.
department_transfer
Тип: { enabled, text }По умолчанию: "Передаём в {department}"
Передача между отделами.
operator_transfer_text
Тип: stringПо умолчанию: "Передаём другому оператору"
Передача между операторами внутри одного отдела.
snoozed
Тип: { enabled, text }По умолчанию: "Откладываем до {time}"
Тикет «уснул» до указанного момента. {time} форматируется в локали посетителя как HH:MM.
resumed
Тип: { enabled, text }По умолчанию: "Возвращаемся к вашему вопросу"
Тикет вернулся в работу из snooze.
reopened
Тип: { enabled, text }По умолчанию: "Тикет переоткрыт"
Закрытый тикет открыли заново.
auto_reply_closed_text
Тип: stringПо умолчанию:
Что показать, когда тикет был закрыт оператором. Используется и для resolved-событий (визитёр сам нажал «Закрыть»).
blocked_reply
Тип: { enabled, text }По умолчанию:
Текст для контактов в чёрном списке. Если включено — посетитель видит, что не может написать; если выключено — UI композера остаётся доступным, но сообщения не отправляются.

Кнопка «Закрыть тикет»

Если хотите, чтобы посетитель сам мог отметить тикет решённым, задайте hours.close_button_text — между сообщениями и композером появится pill-кнопка с этим текстом. Клик отправляет POST /widget/{ws}/ticket/{tid}/resolve и переводит посетителя на главную.

Edge cases

  • Если localStorage визитёра пустой (Safari private mode без сессии) — кнопка покажет inline-error «Не получилось закрыть. Попробуйте ещё раз.» вместо вечного спиннера.
  • После закрытия тикета через WS прилетает ticket.closed → виджет автоматически рендерит system-card с текстом из system_messages.auto_reply_closed_text.
  • Если у вас включён conversation.rating — после закрытия визитёр получит prompt с оценкой 1-5 ★.

Прочее

Авто-скролл вниз

Когда посетитель отправляет своё сообщение → виджет всегда прокручивает к низу. Когда приходит входящее по WS → скролл едет к низу, только если визитёр уже у дна. Если он листает старые сообщения, его не дёргает; вместо этого появляется плавающая круглая кнопка ↓ с переходом к последнему сообщению.

Лайтбокс для медиа

Клик по фото или видео в треде открывает их во встроенном лайтбоксе с zoom (mouse wheel) и pan (drag). Esc или клик по фону — закрытие. Тот же UX, что в инбоксе оператора.

Была ли страница полезной?