◆ Sapport для разработчиков Справочник API Каталог ошибок OpenAPI
Разделы

#Встраивание виджета чата

Статус: Доступно (текущие параметры и блоки 1–5). Планируется — параметры виджета v2, блок 6 «Встроенный блок на странице» и блок 7 «Своя кнопка „Задать вопрос“» в их целевом виде. Статус отмечен у каждого параметра и блока.

Назначение: подключить к сайту окно чата с ИИ-продажником — одной строкой <script> либо через загрузчик модуля — и настроить внешний вид и поведение.

#Содержание

  1. Когда использовать
  2. Доступ и требования
  3. Способы подключения
  4. Параметры: текущие (Доступно)
  5. Параметры v2 (Планируется)
  6. Настройки канала в кабинете
  7. Домен сайта и заголовки кадра
  8. Как выглядит виджет
  9. Готовые блоки
  10. Ошибки и диагностика
  11. Известные ограничения
  12. Заметки
  13. Открытые вопросы

#Когда использовать

#Доступ и требования

Аутентификацияне нужна. channel_id — публичный идентификатор канала, не секрет
Платноответы ИИ списываются с кошелька арендатора (Обзор)
Персональные данныеадрес, заголовок и реферер страницы, первое касание — при согласии посетителя (Страница, источник и UTM)
Что нужно заранееактивный канал типа web_chat и его идентификатор (в кабинете, «Настройки» → канал «Веб-чат», блок «Код для встраивания»)
Домендомен сайта должен входить в разрешённые для кадра (ниже)
АдресаRU https://formula-cream.pro, EN https://wfacademy.org, ID https://wfacademy.id

Скрипт и кадр отдаёт та ячейка, где заведён канал. Идентификатор канала одной ячейки не работает на другой.

#Способы подключения

СпособЧто вставляетеКогда выбрать
Прямой тег<script src="https://<ячейка>/widget.js" data-channel="…">Вы управляете шаблоном сайта и хотите явно задать параметры
Глобальный объектwindow.SapportWidget = {…} до тега widget.jsПараметры известны в коде страницы (шаблонизатор, SPA)
Через загрузчикМодуль Bitrix/WordPress или loader.js?k=…Сайт привязан к Sapport, нужны чат, счётчик и согласие в одном подключении (Загрузчик)

Порядок источников для каждого параметра: data-атрибут тега → ключ window.SapportWidget → значение по умолчанию.

#Параметры: текущие (Доступно)

#Атрибуты тега и ключи window.SapportWidget

АтрибутКлюч объектаТипОбязательныйОграниченияПо умолчаниюПример
data-channelchannelIdстрока (UUID)даИдентификатор канала web_chat. Без него виджет пишет в консоль ошибку и не запускается—00000000-0000-4000-8000-000000000000
data-positionpositionстроканетТолько bottom-right или bottom-left. Другое значение ломает размещениеbottom-rightbottom-left
data-themethemeстроканетlight или dark. Тёмную тему окна понимает только значение dark; тема влияет и на подпись над кнопкойlightdark
data-urlurlстрока (URL)нетБазовый адрес ячейки без завершающего /. Определяет, откуда грузятся кадр и APIorigin адреса скриптаhttps://formula-cream.pro
data-bubble-textbubbleTextстроканетПодпись над кнопкой. Выводится как текст (не как HTML). Одна строка, ширина до 240 px, не переноситсяпустоНужна помощь?
data-delaydelayцелое числонетСекунды до запуска виджета. 0 — сразу010

Ключи без data-атрибута:

КлючТипЗначенияПо умолчаниюСмысл
window.SapportWidget.consentbooleanТолько false отключает расширенный контекст; любое другое значение считается «согласие есть»truefalse: кадр получает только путь страницы (без query, заголовка и реферера), первое касание не пишется. Ключ читается при каждом открытии, поэтому его можно менять после загрузки скрипта
window.SapportWidget.firstTouchbooleanfalse отключает запись и чтение первого касаниявключеноЗадаётся загрузчиком вместе с consent
window.sapportPageобъект {type, id}type: латинские буквы, _, -, до 20 знаков, без цифр; id: буквы, цифры, _, -, до 40 знаковнетТип и идентификатор сущности страницы (товар, курс, статья). Читается при первом открытии чата

window.SapportWidget должен быть задан до тега widget.js. Если вы меняете consent позже, меняйте свойство того же объекта, а не подменяйте объект целиком.

#Что передаётся кадру

При первом открытии окна виджет создаёт iframe с адресом https://<ячейка>/widget/<channel_id> и параметрами.

Параметр адресаОткудаПределБез согласия
themedata-theme—передаётся
pageадрес страницы300 знаковтолько origin и путь, без query
titledocument.title200не передаётся
pt, pidwindow.sapportPage20 / 40передаются
refdocument.referrer300не передаётся
ftпервое касание (JSON)1200не передаётся

Языка в адресе кадра widget.js не ставит: язык кадра берётся из настройки канала locale, а если её нет — из языка браузера посетителя (поддерживаются ru, en, ms, id; по умолчанию en).

#Что делает виджет

#Параметры v2 (Планируется)

Статус: Планируется. Параметры ниже не работают в текущей версии widget.js: неизвестные атрибуты игнорируются. Не используйте их в боевой разметке до публикации в журнале изменений.

АтрибутКлюч объектаТипЗначенияПо умолчаниюСмысл
data-localelocaleстрокаru, en, id (набор уточняется)из канала или браузераЯзык кадра
data-openopenстрокаauto, never или after:N (N — секунды)never (предположительно)Открывать окно автоматически
data-modemodeстрокаbubble, inline, buttonbubblebubble — плавающая кнопка; inline — окно внутри страницы; button — только окно по вызову
data-containercontainerстрока (CSS-селектор)селектор элемента—Куда вставить окно при mode=inline
data-colorcolorстрокацвет #rrggbbцвет каналаЦвет акцента, перекрывает настройку канала
data-greetinggreetingстрокатекстприветствие каналаПриветствие, перекрывает настройку канала
data-launcherlauncherстрокаdefault, nonedefaultnone — не рисовать стандартную кнопку: вызов чата делает ваш код
data-z-indexzIndexцелоечисло2147483647Порядок наложения

Значения по умолчанию, помеченные «предположительно», проект не фиксирует; окончательные значения будут в справочнике при выпуске.

#Настройки канала в кабинете

Часть внешнего вида меняется без правки кода страницы: настройки хранятся в канале и подгружаются запросом init.

Настройка в кабинетеКлюч каналаКак влияетГде применяется
Приветственное сообщениеgreetingПервое сообщение в окне. Если не задано, подставляется приветствие на языке каналав окне, при каждой загрузке
Цвет виджетаcolorЦвет кнопки и шапки окна (#6366f1 по умолчанию)кнопка и окно
URL аватараavatar_urlАватар в шапке окнаокно
Позицияpositionbottom-right или bottom-leftтолько через код для встраивания
Темаthemelight или darkтолько через код для встраивания
Текст пузырькаbubble_textПодпись над кнопкойтолько через код для встраивания
Задержка показаdelayСекунды до появления кнопкитолько через код для встраивания
Текст согласия с офертойconsent_textДо 600 знаков. Задан — посетитель обязан отметить согласиеокно
Ссылка на офертуconsent_urlhttp(s)-адрес, до 500 знаковокно

Позиция, тема, текст пузырька и задержка попадают в виджет только как атрибуты скопированного из кабинета кода. Если подключить виджет через загрузчик (Bitrix/WordPress), эти четыре значения не применяются: загрузчик передаёт только идентификатор канала, адрес и признаки согласия.

Ключи канала, которые читает сервер, но для которых в кабинете нет полей: locale (язык кадра), pre_chat_form (форма перед чатом), ai_daily_limit (суточный предел ответов ИИ). Они задаются записью канала; интерфейса для них сегодня нет.

Код для встраивания в кабинете собирается подстановкой строк: кавычки в тексте пузырька не экранируются. Не используйте символ " в тексте пузырька.

#Домен сайта и заголовки кадра

Окно чата — это страница на домене ячейки, встроенная в ваш сайт. Браузер покажет её, только если ваш сайт разрешён заголовком Content-Security-Policy: frame-ancestors.

Разрешены:

Условия: канал активен; арендатор активен и ему доступен модуль «Продвижение». Ответ кэшируется на 60 секунд. Если база недоступна, заголовок строится только по 'self'.

СимптомПричинаЧто сделать
Кнопка есть, при нажатии окно пустое или с ошибкой браузера «refused to connect»Домена сайта нет в разрешённыхДобавить домен арендатору или привязать сайт; подождать до минуты
Кнопки нет вовсеНе задан data-channel, скрипт не загрузился или не истекла задержка data-delay. Если init вернул ошибку (в том числе 404), кнопка всё равно рисуется с настройками по умолчаниюСм. диагностику

Запрос init не проверяет домен: кнопка может показаться даже там, где окно будет заблокировано.

#Как выглядит виджет

Макеты схематичны; точные отступы и цвета определяет тема.

#Кнопка

 Закрыта:                         Есть непрочитанные:             Открыта:

        Нужна помощь?                                                 ┌────┐
       ┌─────────────┐                                                │ ✕  │
       └─────────▽───┘                          ┌─┐                   └────┘
            ╭────────╮                        ╭─┤3├────╮
            │  ◯◯    │  60×60 px              │ └─┘ ◯◯  │            крестик вместо значка
            ╰────────╯                        ╰────────╯
   подпись над кнопкой —              красный счётчик в углу,
   data-bubble-text                   «9+» при больше девяти

#Окно на десктопе, 380×560

                                   ┌────────────────────────────────┐
                                   │ ◯  Название канала          ✕  │  шапка: аватар,
                                   │    ● отвечаем мгновенно        │  название, закрыть
                                   ├────────────────────────────────┤
                                   │ ┌───────────────────────┐      │
                                   │ │ Здравствуйте! Чем     │      │  приветствие
                                   │ │ можем помочь?         │      │  (из настроек канала)
                                   │ └───────────────────────┘      │
                                   │                  ┌───────────┐ │
                                   │                  │ Сколько   │ │  реплика посетителя
                                   │                  │ стоит?    │ │
                                   │                  └───────────┘ │
                                   │ ◌ ● ● ●                        │  индикатор набора
                                   ├────────────────────────────────┤
                                   │ [ Напишите сообщение…   ] [+] > │  ввод, вложение
                                   ├────────────────────────────────┤
                                   │        Powered by Formula AI   │  подпись в кадре
                                   └────────────────────────────────┘
                                        ╭────────╮
                                        │   ✕    │  кнопка 60×60 в углу, отступ 20 px
                                        ╰────────╯

#Окно на телефоне, ширина ≤ 440 px

 ┌─────────────────────────────┐
 │ ◯ Название канала        ✕  │   ширина: 100vw − 24 px
 │   ● отвечаем мгновенно      │   высота: 100dvh − 100 px
 ├─────────────────────────────┤   отступ от нижнего края 84 px,
 │ ┌─────────────────┐         │   по бокам 12 px
 │ │ Здравствуйте!   │         │
 │ └─────────────────┘         │
 │              ┌────────────┐ │
 │              │ Привет     │ │
 │              └────────────┘ │
 ├─────────────────────────────┤
 │ [ Напишите сообщение… ] [+]> │
 ├─────────────────────────────┤
 │    Powered by Formula AI    │
 └─────────────────────────────┘
          ╭────────╮
          │   ✕    │
          ╰────────╯

#Форма перед чатом

Показывается, если у канала включена pre_chat_form и у посетителя ещё нет сессии. Поля: name, email, phone; обязательные задаёт required.

 ┌────────────────────────────────┐
 │ ◯  Название канала          ✕  │
 ├────────────────────────────────┤
 │             (◯◯)               │
 │        Начните разговор        │
 │ Заполните данные ниже, чтобы   │
 │ начать.                        │
 │                                │
 │ Имя *                          │
 │ [____________________________] │
 │ Email *                        │
 │ [____________________________] │
 │ Телефон                        │
 │ [____________________________] │
 │                                │
 │ [        Начать чат          ] │
 └────────────────────────────────┘

Сервер использует из формы только имя (sender_name). Email и телефон отправляются, но не читаются — известное ограничение.

#Плашка согласия

Показывается над полем ввода, если арендатор задал consent_text. Пока флажок не отмечен, сообщение не отправляется.

 ├────────────────────────────────┤
 │ ☐ Я согласен с условиями       │
 │   оферты. Открыть оферту       │   ссылка из consent_url
 │   Отметьте согласие, чтобы     │   (если задана)
 │   написать.                    │
 ├────────────────────────────────┤
 │ [ Напишите сообщение…   ] [+] > │

#Индикатор набора

 │ ◌ ● ● ●                        │   пока ИИ готовит ответ (пузырь с тремя точками)
 │ ◯ ● ● ●  Анна печатает…        │   оператор печатает: аватар и имя

#Оператор с аватаром

После подключения оператора в шапке показывается его имя, а под шапкой — полоса «Вы на связи с …».

 ┌────────────────────────────────┐
 │ ◯  Анна                     ✕  │   вместо названия канала — имя оператора
 │    ● в сети                    │
 ├────────────────────────────────┤
 │ (◯) Вы на связи с Анна         │   полоса с аватаром 24 px
 ├────────────────────────────────┤
 │  Анна                          │   подпись над репликой оператора
 │ (◯) ┌──────────────────────┐   │   аватар 26 px рядом с пузырём
 │     │ Конечно, расскажу.   │   │
 │     └──────────────────────┘   │

#Готовые блоки

Во всех блоках замените 00000000-0000-4000-8000-000000000000 на идентификатор своего канала, а formula-cream.pro — на домен своей ячейки (wfacademy.org для EN, wfacademy.id для ID). Файлы для копирования лежат в examples/.

#Блок 1. Плавающая кнопка

Статус: Доступно. Файл: examples/floating-button.html.

Стандартное подключение: круглая кнопка в правом нижнем углу.

<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  async></script>

Макет — кнопка и окно.

Если тег загружается синхронно (без async), виджет стартует после DOMContentLoaded; с async — сразу после загрузки скрипта.

#Блок 2. Кнопка слева с подписью

Статус: Доступно.

<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  data-position="bottom-left"
  data-theme="dark"
  data-bubble-text="Нужна помощь?"
  async></script>
 ┌───────────────────────────────────────────┐
 │  страница                                 │
 │                                           │
 │                                           │
 │  Нужна помощь?                            │
 │ ┌──────────────┐                          │
 │ └──▽───────────┘                          │
 │ ╭────────╮                                │
 │ │  ◯◯    │                                │
 │ ╰────────╯                                │
 └───────────────────────────────────────────┘

Эквивалент через глобальный объект:

<script>
  window.SapportWidget = {
    channelId: '00000000-0000-4000-8000-000000000000',
    position: 'bottom-left',
    theme: 'dark',
    bubbleText: 'Нужна помощь?'
  };
</script>
<script src="https://formula-cream.pro/widget.js" async></script>

#Блок 3. Отложенный запуск

Статус: Доступно.

Кнопка появляется через заданное число секунд. До этого скрипт ничего не рисует и не обращается к платформе.

<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  data-bubble-text="Есть вопросы по курсу?"
  data-delay="15"
  async></script>

Через 15 секунд после загрузки скрипта виджет запрашивает настройки канала и рисует кнопку. Окно не открывается само: автоматическое открытие появится в v2 (data-open="after:N", Планируется).

#Блок 4. Контекст страницы товара или курса

Статус: Доступно. Файл: examples/product-page-context.html.

Виджет сам передаёт адрес и заголовок страницы. Тип и идентификатор сущности (курс, товар, статья) задайте объектом window.sapportPage до первого открытия чата. Чтобы значение точно было готово, ставьте его до тега виджета.

<script>
  window.sapportPage = { type: 'course', id: 'hydrolat-basics' };
</script>
<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  async></script>

Что получает модель (в промпте, как данные браузера, не как инструкции):

Текущая страница посетителя: https://shop.example.com/courses/hydrolat-basics · "[course #hydrolat-basics] Основы гидролатов"
ПолеПравило
typeЛатинские буквы, _, -, до 20 знаков. Значение с цифрами или длиннее 20 знаков не будет передано
idСтрока или число; буквы, цифры, _, -, до 40 знаков
Заголовокdocument.title, до 150 знаков вместе с префиксом типа

Контекст читается один раз при первом открытии окна. Переход на другую страницу без перезагрузки (SPA) контекст не обновляет — для этого предназначен Sapport.setPage() из JS API (Планируется). Подробности — Страница, источник и UTM.

Модули Bitrix и WordPress выводят window.sapportPage сами.

Статус: Доступно. Файл: examples/consent-banner.html.

Подходит сайту, привязанному к Sapport: загрузчик подключает чат, счётчик и сбор поведения и сам ждёт согласия посетителя. Канал чата задаётся настройками сайта (chat, chat_channel_id), поэтому в теге нет data-channel.

<!-- 1. Заглушка очереди согласия: ДО загрузчика -->
<script>
  window.sapport = window.sapport || {
    q: [],
    consent: function (v) { this.q.push(['consent', !!v]); }
  };
</script>

<!-- 2. Загрузчик ячейки. k — публичный ключ сайта (не секрет) -->
<script async src="https://formula-cream.pro/api/v1/connector/loader.js?k=0123456789abcdef0123456789abcdef"></script>

<!-- 3. Ваш баннер cookie вызывает consent -->
<script>
  document.getElementById('cookie-accept').addEventListener('click', function () {
    window.sapport.consent(true);
  });
  document.getElementById('cookie-decline').addEventListener('click', function () {
    window.sapport.consent(false);
  });
</script>
 ┌─────────────────────────────────────────────────────┐
 │ Мы используем cookie, чтобы понимать, откуда        │
 │ приходят посетители, и подсказывать в чате.         │
 │                                                     │
 │            [ Принять ]    [ Отклонить ]             │
 └─────────────────────────────────────────────────────┘
Режим сайтаЧто делает чат до решения посетителяПосле consent(true)
waitКнопка и чат работают, но SapportWidget.consent=false: кадру уходит только путь страницы, первое касание не пишетсяРасширенный контекст и первое касание включаются
immediateСогласие считается данным сразу—

Событием: window.dispatchEvent(new CustomEvent('sapport:consent', { detail: true })); допустима и форма { granted: true }. consent(false) возвращает режим минимального контекста.

Согласие в чате — отдельное: это не cookie-баннер, а согласие с офертой арендатора (плашка).

Ручная установка без загрузчика, но с тем же поведением:

<script>
  window.SapportWidget = {
    channelId: '00000000-0000-4000-8000-000000000000',
    consent: false,
    firstTouch: false
  };
  // после согласия посетителя — на том же объекте:
  function onCookieAccepted() {
    window.SapportWidget.consent = true;
    window.SapportWidget.firstTouch = true;
  }
</script>
<script src="https://formula-cream.pro/widget.js" async></script>

Модуль для Bitrix/WordPress ставит этот загрузчик сам; вручную тег добавлять не нужно.

#Блок 6. Встроенный блок на странице

Статус: Планируется (data-mode="inline", data-container). Временного поддерживаемого способа нет; ниже — обходной путь, который работает по коду, но не является контрактом.

Целевая разметка v2 (не работает сегодня):

<div id="sapport-chat" style="height:560px"></div>
<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  data-mode="inline"
  data-container="#sapport-chat"
  async></script>
 ┌───────────────────────────────────────────────────────────┐
 │ Вопросы по курсу?                                         │
 │ ┌───────────────────────────────────────────────────────┐ │
 │ │ ◯ Название канала                                  ✕  │ │
 │ │ ┌───────────────────────┐                             │ │
 │ │ │ Здравствуйте!         │   окно чата внутри          │ │
 │ │ └───────────────────────┘   текста страницы           │ │
 │ │ [ Напишите сообщение…                       ] [+] >   │ │
 │ └───────────────────────────────────────────────────────┘ │
 └───────────────────────────────────────────────────────────┘

Обходной путь сегодня. Страница чата открывается как обычный iframe:

<iframe
  title="Чат"
  src="https://formula-cream.pro/widget/00000000-0000-4000-8000-000000000000?theme=light"
  style="width:100%;max-width:380px;height:560px;border:0"
  allow="clipboard-write"></iframe>

Ограничения обходного пути:

#Блок 7. Своя кнопка «Задать вопрос»

Статус: Планируется (data-launcher="none" и Sapport.open()). Поддерживаемого способа открыть окно из своего кода сегодня нет.

Целевая разметка v2 (не работает сегодня):

<button id="ask">Задать вопрос</button>
<script
  src="https://formula-cream.pro/widget.js"
  data-channel="00000000-0000-4000-8000-000000000000"
  data-launcher="none"
  async></script>
<script>
  document.getElementById('ask').addEventListener('click', function () {
    window.Sapport.open();
  });
</script>
 ┌───────────────────────────────────────────────┐
 │ Курс «Основы гидролатов»                      │
 │ [ Записаться ]   [ Задать вопрос ]            │   ваша кнопка
 │                        │                      │
 │                        ▼                      │
 │              ┌────────────────────┐           │
 │              │ окно чата 380×560  │           │
 │              └────────────────────┘           │
 └───────────────────────────────────────────────┘

Что можно сегодня.

  1. Использовать стандартную плавающую кнопку (блоки 1–3) и подписать её data-bubble-text="Задать вопрос".
  2. Для ссылки «Задать вопрос» открыть страницу чата в своём окне или во всплывающем iframe (обходной путь блока 6).
  3. Нажимать стандартную кнопку программно (document.querySelector('.sapport-bubble').click()) — не рекомендуется: имена внутренних классов sapport-* не являются контрактом и могут измениться без предупреждения.

#Ошибки и диагностика

СимптомВероятная причинаЧто проверить
В консоли [Sapport] Missing channel ID…Не задан data-channel и SapportWidget.channelIdАтрибут тега; window.SapportWidget до тега
Кнопка не появляетсяСкрипт не загрузился (CSP вашего сайта запрещает script-src ячейки), либо задержка data-delayВкладка «Сеть»; CSP сайта
Кнопка есть, окно пустоеДомен сайта не разрешён для кадра; CSP вашего сайта запрещает frame-src ячейкиДомен
Кнопка видна с цветом и приветствием по умолчаниюЗапрос init вернул ошибку: канал выключен, арендатор отключён или сеть недоступнаСтатус канала в кабинете; вкладка «Сеть»
Сообщение не уходит, ответ 503 widget_not_configuredНа сервере не настроена подпись сессийОбратитесь в поддержку ячейки
Сообщение не уходит, 400 consent_requiredНе отмечено согласие с офертойПлашка согласия
429 Too many requestsПревышен предел частотыПределы
На кнопке не появляется счётчикpostMessage из кадра не дошёл: не определился origin страницыПолитика реферера вашего сайта (Заметки)

В «Сети» браузера ищите запросы widget.js, /api/widget/init и после открытия — /widget/<channel_id>.

#Известные ограничения

Эти пункты отражают расхождения между ожиданием и поведением; формулировки нейтральны, источник — код на 11.10.2026.

№ОграничениеЧто делать
1Форма перед чатом: поля email и телефон отправляются, но сервер их не читает; в карточку контакта попадает только имяЕсли нужны контакты, используйте текстовый вопрос ИИ-продажника или identify в v2 (Планируется)
3При подключении через загрузчик чат игнорирует position, theme, bubble_text, delay из настроек каналаДля нестандартной позиции используйте прямой тег
4Поля pre_chat_form, locale, ai_daily_limit не имеют интерфейса в кабинете; язык кадра нельзя задать в коде вставкиПравка записи канала через поддержку; data-locale — в v2
5init не проверяет домен: кнопка может быть видна там, где окно заблокированоПроверьте окно после установки
6Правила для типа и идентификатора страницы расходятся между модулями и виджетом. Модули Bitrix и WordPress принимают type до 32 знаков, в том числе с цифрами, а id до 64 знаков; виджет принимает type до 20 знаков без цифр и id до 40 знаковЗадавайте type из латинских букв и _, -, до 20 знаков, а id не длиннее 40 знаков: тогда значение примут и модуль, и виджет. Иначе виджет молча отбросит значение
7Кнопка закрытия внутри кадра отправляет sapport:close с получателем *; остальные сообщения кадра идут на точный origin родителяНе доверяйте содержимому сообщения: оно не несёт данных
12Сессия посетителя хранится в sessionStorage кадра: новая вкладка начинает новый диалогПланируется: идентификация посетителя через identify
22Код вставки в кабинете собирается подстановкой строк: текст пузырька (bubble_text) не экранируетсяНе используйте символ " в тексте пузырька; проверьте код вставки перед публикацией

Нумерация соответствует перечню расхождений проекта.

#Заметки

#Открытые вопросы