При разработке бизнес-логики в конфигурации 1С:Управление торговлей 11 (и других конфигурациях на базе Библиотеки Стандартных Подсистем) часто возникает задача автоматической отправки уведомлений сотрудникам — например, отправка письма менеджеру при изменении статуса заказа клиента. При этом прикладной код должен четко понимать, ушло ли сообщение на почтовый сервер или в процессе отправки произошел сбой.
Разберем подробно, как реализовать такую функцию с использованием типовых механизмов БСП, а также с помощью низкоуровневых объектов платформы ИнтернетПочта.
В конфигурациях на базе БСП для отправки почты предназначен общий модуль РаботаСПочтовымиСообщениями и его экспортная функция ОтправитьПочтовоеСообщение(). Данная функция принимает учетную запись электронной почты, структуру с параметрами сообщения и возвращает строковый идентификатор письма (Message-ID), присвоенный почтовым сервером.
Если во время соединения с SMTP-сервером или в процессе передачи данных возникает ошибка (неверный логин, недоступен сервер, таймаут), типовая функция генерирует платформенное исключение. Поэтому для возврата булева значения Истина или Ложь вызов необходимо оборачивать в конструкцию Попытка ... Исключение.
Рассмотрим по шагам реализацию функции отправки письма менеджеру:
РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись().УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта().Кому, Тема, Тело и ТипТекста. Для создания базовой структуры можно использовать вспомогательную функцию РаботаСПочтовымиСообщениямиКлиентСервер.ПолучитьПараметрыОтправкиПочтовогоСообщения().Попытка. В случае ошибки записываем событие в журнал регистрации и возвращаем Ложь.Посмотрим на пример реализации законченной функции в общем модуле:
Функция ОтправитьПользователюEmail(Знач ПользовательМенеджер, Знач ТемаПисьма, Знач ТекстПисьма) Экспорт
// 1. Получаем адрес электронной почты менеджера
ВидEmail = Справочники.ВидыКонтактнойИнформации.EmailПользователя;
АдресПолучателя = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
ПользовательМенеджер,
ВидEmail,
ТекущаяДатаСеанса()
);
Если ПустаяСтрока(АдресПолучателя) Тогда
ЗаписьЖурналаРегистрации(
"Отправка почты",
УровеньЖурналаРегистрации.Предупреждение,
,
ПользовательМенеджер,
"У пользователя не заполнен адрес электронной почты."
);
Возврат Ложь;
КонецЕсли;
// 2. Получаем системную учетную запись для отправки
УчетнаяЗапись = РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись();
Если Не ЗначениеЗаполнено(УчетнаяЗапись) Тогда
ЗаписьЖурналаРегистрации(
"Отправка почты",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Не настроена системная учетная запись электронной почты."
);
Возврат Ложь;
КонецЕсли;
// 3. Формируем структуру параметров письма
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", АдресПолучателя);
ПараметрыПисьма.Вставить("Тема", ТемаПисьма);
ПараметрыПисьма.Вставить("Тело", ТекстПисьма);
ПараметрыПисьма.Вставить("ТипТекста", "ПростойТекст"); // Или "HTML"
// 4. Выполняем отправку с перехватом ошибок
Попытка
ИдентификаторСообщения = РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(
УчетнаяЗапись,
ПараметрыПисьма
);
Возврат Истина;
Исключение
ИнформацияОбОшибке = ОписаниеОшибки();
ЗаписьЖурналаРегистрации(
"Отправка почты",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Ошибка при отправке письма: " + ИнформацияОбОшибке
);
Возврат Ложь;
КонецПопытки;
КонецФункции
Проанализируем альтернативный вариант, когда требуется выполнить отправку напрямую средствами платформы 1С:Предприятие без использования подсистем БСП. Для этого применяются объекты ИнтернетПочтовыйПрофиль, ИнтернетПочтовоеСообщение и ИнтернетПочта.
Разберем по шагам создание процедуры отправки:
ИнтернетПочтовыйПрофиль и указываем параметры SMTP (сервер, порт, логин, пароль, использование SSL).ИнтернетПочтовоеСообщение, заполняем отправителя, тему, текст и коллекцию получателей.Подключиться() у объекта ИнтернетПочта, затем Послать() и закрываем соединение методом Отключиться().Посмотрим на пример кода:
Функция ОтправитьEmailНапрямую(Знач АдресПолучателя, Знач Тема, Знач Текст) Экспорт
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "smtp.mail.ru";
Профиль.ПортSMTP = 465;
Профиль.ПользовательSMTP = "robot@domain.ru";
Профиль.ПарольSMTP = "ПарольПриложения";
Профиль.ИспользоватьSSLSMTP = Истина;
Профиль.ТолькоЗащищеннаяАутентификацияSMTP = Истина;
Профиль.Таймаут = 30;
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.ИмяОтправителя = "Уведомления 1С:УТ";
Письмо.Отправитель = "robot@domain.ru";
Письмо.Тема = Тема;
Письмо.Получатели.Добавить(АдресПолучателя);
Письмо.Тексты.Добавить(Текст, ТипТекстаПочтовогоСообщения.ПростойТекст);
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль, ПротоколИнтернетПочты.SMTP);
Почта.Послать(Письмо);
Почта.Отключиться();
Возврат Истина;
Исключение
Попытка
Почта.Отключиться();
Исключение
// Игнорируем ошибку отключения
КонецПопытки;
ЗаписьЖурналаРегистрации(
"Отправка почты",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Сбой прямой отправки SMTP: " + ОписаниеОшибки()
);
Возврат Ложь;
КонецПопытки;
КонецФункции
Выясним технические ограничения, о которых необходимо помнить при разработке механизмов отправки:
ОтправитьПочтовоеСообщение() или Почта.Послать() означает, что письмо успешно передано на исходящий SMTP-сервер (получен ответ 250 OK). Факт фактической доставки письма в почтовый ящик менеджера (не отфильтровано ли оно спам-фильтром, существует ли адрес) по протоколу SMTP синхронно проверить невозможно.