Как настроить отправку почты из 1С, если пользователь не авторизован в системе

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

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

Разберем по шагам, почему возникает эта проблема, почему не стоит использовать COM-автоматизацию настольных почтовых клиентов на сервере и как правильно реализовать отправку электронных писем в 1С.

Выясним причину: почему COM-объект Outlook не работает в фоновом режиме

Проанализируем исходный код вызова внешнего приложения:


Попытка
    Outlook = Новый COMОбъект("Outlook.Application");
Исключение
    // Обработка ошибки
КонецПопытки;
Письмо = Outlook.CreateItem(0);
Письмо.Subject = Тема;
Письмо.Body = Текст;
Письмо.Recipients.Add(Кому);
Письмо.Send();

Данный подход имеет несколько фундаментальных ограничений архитектуры Windows и пакета Microsoft Office:

  1. Отсутствие интерактивного профиля пользователя: COM-объект Outlook.Application жестко завязан на ветку реестра текущего пользователя (HKEY_CURRENT_USER) и созданный в ней почтовый профиль MAPI. Если служба 1С или регламентное задание выполняется в системной сессии (Session 0) либо под системной учетной записью (например, USR1CV8), у процесса нет загруженного профиля пользователя с настроенным почтовым ящиком.
  2. Официальный запрет Microsoft на серверное использование Office: компоненты MS Office не предназначены для выполнения в неинтерактивных службах, фоновых потоках и регламентных сценариях, так как они могут блокировать поток диалоговыми окнами и приводить к утечкам памяти.
  3. Заблуждение о «закрытых портах»: часто считается, что раз Outlook на рабочей станции отправляет письма, а стандартные SMTP-порты (25, 465, 587) закрыты сетевым экраном, отправка возможна только через Outlook. На практике корпоративные почтовые серверы (такие как Microsoft Exchange) работают с клиентом по протоколам MAPI over HTTP или RPC over HTTP через стандартный защищенный веб-порт 443 (HTTPS), а не по классическому SMTP.

Вариант 1. Переход на штатный механизм платформы 1С — объект ИнтернетПочта (Рекомендуемый)

Оптимальным решением является полный отказ от использования внешних COM-объектов в пользу платформенных объектов ИнтернетПочта, ИнтернетПочтовыйПрофиль и ИнтернетПочтовоеСообщение. Это обеспечивает полную автономность кода и позволяет отправлять сообщения как в клиентских формах, так и в серверных фоновых заданиях.

Параметры учетной записи (сервер, порт, логин, пароль) следует хранить не в исходном коде, а в специализированных константах или справочниках базы данных (например, в справочнике учетных записей электронной почты).

Рассмотрим подробнее пример программной отправки через ИнтернетПочта:


Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "smtp.company.ru";
Профиль.ПортSMTP          = 25; // или 465 / 587 в зависимости от настроек
Профиль.ПользовательSMTP = "admin_mail@company.ru";
Профиль.ПарольSMTP       = "СекретныйПароль";
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;

// Если почтовый сервер требует защищенное соединение:
// Профиль.ИспользоватьSSLSMTP = Истина;

Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Уведомление от администрации системы";
Письмо.Отправитель.Адрес = "admin_mail@company.ru";
Письмо.Отправитель.ОтображаемоеИмя = "Администрация";
Письмо.Получатели.Добавить(Кому);

ТекстПисьма = Письмо.Тексты.Добавить(Текст);
ТекстПисьма.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;

Почта = Новый ИнтернетПочта;
Попытка
    Почта.Подключиться(Профиль);
    Почта.Послать(Письмо);
    Почта.Отключиться();
Исключение
    ИнформироватьОбОшибке = ОписаниеОшибки();
    Попытка
        Почта.Отключиться();
    Исключение
    КонецПопытки;
    ВызватьИсключение "Ошибка при отправке почты: " + ИнформироватьОбОшибке;
КонецПопытки;

Если сетевой экран блокирует отправку наружу, системному администратору достаточно открыть внутренний порт к локальному почтовому серверу (SMTP Relay) только для IP-адреса сервера 1С.

Вариант 2. Программная инициализация MAPI-профиля при клиентской работе

Если код выполняется исключительно на стороне клиентского приложения, но требуется принудительно отправлять почту от имени конкретного служебного ящика (администрации), необходимо обратиться к пространству имен MAPI и явно выполнить вход под нужным профилем.

Разберем пример подключения через пространство имен MAPI:


Попытка
    Outlook = Новый COMОбъект("Outlook.Application");
    ПространствоИмен = Outlook.GetNamespace("MAPI");
    
    // Выполняем вход в конкретный MAPI-профиль, созданный в Windows:
    // Logon(ИмяПрофиля, Пароль, ПоказатьДиалог, СоздатьСессию)
    ПространствоИмен.Logon("СлужебныйПрофильАдминистрации", "ПарольПрофиля", Ложь, Истина);
    
    Письмо = Outlook.CreateItem(0);
    Письмо.Subject = Тема;
    Письмо.Body = Текст;
    Письмо.Recipients.Add(Кому);
    Письмо.Send();
    
    ПространствоИмен.Logoff();
Исключение
    Сообщить("Не удалось отправить письмо через Outlook: " + ОписаниеОшибки());
КонецПопытки;

Важно: для работы этого метода на рабочем компьютере в панели управления Windows (раздел Mail / Почта) должен быть предварительно создан и настроен соответствующий профиль почты.

Сравнение подходов

  1. Штатный объект ИнтернетПочта: кроссплатформенный, работает на сервере и клиенте, не требует установленного пакета Microsoft Office, полностью автономен в регламентных заданиях.
  2. COM-объект Outlook.Application: работает только на Windows-клиентах в интерактивной пользовательской сессии, требует наличия установленного и настроенного почтового клиента Outlook на каждом рабочем месте.
← На главную