Скрипт del_message_v3.py - это инструмент для поиска и удаления электронных писем в почтовых ящиках Yandex 360. Скрипт предоставляет комплексное решение для управления сообщениями с использованием API Yandex 360 и IMAP протокола.
Поиск сообщений и их удаление происходит как обычных, так и общих почтовых ящиках.
Подключение к ящику может двумя способами - от имени делегированной учётной записи, параметры которой заданы в конфигурационном файле или через временный токен, полученный с помощью сервисного приложения.
- 🔍 Поиск сообщений по Message-ID - точный поиск конкретного сообщения
- 📊 Автоматический поиск почтовых ящиков - через логи аудита Yandex 360
- 🔍 Поиск и удаление писем как в пользовательских почтовых ящиках, так и в общих
- 🗑️ Удаление сообщений из множества ящиков - параллельная обработка
- 💾 Checkpoint система - сохранение и восстановление состояния почтовых ящиков
- 🔐 Работа с делегированными ящиками - временное назначение прав доступа
- 🧪 Режим dry-run - тестирование без фактического удаления
- 📋 Детальные отчеты - полная информация о результатах обработки
- ⚡ Многопоточность - быстрая обработка множества почтовых ящиков
- 🎯 Интерактивное меню - удобный интерфейс командной строки
После завершения работы скрипт автоматически выводит детальный отчет, содержащий:
- ✅ Было ли найдено сообщение в каждом почтовом ящике
- 📁 В каких папках найдено сообщение (например: "INBOX", "Sent", "Archive")
- 🗑️ Статус удаления (успешно удалено / ошибка / не найдено)
- 📊 Итоговая статистика по всем обработанным ящикам
====================================================================================================
ФИНАЛЬНЫЙ ОТЧЕТ О ПОИСКЕ И УДАЛЕНИИ СООБЩЕНИЯ
====================================================================================================
Искомое сообщение: <example@mail.com>
✓ СООБЩЕНИЕ НАЙДЕНО И ОБРАБОТАНО:
Почтовый ящик: user1@example.ru
Папки: INBOX, Sent
Статус: Успешно удалено
Почтовый ящик: user2@example.ru
Папки: Archive
Статус: Успешно удалено
Сообщение НЕ найдено в следующих ящиках:
- user3@example.ru
----------------------------------------------------------------------------------------------------
ИТОГОВАЯ СТАТИСТИКА:
Всего почтовых ящиков для проверки: 3
Сообщение найдено в ящиках: 2
Сообщение не найдено в ящиках: 1
Пропущено ящиков: 0
Ошибок при обработке: 0
====================================================================================================
Также программа создаёт отдельный лог с указанием сообщения, ящика и успешности удаления сообщения в соответствующем ящике.
Warning
Использовавание логов аудита для поисков почтовых ящиков (опиция меню "8 - Delete messages using audit log") доступна только на некоторых тарифах (где включены логи аудита). В остальных случаях пользуйтесь опицей удаления без поиска в логах аудита (опиця 9).
Максимальное время поиска событий в логах аудита (если они включены) - 190 дней.
Если логи аудита доступны для вашего тарифа, вы должны увидеть их в этом разделе администрирования. Если они доступны и не активированы, вы должны их активировать.
Скрипт использует следующие переменные окружения, которые можно задать в файле .env в каталоге скрипта или непосредственно в окружении:
| Имя параметра | Описание | Обязательный | Пример значения |
|---|---|---|---|
OAUTH_TOKEN_ARG |
OAuth-токен для аутентификации в API Yandex 360. | Да | y0_AgAAAA... |
ORGANIZATION_ID_ARG |
Идентификатор организации в Yandex 360 (целочисленный). | Да | 123456 |
APPLICATION_CLIENT_ID_ARG |
ID сервисного приложения | Нет (наличие зависит от параметра RUN_MODE) |
``y0_AgAAAA..` |
APPLICATION_CLIENT_SECRET_ARG |
Секрет сервисного приложения | Нет (наличие зависит от параметра RUN_MODE) |
``y0_AgAAAA..` |
DELEGATE_ALIAS |
Логин делегата (без домена) для доступа к делегированным ящикам. | Нет (наличие зависит от параметра RUN_MODE) |
i.petrov |
DELEGATE_DOMAIN |
Домен организации для формирования email делегата. | Нет (наличие зависит от параметра RUN_MODE) |
example.ru |
DELEGATE_PASSWORD |
Пароль приложения для доступа делегата к IMAP. | Нет (наличие зависит от параметра RUN_MODE) |
app_password_here |
CHECK_DIR |
Каталог для сохранения состояния почтовых ящиков (checkpoint файлы). | Нет (по умолчанию mailbox_checkpoints) |
mailbox_checkpoints |
DRY_RUN |
Режим "сухого прогона" (true для имитации удаления, false для реального). |
Нет (по умолчанию false) |
true или false |
MAILBOXES_LIST_FILE |
Имя файла со списокм почтовых ящиков для поиска сообщений | Нет (по умолчанию mailboxes.csv) |
mailboxes.csv |
MESSAGES_LIST_FILE |
Имя файла со списоком данных для поиска сообщений | Нет (по умолчанию message-ids.csv.csv) |
message-ids.csv |
REPORTS_DIR |
Каталог для создания файлов отчёта | Нет (по умолчанию reports) |
reports |
RUN_MODE |
Режим запуска скрипта | Да (delegate, service_application, hybrid) |
hybrid |
-
Переменные окружения: Все обязательные параметры (
OAUTH_TOKEN_ARG,ORGANIZATION_ID_ARG,RUN_MODE) должны быть заданы. При их отсутствии скрипт завершится с кодом1. -
Формат даты: Поддерживаются форматы
DD-MM-YYYY,DD.MM.YYYY,DD/MM/YYYY,YYYY-MM-DD,YYYY/MM/DD,MM/DD/YYYY,DD-MM-YY,YYYY.MM.DD, а также текстовые форматы на английском (например,25 December 2023). -
DRY_RUN: Если
DRY_RUN=true, скрипт только имитирует удаление, логируя действия без фактического изменения почтовых ящиков. -
Файл
.env: Пример файла.env:OAUTH_TOKEN_ARG=y0_AgAAAA... ORGANIZATION_ID_ARG=123456 APPLICATION_CLIENT_ID_ARG = f1e4386f276643 APPLICATION_CLIENT_SECRET_ARG = 333bf50d7a8 DELEGATE_ALIAS=i.petrov DELEGATE_DOMAIN=example.ru DELEGATE_PASSWORD=app_password_here CHECK_DIR=mailbox_checkpoints DRY_RUN=false MAILBOXES_LIST_FILE = mailboxes.csv MESSAGES_LIST_FILE = message-ids.csv REPORTS_DIR = reports RUN_MODE = hybrid
Скрипт может производить аутентификацию в IMAP почтовом ящике или через делегированную учетную запись, или через токены сервисного приложения. Скрипт может работать как с одним способом, так и с двумя сразу. Каждый способ имеет свои преимущества. Аутентфиикация через делегированную учётную запись позволяет:
- подключаться к Общим ящикам (недоступно для токенов сервисного приложения);
- подключаться к заблокированным ящикам (недоступно для токено сервисного приложения).
Однако недостатком работы с делегированным ящиком является медленная скрорость обработки (примерно в два раза медленнее, чем для токенов сервисного приложения, так как необходимо выполнять действия по добавлению и удалению делегата в каждый ящик для поиска и удаления сообщения).
Поэтому добавлен режим
hybrid, при котором необходимо иметь как настроенную учётную запись делегата (DELEGATE_ALIAS,DELEGATE_DOMAIN,DELEGATE_PASSWORD), так и корректно настроенное сервисное приложение (APPLICATION_CLIENT_ID_ARG,APPLICATION_CLIENT_SECRET_ARG).
Если вы владеете учётной записью владельца организации и вам важна скорость работы скрипта:
- создайте сервисное приложение, настройте его через скрипт;
- укажите учётку делегата (любая учётка в организации Я360, для которой возможно получить пароль приложения для IMAP протокола);
- пропишите параметры сервисного приложения и делегата в
.envи в RUN_MODE укажитеhybrid.
В тестовой среде работа через делегированную учётную запись удаляет сообщения со средней скоростью 3-4 секунды на один ящик. Работа через сервисное приложение - около 2 секунд на ящик.
Во всех остальных случаях укажите параметры делегата (например, свою учётку в Я360) и в RUN_MODE укажите delegate.
Для работы скрипта необходимо:
- Получить токен OAuth для чтения данных организации Яндекс 360 через API.
- Для работы приложения необходимо сгенериовать OAuth токен для аутентификации в API Яндекс 360. Токен должен содержать необходимые права для выполения операций управления ресурсами в организации Яндекс 360. Документация - Создание приложения. Последовательность шагов для создания токена:
-
заходим на https://oauth.yandex.ru/client/new/. Аутентифицируемся от имени администратора организации Яндекс 360.
-
Заполняем поля в форме создания приложения:
- Поле "Название вашего сервиса" - произвольное название.
- Включаем галочку "Веб сервисы"
- В поле
Redirect URLвводимhttps://oauth.yandex.ru/verification_code - В разделе "Почта для связи" указываем свой email.
-
Добавляем разрешения для токена. Для этого в разделе "Доступ к данным" ищем и добавляем следующие разрешения:
Имя разрешения Что можно делать directory:read_users читать информацию о пользователях ya360_security:audit_log_mail чтение событий аудит лога Почты ya360_admin:mail_read_shared_mailbox_inventory листинг делегирования ящика и чтение общих ящиков ya360_admin:mail_write_shared_mailbox_inventory управление делегированием почтовых ящиков (опционально) ya360_security:service_applications_read чтение сервисных приложений (для режима hybrid)(опционально) ya360_security:service_applications_write запись сервисных приложений (для режима hybrid)
-
нажимаем на кнопку "Создать приложение".
-
Свойства созданного приложения отображаются в новом окне "Мои приложения". Ищем раздел с идентификатором созданного приложения и копируем строку из поля "ClientID":
-
В текстовом редакторе созадем строку вида
https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор приложения>и вставляем в ней вместо<идентификатор приложения>скопированное значение ClientID из предыдущего пункта. Вставляем получившуюся ссылку в браузер и нажимаем "Enter".
-
Warning
Копируем токен и сохраняем в надёжном месте.
-
Получить ID организации в Яндекс 360. Для этого необходимо зайти в консоль администрирования и в левом нижнем углу интерфейса будет необходимый номер.
-
Записываем полученные на предыдущем шаге OAuth токен и Org ID в соответствующие переменные в файле файле
.envв том же каталоге, что и сами скрипты. Эта информация нужна для правильной аутентификации скриптов в API Яндекс 360.
Для работы скрипта через сервисное приложение (RUN_MODE = hybrid) необходимо наличие в правах основного токена прав:
- ya360_security:service_applications_read
- ya360_security:service_applications_wwrite
После этого необходимо создать ещё одно OAuth приложение, шаги по созданию аналогичны шагам создания основного приложения. Но при указании доступных разрешений нужно указать:
- mail:imap_full
После сохранения приложения нужно скопировать его Application ID и APPLICATION Secret, которые необходимо записать в соответствующие параметры в конфигурационном файле (APPLICATION_CLIENT_ID_ARG, APPLICATION_CLIENT_SECRET_ARG).
Warning
Для корректной настройки сервисного приложения токен основного приложения необходимо выписывать от имени учётки-владельца организации (в домене @yandex.ru).
При первом запуске скрипта необходимо перейти в пункт меню 4. Проверить/настроить сервисное приложение для удаления сообщений. и затем выбрать 2. Настроить сервисное приложение.. Это корректно настроит сервисное приложение для работы скрипта.
- Python: версия 3.9 или выше
- Операционная система: Linux, macOS, Windows
- Память: минимум 512 МБ RAM
- Сеть: доступ к
api360.yandex.net,oauth.yandex.ru,imap.yandex.ru - Права: права владельца организации Yandex 360 (для настройки)
# Проверьте версию Python
python3 --version
# Если Python не установлен или версия < 3.7:
# Ubuntu/Debian:
sudo apt update && sudo apt install python3 python3-pip
# macOS (с Homebrew):
brew install python3
# Клонируйте или скачайте репозиторий
cd /path/to/project
# Установите зависимости
pip3 install -r requirements.txt
# Или установите вручную:
pip3 install python-dotenv requests python-dateutil aioimaplib# Скачайте Python с python.org (версия 3.7+)
# Убедитесь, что установлен pip
# Откройте PowerShell или CMD в папке проекта
cd C:\path\to\project
# Установите зависимости
pip install -r requirements.txt
# Или установите вручную:
pip install python-dotenv requests python-dateutil aioimaplibСкрипт поддерживает различные сценарии работы в зависимости от ваших задач.
Задача: Удалить спам-рассылку, которая была отправлена всем сотрудникам организации 2 дня назад.
Последовательность действий:
-
Запустите скрипт:
python del_message_v3.py
-
В главном меню выберите
1(Enter search params manually) -
В меню параметров:
- Выберите
1- введите Message-ID:<spam123@badsite.com> - Выберите
2- введите дату:23-11-2024 - Выберите
8- Delete messages using audit log
- Выберите
-
Скрипт автоматически:
- Запросит логи аудита Yandex 360
- Определит все почтовые ящики, получившие сообщение
- Подключится к каждому ящику через IMAP
- Найдет и удалит сообщения
- Выведет детальный отчет
Результат: Сообщение будет удалено из всех почтовых ящиков, куда оно попало.
Задача: Удалить конфиденциальное сообщение из ящиков конкретных пользователей, отправленное 6 месяцев назад.
Последовательность действий:
-
Запустите скрипт с аргументами:
python del_message_v3.py
-
В главном меню выберите
1 -
В меню параметров:
- Выберите
1- введите Message-ID:<spam123@badsite.com>и через пробел дату "01.06.25" - Выберите
4- введите список ящиков:boss@company.ru, cfo@company.ru, ceo@company.ru - Выберите
9- Delete messages WITHOUT using audit log
- Выберите
-
Скрипт:
- Подключится к указанным ящикам
- Выполнит поиск по Message-ID и дате
- Удалит найденные сообщения
- Предоставит отчет о результатах
Примечание: Для сообщений старше 180 дней логи аудита недоступны, поэтому список ящиков нужно указывать вручную.
Задача: Удалить фишинговое сообщение из всех почтовых ящиков организации (1000+ пользователей).
Последовательность действий:
-
Запустите скрипт:
python del_message_v3.py
-
В главном меню выберите
1 -
В меню параметров:
- Выберите
1- введите Message-ID и дату:<phishing@evil.com> 24-11-2024 - Выберите
4- введите символ*для выбора всех пользователей - Выберите
9- Delete messages WITHOUT using audit log
- Выберите
-
Скрипт:
- Получит список всех пользователей из Yandex 360 API
- Обработает все ящики параллельно (до 5 потоков одновременно)
- Удалит сообщения везде, где они найдены
- Выведет сводный отчет
Преимущество: Параллельная обработка существенно ускоряет работу с большим количеством ящиков.
Задача: Проверить, в каких ящиках находится сообщение, без фактического удаления.
Последовательность действий:
-
Установите режим dry-run в файле
.env:DRY_RUN=true
-
Запустите скрипт и выполните обычную процедуру удаления (любой из сценариев выше)
-
Скрипт:
- Выполнит все действия (подключение, поиск)
- НЕ будет удалять сообщения
- Запишет в лог, что было бы удалено
- Выведет отчет о найденных сообщениях
-
После проверки результатов:
- Установите
DRY_RUN=false - Запустите скрипт снова для реального удаления
- Установите
Рекомендация: Всегда используйте dry-run перед массовым удалением!
Задача: Восстановить исходные права доступа к делегированным ящикам после сбоя.
Последовательность действий:
-
Запустите скрипт:
python del_message_v3.py
-
В главном меню выберите
2(Restore mailbox configuration from checkin file) -
Скрипт:
- Найдет последний checkpoint файл в каталоге
mailbox_checkpoints/ - Предложит выбрать файл (по умолчанию - последний)
- Отобразит информацию о сохраненных настройках
- Запросит подтверждение
- Найдет последний checkpoint файл в каталоге
-
После подтверждения:
- Восстановит настройки делегирования для всех ящиков из файла
- Выведет отчет о результатах восстановления
Checkpoint файлы создаются автоматически перед каждым изменением настроек делегирования.
Задача: Найти и удалить сообщение, если точная дата отправки неизвестна (известен только диапазон).
Последовательность действий:
-
Запустите скрипт:
python del_message_v3.py
-
В главном меню выберите
1 -
В меню параметров:
- Выберите
1- введите Message-ID:<unknown-date@site.com> - Выберите
2- введите примерную дату:20-11-2024 - Выберите
3- введите диапазон дней:5(будет искать ±5 дней от указанной даты) - Выберите
8или9- в зависимости от возраста сообщения
- Выберите
-
Скрипт:
- Выполнит поиск в диапазоне 15-25 ноября 2024
- Найдет сообщение даже если точная дата неизвестна
- Удалит все найденные копии
Примечание: Максимальный диапазон - 180 дней от указанной даты.
Скрипт позволяет определить список почтовых ящиков в файле MAILBOXES_LIST_FILE (по умолчанию mailboxes.csv) и список сообщений для поиска в этих ящиках в файле MESSAGES_LIST_FILE (по умолчанию message-ids.csv).
Формат MAILBOXES_LIST_FILE (по умолчанию mailboxes.csv) - первая строка должна содержать "email", в остальных - nickname пользователя (без домена), его email или uid.
Пример:
email
ivanov
petrov@domain.ru
12923487329847
Формат MESSAGES_LIST_FILE (по умолчанию message-ids.csv) - первая строка должна содержать "message-id;date;days_diff", дальше указываем параметры сообщения (его message-id, дату предполагаемого получения сообщения и количество дней поиска от предполагаемой даты получения сообщения.
Пример:
message-id;date;days_diff
003d01dc8466$641969f0$2c4c3dd0$@domain.ru;01.01.2026;1
003d01dc8466$641969f0$2c4c3dd1$@domain.ru;10.01.2026;3
003d01dc8466$641969f0$2c4c3dd2$@domain.ru;30.12.2025;5
Помимо информации о результатах работы в консоли скрипт сохраняет результаты каждого прогона в отдельном файле (с меткой времени) в каталоге REPORTS_DIR (значение по умолчанию - reports).
Для подключения к почтовым ящикам скрипт использует учётную запись делегата, которая указана в параметре DELEGATE_ALIAS для временного назначения этого пользователя в список доступа к целевому почтовому ящику. После чего выполняется подключение к целевому ящику от имени делегата, поиск и удаление соообщения и в финале восстановление статуса делегирования целевого почтового ящика к первоначальному состоянию.
Для хранения первоначального состояния каждого ящика скрипт использует файл checkin с меткой времени (каждый запуск удаления создаёт новый файл), в котором записывает необходимые данные. После выполнения удаления сообщения и восстановления первоначального состояния скрипт также записывает это действие в другой файл checkout. Если по каким-то причинам выполнение скрипта было прервано на этапе поиска и удаления сообщений в почтовом ящике (а скрипт выполняет операции асинхронно, и в каждый момент времени такая операция может происходить сразу с несколькими ящиками), то возможно возникновение ситуации, когда список делегирования каких-то ящиков не будет восстановлен до исходного состояния.
Чтобы избежать данной проблемы, скрипт при запуске анализирует последние по времени checkin и checkout файлы. Если в файле checkin будут найдены записи, которых нет в checkout файле, это значит, что исходное состояние соответствующих почтовых ящиков не было восстановлено. Поэтому скрипт предложит восстановить список делегатов и статус делегирования соответствующих почтовых ящиков. Пользователь лишь должен подтвердить запуск соответствующей процедуры.
-
Защита учетных данных:
- Никогда не храните
.envфайл в системе контроля версий - Используйте пароли приложений вместо основных паролей
- Регулярно ротируйте OAuth токены
- Ограничьте права доступа к
.envфайлу:chmod 600 .env
- Никогда не храните
-
Тестирование перед удалением:
- ВСЕГДА используйте
DRY_RUN=trueперед первым запуском - Проверьте отчет о найденных сообщениях
- Убедитесь, что список почтовых ящиков корректен
- Только после проверки запускайте реальное удаление
- ВСЕГДА используйте
-
Checkpoint файлы:
- Регулярно создавайте резервные копии каталога
mailbox_checkpoints/ - Не удаляйте checkpoint файлы сразу после операций
- Храните checkpoint файлы минимум 30 дней
- Регулярно создавайте резервные копии каталога
-
Оптимизация для больших организаций:
- При работе с >100 ящиками используйте опцию 9 (без audit log) с символом
* - Запускайте скрипт в периоды низкой нагрузки на сервер
- Мониторьте логи на предмет ошибок подключения
- При работе с >100 ящиками используйте опцию 9 (без audit log) с символом
-
Обработка старых сообщений:
- Для сообщений >180 дней всегда используйте опцию 9
- Заранее подготовьте список почтовых ящиков
- Разбивайте большие списки на части по 50-100 ящиков
-
Диапазон поиска:
- Минимизируйте диапазон дней для ускорения поиска
- Используйте точную дату, если она известна
- Увеличивайте диапазон только при необходимости
-
Анализ результатов:
- Всегда сохраняйте финальный отчет
- Проверяйте статистику ошибок
- Обращайте внимание на ящики, где сообщение не найдено
-
Логи:
- Изучайте
delete_messages.logпри возникновении проблем - Логи содержат
x-request-idдля обращения в поддержку Yandex - Регулярно очищайте старые backup файлы логов
- Изучайте
-
Ошибки подключения IMAP:
- Проверьте правильность
DELEGATE_PASSWORD(пароль приложения) - Убедитесь, что делегат существует в организации
- Проверьте формат домена в
DELEGATE_DOMAIN
- Проверьте правильность
-
Сообщение не найдено:
- Проверьте правильность Message-ID (угловые скобки
<>моугт быть пропущены, программа автоматически обрабатывает эту ситуацию) - Увеличьте диапазон дней поиска
- Убедитесь, что дата указана корректно
- Проверьте, что сообщение действительно находится в ящике
- Проверьте правильность Message-ID (угловые скобки
-
Ошибки API:
- Проверьте срок действия OAuth токена
- Убедитесь, что токен имеет необходимые права
- Проверьте
ORGANIZATION_ID_ARG
Рекомендуемая последовательность для критичных операций:
-
Подготовка:
# Установите dry-run режим echo "DRY_RUN=true" >> .env
-
Тестирование:
# Запустите скрипт в test режиме python del_message_v3.py --id "<test@example.com>" --date "25-11-2024"
-
Анализ:
- Изучите финальный отчет
- Проверьте логи на ошибки
- Убедитесь в корректности списка ящиков
-
Выполнение:
# Отключите dry-run sed -i '' 's/DRY_RUN=true/DRY_RUN=false/' .env # Запустите реальное удаление python del_message_v3.py --id "<test@example.com>" --date "25-11-2024"
-
Проверка:
- Сохраните финальный отчет
- Проверьте checkpoint файлы
- Сделайте запись в журнал операций
⚠️ Удаление необратимо! После выполнения EXPUNGE сообщения нельзя восстановить⚠️ Не прерывайте работу скрипта во время удаления - это может привести к несогласованности состояния⚠️ Проверьте настройки делегата перед массовыми операциями
- Консоль: Сообщения уровня INFO с временными метками (формат:
HH:MM:SS INFO: Сообщение). - Файл: Сообщения уровня DEBUG записываются в
delete_messages.log, ротация происходит при достижении 1 МБ (хранится 5 резервных копий). - Формат записей:
ГГГГ-ММ-ДД ЧЧ:ММ:СС.МСС УРОВЕНЬ: Сообщение - Содержимое логов:
- Все операции API с request-id
- Детали подключений IMAP
- Результаты поиска и удаления
- Ошибки с полным stack trace
- Ошибки конфигурации: Если отсутствуют обязательные переменные окружения или
ORGANIZATION_ID_ARGне является целым числом, скрипт завершается с кодом1. - Проверка делегата при запуске: При инициализации скрипт автоматически проверяет подключение к IMAP с учетными данными делегата. Если подключение неуспешно (неверный пароль, логин или домен), скрипт завершается с кодом
1и выводит подробное сообщение об ошибке. - Ошибки ввода: Неверные форматы даты или email-адреса отклоняются с сообщениями об ошибке.
- Ошибки API/IMAP: Ошибки запросов к API или подключения к IMAP логируются с подробностями (тип ошибки, строка кода).
- Ограничения: Поиск по логам аудита невозможен для сообщений старше 180 дней без вручную заданных почтовых ящиков.
- Минимальный возраст сообщения: Не более 20 лет от текущей даты
- Максимальный возраст для audit log: 180 дней (ограничение API Yandex 360)
- Даты из будущего: Автоматически отклоняются
-
Audit Log:
- Доступен только для событий за последние 180 дней
- Ограничение на количество записей в ответе: 100 записей на страницу
- Требует специальных прав OAuth токена
-
Yandex 360 API:
- Лимиты на количество запросов в секунду (rate limiting)
- Требуется токен владельца организации для сервисных приложений
-
IMAP:
- Максимум параллельных подключений: 5 (настраивается в
MAX_PARALLEL_THREADS) - Timeout подключения: настраивается индивидуально
- Требуется пароль приложения (basic authentication)
- Максимум параллельных подключений: 5 (настраивается в
-
Фильтрация событий:
- Обрабатываются только события типа
message_receive - Константы
FILTERED_EVENTSиFILTERED_MAILBOXESзахардкожены в коде - Изменение фильтров требует модификации исходного кода
- Обрабатываются только события типа
-
Поиск сообщений:
- Поиск выполняется только по Message-ID и дате
- Нет поиска по другим критериям (тема, отправитель и т.д.)
- Поиск во всех папках ящика (невозможно ограничить конкретной папкой)
-
Обработка ошибок:
- При ошибке подключения к одному ящику обработка продолжается для остальных
- Максимум 3 попытки повторного подключения при сбое
- Задержка между попытками: 2 секунды
- Права доступа:
- Делегат должен иметь необходимые права в организации
Q: Можно ли восстановить удаленные сообщения?
A: Нет, после выполнения команды EXPUNGE удаление необратимо. Yandex не предоставляет возможности восстановления. Всегда используйте DRY_RUN=true для тестирования!
Q: Как долго выполняется удаление из 100 ящиков? A: При параллельной обработке (5 потоков) это занимает меньше 10 минут, в зависимости от скорости подключения и количества сообщений в каждом ящике.
Q: Можно ли использовать скрипт для удаления нескольких сообщений? A: Используйте параметры MAILBOXES_LIST_FILE = mailboxes.csv и MESSAGES_LIST_FILE = message-ids.csv.
Q: Нужно ли создавать checkpoint файлы вручную?
A: Нет, checkpoint файлы создаются автоматически перед каждым изменением настроек делегирования. Вам нужно только указать каталог в .env.
Q: Почему скрипт не находит сообщение, хотя я уверен, что оно есть? A: Возможные причины:
- Message-ID указан неверно (проверьте наличие угловых скобок
<>) - Дата отличается от реальной (увеличьте диапазон дней)
- Сообщение находится в архиве или было уже удалено
- IMAP подключение не имеет доступа к некоторым папкам
Q: Что означает ошибка "Required environment vars not provided"?
A: В файле .env отсутствуют обязательные параметры. Проверьте наличие всех переменных из раздела "Параметры".
Q: Можно ли запускать скрипт на Windows?
A: Да, скрипт совместим с Windows. Убедитесь, что установлены Python 3.7+ и все зависимости из requirements.txt.
Q: Как получить Message-ID сообщения? A:
- В веб-интерфейсе Яндекс.Почты откройте сообщение
- Нажмите "Еще" → "Служебные заголовки"
- Найдите строку
Message-ID: - Скопируйте значение (угловые скобки можно не копировать)
Q: Что делать, если скрипт завершается с ошибкой подключения IMAP? A: Проверьте:
- Правильность пароля приложения делегата (
DELEGATE_PASSWORD) - Существование делегата в организации
- Формат домена в
DELEGATE_DOMAIN(без @) - Доступность сервера
imap.yandex.ru:993
Q: Где взять OAuth токен? A: См. раздел "Получение токена OAuth для работы с данными Яндекс 360" в этом документе. Токен нужно создать через интерфейс Яндекс.OAuth.
Q: Что такое "пароль приложения" для делегата? A: Это специальный пароль, создаваемый в настройках аккаунта Яндекс специально для приложений. Не используйте основной пароль! Инструкция: https://yandex.ru/support/id/authorization/app-passwords.html
Q: Нужно ли создавать отдельного пользователя-делегата? A: Нет, это может быть любой пользователь, для которого известен пароль приложения для доступа к IMAP ящику Яндекс 360.
Q: Как изменить количество параллельных потоков?
A: Измените константу MAX_PARALLEL_THREADS в начале файла del_message_v3.py. Рекомендуемое значение: 3-10.
Q: Можно ли использовать скрипт для регулярной очистки спама? A: Да, но рекомендуется создать wrapper-скрипт с заранее заданными параметрами и запускать его по расписанию (например, через cron).
Q: Как удалить сообщение только из определенной папки (например, только из Входящих)? A: В текущей версии это невозможно - скрипт ищет во всех папках. Требуется модификация кода для поддержки этой функции.
Q: Можно ли использовать скрипт для удаления по другим критериям (тема, отправитель)? A: Нет, текущая версия поддерживает только поиск по Message-ID. Для других критериев требуется значительная модификация кода.
Q: Как посмотреть, какие checkpoint файлы созданы?
A: Все checkpoint файлы находятся в каталоге, указанном в CHECK_DIR (по умолчанию mailbox_checkpoints/). Используйте ls -la mailbox_checkpoints/ для просмотра.
Q: Безопасно ли хранить пароли в .env файле?
A: Файл .env должен иметь ограниченные права доступа (chmod 600 .env) и никогда не должен попадать в систему контроля версий. Добавьте .env в .gitignore.
Q: Можно ли использовать OAuth токен вместо пароля приложения для IMAP? A: В текущей реализации скрипт использует basic authentication для IMAP. Для OAuth аутентификации требуется модификация кода.
Q: Логируются ли пароли и токены? A: Нет, скрипт не логирует чувствительные данные. В логах сохраняются только результаты операций и идентификаторы запросов.
Скрипт построен на модульной архитектуре с разделением ответственности:
┌─────────────────────────────────────────────────────────────┐
│ del_message_v3.py │
│ Главный модуль │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Конфигурация │
│ • Загрузка .env (dotenv) │
│ • Валидация параметров │
│ • Инициализация логгера │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Интерактивное │ │ API модуль │ │ IMAP модуль │
│ меню │ │ (Yandex 360) │ │ (aioimaplib) │
├──────────────────┤ ├──────────────────┤ ├──────────────────┤
│ • Главное меню │ │ • Audit Log │ │ • Подключение │
│ • Ввод параметров│ │ • Users API │ │ • Поиск │
│ • Восстановление │ │ • Delegation API │ │ • Удаление │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ │ │
└─────────────────┼─────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Checkpoint система │
│ • Сохранение состояния (checkin) │
│ • Фиксация изменений (checkout) │
│ • Создание дифов (diff) │
│ • Восстановление (restore) │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Многопоточная обработка │
│ • ThreadPoolExecutor (до 5 потоков) │
│ • Асинхронный IMAP (asyncio) │
│ • Обработка ошибок и повторы │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Отчетность и логирование │
│ • Консольный вывод (INFO) │
│ • Файловые логи (DEBUG) │
│ • Финальный отчет │
└─────────────────────────────────────────────────────────────┘
Центральный объект конфигурации, содержит:
- OAuth токен и параметры API
- Параметры делегата
- Настройки поиска (message_id, date, days_diff, mailboxes)
- Кэш пользователей организации
Функции взаимодействия с Yandex 360 API:
get_all_api360_users()- получение списка пользователейfetch_audit_logs()- запрос логов аудитаget_mailbox_delegate_settings()- получение настроек делегированияupdate_mailbox_delegate_settings()- изменение настроек делегирования
Асинхронные функции работы с почтой:
imap_connect()- подключение к серверуsearch_and_delete_message()- поиск и удаление сообщенийtemporary_delegate_and_delete_messages()- работа с делегированными ящиками
Управление состоянием почтовых ящиков:
save_mailbox_state()- сохранение состояния (checkin)save_checkout_state()- фиксация нового состояния (checkout)create_diff_file()- создание файла различийrestore_permissions_from_diff()- восстановление из checkpoint
1. Инициализация
├─ Загрузка .env
├─ Проверка обязательных параметров
└─ Тест подключения IMAP делегата
2. Интерактивная настройка
├─ Ввод Message-ID
├─ Ввод даты и диапазона
└─ Указание списка ящиков (или *)
3. Определение списка почтовых ящиков
├─ Если use_log = true:
│ ├─ Запрос audit logs
│ └─ Извлечение списка ящиков
└─ Иначе: использование заданного списка
4. Для каждого почтового ящика (параллельно):
├─ Checkin: сохранение текущего состояния
├─ Временное назначение прав делегата
├─ Подключение к IMAP
├─ Поиск сообщений по критериям
├─ Удаление найденных сообщений
├─ Восстановление исходных прав
└─ Checkout: сохранение нового состояния
5. Формирование отчета
├─ Сбор статистики по всем ящикам
├─ Группировка результатов
└─ Вывод финального отчета
6. Завершение
└─ Сохранение логов
mailbox@domain.ru|delegation_enabled=true
mailbox@domain.ru|actors=[{"actorId":"12345","resourceId":"67890","roles":["shared_mailbox_owner"]}]
Mailbox: office@company.ru
Old delegation_enabled: true
New delegation_enabled: true
Old actors: [{"actorId":"11111",...}]
New actors: [{"actorId":"11111",...},{"actorId":"22222",...}]
---
====================================================================================================
ФИНАЛЬНЫЙ ОТЧЕТ О ПОИСКЕ И УДАЛЕНИИ СООБЩЕНИЯ
====================================================================================================
Искомое сообщение: <message-id@domain.com>
✓ СООБЩЕНИЕ НАЙДЕНО И ОБРАБОТАНО:
Почтовый ящик: user@domain.ru
Папки: INBOX, Sent
Статус: Успешно удалено
ИТОГОВАЯ СТАТИСТИКА:
Всего почтовых ящиков для проверки: N
Сообщение найдено в ящиках: M
...
====================================================================================================
Ключевые константы в начале файла del_message_v3.py:
DEFAULT_IMAP_SERVER = "imap.yandex.ru"
DEFAULT_IMAP_PORT = 993
DEFAULT_360_API_URL = "https://api360.yandex.net"
DEFAULT_OAUTH_API_URL = "https://oauth.yandex.ru/token"
DEFAULT_DAYS_DIF = 1 # Диапазон дней по умолчанию
MAX_PARALLEL_THREADS = 5 # Количество параллельных потоков
MAX_RETRIES = 3 # Количество повторных попыток
RETRIES_DELAY_SEC = 2 # Задержка между повторами
MAIL_LOGS_MAX_RECORDS = 100 # Записей в одном ответе APIСкрипт использует многоуровневую систему обработки ошибок:
-
Уровень конфигурации:
- Проверка при загрузке
- Немедленное завершение при критических ошибках
-
Уровень API:
- Повторные попытки при временных сбоях
- Логирование x-request-id для поддержки
- Обработка rate limiting
-
Уровень IMAP:
- Try-except блоки для каждого ящика
- Гарантированное восстановление прав делегата (finally)
- Продолжение работы при ошибке на одном ящике
-
Уровень многопоточности:
- Изоляция ошибок в отдельных потоках
- Сбор всех результатов (успешных и неуспешных)
Факторы, влияющие на скорость:
| Фактор | Влияние | Оптимизация |
|---|---|---|
| Количество ящиков | Линейное | Увеличить MAX_PARALLEL_THREADS |
| Размер ящика | Среднее | Уменьшить диапазон дней |
| Скорость сети | Высокое | Запуск с сервера в той же сети |
| API rate limiting | Высокое | Задержки между запросами |
Типичное время выполнения:
- 10 ящиков: ~2-3 минуты
- 300 ящиков: ~15-20 минут
- 1000 ящиков: ~1 час
| Пакет | Версия | Назначение |
|---|---|---|
| python-dotenv | >= 0.19.0 | Загрузка .env файлов |
| requests | >= 2.26.0 | HTTP запросы к API |
| python-dateutil | >= 2.8.0 | Парсинг и работа с датами |
| aioimaplib | >= 0.9.0 | Асинхронный IMAP клиент |
restore_from_checkpoint.py
- Автономная утилита для восстановления из checkpoint
- Можно использовать независимо от основного скрипта
- Поддерживает предпросмотр изменений
example_usage.py
- Примеры программного использования функций
- Демонстрация API для интеграции
- Тестовые сценарии
При возникновении проблем:
- Проверьте FAQ в этом документе
- Изучите логи в файле
delete_messages.log - Проверьте checkpoint файлы в случае проблем с делегированием
- Обратитесь к документации Yandex 360: https://yandex.ru/dev/api360/
Важные ссылки:
- Yandex 360 API: https://yandex.ru/dev/api360/
- OAuth документация: https://yandex.ru/dev/oauth/
- Пароли приложений: https://yandex.ru/support/id/authorization/app-passwords.html
- Сервисные приложения: https://yandex.ru/support/yandex-360/business/admin/ru/security-service-applications
Проект распространяется под лицензией MIT. Подробности см. в файле LICENSE.
