max_auth_provider
No summary provided by the publisher yet.
Install
msc install --appId=max_auth_providerWhat this extension does
Провайдер авторизации MAX
Модуль добавляет в @webresto/core вход через чат-бота MAX. Это Sails hook с именем
max_auth_provider; он регистрирует адаптер max в общей auth-системе и не содержит
отдельного пользовательского интерфейса.
Как работает вход
- Клиент вызывает
startAuthдля провайдераmax. - Core создаёт
AuthState, а модуль возвращает deep link видаhttps://max.ru/<имя-бота>?start=<stateId>. - После перехода пользователя MAX отправляет событие
bot_started. Модуль связывает пользователя MAX сAuthStateи отправляет кнопку «Поделиться контактом». - Полученный контакт проверяется по секрету webhook, соответствию идентификатора
отправителя и HMAC-подписи MAX. После проверки core создаёт или обновляет
UserиAuthIdentity(provider="max"), а затем выдаёт обычную сессиюUserDevice.
Подключение
- Добавьте каталог модуля в набор подключаемых модулей приложения обычным для проекта
способом. После загрузки Sails hook должен быть доступен под именем
max_auth_provider— оно задано вpackage.jsonкакsails.hookName. - Примените миграции приложения. Миграция
migrations/20260809000000-init-max-auth-user.jsсоздаёт таблицуmaxauthuser,migrations/20260824130000-add-user-to-max-auth-user.jsдобавляет ссылку на пользователя,migrations/20260824120000-add-max-channel-to-notification-rules.jsвключает каналmaxв правилах уведомлений. - Перезапустите приложение. После готовности ORM модуль зарегистрирует в core
провайдер с идентификатором
max. - Включите созданный провайдер
maxвAuthProviderи сохраните его конфигурацию, как описано ниже.
Конфигурация
Основной вариант — хранить параметры в AuthProvider.config записи с adapter: "max":
{
"accessToken": "токен доступа MAX-бота",
"botUsername": "id123456_bot",
"webhookSecret": "длинный-случайный-секрет",
"apiBase": "https://platform-api2.max.ru"
}
Параметры можно передать через окружение. Значения в AuthProvider.config имеют приоритет:
| Переменная | Назначение |
|---|---|
MAX_AUTH_BOT_TOKEN |
токен доступа бота |
MAX_AUTH_BOT_USERNAME |
username бота без @ |
MAX_AUTH_WEBHOOK_SECRET |
секрет, с которым MAX подписывает webhook |
MAX_AUTH_API_BASE |
необязательный базовый URL API MAX |
Для успешной проверки обязательны accessToken, botUsername и webhookSecret.
Метод healthcheck() покажет, каких параметров не хватает.
Настройка webhook в MAX
Настройте endpoint https://<ваш-домен>/auth/max/webhook на следующие типы событий:
bot_started;message_created;bot_stopped;dialog_removed.
Пример создания подписки:
curl -X POST "https://platform-api2.max.ru/subscriptions" \
-H "Authorization: $MAX_AUTH_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/auth/max/webhook",
"update_types": ["bot_started", "message_created", "bot_stopped", "dialog_removed"],
"secret": "значение MAX_AUTH_WEBHOOK_SECRET"
}'
Значение secret должно совпадать с webhookSecret в конфигурации модуля. В production
webhook должен быть доступен по HTTPS на порту 443. Если окружение требует сертификат
Минцифры для обращения к API MAX, передайте путь к нему процессу Node.js через
NODE_EXTRA_CA_CERTS.
Уведомления через MAX
Модуль регистрирует канал доставки уведомлений max в NotificationManager ядра. Канал
виден на странице «Каналы уведомлений» сразу после загрузки модуля, даже без токена: реальное
состояние показывают isConfigured() (есть ли accessToken) и isReady() (включён ли
провайдер max).
| Параметр канала | Значение | Смысл |
|---|---|---|
type |
max |
идентификатор канала в правилах уведомлений и шаблонах |
cost |
0 |
сообщения бота бесплатны, поэтому канал идёт раньше платных |
sortOrder |
15 |
после бесплатных push-каналов (10/11), до платных |
forGroupTo |
["user"] |
только пользовательские уведомления, не менеджерские |
stopEscalation |
true |
доставка через MAX завершает waterfall |
templateFields |
title, body, clickUrl |
что показывает редактор шаблонов для канала |
Все параметры (включая stopEscalation) оператор меняет на странице каналов; они хранятся
в настройке ядра NOTIFICATION_CHANNELS_STATE.
Почему stopEscalation
MAX не сообщает о прочтении сообщения, поэтому Notification.readAt не заполнится никогда.
Без этого флага цикл эскалации ядра через NOTIFICATION_UNREAD_ESCALATION_MINUTES продублировал
бы каждое доставленное в MAX сообщение платным каналом — то есть съел бы всю экономию. Флаг
означает: «канал доставил — дальше не идём». Если для критичных уведомлений дублирование нужно,
stopEscalation для канала отключается в админке.
Адресация
Получатель ищется по MaxAuthUser.findForUser(userId):
- денормализованное поле
MaxAuthUser.user(кэш горячего пути); - если кэша нет —
AuthIdentity(provider="max", user)→MaxAuthUser.maxUserId, после чего ссылка сохраняется, а неактуальныйpendingAuthStateочищается.
Источником истины остаётся AuthIdentity. Отдельная модель сопоставления не нужна:
MaxAuthUser и есть эта модель.
Писать боту первым MAX не разрешает — сообщение уходит только тем, кто нажал «Начать»,
а это гарантирует сам вход через MAX. Пользователь, который зарегистрировался по телефону
и позже вошёл через MAX, получает бесплатный канал автоматически: AuthService привязывает
identity к существующему аккаунту по подтверждённому телефону.
Отписка и ошибки
- события
bot_stopped/dialog_removedвыключаютnotificationsEnabledу получателя — поэтому эти типы обязательно должны быть в подписке webhook; - если MAX отвечает «нет диалога / заблокирован» (400 с текстом про chat/user, 404), канал
сам выключает
notificationsEnabled, чтобы не тратить попытку waterfall на каждом следующем уведомлении; - 401 (токен) и 5xx не считаются проблемой получателя: канал помечается неисправным, отписка не выставляется;
- если MAX отверг markdown, сообщение повторяется один раз обычным текстом — несбалансированная
*в шаблоне оператора не должна выдавливать уведомление в платный канал.
Лимиты
Запросы к API сериализуются общей очередью: не чаще ~16 запросов в секунду на домен (документированный предел — 30) и не чаще одного сообщения в 550 мс в один диалог (предел — 2 в секунду). Текст обрезается до 4000 символов.
Правила уведомлений
Ядро о модуле ничего не знает, поэтому канал прописывает себя сам. В режиме waterfall
диспетчер перебирает только каналы из defaultChannels правила, а в правилах ядра указаны
лишь push-каналы — без этого шага канал был бы зарегистрирован, но никогда не использовался.
- на уже развёрнутых инсталляциях миграция модуля
migrations/20260824120000-add-max-channel-to-notification-rules.jsдобавляетmaxв правилаorder_accepted_push,order_on_the_way_push,order_not_completed_followup,user_birthday_greeting(списки, отредактированные оператором, не трогает); - на чистой установке правила заливаются сидами уже после миграций, поэтому канал нужно отметить в редакторе правил вручную. Об этом напоминает пункт setup-чеклиста «MAX notifications enabled in rules», который модуль регистрирует на старте.
Отдельный шаблон для канала не обязателен — без него рендерится шаблон правила по умолчанию.
Ссылка из clickUrl добавляется в текст отдельной строкой. Относительный путь достраивается
до абсолютного через настройку AUTH_CALLBACK_BASE_URL; если она пуста, ссылка не добавляется
(в мессенджере относительный путь всё равно не кликабелен).
OTP-коды через MAX не отправляются: правило user_otp_sms не тронуто.
Безопасность и данные
Каждый webhook проверяется по заголовку X-Max-Bot-Api-Secret. Для контакта дополнительно
проверяются совпадение MAX ID отправителя с данными контакта и
HMAC-SHA256(access_token, vcf_info). Проверенный телефон считается подтверждённым MAX.
Модель MaxAuthUser хранит MAX ID, chat ID, профиль, подтверждённый телефон, ссылку на
пользователя ядра и состояние уведомлений. Бизнес-уведомления идут через канал max
(см. выше). Метод адаптера sendNotification(userId, text) остаётся только для служебных
сообщений в диалоге бота — он обходит шаблоны, бюджет, логи и историю уведомлений.
Контактные данные можно использовать только для взаимодействия пользователя с ботом, которому он их отправил. Это ограничение MAX необходимо учитывать при рассылках.
Changelog
Changelog
1.1.0
- MAX notification channel (
max) registered in the core NotificationManager: free, runs after the push channels and before any paid one, user notifications only. - Terminal delivery: the channel sets
stopEscalation, so a message delivered to the MAX dialog is not duplicated by a paid channel (MAX reports no read receipt). - Recipient resolution through
MaxAuthUser.findForUser, backed by a new denormalizedMaxAuthUser.userlink; the stalependingAuthStateis now cleared after login. - Own migration + setup-checklist item that put the
maxchannel into the core notification rules (core stays unaware of this module). - MAX API client: markdown format, 4000-character limit, request throttling (30 rps domain /
2 messages per second per dialog), typed errors — an unreachable recipient switches
notificationsEnabledoff, a rejected markdown is retried once as plain text.
1.0.0
- Initial release of the MAX bot authorization provider for the
@webresto/coreauth layer.
Release history
3 releases| Version | Channel | Status |
|---|---|---|
| 1.1.1 | main | Latest stable |
| 1.1.0 | main | Archived |
| 1.0.0 | main | Archived |
Support
Issues with the extension itself go to the publisher. Anything about the registry goes to us.