В процессе работы появилась интересная задача. Заказчик дал задание по реализации отправки почтовых сообщений, причём основным условием было создание печатной формы отчёта о доставки электронных писем.
Сам процесс написания программы формирования электронного письма с вложениями не доставил особых трудностей, но вот с отправкой и подтверждением получения письма адресатом возникли сложности.
Для отправки сообщений использовалось два пути:
-
«Почта», с использованием Outlook.
-
«ИнтернетПочта», то есть встроенные функции 1С.
Первый вариант достаточно прост. Учитывая то, что все учётные записи пользователя, вместе с паролями находятся в приложении Outlook, то остаётся только обратиться к ним из 1С, добавить адресата, сформировать само письмо, если необходимо, то с вложениями, и отправить его.
Процедура ОтправкаПисьма(Кнопка)
ПредставлениеСохраняемогоФайла = ПолучитьТекстЗаголовка(Ложь);
Результат = ЭтаФорма.ЭлементыФормы.Результат;
ПолноеИмяФайла = РаботаСФайлами.УдалитьЗапрещенныеСимволыИмени(ПредставлениеСохраняемогоФайла);
КаталогВр = КаталогВременныхФайлов(); //Определение каталога временного файла
Результат.Записать(КаталогВр + ПолноеИмяФайла + ".xls",ТипФайлаТабличногоДокумента.XLS); //Запись таблицы отчёта в файл на диске
ПолучитьПользователя = ПараметрыСеанса.ТекущийПользователь;
ЯщикПользователя = Справочники.КД_ЭлектроннаяПочтаСотрудников.НайтиПоНаименованию(ПолучитьПользователя).ПочтовыйПрофиль;
НовСообщение = Новый ПочтовоеСообщение; //Создание сообщения
ТекстСообщения = "";
ПодсказкаСообщ = "Введите текст сообщения.";
ВвестиСтроку(ТекстСообщения,ПодсказкаСообщ,500,Ложь);
НовСообщение.Текст = ТекстСообщения;
НовСообщение.Отправитель = ЯщикПользователя;
ТекстТема = "";
ПодсказкаТема = "Введите тему письма.";
ВвестиСтроку(ТекстТема,ПодсказкаТема,50,Ложь);
НовСообщение.Тема = ТекстТема;
ТекстПолучатель = "";
ПодсказкаПолуч = "Введите имя получателя.";
ВвестиСтроку(ТекстПолучатель,ПодсказкаПолуч,50,Ложь);
АдресПолучателя = ТекстПолучатель;
ЯщикПолучателя = Справочники.КД_ЭлектроннаяПочтаСотрудников.НайтиПоНаименованию(АдресПолучателя).ПочтовыйПрофиль;
НовСообщение.Получатели.Добавить(ЯщикПолучателя);
ФайлВложения = КаталогВр + ПолноеИмяФайла + ".xls";
НовСообщение.Вложения.Добавить(ФайлВложения,ПолучитьТекстЗаголовка(Ложь));
Почта = Новый Почта;
Почта.Подключиться();
Попытка
Почта.Послать(НовСообщение,Истина);
Исключение
Сообщить(ОписаниеОшибки());
Возврат
КонецПопытки;
Почта.Отключиться();
КонецПроцедуры
Во втором варианте подключение к почтовому ящику без особых условий и запретов получается только на сервисе mail.ru. Yandex и Google не позволяют авторизоваться из-за особенностей протоколов безопасности, проблема решается более тонкой настройкой сервисов (полная справка находится на «саппорте» каждого сервиса).
Упростить работу помогла функция определения сервиса почтового ящика (ведь у пользователя он может быть и не один), функция, помещенная в модуль объекта. Функция определяет почтовый сервис и возвращает значение необходимого профиля почты.
Функция ПолучитьПрофиль(ИмяЯщика,ПочтовыйСервис,ПарольОтЯщика) Экспорт
Профиль = Новый ИнтернетПочтовыйПрофиль;
Если ПочтовыйСервис = "@mail.ru" Тогда
Профиль.АдресСервераSMTP = "smtp.mail.ru";
Профиль.ПортSMTP = 25;
Профиль.Пароль = ПарольОтЯщика;
Профиль.ПарольSMTP = ПарольОтЯщика;
Профиль.Пользователь = ИмяЯщика + ПочтовыйСервис;
Профиль.ПользовательSMTP = ИмяЯщика + ПочтовыйСервис;
Профиль.ВремяОжидания = 60;
Возврат Профиль;
ИначеЕсли ПочтовыйСервис = "@yandex.ru" Тогда
Профиль.АдресСервераSMTP = "smtp.yandex.ru";
Профиль.ПортSMTP = 465;
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;
Профиль.ИспользоватьSSLSMTP = Истина;
Профиль.Пароль = ПарольОтЯщика;
Профиль.ПарольSMTP = ПарольОтЯщика;
Профиль.Пользователь = ИмяЯщика + ПочтовыйСервис;
Профиль.ПользовательSMTP = ИмяЯщика + ПочтовыйСервис;
Профиль.ВремяОжидания = 60;
Возврат Профиль;
ИначеЕсли ПочтовыйСервис = "@gmail.com" Тогда
Профиль.АдресСервераSMTP = "smtp.gmail.com";
Профиль.ПортSMTP = 465;
Профиль.АутентификацияSMTP = СпособSMTPАутентификации.ПоУмолчанию;
Профиль.ИспользоватьSSLSMTP = Истина;
Профиль.Пароль = ПарольОтЯщика;
Профиль.ПарольSMTP = ПарольОтЯщика;
Профиль.Пользователь = ИмяЯщика + ПочтовыйСервис;
Профиль.ПользовательSMTP = ИмяЯщика + ПочтовыйСервис;
Профиль.ВремяОжидания = 60;
Возврат Профиль;
КонецЕсли;
КонецФункции
Затем следует процедура формирования и отправки письма.
Процедура ДействияФормыОсновныеОтправить(Кнопка)
ПредставлениеСохраняемогоФайла = ПолучитьТекстЗаголовка(Ложь);
Результат = ЭтаФорма.ЭлементыФормы.Результат;
ПолноеИмяФайла = РаботаСФайлами.УдалитьЗапрещенныеСимволыИмени(ПредставлениеСохраняемогоФайла);
КаталогВр = КаталогВременныхФайлов();
Результат.Записать(КаталогВр + ПолноеИмяФайла + ".xls",ТипФайлаТабличногоДокумента.XLS);
ПолучитьПользователя = ПараметрыСеанса.ТекущийПользователь;
Запрос = Новый Запрос;
Запрос.Текст = "Выбрать Представление
|ИЗ РегистрСведений.КонтактнаяИнформация
|Где Объект = &ПП";
Запрос.УстановитьПараметр("ПП",ПолучитьПользователя);
РЗ = Запрос.Выполнить().Выгрузить();
Для каждого Стр Из РЗ Цикл
ПочтЯщ = Стр.Представление;
КонецЦикла;
ПрофильПочты = ПолучитьПрофильПочты(ПочтЯщ);
СервисПочты = ПолучитьСервисПочты(ПочтЯщ);
ЯщикПользователя = ПрофильПочты + СервисПочты;
ПарольОтЯщика = "";
ПодсказкаПароля = "Введите пароль от своего почтового ящика!";
ВвестиСтроку(ПарольОтЯщика,ПодсказкаПароля,15,Ложь);
Если ПарольОтЯщика = "" Тогда
Сообщить("Без пароля не получится!");
Возврат;
КонецЕсли;
///////Подключение к почте///////
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(ПолучитьПрофиль(ПрофильПочты,СервисПочты,ПарольОтЯщика));
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Вложения.Добавить(КаталогВр + ПолноеИмяФайла + ".xls",ПолучитьТекстЗаголовка(Ложь));
Письмо.Отправитель = ЯщикПользователя;
Письмо.ИмяОтправителя = ПолучитьПользователя;
ПочтовыеАдреса = Письмо.Получатели;
ПочтовыйАдрес = ПочтовыеАдреса.Добавить();
ВозврЗначАдресат = Справочники.Пользователи.ПолучитьФормуВыбора("ФормаВыбора",ЭтаФорма).ОткрытьМодально();//Получение адресата из списка пользователей
Если ВозврЗначАдресат = "" Тогда
Сообщить("Не заполнено ФИО адресата! Попробуйте ещё раз!");
Возврат;
Иначе
Запрос = Новый Запрос; //Получение почтового ящика из регистра сведений
Запрос.Текст = "Выбрать Представление КАК Ящик
|ИЗ РегистрСведений.КонтактнаяИнформация
|Где Объект.Наименование = &ПП";
Запрос.УстановитьПараметр("ПП",ВозврЗначАдресат.Наименование);
РЕЗ = Запрос.Выполнить().Выгрузить();
Для каждого Стр Из РЕЗ Цикл
ЯщикАдр = Стр.Ящик;
КонецЦикла;
ПрофильАдресата = ПолучитьПрофильПочты(ЯщикАдр);
СервисАдресата = ПолучитьСервисПочты(ЯщикАдр);
ПочтаАдресата = ПрофильАдресата + СервисАдресата;
ПочтовыйАдрес.Адрес = ПочтаАдресата;
КонецЕсли;
Письмо.Тема = "";
ПодсказкаТемы = "Обозначьте тему письма! (Не обязательно)";
ВвестиСтроку(Письмо.Тема,ПодсказкаТемы,50,Ложь);
ИнтернетТекстПочтовогоСообщения = Письмо.Тексты.Добавить();
ИнтернетТекстПочтовогоСообщения.Текст = "С уважением, " + ПолучитьПользователя + ".";
ИнтернетТекстПочтовогоСообщения.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
Попытка
Почта.Послать(Письмо);
Предупреждение("Ваше письмо успешно отправлено. Хорошего завершения дня!",10);
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
Исключение
Сообщить("УПС! " + ОписаниеОшибки());
КонецПопытки;
Почта.Отключиться();
///
РегистрыСведений.АС_ЗадачиПользователя.ПолучитьФормуРедактированияЗаписи(,ЭтаФорма).ОткрытьМодально();//Создание задачи пользователю в планировщике.
КонецПроцедуры
Но даже если не плыть против течения и использовать сервис, который даёт беспрепятственный вход в почтовый ящик (mail.ru, к примеру), то после отправки письма адресату возникает вопрос - "как программно задать получение отчета о прочтении?". Ответом оказалось "Никак". Даже в самом почтовом ящике Mail.ru кнопка, включающая оповещение о доставке письма не активна, то есть при нажатии на неё не происходит абсолютно ничего, письмо отправляется, но отчёт о его доставке не приходит (программно, что естественно, тоже не включается).
Тогда был опробован первый вариант. С помощью Outlook отправлялись сообщения как с сервиса Mail.ru на Yandex и Google, так и обратно. Даже при установке в настройках Outlook флажка о доставке отчёта о доставке и прочтении не происходило ничего.
Выводы.
В процессе поисков решений было выяснено, что на почтовых сервисах, не известно с какого времени (это касается всех почтовых сервисов, описанных выше), была встроена функция, позволяющая пользователю, получающему письмо, не отправлять отчёт о доставке и прочтении. Так, к примеру, на Yandex.ru, при получении письма появляется кнопка, при нажатии которой отправляется отчёт о том, что письмо доставлено, если её не нажимать, то, естественно, отчёт о доставке отправлен не будет, и неважно - сколько потратил времени программист на то, чтобы программно задать запрос проверки доставки письма.
На Gmail.com сделано ещё интересней, конечно же отчёт можно по желанию не отправлять, но разработчики добавили функцию игнорирования письма, при активизации которой полученное письмо просто "испаряется" из почтового ящика, как будто его там и не было.
Ну а Mail.ru просто не отправляют отчёт о доставке и всё.
Из всего вышесказанного следует:
- настроить отправку почты из 1С возможно и не находится за гранью недосягаемого;
- программная установка запроса на подтверждение доставки и прочтения электронного письма не имеет никакого смысла.