🔍 Зачем мигрировать из Telegram в MAX?
MAX — новый российский мессенджер с поддержкой до 4 ГБ файлов, шифрованием и интеграцией с экосистемой. Если вы ведёте технические каналы, архивы проектов или просто хотите сохранить историю переписки — миграция станет отличным решением.
Что мы перенесём:
✅ Текстовые сообщения с форматированием
✅ Ссылки, код, цитаты
✅ Фотографии (PNG, JPG, GIF, WebP)
✅ Видео (MP4, AVI, MOV, MKV)
✅ Файлы любого типа (до 4 ГБ)
✅ Даты, авторы, реакции
🗝️ Ключевое звено: библиотека PyMax
PyMax — неофициальная Python-библиотека для работы с внутренним API мессенджера MAX.
Почему именно PyMax?
Преимущество Описание
🔑 Авторизация по номеру Не нужен токен бота (работает для физлиц)
📦 Поддержка файлов Загрузка фото, видео, документов
⚡ Асинхронность Быстрая отправка без блокировок
🛠️ Гибкость Полный контроль над форматированием
⚠️ Важно: Библиотека неофициальная. Используйте на свой страх и риск. При обновлении протокола MAX скрипты могут потребовать доработки.
📋 Требования
Программное обеспечение
Python 3.10+ (проверено на 3.13)
pip для установки пакетов
Telegram Desktop для экспорта данных
Учётные записи
Аккаунт в MAX (подтверждённый номер телефона)
Доступ к исходному чату в Telegram
Структура проекта
E:\MAX\Migration\
├── migrate.py # Скрипт миграции
├── Telegram_Export_2026-04-26\ # Папка экспорта
│ ├── result.json # Данные чата
│ ├── files/ # Документы
│ ├── photos/ # Фотографии
│ └── video_files/ # Видео
└── max_session/ # Кэш авторизации (создаётся автоматически)
🚀 Пошаговая инструкция
Шаг 1: Экспорт данных из Telegram
1. Откройте Telegram Desktop
2. Перейдите в нужный чат/канал
3. Настройки → Продвинутые настройки → Экспорт данных
4. Выберите:
✅ Фотографии
✅ Видео
✅ Голосовые сообщения
✅ Файлы
📁 Формат: JSON (не HTML!)
4. Укажите папку для экспорта и нажмите Экспортировать
⏱ Время экспорта зависит от размера чата. Для 1000 сообщений с файлами — ~5-15 минут.
Шаг 2: Установка зависимостей
Откройте терминал (PowerShell или CMD, а лучше GIT BASH) и выполните:
- # Установка библиотеки прямо из репозитория
- pip install git+https://github.com/MaxApiTeam/PyMax.git
- # Проверка установки
- python -c "from pymax import MaxClient; print('✅ PyMax установлен')"
Шаг 3: Настройка скрипта миграции
(нижеприведённый код при вставке наверняка "поедет", поэтому файл migrate.py лежит в группе МАКС , ссылка в конце статьи)
Создайте файл migrate.py и вставьте код:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Миграция чата из Telegram в MAX через PyMax
"""
import asyncio
import json
import os
import time
import logging
from pathlib import Path
from datetime import timedelta
from pymax import MaxClient
from pymax.files import Photo, File, Video
# ==================== НАСТРОЙКИ ====================
PHONE = "+79XXXXXXXXXX" # Ваш номер в MAX
EXPORT_DIR = Path("E:/MAX/Telegram_Export") # Папка экспорта
TARGET_CHAT_NAME = "MyChannel" # Имя чата в MAX
MESSAGES_PER_RUN = 100 # Сообщений за запуск
DELAY_BETWEEN_MESSAGES = 2.0 # Пауза (сек)
PROGRESS_FILE = "migration_progress.json" # Файл прогресса
SESSION_DIR = "max_session" # Папка сессии
# ================================================
logging.basicConfig(level=logging.WARNING, format='%(levelname)s: %(message)s')
def load_progress():
if os.path.exists(PROGRESS_FILE):
with open(PROGRESS_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
return {'sent': 0, 'total': 0}
def save_progress(sent, total):
with open(PROGRESS_FILE, 'w', encoding='utf-8') as f:
json.dump({'sent': sent, 'total': total}, f)
def format_text_with_entities(msg):
"""Форматирование текста с учётом сущностей (ссылки, код, жирный)"""
text = msg.get('text', '')
entities = msg.get('text_entities', [])
if isinstance(text, list):
parts = []
for item in text:
if isinstance(item, str):
parts.append(item)
elif isinstance(item, dict):
etype = item.get('type', 'plain')
etext = item.get('text', '')
if etype == 'link':
url = item.get('url', etext)
parts.append(f"{etext} ({url})")
elif etype == 'pre':
lang = item.get('language', '')
parts.append(f"\n```{lang}\n{etext}\n```")
elif etype == 'bold':
parts.append(f"*{etext}*")
elif etype == 'italic':
parts.append(f"_{etext}_")
elif etype == 'code':
parts.append(f"`{etext}`")
else:
parts.append(etext)
text = ''.join(parts)
for entity in entities:
if isinstance(entity, dict) and entity.get('type') == 'link' and entity.get('url'):
if entity['url'] not in text:
text += f"\n🔗 {entity['url']}"
return text.strip()
def get_attachments(msg, export_dir):
"""Определение типа вложения и создание объекта"""
attachments = []
# Фото из поля photo
if msg.get('photo'):
ref = msg['photo']
path = export_dir / ref if isinstance(ref, str) else None
if path and path.exists():
attachments.append(Photo(path=str(path)))
print(f" 📷 Фото: {path.name}")
# Видео из поля video_file
if msg.get('video_file'):
ref = msg['video_file']
path = export_dir / ref if isinstance(ref, str) else None
if path and path.exists():
attachments.append(Video(path=str(path)))
print(f" 🎬 Видео: {path.name}")
# Файлы с автоопределением типа
if msg.get('file'):
ref = msg['file']
mime = msg.get('mime_type', '')
path = export_dir / ref if isinstance(ref, str) else None
if path and path.exists():
# Видео форматы
video_exts = {'.mp4', '.avi', '.mov', '.mkv', '.webm', '.wmv'}
video_mimes = {'video/mp4', 'video/avi', 'video/quicktime'}
# Изображения (поддерживаемые как Photo в MAX)
photo_exts = {'.png', '.jpg', '.jpeg', '.gif', '.webp'}
photo_mimes = {'image/png', 'image/jpeg', 'image/gif'}
if mime.lower().startswith('video/') or path.suffix.lower() in video_exts:
attachments.append(Video(path=str(path)))
print(f" 🎬 Видео: {path.name}")
elif mime.lower() in photo_mimes or path.suffix.lower() in photo_exts:
attachments.append(Photo(path=str(path)))
print(f" 📷 Фото: {path.name}")
else:
attachments.append(File(path=str(path)))
print(f" 📄 Файл: {path.name}")
return attachments
def get_chats_list(client):
"""Получение списка чатов из клиента"""
for attr in ['chats', 'dialogs']:
if hasattr(client, attr) and getattr(client, attr):
val = getattr(client, attr)
if isinstance(val, dict):
return list(val.values())
elif hasattr(val, '__iter__') and not isinstance(val, str):
try:
return list(val)
except:
pass
return None
async def main():
print("\n📤 МИГРАЦИЯ TELEGRAM → MAX\n" + "="*50)
# Загрузка сообщений
json_file = EXPORT_DIR / "result.json"
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
messages = [m for m in data.get('messages', []) if m.get('type') == 'message']
total = len(messages)
print(f"✅ Загружено {total} сообщений")
# Прогресс
progress = load_progress()
start = progress.get('sent', 0)
if start >= total:
print("✅ Всё уже отправлено!")
return
# Подключение к MAX
client = MaxClient(phone=PHONE, work_dir=SESSION_DIR, reconnect=True)
task = asyncio.create_task(client.start())
# Ожидание авторизации
for _ in range(120):
if hasattr(client, 'me') and client.me:
break
await asyncio.sleep(1)
else:
print("❌ Таймаут авторизации")
return
print(f"✅ Авторизован: {client.me.names[0].name}")
# Поиск целевого чата
chats = get_chats_list(client)
target = next((c for c in chats if TARGET_CHAT_NAME.lower() in (getattr(c, 'title', '') or '').lower()), chats[0] if chats else None)
if not target:
print("❌ Чат не найден")
return
chat_id = getattr(target, 'id', getattr(target, 'cid', None))
print(f"📤 Чат: {getattr(target, 'title')} (ID: {chat_id})")
# Отправка
end = min(start + MESSAGES_PER_RUN, total)
batch_start = time.time()
for i in range(start, end):
msg = messages[i]
text = f"[{msg.get('date','')[:19].replace('T',' ')}] {msg.get('from','')}:\n{format_text_with_entities(msg)}"
attachments = get_attachments(msg, EXPORT_DIR)
# Обработка лимитов
for retry in range(5):
try:
await client.send_message(chat_id=chat_id, text=text, attachments=attachments if attachments else None)
break
except Exception as e:
if "too.many.requests" in str(e):
await asyncio.sleep(2 ** retry)
else:
print(f"⚠️ {e}")
break
progress['sent'] = i + 1
save_progress(progress['sent'], total)
if (i + 1) % 10 == 0:
elapsed = time.time() - batch_start
eta = timedelta(seconds=int((total - i - 1) * DELAY_BETWEEN_MESSAGES))
print(f"📊 {i+1}/{total} | ETA: {eta}")
await asyncio.sleep(DELAY_BETWEEN_MESSAGES)
# Завершение
await client.close()
task.cancel()
print(f"\n🎉 Готово! Отправлено: {progress['sent']}/{total}")
if __name__ == "__main__":
asyncio.run(main())
```
Примечание 1 : вышеприведённый код при вставке наверняка "поедет", поэтому файл migrate.py лежит в группе МАКС , ссылка в конце статьи)
Примечание 2 : структура файлов экспорта чата группы и канала может различаться, обсуждение в группе МАКС , ссылка в конце статьи
Шаг 4: Настройка параметров
Откройте migrate.py и отредактируйте блок настроек:
- PHONE = "+79XXXXXXXXXX" # ← Ваш номер в международном формате
- EXPORT_DIR = Path("E:/MAX/Telegram_Export") # ← Путь к папке экспорта
- TARGET_CHAT_NAME = "MyChannel" # ← Имя чата в MAX (создайте его заранее!)
- MESSAGES_PER_RUN = 100 # ← Начните с 100, потом увеличивайте
- DELAY_BETWEEN_MESSAGES = 2.0 # ← Пауза между сообщениями
💡 Совет: Начните с малых значений (MESSAGES_PER_RUN=20), чтобы протестировать. После успешного теста увеличьте до 100-300.
Шаг 5: Запуск миграции
- # Перейдите в папку со скриптом
- cd E:\MAX\Migration
- # Запустите миграцию
- python migrate.py
Что вы увидите в консоли:
📤 МИГРАЦИЯ TELEGRAM → MAX
==================================================
✅ Загружено 1154 сообщений
✅ Авторизован: Андрей
📤 Чат: MyChannel (ID: -123456789)
🚀 Отправка 100 сообщений...
📷 Фото: screenshot.png
✅ 1/1154 — текст + 1 влож. (0.3 MB, 2.1с)
✅ 2/1154 — текст
🎬 Видео: demo.mp4
✅ 3/1154 — текст + 1 влож. (15.2 MB, 8.4с)
📊 10/1154 | ETA: 0:03:45
...
🎉 Готово! Отправлено: 100/1154
Шаг 6: Продолжение после перерыва
Скрипт автоматически сохраняет прогресс в файл migration_progress.json. Чтобы продолжить:
# Просто запустите снова — скрипт продолжит с места остановки
python migrate.py
Для полного перезапуска удалите файл прогресса:
del migration_progress.json
python migrate.py
⚠️ Важные ограничения и советы
🔒 Лимиты сервера MAX
- Скорость: Не более ~30 сообщений/секунду
- Размер файла: До 4 ГБ (но большие файлы загружаются дольше)
- Паузы: При ошибке RateLimitError скрипт автоматически ждёт
📁 Поддерживаемые форматы
Тип Форматы Как отправляется
🖼️ Фото PNG, JPG, JPEG, GIF, WebP Как изображение с превью
🎬 Видео MP4, AVI, MOV, MKV, WebM Как видео с превью
📄 Файлы Любые (PDF, ZIP, DOC, BMP, etc.) Как файл для скачивания
⚠️ BMP-файлы отправляются как обычные файлы (MAX не поддерживает BMP как изображения).
🔄 Если что-то пошло не так
Проблема Решение
❌ Таймаут авторизации Проверьте интернет, откройте приложение MAX на телефоне
❌ Файл не найден Убедитесь, что папки files/, photos/ существуют
❌ Чат не найден Создайте чат в MAX с точным именем из TARGET_CHAT_NAME
❌ Ошибка RateLimitError Увеличьте DELAY_BETWEEN_MESSAGES до 3-5 секунд
❌ Прервалось соединение Просто запустите скрипт снова — он продолжит с места остановки
🎯 Продвинутые настройки
Ускорение миграции
- MESSAGES_PER_RUN = 300 # Больше сообщений за запуск
- DELAY_BETWEEN_MESSAGES = 1.0 # Меньше пауза (рискованно)
- ⚠️ Не ставьте DELAY_BETWEEN_MESSAGES < 1.0 — высокий риск блокировки.
Отладка
logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s')
🏁 Заключение
Миграция чатов из Telegram в MAX — теперь реальность благодаря библиотеке PyMax.
Что мы получили:
✅ Полностью автоматизированный процесс
✅ Сохранение форматирования, ссылок, кода
✅ Корректная загрузка фото, видео, файлов
✅ Обработка ошибок и продолжение после сбоев
✅ Работа для физических лиц (без токена бота)
Дальнейшие шаги:
🔄 Адаптируйте скрипт под ваши нужды
📦 Добавьте обработку голосовых сообщений (если нужно)
🎨 Улучшите форматирование под стиль вашего канала
🤝 Поделитесь опытом в комментариях!
💬 Есть вопросы? Пишите в комментариях — помогу настроить миграцию под ваш случай!
🔗 Ссылки:
PyMax на GitHub https://github.com/MaxApiTeam/PyMax
Обсуждение этой темы - группа в MAX https://max.ru/join/lenkF9BQ8jNiorA10ehPAiFSdd3FmGdAES73mxPMK_Y
Экспорт данных в Telegram https://telegram.org/export?spm=a2ty_o01.29997173.0.0.68e455fbTf7bIw
Статья актуальна на апрель 2026. Протоколы мессенджеров могут меняться — следите за обновлениями библиотеки PyMax.