В процессе автоматизации бизнес-процессов часто возникает необходимость интеграции 1С с почтовыми сервисами. Одним из самых популярных решений является использование протокола IMAP для получения и обработки входящей корреспонденции. Однако разработчики часто сталкиваются с ситуацией, когда код, успешно работавший месяцами, внезапно начинает «пропускать» письма от определенных отправителей, хотя в веб-интерфейсе почтового ящика эти письма присутствуют. Особенно часто эта проблема проявляется при работе с сервисом Яндекс.Почта.
В данной статье мы подробно разберем, почему стандартные фильтры 1С могут давать сбои, проанализируем причины нестабильной работы серверной части и выработаем надежный алгоритм получения почты, который гарантирует обработку всех входящих сообщений.
Типичный код для получения писем в 1С предполагает использование объекта ИнтернетПочта и структуры ПараметрыОтбораIMAP. Рассмотрим пример, который на первый взгляд кажется абсолютно корректным:
ПрофильПочты = Новый ИнтернетПочтовыйПрофиль;
// Настройка профиля (сервер, порт, логин, пароль)
...
Почта = Новый ИнтернетПочта;
Почта.Подключиться(ПрофильПочты, ПротоколИнтернетПочты.IMAP);
ПараметрыОтбораIMAP = Новый Структура;
ПараметрыОтбораIMAP.Вставить("Отправитель", "ivanov@yandex.ru");
// Получаем только заголовки подходящих писем
ЗаголовкиСообщений = Почта.ПолучитьЗаголовки(ПараметрыОтбораIMAP);
Для Каждого Заголовок Из ЗаголовкиСообщений Цикл
// Обработка письма
КонецЦикла;
Проблема заключается в том, что когда мы передаем ПараметрыОтбораIMAP в метод ПолучитьЗаголовки, 1С транслирует этот фильтр в команду SEARCH протокола IMAP и отправляет ее на почтовый сервер. В этот момент выполнение задачи переходит на сторону сервера (в нашем случае — Яндекса). Выясним причину, по которой сервер может вернуть пустой результат, даже если письма есть.
Во-первых, механизмы индексации сообщений на сервере могут работать с задержкой. Новое письмо может быть физически записано в базу данных, но еще не попасть в поисковый индекс, по которому отрабатывает команда SEARCH. Во-вторых, специфика кодировок в MIME-заголовках часто приводит к тому, что адрес отправителя, записанный в формате Quoted-Printable (например, если в имени есть кириллица), не совпадает с текстовой строкой фильтра, которую ожидает сервер.
Проанализируем наиболее эффективный способ решения данной проблемы. Поскольку мы не можем напрямую контролировать работу поисковых алгоритмов Яндекса, самым надежным вариантом будет отказ от использования сложных фильтров в параметрах метода ПолучитьЗаголовки.
Вместо того чтобы просить сервер «найти письма от Иванова», мы попросим сервер «отдать заголовки всех писем за определенный период», а затем самостоятельно проверим каждое письмо средствами встроенного языка 1С. Разберем по шагам, как это реализовать.
Чтобы не перегружать память и не скачивать заголовки тысяч старых писем, рекомендуется использовать только фильтр по дате. Это самый стабильный фильтр в протоколе IMAP, который практически никогда не дает сбоев.
ПараметрыОтбораIMAP = Новый Структура;
// Ограничим выборку, например, последними тремя днями
ПараметрыОтбораIMAP.Вставить("ДатаОтправления", ТекущаяДата() - 3 * 24 * 3600);
ЗаголовкиСообщений = Почта.ПолучитьЗаголовки(ПараметрыОтбораIMAP);
Теперь, когда у нас есть массив всех заголовков за последние дни, мы проанализируем свойство Отправитель каждого объекта ИнтернетПочтовоеСообщение. Рассмотрим пример реализации:
НужныйАдрес = "ivanov@yandex.ru";
СписокПисемДляЗагрузки = Новый Массив;
Для Каждого Заголовок Из ЗаголовкиСообщений Цикл
// Тщательно проверяем адрес отправителя
// Учтите, что в поле Отправитель может быть как просто адрес, так и имя
Если Найти(НРег(Заголовок.Отправитель.Адрес), НРег(НужныйАдрес)) > 0 Тогда
СписокПисемДляЗагрузки.Добавить(Заголовок);
КонецЕсли;
КонецЦикла;
// Загружаем полные тексты только для отфильтрованных писем
Если СписокПисемДляЗагрузки.Количество() > 0 Тогда
МассивСообщений = Почта.Выбрать(Ложь, СписокПисемДляЗагрузки);
КонецЕсли;
Использование метода НРег() (приведение к нижнему регистру) при сравнении крайне важно, так как почтовые серверы иногда могут менять регистр символов в адресах, что приведет к ложному отрицательному результату при обычном сравнении строк.
Разберем еще несколько важных моментов, которые помогут избежать потерь сообщений при работе с ИнтернетПочта:
Таймаут в объекте ИнтернетПочтовыйПрофиль. Для IMAP Яндекса оптимальным значением будет 60-120 секунд.Выбрать() первым параметром принимает булево значение — помечать ли письма как прочитанные. Если вы используете Истина, другие клиенты (например, мобильное приложение) могут не увидеть новые письма, что иногда путает пользователей.Подведем итог: использование серверной фильтрации через ПараметрыОтбораIMAP — это удобный, но не всегда надежный инструмент при работе с публичными почтовыми сервисами. Чтобы ваша обработка работала «как часы», всегда используйте комбинацию из широкого фильтра по дате и последующей детальной проверки свойств сообщения (Отправитель, Тема) непосредственно в коде 1С.