v1.7 — One-click Telegram linking
v1.7 — One-click Telegram + manual fallback
Сотрудник подключает Telegram одной кнопкой — открывается бот, жмёт Start, готово. Manual путь через @userinfobot остаётся как fallback.
Flow
- Сотрудник на /profile/integrations жмёт «🔗 Открыть Telegram»
- Бэк генерит one-time токен (10 мин TTL) → редирект на `t.me/?start=`
- Сотрудник жмёт Start в Telegram-приложении
- Telegram POST'ит наш `/telegram/webhook` с подписью в `X-Telegram-Bot-Api-Secret-Token`
- Webhook валидирует secret, матчит token, сохраняет chat_id, бот пишет юзеру "✓ Готово, привязано к email@..."
Setup
Админу в /settings/communications:
- Кнопка Зарегистрировать webhook → setWebhook + generated secret_token
- Бэдж «активен/не настроен», re-register / remove
- На localhost блокируется с подсказкой про `APP_BASE_URL` + ngrok-туннель
UI states
Profile/integrations показывает один из трёх блоков:
- Webhook активен → большая primary-кнопка "Открыть Telegram" + collapsed `` с manual fallback
- Webhook нет → manual инструкция через @userinfobot
- Бот не настроен → ⚠ alert и disabled-поле
Безопасность
- `X-Telegram-Bot-Api-Secret-Token` верифицируется через `ActiveSupport::SecurityUtils.secure_compare`
- `tg_link_token`: 16-byte URL-safe random, 10 мин TTL, single-use (зануляется на успех)
- Webhook endpoint: `skip_before_action :verify_authenticity_token` + `protect_from_forgery with: :null_session`
Migration
- `users.tg_link_token` (unique partial index, NULLable)
- `users.tg_link_token_at` (для TTL-проверки)
i18n
- +24 ключа × 3 локали → паритет 2316/2316/2316
Production-only
Telegram требует HTTPS-публичный URL для webhook. На `localhost:4000` registration блокируется — для теста используй `APP_BASE_URL=https://your-ngrok.io\` или продакшен-домен. Manual fallback работает везде.