При автоматизации почтовых рассылок из 1С часто возникает задача отправки писем с фирменным оформлением: логотипом компании, графическими баннерами, таблицами и стилизованными шрифтами. Формирование обычного текстового письма не вызывает трудностей, однако при переходе на формат HTML разработчики сталкиваются с проблемами отображения встроенных изображений и ошибками поиска каталогов при обработке текста сообщения.
Разберем по шагам, как правильно формировать HTML-письма в 1С, выясним причину распространенных ошибок и подробно изучим все рабочие способы вставки графических файлов в тело письма.
Проанализируем самый надежный и универсальный метод внедрения графических элементов в HTML-письмо. Этот подход поддерживается большинством почтовых клиентов (включая Microsoft Outlook, почтовые веб-сервисы и мобильные приложения). Суть метода заключается в том, что изображение передается как почтовое вложение со специальным внутренним идентификатором, а в HTML-разметке на него ставится ссылка вида src="cid:ИмяИдентификатора".
Рассмотрим по шагам реализацию этого механизма с использованием стандартного объекта ИнтернетПочтовоеСообщение:
ИнтернетПочтовоеСообщение.Вложения и заполняем свойство Идентификатор.ТипТекстаПочтовогоСообщения.HTML и задаем кодировку сообщения.Посмотрим на пример программного кода на стороне 1С:
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Информационное сообщение";
Письмо.Отправитель.Адрес = "info@company.ru";
Письмо.Получатели.Добавить("client@example.com");
Письмо.Кодировка = "UTF-8";
// Получаем двоичные данные картинки (например, из макета или общих картинок)
ДвоичныеДанныеЛоготипа = БиблиотекаКартинок.ЛоготипКомпании.ПолучитьДвоичныеДанные();
// Добавляем картинку во вложения и задаем уникальный идентификатор CID
Вложение = Письмо.Вложения.Добавить(ДвоичныеДанныеЛоготипа, "logo.png");
Вложение.Идентификатор = "CompanyLogoCID";
// Формируем тело письма на языке HTML
ТекстПисьма = "<html><body>"
+ "<div style='border-bottom: 2px solid #333; padding-bottom: 10px;'>"
+ " <img src='cid:CompanyLogoCID' alt='Логотип' />"
+ "</div>"
+ "<p>Добрый день!</p>"
+ "<p>Направляем вам документы по взаиморасчетам.</p>"
+ "</body></html>";
ТекстСообщения = Письмо.Тексты.Добавить(ТекстПисьма, ТипТекстаПочтовогоСообщения.HTML);
// Отправка через ИнтернетПочта
Почта = Новый ИнтернетПочта;
Почта.Подключиться(ПрофильПочты);
Почта.Послать(Письмо);
Почта.Отключиться();
Рассмотрим второй популярный способ, который часто применяется для маркетинговых и сервисных рассылок. Если изображения размещены на корпоративном сайте или общедоступном файловом хранилище с доступом по протоколу HTTPS, их можно не прикреплять к самому письму, а ссылаться на них напрямую через тег <img src="https://...">.
Плюсы данного подхода:
Ограничения: почтовые программы в целях безопасности могут блокировать загрузку внешнего контента по умолчанию, пока пользователь явно не разрешит отображение картинок для отправителя.
Выясним причину ошибки, возникающей при вызове метода ОбработатьТексты(). Если в HTML-документе вставлены ссылки на объекты конфигурации вида mdpicture/... или локальные пути клиента, метод выдает исключение об отсутствии каталога. Это происходит потому, что платформа ожидает реальные физические пути к файлам на диске, доступные тому сеансу (клиентскому или серверному), в котором выполняется код.
Если требуется использовать встроенный механизм автоматического преобразования путей, разберем по шагам корректный алгоритм работы:
ПолучитьИмяВременногоФайла().Письмо.ОбработатьТексты(), который автоматически преобразует локальные файлы во внутренние CID-вложения.Посмотрим на реализацию с временными файлами:
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("png");
ДвоичныеДанныеЛоготипа = БиблиотекаКартинок.ЛоготипКомпании.ПолучитьДвоичныеДанные();
ДвоичныеДанныеЛоготипа.Записать(ИмяВременногоФайла);
HTMLТекст = "<html><body>"
+ "<img src='" + ИмяВременногоФайла + "' />"
+ "<p>Текст письма с автоматической обработкой вложений.</p>"
+ "</body></html>";
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тексты.Добавить(HTMLТекст, ТипТекстаПочтовогоСообщения.HTML);
// Автоматическая обработка ссылок на локальные файлы
Письмо.ОбработатьТексты();
// Отправка письма
Почта = Новый ИнтернетПочта;
Почта.Подключиться(ПрофильПочты);
Почта.Послать(Письмо);
Почта.Отключиться();
// Удаление временного файла после отправки
УдалитьФайлы(ИмяВременногоФайла);
Если на рабочих станциях пользователей установлен локальный почтовый клиент (например, Microsoft Outlook), можно автоматизировать отправку через создание COM-объекта. В этом случае свойство HTMLBody принимает готовый текст HTML.
Посмотрим на пример отправки через COM-соединение:
Попытка
ПочтовоеПриложение = Новый COMОбъект("Outlook.Application");
НовоеПисьмо = ПочтовоеПриложение.CreateItem(0);
НовоеПисьмо.Subject = "Тема сообщения";
НовоеПисьмо.To = "client@example.com";
НовоеПисьмо.HTMLBody = "<html><body><h2>Здравствуйте!</h2><p>Тело письма.</p></body></html>";
НовоеПисьмо.Send();
Исключение
ВызватьИсключение "Не удалось отправить сообщение через Outlook: " + ОписаниеОшибки();
КонецПопытки;
Рассмотрим, почему не стоит кодировать изображения в строку data:image/png;base64,... непосредственно в HTML-тег <img>. Несмотря на то что веб-браузеры корректно отображают такие картинки, настольный почтовый клиент Microsoft Outlook (использующий движок рендеринга Microsoft Word) блокирует внедренные Base64-изображения. В результате получатель видит пустую рамку или значок отсутствующего рисунка. Для гарантированной доставки рекомендуется применять либо привязку через Content-ID (CID), либо прямые URL-ссылки на внешний сервер.