Howto: настроить MAX Mini App над парком¶
Это пошаговая инструкция для новой организации: вы хотите чтобы ваши операторы управляли парком AWDC-контроллеров через приложение MAX, не запоминая текстовые команды и не открывая chat-доску каждый раз.
После настройки оператор открывает Mini App из чата с ботом (или из закрепа в групповом чате-доске), собирает команду в форме («Бокс, канал, prop=50»), жмёт «Отправить» — текст уходит в чат-доску, контроллер исполняет, ответ возвращается прямо в Mini App в течение ~60 секунд.
Картина целиком¶
Оператор тапает «Открыть»
│
▼
┌────────────────────────────┐
│ Mini App в MAX-вебвью │ ← статика на app.yourcompany.ru
│ (форма + результаты) │
└─────────────┬──────────────┘
│ fetch с Authorization: <token>
▼
┌────────────────────────────┐
│ nginx /max-proxy/ pass- │ ← на том же сервере
│ through к MAX Bot API │ (токен НЕ хранится)
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ platform-api.max.ru │
│ POST/GET /messages │
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ Чат-доска MAX (группа) │
│ бот в ней админ │
└─────────────┬──────────────┘
│
▼
┌────────────────────────────┐
│ Контроллеры парка │ ← каждый поллит группу
│ board-mode poll │ через свой NVS-токен бота
└────────────────────────────┘
Почему так:
- Mini App не может напрямую дойти до контроллера (NAT). Поэтому обмен идёт через MAX как через шину.
- MAX Bot API не разрешает кросс-доменные вызовы из браузера (CORS).
Поэтому Mini App ходит через свой же домен →
/max-proxy/→platform-api.max.ru. Прокси не хранит секретов, токен летит из Mini App в каждом запросе. - Контроллер тоже использует токен бота, чтобы поллить группу и отвечать. Это тот же токен, что в Mini App у оператора.
Что нужно подготовить¶
| Что | Зачем |
|---|---|
| ИП или ООО РФ | MAX публикует ботов и Mini App только через юр.лица РФ |
| Бот в платформе MAX | Сервисный аккаунт-ключ, без него API недоступно |
| Групповой чат в MAX, бот в нём админ | Тут пересекаются операторы и контроллеры. Админ-права нужны чтобы бот мог читать GET /messages |
| ВПС с публичным IP и nginx | Хост для статики Mini App |
| Доменное имя на ВПС | MAX требует валидный https для Mini App |
AWDC-контроллеры с прошивкой ≥ 732ea21 |
Принимают команды через бота (snятый whitelist для bot-сообщений) |
Шаг 1 — Бот и групповой чат в MAX¶
Если бот ещё не создан:
- Платформа MAX для партнёров → ваша организация → Чат-боты → Создать.
- Заполнить карточку бота, отправить на модерацию.
- После одобрения — получить токен (бот → Настройки → API).
Группа:
- В MAX создать приватный групповой чат (название по смыслу — «AWDC-Парк», «Мойка-Север» и т.п.).
- Пригласить бота в чат.
- Назначить бота администратором группы. Без админских прав
GET /messagesдля бота вернёт пусто. - Пригласить операторов, которым нужен доступ.
Шаг 2 — Настроить контроллеры в board-режим¶
Каждый контроллер парка → web-UI (http://<box>.local/ или IP):
- Сеть → MaxBot → раскрыть карточку.
- Шаг 1 (Токен) — вставить токен бота, «Проверить» (контроллер обратится к MAX и покажет имя бота), «Сохранить».
- Шаг 2 (Чат-доска) — нажать «Чаты бота», в выпадающем списке
выбрать вашу группу.
board_chat_idподставится автоматически. - Шаг 3 (Кто управляет) — написать в группу любое сообщение от
оператора → в карточке появится его user_id → нажать
+, чтобы добавить в whitelist. Whitelist рубит людей, постящих руками; команды от бота (от Mini App) проходят без whitelist. - Шаг 4 (Запуск) — включить тумблер «Включить бот», «Сохранить».
- Система → Устройство → задать имя устройства
(
box-1,awdc-east,мойка-7). По нему адресуются команды (SET@box-1). Латиница / цифры / дефис, без пробелов.
Повторить для каждого контроллера парка. Все указывают на один и тот
же board_chat_id. Имена устройств должны быть уникальны внутри
группы.
Шаг 3 — Поднять хостинг Mini App¶
На ВПС (один раз):
# DNS: запись A app.yourcompany.ru → IP вашего ВПС
# Сертификат
sudo certbot certonly --nginx -d app.yourcompany.ru
# Каталог для статики
sudo mkdir -p /var/www/app.yourcompany.ru
sudo chown ops:www-data /var/www/app.yourcompany.ru
sudo chmod 775 /var/www/app.yourcompany.ru
Где ops — пользователь, под которым будете деплоить (можно ваш
обычный SSH-логин, главное чтобы у него был ssh-доступ на ВПС).
nginx-конфиг¶
Возьмите max-webapp/scripts/nginx.conf.example, замените
your-domain.example на ваш домен (4-5 мест), положите в
/etc/nginx/sites-available/<your-domain>, симлинк в sites-enabled/,
перезагрузите nginx.
В конфиге обязательно должны быть:
listen 443 ssl http2;с SSL-сертификатомroot /var/www/<your-domain>;add_header Cache-Control "no-store" always;для/— иначе MAX webview закэширует index.html и не будет обновлятьсяlocation /max-proxy/ { rewrite ^/max-proxy/(.*)$ /$1 break; proxy_pass https://platform-api.max.ru; ... }— критично, без этого Mini App не сможет постить в чат из-за CORS
Проверить:
sudo nginx -t && sudo systemctl reload nginx
curl -I https://app.yourcompany.ru/ # должно быть 200 или 404 (если ещё пусто)
Шаг 4 — Собрать и задеплоить Mini App¶
На сборочной машине (любой компьютер с git + node):
git clone https://git.nikolaev.world/Home/AWDC-ESP32.git
cd AWDC-ESP32/max-webapp
# Конфигурация деплоя — нигде в репо не хранится, у каждой
# организации свой deploy.env
cp deploy.env.example deploy.env
$EDITOR deploy.env # вписать DEPLOY_HOST=ops@app.yourcompany.ru
# DEPLOY_PATH=/var/www/app.yourcompany.ru/
# DEPLOY_URL=https://app.yourcompany.ru/
# Сборка и деплой одной командой
bash scripts/deploy.sh
Открыть https://app.yourcompany.ru/ в браузере — должна загрузиться
форма «Управление парком». Это значит статика разложена и nginx отдаёт.
Шаг 5 — Зарегистрировать Mini App у бота в MAX¶
Платформа MAX → ваш бот → Мини-приложения → Добавить:
- URL:
https://app.yourcompany.ru/ - Название кнопки: «Открыть» / «Управление» / «Старт» (на ваш вкус)
Отправить на модерацию (от часов до суток). После одобрения в личном чате с ботом появится кнопка «Открыть» вверху.
Шаг 6 — Кнопка запуска в чате-доске (опционально)¶
Чтобы операторы могли запускать Mini App прямо из группового чата
(а не лезть в бот), бот может запостить в чат-доску закреп с
inline-кнопкой open_app:
Web-UI любого контроллера → Сеть → MaxBot → раздел «Чат-доска» →
подраздел «Кнопка запуска Mini App» → URL уже подставлен (deeplink
https://max.ru/<chat_bot>?startapp) → «Запостить».
В групповом чате появится сообщение «Управление парком — нажмите кнопку ниже». Закрепите его руками (MAX не даёт ботам закреплять). С этого момента кнопка всегда видна в шапке чата.
Шаг 7 — Раздать токен и chat_id операторам¶
Mini App у каждого оператора знает где постить команды через два
значения: bot-токен и board_chat_id. Сами они не подгружаются —
оператор вставляет их один раз. Это намеренно: токен = ключ к управлению
парком, выдаётся доверенным.
Как удобно получить: web-UI любого контроллера → Сеть → MaxBot → раздел «Чат-доска» → подраздел «Данные для Mini App» → «Показать токен и chat_id». В каждом поле — иконка двойного листика, тапнул — скопировал (на http://awdc.local/ может вместо buffer попросить вручную Ctrl+C — nginx над web-UI не https). После копирования иконка на 2 секунды становится зелёной галочкой — подтверждение.
Оператор:
- Открывает в MAX чат-доску (или 1:1 с ботом) → «Управление» (кнопка
open_app) или «Открыть» (заглавная кнопка бота). - Mini App открывается; при первом запуске сразу показывает экран ⚙ настроек.
- Вставляет токен и chat_id из ваших инструкций (можно ему скинуть текстом в личку — токен это «пароль» от парка, не публикуйте).
- «Сохранить и закрыть».
Дальше Mini App работает: оператор собирает команды в форме, ответы приходят inline.
Проверка end-to-end¶
- Mini App в MAX, ⚙ заполнен, на главном экране есть один бокс из
списка → команда
STATUS@<имя>→ «Отправить». - Зелёный статус «Команда отправлена. Жду ответ…».
- В MAX чат-доске появилось сообщение от бота
STATUS@<имя>— Mini App запостил. - Через ≤ 50 секунд (по
poll_interval_s) контроллер делает poll, видит команду, исполняет, отвечает:[<имя>] OK: uptime 12m, heap 145000, net OK | ch1 on/11% ch2 off/55% ch3 on/99%. - Mini App в течение 3 секунд после reply показывает его inline под формой. Статус — «Ответ получен».
Если что-то не сошлось — см. раздел «Если что-то не работает» ниже.
Если что-то не работает¶
Mini App: «Не удалось отправить (HTTP 405)»¶
nginx не настроен на проксирование MAX API. Проверьте location /max-proxy/
в вашем nginx-конфиге, nginx -t && systemctl reload nginx.
Mini App: «Не удалось отправить (HTTP 400)» с Failed to convert value¶
В Mini App ⚙ в поле chat_id вставлено что-то не то (например, URL вместо
числа). Должно быть -100... или 123456789 — число, возможно
отрицательное. Перезаберите из «Данных для Mini App».
Mini App: «Не удалось отправить (HTTP 401)» или 403¶
Токен невалиден / отозван / опечатка. Заново скопируйте из контроллера.
Команда в чате-доске видна, но контроллер не отвечает¶
- Проверьте, что у контроллера прошивка ≥
732ea21. До неё стоял фильтр!is_bot— команды от бота отбрасывались. Boot-manifest в сериале (I (...) FW-MANIFEST: ... sha=...) или web-UI → Диагностика → Система. - Проверьте имя устройства на контроллере (Система → Устройство)
— должно быть ровно то, что в команде после
@. Регистр не важен, пробелов быть не должно. - Проверьте, что бот включён в карточке MaxBot (тумблер «Включить бот»).
- Подождите до
poll_interval_sсекунд (по умолчанию 50). До первого poll'а после запуска контроллер только запоминает baseline-seq, команды не исполняет.
Mini App «N не ответил за 90 секунд»¶
Либо контроллер действительно молчит (см. выше), либо его reply ушёл,
но Mini App не успел дёрнуть GET /messages за окно 90 секунд. Бывает
если контроллер только что вышел из STA-провала. Повторите команду.
MAX webview показывает старую версию Mini App после деплоя¶
Закройте Mini App (свайп вниз), убейте процесс MAX в задачах, откройте
снова. nginx должен отдавать Cache-Control: no-store для index.html —
проверьте curl -I https://app.yourcompany.ru/. Без этого MAX
кэширует страницу агрессивно.
Безопасность¶
Токен бота — это полный контроль над парком. Кто им владеет — может постить любые команды от имени бота, контроллеры доверяют. Выдача:
- Только проверенным операторам. Не публикуйте, не пересылайте в открытые чаты, не клейте в общие документы.
- Через защищённый канал. Лучше всего — лично, по защищённому мессенджеру, или одноразовой ссылкой.
- Ротация при увольнении/смене состава. Пересоздайте токен в настройках бота в платформе MAX, перенастройте контроллеры (на каждом — карточка MaxBot → Токен → Проверить → Сохранить). У отозванного оператора в SecureStorage останется неработающий токен.
Сервер с Mini App в нашей схеме секретов не хранит. Если кто-то получит root на ВПС — найдёт HTML/JS Mini App'а (тот же, что и так публично доступен через браузер) и больше ничего. Это сознательный выбор архитектуры — токены не должны жить на промежуточных хостах.
Whitelist allowed_user_id на контроллерах остаётся для людей,
пишущих в группу руками (например, оператор печатает STATUS@box-1
сам без Mini App). Команды от бота (от Mini App) whitelist пропускает —
credential там сам токен.
См. также¶
- setup-maxbot.md — настройка board-режима бота без Mini App
- doc/api/integrations.md — полный список команд
- max-webapp/README.md — внутреннее устройство и dev-mode
- ADR-010 — обоснование архитектуры