Перейти к содержанию

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

Если бот ещё не создан:

  1. Платформа MAX для партнёров → ваша организация → Чат-боты → Создать.
  2. Заполнить карточку бота, отправить на модерацию.
  3. После одобрения — получить токен (бот → Настройки → API).

Группа:

  1. В MAX создать приватный групповой чат (название по смыслу — «AWDC-Парк», «Мойка-Север» и т.п.).
  2. Пригласить бота в чат.
  3. Назначить бота администратором группы. Без админских прав GET /messages для бота вернёт пусто.
  4. Пригласить операторов, которым нужен доступ.

Шаг 2 — Настроить контроллеры в board-режим

Каждый контроллер парка → web-UI (http://<box>.local/ или IP):

  1. Сеть → MaxBot → раскрыть карточку.
  2. Шаг 1 (Токен) — вставить токен бота, «Проверить» (контроллер обратится к MAX и покажет имя бота), «Сохранить».
  3. Шаг 2 (Чат-доска) — нажать «Чаты бота», в выпадающем списке выбрать вашу группу. board_chat_id подставится автоматически.
  4. Шаг 3 (Кто управляет) — написать в группу любое сообщение от оператора → в карточке появится его user_id → нажать +, чтобы добавить в whitelist. Whitelist рубит людей, постящих руками; команды от бота (от Mini App) проходят без whitelist.
  5. Шаг 4 (Запуск) — включить тумблер «Включить бот», «Сохранить».
  6. Система → Устройство → задать имя устройства (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 секунды становится зелёной галочкой — подтверждение.

Оператор:

  1. Открывает в MAX чат-доску (или 1:1 с ботом) → «Управление» (кнопка open_app) или «Открыть» (заглавная кнопка бота).
  2. Mini App открывается; при первом запуске сразу показывает экран ⚙ настроек.
  3. Вставляет токен и chat_id из ваших инструкций (можно ему скинуть текстом в личку — токен это «пароль» от парка, не публикуйте).
  4. «Сохранить и закрыть».

Дальше Mini App работает: оператор собирает команды в форме, ответы приходят inline.


Проверка end-to-end

  1. Mini App в MAX, ⚙ заполнен, на главном экране есть один бокс из списка → команда STATUS@<имя> → «Отправить».
  2. Зелёный статус «Команда отправлена. Жду ответ…».
  3. В MAX чат-доске появилось сообщение от бота STATUS@<имя> — Mini App запостил.
  4. Через ≤ 50 секунд (по poll_interval_s) контроллер делает poll, видит команду, исполняет, отвечает: [<имя>] OK: uptime 12m, heap 145000, net OK | ch1 on/11% ch2 off/55% ch3 on/99%.
  5. 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 там сам токен.


См. также