Почему при автоматической рассылке одному из получателей не приходит письмо, а вручную все работает?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

В практике автоматизации рассылок из 1С мы часто сталкиваемся с ситуациями, которые на первый взгляд кажутся мистическими. Одна из таких проблем: есть список получателей (например, 5 человек), настроена типовая рассылка отчета по расписанию. Четверым письмо приходит стабильно, а пятому — нет. При этом, если запустить ту же самую обработку вручную, письма получают все. В Журнале регистрации 1С ошибок нет, статус — "Выполнено".

Давайте разберем эту ситуацию подробно, выясним технические причины такого поведения и рассмотрим надежные способы решения.

Анализ симптомов: почему "ручной" режим отличается от "автоматического"

Первое, что нам нужно понять: почему результат зависит от способа запуска? Казалось бы, код выполняется один и тот же. Однако есть два критических фактора:

  1. Контекст выполнения и права. Автоматическая рассылка выполняется в фоновом задании на сервере. Часто она запускается под служебным пользователем (например, USR1CV8), у которого могут отличаться настройки прокси или доступ к временным файлам. Но в нашем случае проблема выборочная (одному не приходит), значит, сетевой доступ есть.
  2. Скорость выполнения (Тайминг). Это ключевой момент. При ручной отправке, даже если вы нажимаете кнопку "Отправить всем", процесс часто сопровождается отрисовкой интерфейса, или формированием печатных форм на клиенте/сервере с участием клиентского контекста. Это создает микро-паузы. Фоновое задание работает на сервере с максимальной скоростью, которую позволяет процессор. Письма "выстреливаются" в почтовый сервер очередью за доли секунды.

Истинная причина: SMTP Throttling и защита от спама

Большинство современных почтовых серверов (MS Exchange, Exim, Postfix, облачные сервисы вроде Mail.ru или Yandex) имеют встроенные механизмы защиты от спама и перегрузок. Один из таких механизмов называется Throttling (регулирование полосы пропускания).

Когда 1С отправляет 5 писем подряд без пауз, для почтового сервера это выглядит как спам-атака или флуд. Сервер может иметь настройки:

Если лимит превышен (например, на 5-м письме), сервер может вернуть не фатальную ошибку (код 5xx), а временную ошибку (код 4xx, например, 421 Too many messages или 450 Greylisted).

Почему мы не видим ошибку в 1С?
Стандартные механизмы БСП (Библиотеки Стандартных Подсистем) или простые обработки могут некорректно обрабатывать коды 4xx. Если сервер разрывает соединение, 1С может посчитать, что отправка завершена, или записать ошибку в глубокий лог, который не виден в обычном Журнале регистрации.

Диагностика проблемы

Журнал регистрации (ЖР) часто бесполезен в таких случаях, так как он фиксирует логический факт "Попытка отправки выполнена", но не детали сетевого обмена. Чтобы убедиться, что проблема именно в ответе почтового сервера, нам необходимо включить Технологический журнал (TechLog).

Давайте настроим сбор логов по событию MAIL. Для этого в файл logcfg.xml на сервере 1С добавим следующую настройку:



    
        
    
    

После сбора логов во время сбоя, мы увидим полный протокол общения с SMTP-сервером. Ищем строки, где после команд RCPT TO или DATA сервер возвращает ответ. Скорее всего, вы увидите что-то подобное на 5-м письме:

SMTP response: 421 4.7.0 Too many messages from 192.168.1.10

Решения проблемы

Разберем несколько способов исправления ситуации, от простых к архитектурно правильным.

Решение 1. Искусственная задержка (Пауза)

Самое простое решение, которое подтвердило свою эффективность в рассматриваемой теме — снизить скорость отправки. Если проблема возникает из-за того, что мы отправляем письма слишком быстро, давайте добавим паузу.

Если вы пишете свой механизм рассылки, внутри цикла отправки можно добавить ожидание. В современных версиях платформы 8.3 есть нативные методы для асинхронных пауз, но в фоновом задании на сервере часто используют старый проверенный способ через команду Ping, так как метод Предупреждение или Ожидание там недоступен.


Для Каждого Адресат Из СписокПолучателей Цикл
    // Формирование письма
    // ...
    // Отправка письма
    Соединение.Послать(Письмо);
    
    // Пауза 2 секунды, чтобы "успокоить" почтовый сервер
    ЗапуститьПриложение("ping -n 2 127.0.0.1", , Истина); 
КонецЦикла;

Плюсы: Легко реализовать.
Минусы: Увеличивает общее время выполнения задания. Это "костыль".

Решение 2. Использование скрытой копии (BCC)

Это наиболее профессиональный подход, если содержимое письма (вложение) одинаково для всех получателей. Вместо того чтобы создавать 5 отдельных писем и 5 раз стучаться на почтовый сервер, мы формируем одно письмо.

Алгоритм действий:

  1. Создаем объект ИнтернетПочтовоеСообщение.
  2. В поле "Кому" (To) ставим первого получателя или общего ответственного.
  3. Всех остальных получателей добавляем в коллекцию СлепыеКопии (BCC).
  4. Отправляем письмо один раз.

Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Ежедневный отчет";

// Основной получатель (или технический ящик)
Письмо.Получатели.Добавить("main@company.com");

// Массовая рассылка через скрытую копию
Для Каждого Адрес Из МассивАдресов Цикл
    Письмо.СлепыеКопии.Добавить(Адрес);
КонецЦикла;

// Одна отправка - одна сессия
Почта.Послать(Письмо);

Плюсы: Мгновенная отправка, минимальная нагрузка на сервер, 100% гарантия, что спам-фильтр по частоте не сработает.
Минусы: Не подходит, если каждому получателю нужно отправить уникальный отчет (например, расчетный листок).

Решение 3. Переподключение к серверу

Некоторые SMTP-серверы ограничивают количество писем в рамках одной сессии. Если вы открыли соединение командой Соединение.Подключиться() и в цикле шлете 100 писем, сервер может разорвать связь после 10-го.

Решение заключается в том, чтобы получить настройки учетных записей и обновлять соединение каждые N писем (или даже каждое письмо).


Профиль = Новый ИнтернетПочтовыйПрофиль;
// Заполнение профиля...

Для Каждого Адресат Из СписокПолучателей Цикл
    Почта = Новый ИнтернетПочта;
    Почта.Подключиться(Профиль); // Подключаемся заново для каждого письма
    
    Попытка
        Почта.Послать(СоздатьПисьмо(Адресат));
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка почты", , , , ОписаниеОшибки());
    КонецПопытки;
    
    Почта.Отключиться(); // Разрываем сессию
КонецЦикла;

Этот метод работает медленнее, чем BCC, но надежнее, чем просто цикл, так как сбрасывает счетчики сессии на стороне сервера.

Проверка репутации сервера

Если вы используете собственный почтовый сервер, убедитесь, что проблемы доставки не связаны с глобальными блокировками. Проверьте:

  1. Наличие PTR-записи (обратной записи DNS) для IP-адреса вашего сервера. Многие принимающие серверы (Mail.ru, Gmail) автоматически отвергают почту без PTR.
  2. Не находится ли ваш IP в черных списках (Blacklists). Используйте сервисы вроде mxtoolbox или 2ip.

Итог

Если рассылка не работает выборочно и только в автоматическом режиме — это почти всегда срабатывание защиты почтового сервера от частых запросов. Рекомендуем начать с метода использования Скрытой копии (BCC), если это позволяет бизнес-логика, либо добавить принудительные паузы в цикл отправки.

← На главную