# Чат и заказы через Telegram

Реализация адаптирована из собственного проекта DOGU: окно на сайте, секретный cookie посетителя, отдельная тема группы на диалог и ответы сотрудников из Telegram. Реквизиты DOGU не копировались. Используется официальный [Telegram Bot API](https://core.telegram.org/bots/api), а не пользовательский Telegram-аккаунт.

## Подключение владельцем

1. Откройте **Админка → Чат и Telegram**. Введите существующий токен BotFather и числовой ID группы. После сохранения токен больше не показывается. В чате с разработчиком токен не нужен.
2. Один бот обслуживает один сайт: два независимых getUpdates-получателя будут забирать сообщения друг у друга. Группу можно использовать общую. Подключение не перезаписывает чужой webhook: при обнаружении другого URL появится ошибка.
3. Добавьте бота в группу. Для отдельных тем включите темы супергруппы и дайте боту право управления темами. Если группа обычная, снимите флажок отдельных тем: сообщения можно обслуживать через «Ответить» на сообщение бота.
4. При необходимости задайте числовые ID сотрудников. Пустой список разрешает ответы всех участников выбранной рабочей группы; список ограничивает их конкретными сотрудниками.
5. Для локальной работы выберите «Опрос Telegram». Сохраните настройки и отдельно нажмите «Проверить бота и группу» и «Подключить получение ответов». Проверка использует getMe/getChat/getChatMember и не отправляет тестовое сообщение.
6. Включите чат и уведомления о заказах независимо друг от друга. ID темы заказов можно указать вручную; 0 создаёт тему «Заказы · La Fleur» автоматически при первой доставке. Нельзя использовать тему клиентского диалога для заказов.
7. После размещения на публичном HTTPS-домене можно выбрать webhook и нажать подключение. Используется /chat/telegram/webhook/ и случайный secret_token в заголовке X-Telegram-Bot-Api-Secret-Token. Для исходящих очередей планировщик нужен и в webhook-режиме.

Чат до настройки доступен как окно с альтернативными контактами; он не обещает, что сотрудник сейчас в сети. Сообщения передаются после отдельного согласия. Текст обработки данных доступен по /chat/privacy/; сохраняется его точная копия и версия на момент открытия переписки.

## Работа сотрудников

- В теме диалога пишите обычный текст: он появится у соответствующего посетителя. В обычной группе используйте Reply на сообщение бота. Сообщения вне сопоставленной темы/Reply посетителю не показываются.
- Ответы из темы «Заказы» не попадают в покупательский чат.
- /close завершает выбранную переписку. Следующий вопрос покупателя начинает новый диалог с новым секретным cookie.
- В админке можно прочитать последние диалоги, ответить покупателю на сайте и завершить диалог. Настройки, удаление истории и ручные повторы доступны владельцу. Менеджер и поддержка могут читать переписки, отвечать и менять статус.
- Удаление с сайта не удаляет сообщения из Telegram. Копии в группе нужно удалить отдельно.

## События заказов

Новый заказ, изменение статуса и подтверждённая сервером оплата WEBPAY сохраняют уведомление в SQL-очередь в той же транзакции. Повтор оформления с прежним ключом, повтор статуса и повтор платёжного callback не создают новое событие. Подключение не рассылает существующие заказы задним числом.

По умолчанию передаются номер, товары, суммы, способ/город получения, дата, статус и ссылка в защищённую админку. Имя, телефон и адрес передаются только после включения соответствующей настройки владельцем; email, комментарии и текст открытки не отправляются. Секретные ссылки оплаты и ключи сеанса никогда не включаются. Учитывайте Telegram в фактических документах обработки данных магазина перед включением передачи контактов.

Отключённые уведомления остаются в журнале со статусом «Не отправляется» и не активируются автоматически при включении. Владелец может поставить конкретное событие в очередь явно.

## Ошибки и повторы

В журнале различаются: очередь, отправка, подтверждённая передача Telegram, явный отказ и неизвестный результат. Статус «Передано Telegram» не означает прочтение сотрудником.

При явном отказе — до пяти попыток с паузами. Таймаут или остановка во время отправки дают неизвестный результат: автоматический повтор запрещён, потому что сообщение могло уже прийти. Для ручного повтора владелец сначала проверяет группу и подтверждает риск дубля. При многочастном уведомлении подтверждённые части сохраняются, повтор начинается с неподтверждённой.

После смены бота или группы старые события и диалоги не переносятся в новое подключение. Тема заказов сбрасывается; старые истории остаются доступны только по прежнему секретному cookie и отмечаются завершёнными.

## Схема, задачи и выпуск

Добавочная миграция: php tools/migrate-chat.php. Общая php tools/migrate-schema.php также вызывает её. Создаются только lf_chat_settings, lf_chat_conversations, lf_chat_messages, lf_chat_updates, lf_chat_state, lf_order_notifications; прежние товары/заказы/настройки не меняются.

Windows: tools/install-telegram-task.ps1 -StartNow создаёт скрытую задачу LaFleur-Telegram-flowers.local раз в минуту с обычными правами текущего пользователя. tools/run-telegram-task.ps1 запускает обработчик --loop: опрос каждые пять секунд в пределах 55 секунд. Требуется вход пользователя в Windows; блокировка экрана допускается. На хостинге настройте отдельный cron/сервис:

    * * * * * /path/to/php /path/to/shop/tools/telegram-worker.php --loop >> /private/path/telegram-worker.log 2>&1

Разовый проход: php tools/telegram-worker.php. Без включённых настроек запросов к Telegram нет. Конкурирующие отправки и опрос блокируются через GET_LOCK. Сигнал планировщика — storage/telegram-worker-status.json; он виден в админке. В логах нет переписки и токенов.

Токен и webhook-секрет зашифрованы AES-256-GCM в БД. Ключ storage/private/lafleur-chat.key включайте только в закрытую резервную копию вместе с БД. Обычная сборка релиза не содержит ни ключа, ни данных БД. Потеря ключа требует повторного ввода реквизитов; не переносите старые очереди в другое подключение.

По умолчанию переписки удаляются с сайта после 30 дней без активности. Настройка — от 7 до 365 дней. Журнал уведомлений очищается по возрасту создания, обработанные update-ID — через 30 дней. История с истёкшим сроком недоступна посетителю даже до прохода уборщика. Корзина и записи заказов очисткой чата не затрагиваются.

## Проверки

- php tests/chat.php — изолированные TEMP-таблицы, тестовый транспорт, реальные транзакции OrderService; ни одного настоящего сообщения.
- php tests/chat-http.php http://flowers.local и http://127.0.0.1:8097 — чтение маршрутов, отсутствие секретов, отказ CSRF/чужому Origin/неверному webhook, размер тела, закрытый ключ и включение виджета. Успешных POST отправки нет.
- tests/backend.php использует TEMP-таблицы и для новой очереди, поэтому тестовые заказы не попадают в рабочие уведомления.
- Обводка launcher: светлая граница 2px, наружный тёмный контур и тень, версия chat.css?v=2.

Реальная доставка и двусторонний ответ требуют ввода реквизитов владельцем. Они не проверяются тестовым транспортом. Проверка через браузер в этом сеансе не выполнялась.
