Документация Webchatix

Telegram-first live chat: посетитель пишет в виджет на сайте, команда отвечает из Telegram и веб-панели. Слева — разделы, справа — подробности.

За 5 минут

  1. Откройте бота → /start — создаётся аккаунт на тарифе Free и первый сайт.
  2. Скопируйте HTML-сниппет и вставьте на сайт перед </body>.
  3. /panel — одноразовая ссылка в веб-кабинет (или меню «Веб-панель»).
  4. Пригласите оператора: /invite или меню → «Команда» → ➕.
  5. Подключите Telegram-группу: добавьте бота в группу (или напишите в ней /addgroup) и назначьте её на сайт в «Маршрутах».
  6. Запасной вариант — весь сайт в одну группу: /bindsite site_key в группе.

Тарифы и оплата

Регистрация открытая: /start в боте создаёт аккаунт на тарифе Free. Платные тарифы оплачиваются картой в кабинете, раздел Счета — оплата идёт через Stripe.

ТарифСайтыКлиенты / мес.ОператорыЗа месяц
free1301$0
basic2010005$10 ($8 при оплате за год)
unlimited∞∞∞$20 ($16 при оплате за год)

Цены указаны за месяц. Оплата за год — на 20% дешевле и списывается одним платежом ($96 и $192 в год); в кабинете годовая выбрана по умолчанию.

Premium (с Basic): шаблоны, active invite, visibility rules, заметки, рейтинги.

Клиент — уникальный посетитель, начавший диалог в текущем календарном месяце; счётчик обнуляется 1-го числа.

Как устроена оплата

  • Кабинет → Счета: текущий тариф, расход лимитов, смена тарифа, список оплат со ссылками на PDF.
  • Данные карты на наши серверы не попадают — страница оплаты и портал управления принадлежат Stripe.
  • Смена тарифа в середине периода пересчитывается Stripe пропорционально; отмена оставляет платный тариф до конца оплаченного периода, потом аккаунт возвращается на Free.
  • На почту из этого же раздела приходят чек, сообщение о неудачном списании и напоминание о продлении за несколько дней.

Меню бота

Главное меню после /start / /menu. Кнопки обычно по две в ряд.

ПунктЧто делает
🌐 СайтыСписок сайтов аккаунта: настройки, Online/Offline, сниппет, удаление.
👥 КомандаОператоры / участники аккаунта.
➕ ПригласитьКод и deep-link для нового оператора.
💬 ГруппыTelegram-группы, принимающие обращения: подключить, назначить на сайт, отключить.
🔗 Веб-панельMagic-link входа (одноразовый, ~10 мин).
🗺 МаршрутыКто принимает диалоги с какого сайта/страницы.
🔑 Ключ APIКлюч API статистики аккаунта, сводка за сегодня по всем сайтам, замена ключа (owner/admin).
⚙️ ПанельБыстрый доступ: ops / sites / routes.
📝 ШаблоныБыстрые ответы (Basic+).
💳 Тарифы и оплатаЦены, оплата картой, счета (owner).
👑 ВладелецПередать ownership другому участнику.
🗑 Удалить аккаунтКаскадное удаление после подтверждения именем.

Карточка сайта

  • Online / Offline — пауза виджета (чат офлайн).
  • Настройки — поля брендинга, invite, GDPR и т.д. (по 2 кнопки в ряд).
  • Оператор — назначить маршрутизацию на человека/группу.
  • Удалить — с подтверждением названием сайта.

Команды бота

КомандаКтоСмысл
/start [CODE]всеОнбординг / redeem инвайта.
/menumemberГлавное меню аккаунта.
/helpвсеСправка по командам (по вашей роли).
/panelmemberMagic-link веб-панели.
/newsite [имя | origin]admin+Создать сайт (+ CORS origins).
/addgroupadmin+ в группеПодключить группу как оператора-группу (chat_id не нужен).
/bindsite KEYadmin+ в группеПривязать группу как fallback-чат.
/inviteadmin+Инвайт оператора.
/op_me CODEлюбойПринять инвайт.
/tplmemberСписок / add / del / отправка reply+/tpl id.
/notememberЗаметка к диалогу (Basic+).
/releasememberОсвободить диалог (+ запрос рейтинга).
/langвсеЯзык интерфейса бота: en / pl / de / ru / uk / be / ar.
/setrole id roleownerowner|admin|operator.
/crm on|offownerВкл/выкл CRM-мост аккаунта.
/deleteaccountownerУдалить аккаунт.
/idв чатеПоказать chat_id.

Веб-панель

Вход тенанта: ссылка из /panel или токен на /account/login/.

РазделЗачем
ОбзорСчётчики и последние диалоги; название компании; CRM-мост для owner — переключатель и ссылка вебхука (пусто — общая из config).
СайтыСоздание, сниппет, полные настройки виджета.
ОператорыУчастники, инвайты, роли, группы.
МаршрутыAssignments: сайт → оператор/группа.
ДиалогиИстория, release, заметки, рейтинг.
СтатистикаПосещения, боты, формы и чат по всем сайтам или по одному; страницы; код «только статистика»; ключ API аккаунта.
ШаблоныCRUD шаблонов + сводка рейтингов (Basic+).

Настройки сайта

Доступны в боте («Настройки») и в веб Сайты → шестерёнка.

ПолеЗначение
Название / заголовок / подзаголовокШапка чата.
Приветствие / логоПервое сообщение и бренд.
Онлайн с–до, TZ, паузаСтатус Online/Offline.
Эскалация (мин)Алерт, если нет ответа.
Цвет / позиция / отступыКнопка виджета.
Язык / звукen|pl|de|ru|uk|be|ar и URL mp3.
Allowed originsCORS: домены через запятую или *.
Invite *Bubble-приглашение (Basic+).
Visibility JSONГде показывать кнопку/invite (Basic+).
GDPRЧекбокс согласия до первого send.
ИИ-ответчикОтвечает клиенту, если никто не ответил N минут (по умолчанию 3).

ИИ-ответчик (Gemini)

Посетитель написал, оператор молчит — через заданное число минут в диалог отвечает Google Gemini. Ответ приходит клиенту в виджет, а операторам в Telegram прилетает карточка «Ответил ИИ» с тем же текстом, чтобы никто не повторял сказанное.

  • Включается на каждом сайте отдельно: Сайты → шестерёнка → ИИ-ответчик. Там же задержка и поле «Что ИИ должен знать о компании» — часы работы, доставка, чего обещать нельзя.
  • Ответ человека обнуляет отсчёт; диалог, который оператор взял себе (claim), ИИ не трогает.
  • Эскалацию ответ робота не отменяет: админ всё равно получит алерт, что живой человек не ответил.
  • Модель отвечает коротко, не выдумывает цены и сроки, а на прямой вопрос признаётся, что она автоматический ассистент.
  • Ключ API ставится один раз на всю установку: gemini_api_key в config/config.php (ключ берут в Google AI Studio, у него есть бесплатный лимит). Без ключа галочка ничего не делает.

Пример visibility

{"include":["/pricing","/contacts"],"exclude":["/admin"],"desktop":true,"mobile":true}

Виджет на сайте

<script async src="https://webchatix.online/widget/webchatix.js"
  data-site-key="SITE_KEY"></script>

Управление со страницы:

webchatix("show");   // показать кнопку
webchatix("hide");   // спрятать
webchatix("open");   // открыть чат
webchatix("close");  // закрыть панель
webchatix("form", "report"); // засчитать отправку формы (статистика)

Язык виджета берётся из data-lang, затем из <html lang> страницы, затем из браузера; поддерживаются en / pl / de / ru / uk / be / ar, запасной — английский. После смены настроек обновите страницу клиента (версия виджета в query ?v=).

Если на сайте настроена Content-Security-Policy, разрешите домен виджета в трёх директивах: script-src, style-src и connect-src. Оформление виджет подключает отдельным файлом webchatix.css, так что держать ради него 'unsafe-inline' в style-src не нужно.

Статистика посещений и API

Виджет считает посещения сайта, на котором он стоит. Статистика хранится без срока — дневными счётчиками (сутки по UTC); отчёт можно взять за любой период. Данные отдаются через API по секретному ключу аккаунта — один ключ открывает все сайты аккаунта.

ПолеЧто считается
unique_visitorsУникальные посетители — по cookie виджета (без cookie — по IP + браузеру за сутки). За период — без повторов: один человек за неделю считается один раз.
visitsВходы — первая страница после 30 минут тишины, а также первая страница посетителя за сутки.
page_viewsПросмотры страниц людьми, включая переходы в SPA (history.pushState).
bot_hitsОбходы страниц ботами: поисковики (Googlebot, Bingbot, YandexBot…), ИИ-краулеры (GPTBot, ClaudeBot, PerplexityBot…), соцсети, SEO-сервисы, headless-браузеры. В просмотры и уникальные они не попадают.
form_submitsОтправки форм на страницах сайта (событие submit, в том числе формы, которые сайт отправляет через fetch). Значения полей не передаются — только имя формы: #id, name или путь action. Отправки ботами не считаются.
chat_messagesСообщения посетителей в чат Webchatix (текст и фото).
chat_visitorsСколько посетителей написали в чат — по диалогам, за период без повторов.
ads_googleПереходы из рекламы Google Ads: в адресе страницы входа есть gclid, gbraid, wbraid или gad_source, либо utm_source=google с платным utm_medium (cpc, ppc, paid…). Считается один раз на вход: обновление страницы клик не удваивает.
ads_yandexПереходы из Яндекс Директа: в адресе есть yclid, либо utm_source=yandex с платным utm_medium. Тоже один раз на вход.

Обычный сниппет чата уже считает статистику — ничего добавлять не нужно.

Установка только для статистики (без интерфейса)

Атрибут data-mode="stats" ставит виджет без кнопки, окна чата и стилей: скрипт только отправляет один лёгкий хит на страницу. Пиксель в <noscript> необязателен — он ловит ботов, которые не исполняют JavaScript, но загружают картинки.

<script async src="https://webchatix.online/widget/webchatix.js"
  data-site-key="SITE_KEY" data-mode="stats"></script>
<noscript><img src="https://webchatix.online/wx-api.php?action=track&site_key=SITE_KEY"
  width="1" height="1" alt="" style="position:absolute"></noscript>

SITE_KEY — публичный ключ сайта, тот же, что в сниппете чата (бот: «📋 Код установки», кабинет: «Сайты»). Это не ключ API wxs_…: тот секретный и в код страниц не ставится.

Если у сайта задан Allowed origins, хиты со страниц других доменов не считаются.

Формы без тега <form>

Отправку обычной <form> виджет ловит сам — по событию submit, в том числе когда сайт отправляет её через fetch. Но часто форма — это поля и кнопка <button type="button">, а данные отправляет JavaScript сайта; события submit тогда нет, и отправка не считается. Для таких форм есть два способа.

1. Атрибут data-wx-form на кнопке отправки: клик по ней считается отправкой формы с этим именем. Неактивная кнопка (disabled) не считается, двойной клик даёт одну отправку.

<button type="button" class="get_report" data-wx-form="report">…</button>

2. Вызов из кода сайта — когда отправку нужно считать, например, только после успешной проверки полей. Работает и с обычным виджетом, и с data-mode="stats". Если ваш код может выполниться раньше, чем загрузится виджет, поставьте выше заглушку — вызовы встанут в очередь и не потеряются.

// после успешной проверки полей
webchatix("form", "report");

// заглушка — выше вызовов, если код может сработать раньше виджета
window.webchatix = window.webchatix || function () {
  (webchatix.q = webchatix.q || []).push(arguments);
};

Атрибут data-wx-form на <form> или на её кнопке submit задаёт имя формы в отчёте вместо #id / name / action.

Ключ API

Ключ вида wxs_… один на весь аккаунт. Где взять и заменить: в Telegram-боте — кнопка 🔑 Ключ API в главном меню (там же сводка по всем сайтам), в кабинете — Сайты → шестерёнка. Кнопка «Заменить ключ» выдаёт новый, старый перестаёт работать сразу. Видят и меняют ключ owner и admin аккаунта.

Ключ секретный: публичный site_key для чтения не подходит, а сам ключ не вставляйте в код страниц — запрашивайте статистику со своего сервера. Статистика одного сайта есть и в боте: 🌐 Сайты → сайт → 📊 Статистика.

Ключ передаётся одним из способов: заголовок X-Stats-Key: wxs_…, заголовок Authorization: Bearer wxs_… или параметр ?key=wxs_….

Два ключа

КлючГде используетсяПубличный?
SITE_KEY — ключ сайтасниппет чата, data-mode="stats", пиксель wx-api.php?action=track — всё, что стоит в коде страниц и только записывает хитыда
wxs_… — ключ API аккаунтаstats-api.php: чтение статистики (action=stats) и серверные хиты (action=hit) — только с вашего сервера. Один на все сайты аккаунта.нет, секретный

Ключ API в пикселе или в коде страницы увидит любой посетитель через «Просмотр кода» — и сможет читать и накручивать статистику. Если ключ всё же попал наружу, замените его.

GET /stats-api.php?action=stats

Параметры: site_key — только этот сайт аккаунта (без него — все сайты); период — days (последние N дней по сегодняшний, 1–366, по умолчанию 7) или from и to (даты ГГГГ-ММ-ДД включительно, не длиннее 366 дней; если задана одна дата, вторая отсчитывается на days); limit — сколько страниц в топе каждого сайта (1–1000, по умолчанию 50).

curl -H "X-Stats-Key: wxs_…" "https://webchatix.online/stats-api.php?action=stats&days=7&limit=20"
curl -H "X-Stats-Key: wxs_…" "https://webchatix.online/stats-api.php?action=stats&site_key=SITE_KEY"
curl -H "X-Stats-Key: wxs_…" "https://webchatix.online/stats-api.php?action=stats&from=2026-01-01&to=2026-03-31"
{
  "ok": true,
  "account": {"id": 42, "name": "My company"},
  "timezone": "UTC",
  "from": "2026-10-12",
  "to": "2026-10-18",
  "totals": {"unique_visitors": 412, "visits": 530, "page_views": 1874, "bot_hits": 961,
             "form_submits": 23, "chat_messages": 57, "chat_visitors": 14,
             "ads_google": 48, "ads_yandex": 31},
  "days": [
    {"date": "2026-10-18", "unique_visitors": 61, "visits": 74, "page_views": 255, "bot_hits": 140,
     "form_submits": 4, "chat_messages": 9, "chat_visitors": 3,
     "ads_google": 6, "ads_yandex": 4}
  ],
  "sites": [
    {
      "site_key": "SITE_KEY",
      "name": "My site",
      "totals": {"unique_visitors": 300, "visits": 391, "page_views": 1402, "bot_hits": 700,
                 "form_submits": 15, "chat_messages": 40, "chat_visitors": 9,
                 "ads_google": 35, "ads_yandex": 20},
      "days": [ … ],
      "pages": [{"path": "/pricing/", "page_views": 310, "bot_hits": 88, "form_submits": 6}],
      "bots": [{"bot": "Googlebot", "hits": 402}, {"bot": "GPTBot", "hits": 97}],
      "forms": [{"form": "#contact", "submits": 15}]
    }
  ]
}

totals и days — сумма по сайтам ответа; посетители считаются по каждому сайту отдельно. В sites — отчёт каждого сайта: days — по дню на каждую дату периода (дни без посещений идут с нулями), pages — топ страниц (путь без query-строки) по сумме просмотров и обходов, bots — обходы по именам ботов, forms — отправки по именам форм.

POST /stats-api.php?action=hit — серверные хиты

Большинство поисковых ботов не исполняет JavaScript, и виджет их не видит. Чтобы считать и их, бэкенд сайта может сам сообщать о принятых запросах: поля site_key (какой сайт аккаунта; обязателен), url (или путь), ua — User-Agent, необязательные ip, referrer, visitor_id. Пачкой — {"site_key": "…", "hits": [ … ]}, до 500 хитов за запрос; site_key у отдельного хита перекрывает общий. Бот или человек определяется по ua.

curl -X POST "https://webchatix.online/stats-api.php?action=hit" \
  -H "X-Stats-Key: wxs_…" -H "Content-Type: application/json" \
  -d '{"site_key": "SITE_KEY", "url": "https://example.com/pricing/", "ua": "Mozilla/5.0 (compatible; bingbot/2.0)", "ip": "203.0.113.7"}'
# → {"ok": true, "views": 0, "bots": 1, "skipped": 0}

Ошибки

HTTPerrorПричина
401key_requiredКлюч не передан.
403invalid_keyКлюч неверный или заменён.
403plan_requiredКлюч API работает на тарифах Basic и Unlimited.
403disabledАккаунт приостановлен.
400too_many_hitsБольше 500 хитов в одном запросе.
400unknown_sitesite_key не указан или это сайт другого аккаунта.
400bad_periodПериод не подошёл: дата не в формате ГГГГ-ММ-ДД, from позже to или длиннее 366 дней.

Хранятся только счётчики и обезличенные хэши посетителей — без IP, адресов и User-Agent в открытом виде.

Операторы и роли

  • owner — полный контроль, тарифные запросы, удаление аккаунта, CRM, передача ownership.
  • admin — сайты, инвайты, маршруты, настройки.
  • operator — ответы в диалогах, заметки/шаблоны по плану.

Один Telegram-пользователь = один owned-аккаунт. В чужих аккаунтах можно быть оператором по инвайту.

Группы

Кроме людей оператором может быть Telegram-группа: обращения падают карточкой в чат, отвечает любой участник — Reply на карточку. Подключение: добавьте бота в группу (кнопка «Группы» → «Подключить группу») или напишите в группе /addgroup; chat_id вводить не нужно, бот берёт его сам. Группы не занимают лимит операторов по тарифу.

Диалоги

  • Сообщение клиента уходит в Telegram (группа/оператор по маршруту).
  • Принять — claim; system message в истории.
  • Передать — только active member того же аккаунта.
  • Освободить / release — можно запросить рейтинг у посетителя.
  • Заметки — видны команде, не клиенту (Basic+).
  • Шаблоны — Reply на диалог + /tpl id или кнопка шаблона → Reply.

Безопасность и GDPR

  • Аккаунты изолированы по account_id.
  • Magic-link одноразовый; лимит выдачи ссылок.
  • Suspend гасит виджет, бот и кабинет тенанта.
  • CORS: задайте allowed_origins (не оставляйте * на проде без нужды).
  • GDPR-чекбокс — до первого сообщения клиента.
  • Квота upload по тарифу (max_upload_mb).
  • Не больше 10 новых сайтов в час на аккаунт.