При автоматизации взаимодействия с электронной почтой в 1С часто возникает задача загружать не всю входящую корреспонденцию, а только определенные сообщения (например, с конкретной темой, от заданного контрагента или только непрочитанные). Однако стандартная попытка передать структуру отбора в метод ПолучитьИдентификаторы() нередко приводит к тому, что в массив попадают абсолютно все письма из ящика. Разберем причины такого поведения платформы 1С и рассмотрим надежные способы решения задачи.
Основная причина игнорирования параметров отбора заключается в используемом почтовом протоколе:
мОтбор и возвращает идентификаторы всех сообщений в почтовом ящике.SEARCH.Проанализируем правильный порядок настройки подключения к почтовому ящику по протоколу IMAP. Для выполнения поиска на стороне сервера необходимо явно указать параметры IMAP в профиле и передать объект перечисления ПротоколИнтернетПочты.IMAP при вызове метода Подключиться().
Рассмотрим структуру допустимых ключей отбора. Платформа 1С поддерживает следующие параметры (регистр букв значения не имеет):
"Тема" (или "Subject"), "Отправитель" ("From"), "Получатели" ("To"), "Копии" ("Cc"), "Текст" ("Text"), "ТелоСообщения" ("Body").Дата): "ДатаОтправления", "ДоДатыОтправления", "ПослеДатыОтправления".Булево): "Прочитанные" (или "Seen"), "Новые" ("New"), "Недавние" ("Recent"), "Удаленные" ("Deleted"), "Важные" ("Flagged").Посмотрим на практический пример кода для получения только непрочитанных писем с определенной темой:
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераIMAP = "imap.mail.ru";
Профиль.ПортIMAP = 993;
Профиль.ИспользоватьSSLIMAP = Истина;
Профиль.ПользовательIMAP = "robot@mail.ru";
Профиль.ПарольIMAP = "ПарольПриложения";
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP);
// Обязательно указываем целевую папку, обычно это INBOX
Почта.ТекущийПочтовыйЯщик = "INBOX";
// Формируем параметры отбора (условия объединяются по "И")
Отбор = Новый Структура;
Отбор.Вставить("Seen", Ложь);
Отбор.Вставить("Тема", "VedomostTovarov");
// Получаем массив идентификаторов подходящих писем
МассивИдентификаторов = Почта.ПолучитьИдентификаторы(, Отбор);
Если МассивИдентификаторов.Количество() > 0 Тогда
// Загружаем только отфильтрованные сообщения целиком
МассивПисем = Почта.Выбрать(Ложь, МассивИдентификаторов);
Для Каждого Письмо Из МассивПисем Цикл
// Обработка письма и его вложений
КонецЦикла;
КонецЕсли;
Почта.Отключиться();
Важное замечание: при вызове метода Выбрать() обязательно передавайте полученный МассивИдентификаторов вторым параметром. Если вызвать Почта.Выбрать(Ложь) без передачи массива, платформа начнет последовательно скачивать все письма из почтового ящика целиком.
Если используемый почтовый сервер нестабильно обрабатывает поиск по кириллице через IMAP или если подключение возможно только по протоколу POP3, разберем самый надежный и универсальный двухэтапный алгоритм.
Метод ПолучитьЗаголовки() скачивает только служебную информацию о сообщениях (тему, отправителя, дату, идентификатор) без тяжелого тела письма и вложений. Это обеспечивает минимальный трафик и высокую скорость работы.
Разберем реализацию этого способа по шагам:
ПолучитьЗаголовки() для всей папки.Выбрать().Посмотрим на пример реализации:
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль, ПротоколИнтернетПочты.IMAP);
Почта.ТекущийПочтовыйЯщик = "INBOX";
// Загружаем только легкие заголовки всех сообщений
МассивЗаголовков = Почта.ПолучитьЗаголовки();
ИдентификаторыДляЗагрузки = Новый Массив;
СтрокаПоиска = ВРег("VedomostTovarov");
Для Каждого Заголовок Из МассивЗаголовков Цикл
// Проверяем вхождение нужной подстроки в тему письма
Если Найти(ВРег(Заголовок.Тема), СтрокаПоиска) > 0 Тогда
// Заголовок содержит массив идентификаторов (обычно из одного элемента)
ИдентификаторыДляЗагрузки.Добавить(Заголовок.Идентификатор[0]);
КонецЕсли;
КонецЦикла;
// Если найдены целевые письма, скачиваем их полностью
Если ИдентификаторыДляЗагрузки.Количество() > 0 Тогда
МассивПисем = Почта.Выбрать(Ложь, ИдентификаторыДляЗагрузки);
Для Каждого Письмо Из МассивПисем Цикл
// Выполняем разбор и обработку письма
КонецЦикла;
КонецЕсли;
Почта.Отключиться();
Если входящий поток писем очень большой, самым производительным решением является предварительная фильтрация средствами самого почтового сервиса (Яндекс, Mail.ru, Gmail, Exchange):
VedomostTovarov), перемещать письмо в отдельную папку (например, INBOX/Orders).Почта.ТекущийПочтовыйЯщик = "INBOX/Orders";.