brainstate

Trollobot/Telemax · source

Snapshot 0 · 2026-11-04T12:47:28Z · TypeScript · AGPL-3.0

Content fingerprint97a2b748af3db616875ed41895a4f7301e83a71ff4e24faa076088fd07d14ebb

GitHub description at capture

Мост MAX ↔ Telegram через ваш личный MAX-аккаунт (по номеру, не бот) — все чаты Макса зеркалятся в Telegram автоматически. Свой сервер, приватно, без установки MAX на телефон.

README at capture

# Telemax — двусторонний мост MAX ↔ Telegram

🌐 Сайт проекта: **[telemax.svnest.ru](https://telemax.svnest.ru/)**

Двусторонний мост между мессенджером **MAX** и **Telegram**. Подключается к вашему **личному MAX-аккаунту по номеру телефона — а не через бота**, поэтому в Telegram зеркалятся **все** ваши чаты Макса автоматически (у бот-мостов так не выйдет — только там, куда добавили бота). Каждый номер MAX превращается в Telegram-группу с форум-темами (по одной на каждый MAX-чат), переписка идёт в обе стороны как в едином окне. На стороне Telegram — свой бот, всё крутится на вашем сервере: данные идут только через вашу инфраструктуру, без облачных прослоек.

> ⚠️ Неофициальный проект. Не связан с MAX и Telegram, работает поверх вашего собственного номера/аккаунта на свой страх и риск — см. [«Отказ от ответственности»](#отказ-от-ответственности).

## Возможности

- Текстовые сообщения, фото, файлы, голосовые, видео и видео-кружки (обе стороны)
- Большие файлы — по ссылке: из Telegram в MAX больше 20 МБ (до 4 ГБ — лимит MAX), из MAX в Telegram больше 50 МБ; свой файлообменник в пульте (см. [«Большие файлы»](#большие-файлы))
- Кнопки ботов MAX — в Telegram: ссылки, копирование, нажатия; мини-приложения открываются ссылкой в MAX
- Стикеры — статичные и анимированные (обе стороны)
- Геолокация и контакты (обе стороны)
- Опросы: создание и голосование в обе стороны, актуальный счёт по команде `/poll`
- Удаление сообщений в обе стороны; удаление чата в MAX удаляет и его тему в Telegram
- Ответы на сообщения (reply) — нативные в обе стороны, с переходом к оригиналу
- Пересылка сообщений — обычным drag-forward в Telegram, с автоматической пометкой источника
- 📡 Трансляция: новые сообщения чата MAX копируются в любые группы и каналы Telegram — для тех, у кого нет MAX (`/broadcast`, см. [«Трансляция»](#трансляция))
- 🎛 Пульт управления (`/panel`, закреплён в теме группы): поиск контакта MAX по номеру, нику или MAX ID и старт чата в один тап, пауза/возобновление MAX, бан/разбан чатов, вход в MAX, обновление — всё кнопками
- Управление MAX-группами прямо из Telegram: создание, приглашение/удаление участников, переименование, описание, выход, удаление
- Уведомления о звонках (входящий/завершённый/пропущенный) — только текстом, без передачи аудио
- Авторизация MAX прямо в боте: `/login` в личке (номер + код из SMS, поддерживается пароль/2FA) — код и пароль в группу не попадают
- `/reboot` — полный сброс и пересинхронизация Telegram-стороны без повторной авторизации в MAX
- `/logout` (или пульт → «🔐 Вход в MAX» → «🚪 Выйти из MAX») — выйти из MAX без удаления: сессия завершается и в самом MAX, темы, история и настройки остаются; войти снова — `/login`
- `/kill` — аварийный сброс: то же самое + выход из MAX (сессия завершается и в самом MAX) и стирание сохранённой сессии и всех данных
- `/version` — проверка обновлений и обновление по кнопке прямо из Telegram (см. [«Обновление»](#обновление))
- Прокси для Telegram (SOCKS5/HTTP) — если сервер выходит в Telegram только через прокси; MAX при этом идёт напрямую (см. [«Прокси для Telegram»](#прокси-для-telegram))
- Уведомления о сбоях (потеря связи с MAX, ошибки доставки, внутренние ошибки) прямо в Telegram-группу, с защитой от спама
- 🐞 Приём баг-репортов в личку бота с двусторонней перепиской (опционально, включается `BUGREPORT_INBOX`); по умолчанию посторонним, написавшим боту в личку, показывается ссылка на баг-репорт-бот проекта
- Аватарка группы и цвет иконки каждой темы форума выставляются автоматически

Полный список команд бота — `/help` прямо в боте после запуска.

## Пульт управления

Команда `/panel` (и закреплённое в теме группы сообщение) открывает пульт с кнопками — меню прямо в Telegram-группе:

- **👤 Найти контакт** — поиск MAX-контакта по номеру, нику или MAX ID; из карточки результата «Начать чат» в один тап создаёт диалог и его тему, а «➕ В контакты MAX» сохраняет человека в контакты вашего MAX (их видно и в приложении на телефоне). Или просто поделитесь в общей теме группы контактом из Telegram — бот найдёт его в MAX по номеру, а в контакты MAX сохранит под тем же именем, что у вас в Telegram (читать вашу книгу контактов Telegram бот не может: Bot API такого доступа не даёт). Человека, который закрыл поиск по номеру в настройках приватности MAX, не найти никак — попросите его написать вам первым, и чат сам появится темой. Каналы MAX находятся по нику или названию: в карточке канала — «📢 Подписаться», и канал появляется темой с последними 10 постами (писать в чужой канал нельзя). Вставьте ссылку-приглашение `max.ru/join/…` — вступите в группу или канал прямо из пульта.
- **🚫 Управление чатами** — заглушить (бан) или вернуть чат.
- **🔐 Вход в MAX** — кнопка ведёт в личку бота, где проходит авторизация (номер + SMS-код, при 2FA — пароль).
- **⚙️ Система** — «📊 Статус» (версия, аптайм, состояние MAX и Telegram, последние сообщения, диск/RAM/нагрузка, доступность обновления), пауза MAX на время (10 мин / 1 час / 1 сутки / до перезапуска моста), обновление, пересинхронизация, список команд и «🔁 Перезапустить мост» — без пересборки и без SSH, за 10–20 секунд.

Пульт виден всем участникам группы, но кнопки/команды срабатывают только у администраторов.

## Требования

- Сервер на Ubuntu 22.04+ или Debian 12+ (нужен git 2.34+ — им проверяется подпись релизов; на Ubuntu 20.04 / Debian 11 git старее)
- Docker + Docker Compose
- Telegram-бот (токен из [@BotFather](https://t.me/BotFather)) и Telegram-группа с включёнными темами (forum topics), куда бот добавлен администратором **с правом «Управление темами» (Manage Topics)** — без него бот не сможет создавать темы под MAX-чаты
- Номер MAX, на который будет авторизован мост

## Быстрый старт

На чистом сервере Ubuntu 22.04+ / Debian 12+ (по SSH, от root) — одна команда:

```bash
curl -fsSL https://raw.githubusercontent.com/Trollobot/Telemax/main/install.sh | bash
```

Если GitHub с вашего сервера недоступен (заблокирован или лежит) — та же установка с резервного зеркала проекта:

```bash
curl -fsSL https://zergont-gate.duckdns.org/install.sh | bash
```

Скрипт в обоих случаях один и тот же: сначала пробует GitHub, при неудаче сам переключается на зеркало; обновления и проверка версий работают так же, с автоматическим фолбэком. Подлинность каждого релиза в любом случае проверяется по подписи тега — зеркало лишь транспорт.

Она сама обновит систему, поставит git, Docker и jq (если их ещё нет), предложит включить Fail2ban — защиту SSH от подбора пароля (по умолчанию — да), склонирует проект в `/opt/telemax` и запустит интерактивную настройку. Если на сервере уже есть установленный мост, та же команда вместо этого откроет меню: обновить или перенастроить существующий (в том числе переустановить начисто), поставить ещё один или удалить ненужный (см. [«Несколько мостов на одном сервере»](#несколько-мостов-на-одном-сервере)). Спросит токен Telegram-бота (создаётся через [@BotFather](https://t.me/BotFather)) — id группы искать не придётся: добавьте бота в свою группу (с включёнными темами) администратором, отправьте туда любое сообщение, и скрипт сам определит нужный id. Секретные ключи сгенерирует сама, соберёт образ и запустит контейнер. Первая сборка дольше обычного (внутри образа headless-браузер для рендера анимированных стикеров) — это нормально, обычно несколько минут. Останется один шаг: авторизовать MAX командой `/login` в личке бота (подробнее — [«Первая авторизация»](#первая-авторизация)). Повторный запуск `setup.sh` безопасен — на настроенной установке он открывает меню изменения настроек (см. [«Изменение настроек после установки»](#изменение-настроек-после-установки)).

Если Docker и git уже стоят (или разворачиваете не с нуля) — то же самое, но без системной части:

```bash
git clone https://github.com/Trollobot/Telemax.git
cd Telemax
./setup.sh
```

Совсем руками, без интерактивных скриптов:

```bash
cp .env.example .env
# впишите TELEGRAM_BOT_TOKEN и TARGET_TELEGRAM_GROUP, ключ шифрования сгенерируйте:
# openssl rand -hex 32   -> MAX_SESSION_KEY
docker compose up -d --build
```

Так не будет автообновления: его ставит только `setup.sh`, запущенный от root. Без него не работают и большие файлы — их службу запускает автообновление, поэтому добавьте в `.env` строку `FILES=off`. Обновлять такой мост — вручную: `git pull`, затем `docker compose up -d --build`.

**Свои настройки Docker** — порты, тома, сеть, лимиты памяти — не вписывайте в `docker-compose.yml`: обновление откажется ставиться поверх правок в файлах моста. Положите их в `docker-compose.override.yml` рядом с ним — Docker Compose сам добавит его к основному файлу, а обновления его не трогают. Например:

```yaml
services:
  telemax:
    mem_limit: 512m
```

## Несколько мостов на одном сервере

На одном сервере может жить сколько угодно независимых мостов — например, два номера MAX, каждый со своей Telegram-группой. У каждого моста всё своё: каталог (`/opt/telemax`, `/opt/telemax-2`, …), **свой Telegram-бот** (токен нельзя переиспользовать — два моста на одном токене отбирают обновления друг у друга), **своя группа** и **свой номер MAX**, свои настройки (`.env`) и данные (`data/`). Общие на сервер — только Docker (одинаковые слои образов кэшируются, поэтому второй мост занимает на диске заметно меньше первого), единый таймер автообновления `telemax-updater`, который сам обслуживает все мосты, и Fail2ban.

Установщик сам находит уже установленные мосты: запустите ту же команду установки ещё раз, и вместо установки откроется меню —

1. **Обновить или перенастроить** существующий мост (если их несколько — выбор какого). Внутри два уровня: обычное обновление с сохранением настроек (только до релиза с проверенной подписью, как и при автообновлении; если такого нет — мост остаётся на своей версии) или **переустановка начисто** — настройки и данные сбрасываются, но перед этим автоматически сохраняются в архив `/root/telemax-backup-<имя>-<дата>.tar.gz` (доступен только root). Если бэкап сохранить не удалось, ничего не удаляется.
2. **Установить ещё один мост** — установщик предложит первый свободный каталог (`/opt/telemax-2`), путь можно поменять. Дальше — обычная настройка: токен нового бота, новая группа, `/login` с новым номером.
3. **Удалить мост** — один по выбору или сразу все. Удаляются контейнер, образ и каталог; настройки и данные перед этим сохраняются в такой же бэкап-архив, а без бэкапа удаление не выполняется. Вместе с последним мостом убирается и общий таймер автообновления (Docker и Fail2ban остаются — они серверные).

Меню появляется только при интерактивном запуске; если каталог задан явно через `INSTALL_DIR`, установщик молча работает с ним — так что второй мост по-прежнему можно поставить и одной командой:

```bash
curl -fsSL https://raw.githubusercontent.com/Trollobot/Telemax/main/install.sh | INSTALL_DIR=/opt/telemax-2 bash
```

Практические мелочи: полный образ (с Chromium для анимированных стикеров) — это ~1,7 ГБ и заметный кусок RAM на каждый контейнер, на небольшом сервере для второго моста стоит выбрать режим `slim`; все команды обслуживания (`docker compose logs -f`, `./setup.sh`, `./update.sh`) выполняются из каталога конкретного моста.

## Первая авторизация

> ⚠️ **Не пропустите этот шаг.** Без авторизации MAX мост поднят, но ни к какому аккаунту не подключён и ничего не пересылает.

После запуска контейнера откройте вашего бота в Telegram и напишите ему **в личку** команду `/login` (либо в группе: `/panel` → «🔐 Вход в MAX»). Бот спросит номер телефона MAX и код из SMS — всё в личной переписке, в группу они не попадают; если на аккаунте включён пароль (2FA), бот спросит и его и сразу удалит сообщение с паролем из чата. Вход доступен только администраторам группы.

После успешной авторизации сессия сохраняется зашифрованной в `./data` — повторной авторизации при перезапуске контейнера не требуется. Повторный вход тем же путём (`/login`) нужен только после `/kill`, смены номера или если MAX отклонил сессию (бот сам напишет об этом в группу).

После входа мост переносит историю чатов в темы. Telegram разрешает боту писать в группу примерно 20 сообщений в минуту, поэтому большая история заливается долго: чат на 5 000 сообщений — около 4 часов (новые сообщения при этом приходят сразу). Перед первой заливкой бот спрашивает в группе, сколько истории перенести: 1 день, 7 дней (по умолчанию), 30 дней или всю. Поменять потом — /panel → ⚙️ Система → «📜 История». Выбор касается тем, которые заполняются с нуля: первая синхронизация, /reboot, новый чат, восстановленная тема — уже заполненные темы он не трогает. Дополнительно можно ограничить число сообщений: `HISTORY_LIMIT=300` в `.env` (затем `docker compose up -d --force-recreate`). Тема, куда попала не вся история, начинается с пометки об этом. У сообщений из истории и у всех, что пришли с опозданием больше 5 минут, в конце стоит время отправки в MAX: «🕓 10.09.2026, 11:27» (выключить — `BACKFILL_TIME=off` в `.env`).

В личке бот работает только для входа в MAX (`/login`); все остальные команды — в группе моста. Если администратор напишет в личку что-то другое, бот подскажет, где пульт.

## Большие файлы

У ботов Telegram жёсткие лимиты: скачать из Telegram бот может файл не больше **20 МБ**, отправить в Telegram — не больше **50 МБ**. MAX принимает файлы до 4 ГБ. Всё, что не пролезает, мост пересылает по ссылке:

- **Из Telegram в MAX, больше 20 МБ.** Бот отвечает в теме кнопкой «📤 Загрузить файл»: по ссылке открывается страница на вашем сервере, файл загружается из браузера, и мост отправляет его в MAX обычным файлом — до 4 ГБ, это лимит MAX. Чтобы не ждать загрузку дважды (сначала в Telegram, потом по ссылке), напишите в теме чата `/file` — ссылка на загрузку придёт сразу. Большой файл MAX обрабатывает несколько минут — мост дожидается этого сам.
- **Из MAX в Telegram, больше 50 МБ.** В теме сразу появляется «📥 Пришёл файл» с прогрессом сохранения, а когда файл ляжет на сервер — кнопка «⬇️ Скачать».
- **Пульт → «📁 Файлы».** Список файлов на сервере: новая ссылка (продлевает хранение), удаление, повторная отправка в MAX, если она не удалась. Кнопка «📤 Загрузить файл» — свой файлообменник: положить на сервер файл любого размера (сколько вместит диск, лимит MAX тут ни при чём) и делиться ссылкой на скачивание где угодно. Файл живёт 3 дня от последней выданной ссылки, потом удаляется сам. Отправленные в MAX файлы на сервере не хранятся.

Как это устроено:

- Ссылки обслуживает одна общая служба на сервер (`files-service/`: Caddy + маленькое приложение на Node) — для всех мостов сразу. Её запускает автообновление, и **только пока есть действующие ссылки**: тогда открыты порты 80 и 443. Ссылок нет — служба остановлена, порты закрыты. Запускается она за несколько секунд: за появлением ссылок следит systemd (`telemax-files.path`), его ставит само автообновление. Настройки адреса (`FILES_DOMAIN`, `FILES_PUBLIC_URL`, `FILES_LISTEN`) общие для всех мостов сервера и берутся из `.env` первого из них.
- HTTPS — без домена: сертификат Let's Encrypt выпускается на IP-адрес сервера и продлевается сам. Если есть свой домен, укажите его: `FILES_DOMAIN=files.example.ru` в `.env` первого моста.
- **Порты 80 и 443 должны открываться из интернета** — иначе Let's Encrypt не сможет выдать сертификат, и ссылки не заработают. Сервер дома за роутером — нужен белый IP у роутера и проброс на сервер портов 80 и 443 (с серым IP проброс не поможет: белый IP подключают у провайдера, или мост ставят на VPS); хостинг закрывает порты файрволом — откройте их в его панели. Если что-то мешает, бот прямо назовёт причину. Не нужны большие файлы — `FILES=off`.
- **Установщик проверяет это сам.** Если у сервера нет своего белого IP (он дома за роутером) или порты 80/443 заняты другим веб-сервером, он объясняет, что нужно, и предлагает включить большие файлы, только если всё уже настроено — иначе ставит `FILES=off`. Включить позже — `./setup.sh` → «Большие файлы».
- Ссылка на загрузку, по которой ничего не загрузили, живёт 24 часа: сообщение с ней скажет, что она истекла. Загрузка, которая уже идёт, не обрывается, даже если срок вышел. Все ждущие ссылки видны в «📁 Файлы» — там их можно открыть или отменить.
- Перед каждой передачей проверяется свободное место, и мост всегда оставляет запас 1,5 ГБ — столько нужно для обновления.
- По ссылке открывается страница с кнопкой, а не сам файл: предпросмотр ссылок в мессенджерах её не «съедает». Ссылки случайные, без списков файлов, с ограниченным сроком.
- Нужны свободные порты 80 и 443. Если на сервере уже есть свой веб-сервер (Caddy, nginx), службу файлов можно пустить через него: она будет слушать только локальный порт, а ваш сервер — передавать ей запросы по выбранному пути. Пример для Caddy — в блок вашего сайта:

  ```
  handle_path /tlmx-files/* {
  	reverse_proxy 127.0.0.1:3300
  }
  ```

  и в `.env` первого моста: `FILES_PUBLIC_URL=https://ваш-домен/tlmx-files` и `FILES_LISTEN=127.0.0.1:3300`. Без этого при занятых портах бот так и скажет, а файлы больше лимитов пересылаться не будут.

Настройки в `.env` (необязательные):

```bash
FILES=off              # выключить пересылку больших файлов совсем
FILES_TTL_HOURS=72     # сколько живёт файл после выдачи ссылки
FILES_UPLOAD_TTL_HOURS=24  # сколько живёт неиспользованная ссылка на загрузку
FILES_RESERVE_MB=1536  # сколько места всегда оставлять свободным
FILES_DOMAIN=          # свой домен вместо IP-адреса
FILES_PUBLIC_URL=      # адрес за вашим веб-сервером, например https://example.ru/tlmx-files
FILES_LISTEN=          # локальный порт службы для вашего веб-сервера, например 127.0.0.1:3300
```

## Трансляция

Новые сообщения чата MAX можно копировать в обычные группы и каналы Telegram — для тех, у кого MAX нет. Например, чат садового товарищества — в канал, который читают соседи.

- **Включить.** Напишите `/broadcast` в теме чата и нажмите «👥 В группу» или «📢 В канал»: Telegram покажет ваши группы или каналы и сам добавит туда бота администратором (публиковать, закреплять). Если бот там уже есть — «🔎 Бот уже в группе или канале»: выбор откроется в личке с ботом. Карточка `/broadcast` в теме сразу покажет новое место — там же «📌» и «⏹».
- **Мест — сколько угодно.** Один чат можно транслировать в несколько групп и каналов, а в одну группу — несколько чатов. `/broadcast` в теме показывает, куда идёт трансляция, и останавливает любую кнопкой «⏹».
- **Что копируется.** Новые сообщения с момента включения: текст, фото, файлы, голосовые, с подписью автора, как в теме. Вместо «🧑 Вы» стоит ваше имя из MAX, ваши сообщения, написанные в теме из Telegram, тоже идут туда. Правки и удаления в MAX повторяются, пока мост не перезапускался. Опросы — текстом: голоса из Telegram в MAX не попадут. История до включения не переносится, сообщения, пришедшие пока мост был выключен, — догоняются.
- **Закреп «📌».** Кнопка «📌 Закреп» в `/broadcast` включает закрепление каждого нового сообщения в этом месте — тихо, без уведомлений. В группе, где все пишут, сообщения из MAX легко найти по закрепам. В группу, куда бота добавили с правом закреплять, закреп включается сразу; в канале — кнопкой. Боту нужно право закреплять сообщения (в канале — редактировать); с правом удалять он ещё и убирает строку «… закрепил».
- **В одну сторону.** Что пишут в группе трансляции, в MAX не уходит — бот там молчит. Чтобы участники только читали, выберите канал или закройте отправку сообщений в настройках группы.
- Если бота удалят из группы или канала, трансляция туда остановится сама, а в теме чата появится сообщение.

## Безопасность

Бот отвечает только внутри той Telegram-группы, что указана в `TARGET_TELEGRAM_GROUP` — любое сообщение или нажатие кнопки из другого чата (личка боту, добавление в чужую группу и т.п.) игнорируется. Исключение — группы и каналы трансляции: туда бот только пишет, а включить трансляцию может лишь администратор группы моста по одноразовой ссылке из `/broadcast`.

Внутри группы доступ разграничен: обычные участники могут читать и писать (в группу можно добавлять людей для общего обсуждения), но **команды боту выполняются только для администраторов группы** — снести сессию (`/kill`), пересобрать мост (`/reboot`), войти в MAX (`/login`), управлять MAX-группами может лишь админ, рядовой участник — нет.

Учтите: любой участник Telegram-группы видит в ней **все** зеркалированные MAX-чаты (по теме на чат), а не какой-то один. Доступ к самой группе — чувствительная вещь, раздавайте его осознанно.

Мост не открывает входящих портов: MAX — исходящее TCP-соединение, Telegram — long-polling. Единственное исключение — пересылка больших файлов (см. [«Большие файлы»](#большие-файлы)): пока на сервере есть хотя бы одна действующая ссылка на файл, открыты порты 80 и 443, а когда ссылок нет — служба останавливается и порты закрываются. Управление — только из Telegram-группы (админами) и по SSH через `./setup.sh`. Единственная открытая дверь на сервере — SSH; `install.sh` предлагает поставить Fail2ban, который банит подбор пароля (5 промахов за 10 минут → бан на 10 минут; IP вашей сессии установки — в белом списке).

Сертификаты российского государственного УЦ (нужны только потому, что через них выпущен TLS-сертификат самого MAX) доверяются **только** соединениям с серверами MAX — запросы к Telegram, GitHub и всему остальному проверяются исключительно по стандартному набору корневых сертификатов Mozilla (подробнее — `certs/README.md`).

## Обслуживание

```bash
docker compose logs -f      # логи
docker compose restart      # перезапуск
docker compose down         # остановка
```

Все состояние (сессия MAX, привязка чатов к темам) лежит в `./data` на хосте — бэкап этой папки достаточен для переноса на другой сервер.

## Изменение настроек после установки

Все настройки живут в одном месте — файле `.env`. Штатный способ их менять — зайти на сервер по SSH и запустить `setup.sh` ещё раз:

```bash
cd /opt/telemax && ./setup.sh
```

На настроенной установке он открывает меню:

1. Показать текущие настройки (токен маской, группа, прокси без пароля, режим стикеров, статус контейнера)
2. Изменить прокси Telegram — **с живой проверкой соединения до записи**
3. Сменить токен бота / целевую группу (с повторным автоопределением группы)
4. Переключить режим стикеров full/slim (с пересборкой образа)
5. Проверить связь с MAX и Telegram
6. Пересобрать и перезапустить контейнер
7. Большие файлы: включить или выключить — с проверкой, есть ли у сервера свой белый IP и свободны ли порты 80/443

Изменения применяются пересозданием контейнера (меню предложит это само) — Docker читает `.env` только при создании контейнера, простого рестарта недостаточно.

**Аварийный случай:** бот молчит, потому что прокси умер, а починить через Telegram нельзя (канал управления идёт через тот самый прокси). По SSH это один заход: `./setup.sh` → пункт 2 — или совсем вручную:

```bash
cd /opt/telemax && (umask 077; grep -v '^TELEGRAM_PROXY=' .env > .env.tmp && printf "TELEGRAM_PROXY='%s'\n" 'socks5://логин:пароль@хост:порт' >> .env.tmp) && mv .env.tmp .env && chmod 600 .env && docker compose up -d --force-recreate
```

Значение записывается **в одинарных кавычках** — так же, как это делает `setup.sh`. Без кавычек Docker Compose подставляет переменные в `.env`, и пароль с символом `$` доходит до контейнера искажённым (`pa$w0rd` превращается в `pa`) — бот просто молча не подключается к Telegram. Адрес прокси в команде тоже взят в одинарные кавычки, поэтому `$`, `&` и `#` в пароле безопасны; если в пароле есть сам символ `'`, запишите его как `%27` (например, `pa%27ss`) — так его принимает и `setup.sh`.

## Прокси для Telegram

Если сервер выходит в Telegram только через прокси (например, домашний сервер, где прямой доступ к `api.telegram.org` закрыт) — укажите его. **MAX при этом всегда идёт напрямую**, через прокси гоняется только Telegram-трафик. Форматы: `socks5://[логин:пароль@]хост:порт` или `http://[логин:пароль@]хост:порт`.

Задать можно тремя способами:

- **При установке** — `setup.sh` спрашивает про прокси ещё до проверки связи (иначе на proxy-only хосте проверка Telegram ложно упала бы), и тут же проверяет доступность через него.
- **После установки** — повторный запуск `./setup.sh` → пункт «Изменить прокси Telegram»: новая настройка сначала проверяется вживую и только потом записывается (см. [«Изменение настроек после установки»](#изменение-настроек-после-установки)).
- **В `.env`** — переменная `TELEGRAM_PROXY`, затем `docker compose up -d --force-recreate` (Telegraf задаёт прокси при старте, на лету не подменяется).

## Если что-то не работает

Сама установка проходит на любом Ubuntu 22.04+ / Debian 12+ (проверено вплоть до Debian 13 trixie) даже на VPS с менее чем 1 ГБ RAM — окружение почти никогда не причём. Быстрее всего локализовать проблему по одному признаку — **проявляется ли бот в вашей Telegram-группе хоть как-то**: приходит ли после старта его сообщение «✅ Telemax подключён к этой группе», заводятся ли темы под MAX-чаты.

- **Бота в группе не видно вообще** (ни стартового сообщения, ни тем) — он не достучался до Telegram или до группы: пункты 1–3.
- **Бот активен, но сообщения из MAX не приходят** — почти всегда не завершена авторизация MAX: пункт 4.

Все команды — из папки установки (`cd /opt/telemax`):

1. **Бот не достучался до Telegram (частый случай на хостингах в РФ).** На dual-stack серверах IPv6-маршрут до `api.telegram.org` бывает заблокирован, а система по умолчанию пробует сначала именно IPv6 — бот виснет на подключении, в группе полная тишина. Свежие версии форсируют IPv4 сами, так что первым делом обновитесь: `/version` в группе → «Обновить» (или `./update.sh`). Если по какой-то причине не помогло — как временный обходной путь можно прибить IPv4-адрес Telegram в `/etc/hosts`: `149.154.167.220 api.telegram.org`.

2. **Контейнер не запущен.**
   ```bash
   docker ps
   ```
   Если в списке пусто — посмотрите причину падения (`docker compose logs --tail=50`) и поднимите заново: `docker compose up -d`.

3. **Бот добавлен в группу без нужных прав.** Он должен быть в группе администратором **с правом «Управление темами» (Manage Topics)** — без него бот не может создавать темы под MAX-чаты. И `TARGET_TELEGRAM_GROUP` в `.env` должен быть id именно этой группы. Если прав не хватает, бот сам напишет об этом в группу.

4. **Не завершена авторизация MAX — самая частая причина, когда бот в группе есть, а переписки нет.** Проверьте логи:
   ```bash
   docker compose logs --tail=30
   ```
   Если нет строки `Resumed session for +…` — аккаунт не подключён. Авторизация делается прямо в боте: напишите ему **в личку** `/login` и введите номер MAX и код из SMS (см. [«Первая авторизация»](#первая-авторизация)).

5. **Установка встала на проверке связи.** `setup.sh` в начале проверяет доступность MAX и Telegram и падает с явной ошибкой, если один из серверов недоступен (файрвол хостинга или гео-блокировка). Если установка остановилась именно на этой проверке — дело в сети сервера. Перепроверить связь в любой момент: `./setup.sh` → пункт «Проверить связь».

6. **При входе в MAX: «Приложение устарело, пожалуйста, обновитесь».** MAX время от времени перестаёт пускать старые версии клиента, а мост представляется ему десктопным MAX. Сначала проверьте обновление моста: `/version` в группе → «Обновить» — исправление может быть уже выпущено. Если обновления нет — впишите актуальную версию сами, в `.env`:
   ```bash
   MAX_APP_VERSION=26.38.0
   MAX_BUILD_NUMBER=82021
   ```
   и пересоздайте контейнер: `docker compose up -d --force-recreate`. Текущие номера — в репозитории MAX для Linux: https://download.max.ru/linux/deb/dists/stable/main/binary-amd64/Packages. Первая строка `Version:` — это версия, а число перед `.deb` в строке `Filename:` (например, `MAX-26.38.0.82021.deb`) — номер сборки.

7. **Обновление не прошло на шаге «сборка образа».** Почти всегда на сервере кончилось место: образ с Chromium весит около 1,7 ГБ, и при сборке новый должен поместиться рядом со старым. Мост при этом остаётся на прежней версии и работает. Сначала просто нажмите «Обновить» ещё раз — тяжёлая часть уже собрана и повторно не скачивается. Не помогло — освободите место и повторите:
   ```bash
   docker builder prune -af   # кэш прошлых сборок
   docker image prune -f      # образы, оставшиеся от неудачных попыток
   df -h /                    # сколько свободно; для обновления нужно от 1,5 ГБ, для первой сборки — от 3 ГБ
   ```
   На совсем маленьком диске помогает образ без Chromium: `./setup.sh` → «Переключить режим стикеров» → slim (анимированные стикеры тогда приходят статичной картинкой).

Не нашли причину — заводите [Issue](https://github.com/Trollobot/Telemax/issues) с выводом `docker compose logs --tail=50` (ключи/токены из `.env` не прикладывайте, а номер телефона MAX в логе — например в строке `Resumed session for +…` — замажьте).

## Обновление

Раз в сутки (в случайное время) бот сам проверяет на GitHub, не вышел ли новый **релиз** (тег версии новее текущей), и если да — присылает в группу сообщение с кнопками **«Обновить»** / **«Позже»**. То же самое можно спросить в любой момент командой `/version`. Проверка идёт по версии из `package.json` и тегам GitHub (semver), поэтому работает для любой сборки — в том числе собранной напрямую, без `GIT_COMMIT`.

Технически апдейт устроен так: сам контейнер с ботом ничего не обновляет и не перезапускает — у него нет и не будет доступа ни к докеру, ни к хосту (это осознанный выбор: код, который разбирает сообщения из MAX/Telegram, не должен иметь возможность управлять сервером). Вместо этого:

- Кнопка «Обновить» просто оставляет файл-маркер в `./data`.
- На хосте (не в контейнере) параллельно работает **systemd-таймер `telemax-updater`**, который ставит `setup.sh` — раз в минуту проверяет этот маркер, и если он есть, запускает `update.sh`: он скачивает свежий код, но переходит только на тег релиза с проверенной подписью (нет такого, есть локальные правки или git старше 2.34 — обновление отклоняется), затем пересборка образа → `docker compose up -d`; при сбое возвращает прежнюю версию.
- Таймер добавлен в автозапуск (`systemctl enable`), то есть переживает перезагрузку сервера.
- `update.sh` пишет в группу на каждом шаге: сразу — что начал, при ошибке (проверка подписи/сборка/рестарт/контейнер не поднялся) — что именно сломалось и что мост остался на прежней версии. После успешного перезапуска бот сам напишет, до какой версии обновился.

Проверить/поуправлять им можно как обычным systemd-юнитом:

```bash
systemctl status telemax-updater.timer   # включён ли, когда сработает в следующий раз
systemctl disable --now telemax-updater.timer   # выключить совсем — обновляться придётся вручную: ./update.sh
```

## Отказ от ответственности

Проект не аффилирован ни с MAX, ни с Telegram, ни с их правообладателями. Используя его, вы работаете со своим собственным аккаунтом MAX на свой страх и риск, в том числе в части соблюдения условий использования сервиса.

Переписка, которую бот пересылает, временно оседает на вашем собственном сервере: в логах контейнера, в персистентном хранилище (`./data`) и в истории самой Telegram-группы. Проект не несёт ответственности за сохранность, утечку или неправомерное использование этих данных — обеспечение их безопасности (доступ к серверу, шифрование диска, ротация логов и т.д.) целиком на вас.

## Лицензия

Код распространяется по лицензии **GNU AGPL-3.0** — полный текст в файле [LICENSE](LICENSE). Это open source.

Коротко, что это значит:

- **Ставить, использовать и менять под себя** — свободно, в том числе в бизнесе.
- **Открытость обязательна.** Если вы распространяете изменённую версию **или запускаете её как сервис для других** (в этом отличие AGPL от обычной GPL), вы обязаны открыть исходный код своих изменений под той же лицензией.
- **Хотите закрыть код?** Использовать Telemax без обязательств AGPL — в закрытом продукте или сервисе, не публикуя изменения — можно только по отдельной **коммерческой лицензии**. Пишите: zergont@gmail.com.
- **Имя «Telemax»** лицензией на код не передаётся: выпускать свой продукт или сервис под этим названием без согласия правообладателя нельзя.
- Программа поставляется **как есть, без каких-либо гарантий** — см. разделы 15–16 лицензии и «Отказ от ответственности» выше.

© 2026 Zergont · zergont@gmail.com

## Обратная связь

Нашли баг или есть вопрос — напишите боту [@TelemaxSvv_bot](https://t.me/TelemaxSvv_bot) прямо в Telegram (ответим там же) или заведите [Issue](https://github.com/Trollobot/Telemax/issues). Идеями и впечатлениями можно поделиться в [Discussions](https://github.com/Trollobot/Telemax/discussions).

## Поддержать проект

- Рублями: [pay.cloudtips.ru/p/3c71b5e8](https://pay.cloudtips.ru/p/3c71b5e8)
- GRAM (TON): `UQALpK2PKI90-XpupOM8sRJGdwrFMsPcwQZPR0k180umXBcA`

## Разработка

```bash
npm install
npm run dev       # мост в watch-режиме (tsx)
npm run lint      # проверка типов
npm test          # vitest
```

## Телеметрия

Чтобы понимать, сколько инстансов моста реально работает, раз в сутки бот отправляет **анонимный** пинг: случайный идентификатор установки (UUID, генерируется один раз и хранится в `./data/install-id`) и текущую версию. **Никаких** номеров телефонов, содержимого сообщений, IP или иных персональных данных не передаётся и не хранится — только «эта установка жива, версия такая-то».

### Анонимные отчёты об ошибках

Если что-то ломается, мост сам отправляет разработчику короткий **анонимный** отчёт — чтобы ошибку можно было исправить, не прося вас искать логи на сервере. Отчёт уходит в пяти случаях:

- `internal` — внутренняя ошибка моста (необработанное исключение или сбой обработчика Telegram);
- `session-rejected` — MAX окончательно отклонил сохранённую сессию (то же событие, что и сообщение «❌ MAX-сессия отклонена»);
- `restart-loop` — контейнер перезапустился три раза или больше за 10 минут;
- `fatal` — мост не смог запуститься;
- `update` — не удалось или было отклонено обновление (отправляет `update.sh`; в сообщении бота тогда есть строка «Анонимный отчёт отправлен разработчику»).

Что именно в отчёте — полный список полей:

| Поле | Содержимое |
| --- | --- |
| `installId` | тот же случайный идентификатор установки, что и в пинге |
| `version` | версия моста |
| `kind` | один из пяти видов выше |
| `step` | где произошла ошибка (шаг обновления или название обработчика) |
| `error` | первая строка текста ошибки, не длиннее 300 символов; токены, пароли прокси, текст в кавычках и длинные числа (номера, идентификаторы) перед отправкой вырезаются |
| `toVersion` | версия, на которую шло обновление (только `update`) |
| `freeMb`, `memMb` | свободное место на диске и свободная память, МБ |
| `os` | название и версия ОС |
| `docker`, `git` | версии Docker и git (только `update`) |
| `node` | версия Node.js (только отчёты моста) |

В отчёте **нет** содержимого сообщений, названий чатов, идентификаторов чатов и собеседников, номера телефона и ничего из `.env`. Сервер принимает отчёты только от установок, которые уже известны ему по ежедневному пингу, и хранит их в сведённом виде: «такая-то ошибка встретилась столько-то раз на таких-то версиях». Мост отправляет не больше пяти отчётов в сутки и не повторяет один и тот же чаще раза в шесть часов.

### Как отключить

Добавьте в `.env`:

```bash
TELEMETRY=off
```

и перезапустите контейнер (`docker compose up -d`). После этого не отправляется ничего: ни ежедневный пинг, ни отчёты об ошибках — в том числе при обновлении.