Руководство по восстановлению удаленных сообщений и медиаданных в Telegram
Ситуации, когда важные данные случайно удаляются, могут стать настоящей катастрофой. Особенно если это касается многолетней переписки или архива важных файлов. Однажды я столкнулся с этим сам: из-за невнимательности я удалил все сообщения и медиаданные из важной для меня группы в Telegram.
Меня зовут Дмитрий Гусев, я Frontend-разработчик в команде Bricks в кластере Architecture в Авито. И, как ни странно, сегодня речь пойдет не о рабочих задачах, а о личной истории, которая потребовала от меня такого же инженерного подхода и нестандартных решений, с какими приходится сталкиваться на работе.
На первый взгляд, все выглядело безнадежно. Telegram предоставляет возможность отменить удаление лишь в течение 5 секунд после действия. А если вы упустили этот момент — данные исчезают навсегда. Или почти навсегда?
В этой статье я расскажу, как удалось решить проблему, которая на первый взгляд казалась безвыходной. Вместе мы пройдем путь от осознания безысходности до практического применения найденного решения для восстановления потерянных данных.
Дисклеймер: Восстановление удаленных данных не работает для личных диалогов. Этот метод применим только для сообщений в группах и каналах Telegram.
Ошибка на миллион. Сообщений.
23 сентября 2024 года произошло страшное для меня и моих друзей событие: по случайности я полностью удалил все их сообщения совместно с медиа из нашей группы в телеграмме.
Насколько вы можете знать — все, что удаляется из телеграмма «для всех», можно восстановить только в течение 5 секунд по нажатии на кнопку «Undo». Данные удаляются безвозвратно.
Сказать, что это меня расстроило — ничего не сказать, я был в состоянии полной прострации. Наша группа существовала с лета 2021 года, количество медиафайлов (включая музыку, голосовые, кружки) превышало 20к элементов, количество текстовых сообщений (судя по итоговому JSON-дампу, о котором чуть позже) — более 350к.
go run panic.go
В панике я перерыл весь телеграм на наличие функционала восстановления, экспорта существующего диалога (такая возможность есть, но выгрузка произойдет только из существующих данных в кеше, что не является решением проблемы), но попытки были тщетны — информации ноль, да и возможностей тоже.
Гофер недоволен
Я просто [осел]. Я удалил [к чертовой матери] все ваши сообщения случайно. Что делать? Все осталось только в недавних действиях… Я сейчас [сойду с ума]. Щас я что-нибудь придумаю. Я вам дал полных админов, помогите. [Блин], я сейчас самоуничтожусь.
Recent actions
Надежду дала только вкладка «Recent actions».
Данная вкладка присутствует только в группах и каналах телеграма. Она показывает последние произошедшие за период 48 часов действия, например:
Вступление человека в канал.
Выход из канала.
Удаление сообщения другим пользователем, etc.
В целом, администраторы могут видеть абсолютно все события последних 48 часов, но есть важный нюанс: восстановлению они не подлежат.
Единственное, что можно сделать — это копировать текстовые сообщения (только по одному), а медиа вручную сохранять на устройство.
Поиски решения проблемы
Как минимум надежда уже была, в погоне за целью я взялся за research API «недавних действий», но, увы, особо полезной информации не было, помимо единственного на просторах всего Интернета Github Gist.
Изучив скрипт и все сопутствующие комментарии, я принялся за реализацию скрипта по восстановлению данных.
Главное требование к скрипту — выгрузка сообщений по MTProto.
Цитата автора оригинального скрипта:
There’s not telegram API method for this, we need to call MTProto methods to retrieve messages from the «Recent Actions» (Admin Log) since deleted messages (and medias) gets moved there for 48 hours before the permanent deletion.
Возможности найденного backup_script.py
Текстовые сообщения можно выгружаются в dump в виде JSON-структуры.
Медиафайлы сохраняются на локальное устройство, с которого скрипт запущен.
Из дампа текстовых сообщений впоследствии имеется возможность переслать все сообщения / медиа другим скриптом (например, resender.py) назад в группу или куда-либо еще.
Как вы понимаете, задача отнюдь не быстрая, а сообщения будут отправляться либо от вашего лица, либо ботом.
С медиа вопрос обстоит проще — после выгрузки их можно положить в облако и со спокойной душой жить дальше.
Доработки скрипта
Запустив скрипт, оказалось, что он полурабочий, и в него необходимо вносить правки.
По итогу для восстановления сообщений можно выделить такие ключевые FR как:
Интеграция библиотеки Telethon, обеспечивающая взаимодействие с Telegram API через MTProto.
Экспорт сообщений в
dump.json
:Возможность выбрать режим экспорта: только текст, только медиа или все сообщения.
Фильтрация сообщений по
min_id
иmax_id
.
Сохранение медиафайлов на локальное устройство, привязанных к соответствующим сообщениям.
Обработка удаленных сообщений через Admin Log (iter_admin_log), включая текст и медиа.
Опциональные FR:
Создание дополнительного скрипта resender для автоматической пересылки выгруженных сообщений и медиа:
Скрипт может использовать данные из
dump.json
и выгруженные медиа для восстановления всей переписки или её части.Пересылка осуществляется в исходную группу, другую группу или личный чат.
Возможность настройки, например, отправки сообщений от имени пользователя или бота.
Для реализации описанных требований была использована библиотека Telethon, которая значительно упрощает работу с Telegram API. Telethon — это мощный инструмент для взаимодействия с Telegram, предоставляющий такие возможности как:
Отправлять и получать сообщения.
Выгружать историю чатов.
Работать с медиа.
Управлять аккаунтами и ботами.
Мониторить события.
Успешно приведя скрипт в порядок, по договору с друзьями было решено выгрузить только все медиафайлы нашей группы, ибо оставшихся 30 часов бы не хватило на дамп всей истории текстовых сообщений нашего диалога.
Скрипт отработал за ±8 часов, выгрузив абсолютно все данные за период с июля 21 года по сентябрь 24. Задача была решена!
Резюмируя
Будьте внимательны и бдительны во избежание моей ситуации, а если все-таки столкнетесь, — документация по использованию утилиты вам в помощь (см. главу «Документация по использованию утилиты tg-message-lifeguard»).
Цитата автора усовершенствованного скрипта:
Да, естественно, скрипт можно улучшить, переписать его на условный go, запустить в несколько потоков на виртуальной машине для ускорения выгрузки и т.д., но это уже будет вашей домашкой, можете контрибьютить в мой репозиторий.
Документация по использованию утилиты tg-message-lifeguard
Установка Python3 для чайников
Если вы обладатель MacOS, первым делом устанавливаем Homebrew.
По установке Python3 на MacOS через Homebrew есть прекрасная статья.
Если вы пользуетесь Windows или Linux, идем сюда.
Далее ставим любой редактор кода или IDE, рекомендую использовать vscode. Не забываем установить плагин Python для IDE.
Устанавливаем Git и клонируем проект.
Непосредственно к восстановлению
[желательно] Установка и настройка виртуального окружения (venv)
venv — это изолированная среда для Python-проектов. Она позволяет устанавливать библиотеки и зависимости, не влияя на глобальную установку Python на вашем устройстве.
Это особенно важно, если вам нужно работать с несколькими проектами, каждый из которых требует разные версии библиотек.
Как создать виртуальное окружение?
Открываем терминал
bash
/zsh
(сделать это можно прямо внутри vscode).Создаем виртуальное окружение:
$ python3 -m venv venv
Здесь venv — это имя директории, которая будет содержать ваше виртуальное окружение. Вы можете выбрать любое имя для этой папки.
$ source venv/bin/activate
На Windows:
$ .\venv\Scripts\activate
После активации виртуального окружения в командной строке появится название окружения в скобках, например,
(venv)
. Это значит, что вы работаете в изолированном окружении, и любые установленные библиотеки не повлияют на систему.
После завершения работы с проектом деактивируем venv:
$ deactivate
Установка зависимостей для проекта
Для установки библиотек желательно, чтобы виртуальное окружение было активировано.
$ pip3 install -r requirements.txt
Теперь, когда у вас установлены все зависимости, вы можете запускать Python-скрипты.
Как использовать backup модуль для восстановления данных
Перед непосредственным началом работы над восстановлением надо узнать свои api_id
, api_hash
и group_chat_id
.
A. Чтобы узнать свои api_id
, api_hash
:
Переходим на сайт и авторизуемся.
Указываем номер телефона в формате `+XXXXXXXXXXXX`.
Подтверждаем аутентификацию кодом 2FA.
Кликаем по `API development tools`.
На открывшейся странице вы найдете
api_id
,api_hash
.
B. Получаем group_chat_id
и / или channel_id
, следуя инструкции.
Сохраните эти значения, они понадобятся для восстановления данных.
Приступаем к восстановлению
Запускаем модуль backup:
$ python3 -m src.backup
При запуске скрипта вам будет предложено ввести:
После нас ожидает важный шаг — авторизация.
$ Please enter your phone (or bot token):
Тут есть 2 варианта развития событий:
Авторизоваться через свой аккаунт: для этого укажите номер телефона и введите пароль, дальше введите код 2FA, который придет от TSN (Telegram Service Notifications).
[TL; DR: recommended, but restricted] Создать так называемого recover_bot’а и авторизоваться через его API Token. Для этого идем к @BotFather и регистрируем нового бота. После этого получаем API Token нашего помощника и вставляем в терминал.
P.S. К сожалению, на момент написания статьи, при выборе второго варианта скрипт будет падать с ошибкой:
telethon.errors.rpcerrorlist.BotMethodInvalidError: The API access for bot users is restricted. The method you tried to invoke cannot be executed as a bot (caused by GetAdminLogRequest)
На данный момент метод не может использоваться с bot API, поэтому придется авторизироваться как пользователь.
Режимы экспорта
Далее выбираем режим для выгрузки данных:
Выгрузка всех сообщений и медиа.
Выгрузка только медиафайлов.
Выгрузка только текстовых сообщений.
Вводим необходимый.
Далее указываем ID минимального и максимального сообщения — это диапазон от первого сообщения в чате до последнего.
Минимальный ID сообщения: 0 — начинаем с самого первого сообщения в диалоге.
Максимальный ID сообщения: 0 — получаем все сообщения чата.
То есть, если указываем min_message_id = 23456, max_message_id = 25673, то восстанавливается указанный диапазон — от сообщения с ID23456 до сообщения с ID 25673.
Медиафайлы и dump.json
выгружаются в папку backup_will_be_inside_me
, она будет автоматически создана в рабочей директории на этапе восстановления.
Очень важное замечание: каждый выгруженный медиафайл будет иметь имя файла, соответствующее ID сообщения (ID текстового сообщения можно посмотреть в dump.json
).
Это может быть очень полезно, если на каком-то этапе скрипт завершил работу, и вам придется все начинать сначала. Тут на помощь придет знание ID последнего выгруженного медиафайла / текстового сообщения: перезапустив скрипт, укажите min_message_id равный id медиафайла. Таким образом, скрипт продолжит выгрузку, начав с указанного ID.
После запуска остается только ждать и следить за консолью.
По моему опыту рекомендую установить данный плагин (MacOS) и оставить ваше устройство заниматься реабилитацией ваших сообщений.
Заключение
Подводя итоги, если у вас появятся какие-то вопросы, на которые тут не были даны / неполно раскрыты ответы — буду рад разобрать их в комментариях к статье. Также можете написать мне напрямую.
Если есть идеи по улучшению проекта — добро пожаловать в контрибьют!
Нашли баг — пожалуйста, заведите issue.
Спасибо за уделенное время. Надеюсь, вы никогда не столкнетесь с подобной проблемой, но если это случится, теперь вы знаете, что делать.