Интеграция 1С с почтовыми сервисами по протоколу IMAP — стандартная задача для автоматизации бизнес-процессов. Мы часто сталкиваемся с необходимостью обрабатывать только новые или непрочитанные письма: загружать заказы, обрабатывать уведомления или импортировать отчеты. Однако разработчики нередко натыкаются на крайне неприятную особенность платформы: при попытке получить только непрочитанные письма, если их в ящике нет, 1С внезапно начинает скачивать абсолютно всю историю переписки, перегружая память и процессор.
В этой статье мы подробно разберем, почему возникает такое поведение системы, проанализируем внутреннюю логику работы почтового клиента в 1С и реализуем надежный и отказоустойчивый алгоритм фильтрации писем на примере Яндекс.Почты.
Рассмотрим стандартный сценарий, который часто пишут разработчики. Мы создаем объект типа ИнтернетПочта, подключаемся к серверу, задаем структуру отбора, получаем заголовки и затем пытаемся скачать сами письма:
ПараметрыОтбораIMAP = Новый Структура;
ПараметрыОтбораIMAP.Вставить("Прочитанные", Ложь);
Заголовки = Почта.ПолучитьЗаголовки(ПараметрыОтбораIMAP);
Письма = Почта.Выбрать(Ложь, Заголовки, Истина);
На первый взгляд код выглядит абсолютно логично. Но именно в связке методов ПолучитьЗаголовки() и Выбрать() кроется подвох. Выясним причину такого поведения платформы:
ПолучитьЗаголовки(ПараметрыОтбораIMAP) обращается к серверу и ищет письма, соответствующие условию (в нашем случае — непрочитанные).Заголовки становится пустым массивом (его количество элементов равно 0).Выбрать(УдалятьСообщения, Источник, ОтмечатьКакПрочтенные).Выбрать() передается значение Неопределено или пустой массив, метод считает, что никаких ограничений на выборку нет. Платформа игнорирует тот факт, что вы передали пустой массив намеренно, и начинает последовательно скачивать абсолютно все письма, хранящиеся в текущей папке почтового ящика.Таким образом, если в ящике лежит 10 000 старых писем, а новых нет, ваш код вместо быстрого завершения работы начнет ресурсоемкий процесс скачивания всех десяти тысяч писем.
Чтобы избежать этой ошибки, нам необходимо внедрить обязательную проверку количества полученных заголовков перед тем, как обращаться к серверу за телом писем. Рассмотрим правильную архитектуру этого процесса по шагам.
Для надежной фильтрации писем на сервере (особенно на таких строгих сервисах, как Яндекс.Почта) рекомендуется комбинировать фильтр по прочтению с ограничением по дате получения. Это защитит систему от случайной обработки старых писем, если кто-то вручную снимет с них пометку прочтения в веб-интерфейсе.
В качестве ограничения по дате отлично подходит функция НачалоДня(ТекущаяДата()). Серверы IMAP обычно игнорируют время (часы, минуты, секунды) при фильтрации дат, поэтому передача «чистой» даты начала дня — наиболее стабильный вариант.
Перед вызовом метода Выбрать() мы обязаны убедиться, что массив заголовков не пуст. Только если в нем есть хотя бы один элемент, мы инициируем скачивание содержимого писем.
Посмотрим на пример правильной реализации:
// Настройка параметров подключения и выбор папки
Почта.ТекущийПочтовыйЯщик = "Delivery"; // Имя папки в Яндекс.Почте
// Формируем структуру отбора IMAP
ПараметрыОтбораIMAP = Новый Структура;
ПараметрыОтбораIMAP.Вставить("ПослеДатыОтправления", НачалоДня(ТекущаяДата()));
ПараметрыОтбораIMAP.Вставить("Прочитанные", Ложь);
// Получаем только заголовки (легковесный запрос)
Заголовки = Почта.ПолучитьЗаголовки(ПараметрыОтбораIMAP);
// КРИТИЧЕСКИ ВАЖНАЯ ПРОВЕРКА: скачиваем письма, только если они найдены
Если Заголовки.Количество() > 0 Тогда
// Получаем письма (тело писем, вложения) и помечаем их на сервере как прочтенные
Письма = Почта.Выбрать(Ложь, Заголовки, Истина);
Для Каждого Сообщение Из Письма Цикл
// Здесь выполняется логика обработки конкретного письма
Сообщить("Обработано письмо от: " + Сообщение.Отправитель + " с темой: " + Сообщение.Тема);
КонецЦикла;
Иначе
Сообщить("Новых писем, соответствующих фильтрам, не обнаружено. Выборка пропущена.");
КонецЕсли;
Даже написав идеальный код в 1С, вы можете столкнуться с тем, что почта не загружается или фильтры работают некорректно. Разберем ключевые технические нюансы работы с серверами Яндекс.Почты:
ПараметрыОтбораIMAP.Вставить("Тема", "Заказ")), Яндекс.Почта может вернуть пустой массив из-за некорректной интерпретации кодировки UTF-8 в поисковых IMAP-запросах платформы. Рекомендация: получайте заголовки по дате и признаку прочтения, а фильтрацию по текстовой теме или отправителю производите уже на стороне 1С, перебирая полученную коллекцию заголовков в цикле перед скачиванием тела письма."Прочитанные" — аналогично "Seen" (Булево)"Новые" — аналогично "New" или "Recent" (Булево)"ПослеДатыОтправления" — аналогично "AfterDateOfPosting" (Дата)"Отправитель" — аналогично "From" (Строка)Применяя описанную выше проверку на количество заголовков и правильно комбинируя параметры фильтрации, вы полностью обезопасите свои фоновые задания от зависаний, сэкономите интернет-трафик и обеспечите быструю, стабильную работу интеграции вашей базы 1С с почтовым сервером Яндекс.