@@ -1,122 +1,48 @@
|
||||
# max2telegram
|
||||
|
||||
Мост для пересылки сообщений из Max в Telegram.
|
||||
Асинхронный мост для двусторонней синхронизации переписки между мессенджером **MAX** и **Telegram** (форум-канал с топиками).
|
||||
|
||||
## Что умеет
|
||||
## Архитектура
|
||||
|
||||
- Слушает входящие сообщения в Max через `PyMax`.
|
||||
- Пересылает в Telegram:
|
||||
- текст;
|
||||
- фото;
|
||||
- видео.
|
||||
- Для нескольких вложений отправляет единым альбомом (`sendMediaGroup`).
|
||||
- В тексте указывает источник в формате: `MAX: <ник> / <название чата>`.
|
||||
- Защищает от дублей через SQLite (`forwarded_messages`).
|
||||
Приложение построено по слоям:
|
||||
|
||||
## Логика выбора чата в Telegram
|
||||
| Слой | Назначение |
|
||||
|------|------------|
|
||||
| `max_layer` | WebSocket-клиент MAX (PyMAX WebClient), listener и worker |
|
||||
| `telegram_layer` | Aiogram dispatcher, TG worker, admin-команды |
|
||||
| `router` | Маршрутизация по ID, дедупликация, постановка в очереди |
|
||||
| `queue` | Redis-очереди `max2tg_queue` и `tg2max_queue` |
|
||||
| `storage` | SQLite: маппинги, маркеры, связи сообщений |
|
||||
|
||||
1. Берется название чата из Max.
|
||||
2. Если для этого Max-чата есть явная привязка (см. `/bind_max` ниже), сообщение отправляется в привязанный Telegram-чат.
|
||||
3. Иначе: если у бота найден Telegram-чат с таким же названием, сообщение отправляется туда.
|
||||
4. Если совпадения нет, сообщение уходит в личку на `TELEGRAM_FALLBACK_USER_ID`.
|
||||
## Быстрый старт
|
||||
|
||||
## Важно про поиск чатов
|
||||
1. Скопируйте `.env.example` в `.env` и заполните переменные.
|
||||
2. Создайте папку `data/` (монтируется для SQLite и сессии PyMAX).
|
||||
3. Запустите:
|
||||
|
||||
Поиск чатов по названию выполняется через `getUpdates`, поэтому:
|
||||
|
||||
- бот должен быть добавлен в нужные Telegram-чаты;
|
||||
- в этих чатах должен быть хотя бы один апдейт (сообщение/событие), чтобы чат появился в апдейтах;
|
||||
- если у бота включен privacy mode, он может не получать обычные сообщения из групп — тогда чат может не “обнаружиться” через `getUpdates`.
|
||||
|
||||
### Привязка Max-чата к Telegram-чату (рекомендуется)
|
||||
|
||||
Чтобы не зависеть от `getUpdates` и privacy mode, можно один раз “забиндить” нужный Telegram-чат на название чата в Max.
|
||||
|
||||
В целевом Telegram-чате напиши команду:
|
||||
|
||||
- `/bind_max <точное название чата в Max>`
|
||||
|
||||
Пример:
|
||||
|
||||
- `/bind_max Свободный микрофон`
|
||||
|
||||
После этого пересылка **из Max в Telegram** для чата `Свободный микрофон` будет идти строго в этот Telegram-чат (привязка хранится в SQLite).
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
Используется файл `.env` в корне проекта.
|
||||
См. `tech-specs.md`, раздел 6, и `.env.example`.
|
||||
|
||||
Пример смотри в `.env.sample`.
|
||||
## Команды (только FALLBACK_USER_ID в ЛС с ботом)
|
||||
|
||||
Обязательные переменные:
|
||||
- `/start` — статус подключения
|
||||
- `/help` — справка
|
||||
- `/list` — список маппингов
|
||||
- `/join <ссылка>` — вступить в MAX-группу
|
||||
- `/leave <id или название>` — выйти из MAX-чата
|
||||
- `/last_messages <id или название>` — последние 10 сообщений
|
||||
|
||||
- `MAX_PHONE` - номер телефона аккаунта Max;
|
||||
- `MAX_WORK_DIR` - директория сессии Max (обычно `cache`);
|
||||
- `TELEGRAM_BOT_TOKEN` - токен Telegram-бота;
|
||||
- `TELEGRAM_FALLBACK_USER_ID` - id пользователя Telegram для fallback отправки;
|
||||
- `SQLITE_PATH` - путь к SQLite базе (рекомендуется `cache/max2telegram.db`, по умолчанию так и будет).
|
||||
## Локальная разработка
|
||||
|
||||
Дополнительно:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
export $(cat .env | xargs) # Linux/macOS
|
||||
python -m app.main
|
||||
```
|
||||
|
||||
- `TZ` - таймзона контейнера;
|
||||
- `PYTHONUNBUFFERED` - режим буферизации вывода Python.
|
||||
|
||||
## Быстрый старт (Docker)
|
||||
|
||||
1. Скопировать шаблон:
|
||||
- `copy .env.sample .env` (Windows)
|
||||
2. Заполнить `.env` своими значениями.
|
||||
3. Пройти аутентификацию Max (см. ниже).
|
||||
4. Запустить:
|
||||
- `docker compose up -d --build`
|
||||
5. Логи:
|
||||
- `docker compose logs -f`
|
||||
|
||||
## Аутентификация Max
|
||||
|
||||
Перед запуском приложения необходимо пройти аутентификацию Max, чтобы создать сессионный файл.
|
||||
|
||||
### Локально (без Docker)
|
||||
|
||||
1. Убедиться, что `.env` заполнен, особенно `MAX_PHONE`.
|
||||
2. Запустить скрипт аутентификации:
|
||||
- `python auth.py`
|
||||
3. Следовать инструкциям в консоли (ввод кода подтверждения и т.д.).
|
||||
4. После успешной аутентификации сессионный файл сохранится в директории `MAX_WORK_DIR` (по умолчанию `cache`).
|
||||
|
||||
### В Docker
|
||||
|
||||
1. Запустить контейнер с интерактивной сессией:
|
||||
- `docker compose run --rm max2telegram python auth.py`
|
||||
2. Следовать инструкциям в консоли.
|
||||
3. После завершения запустить основное приложение:
|
||||
- `docker compose up -d`
|
||||
|
||||
## Запуск локально (без Docker)
|
||||
|
||||
1. Установить зависимости:
|
||||
- `pip install -r src/requirements.txt`
|
||||
2. Создать `.env` на основе `.env.sample`.
|
||||
3. Пройти аутентификацию Max:
|
||||
- `python auth.py`
|
||||
4. Запустить приложение:
|
||||
- `python src/main.py`
|
||||
|
||||
## Структура проекта
|
||||
|
||||
- `auth.py` - скрипт аутентификации Max (создание сессии).
|
||||
- `src/main.py` - точка входа, инициализация клиентов.
|
||||
- `src/bridge.py` - основная логика маршрутизации и отправки.
|
||||
- `src/telegram_api.py` - Telegram Bot API клиент.
|
||||
- `src/max_parser.py` - разбор входящих сообщений Max.
|
||||
- `src/storage.py` - SQLite слой для дедупликации.
|
||||
- `src/config.py` - загрузка конфигурации из окружения.
|
||||
|
||||
## Типичные проблемы
|
||||
|
||||
- Фото/видео не приходят:
|
||||
- проверь, что бот имеет доступ к целевому чату;
|
||||
- проверь валидность URL вложений и токена бота.
|
||||
- Сообщения идут только в fallback:
|
||||
- бот еще не видел апдейты из нужного чата;
|
||||
- название чата в Max и Telegram не совпадает.
|
||||
Redis должен быть доступен по `REDIS_URL`.
|
||||
|
||||
Reference in New Issue
Block a user