При разработке механизмов отправки писем из среды 1С программисты часто сталкиваются с неприятной ситуацией. Мы создаем красивый HTML-макет в конфигураторе, вставляем туда изображения, пишем код для отправки, но получатель открывает письмо в Microsoft Outlook, Gmail или через веб-интерфейс почтового сервиса и видит лишь пустые рамки с красными крестиками вместо картинок. В этой статье мы подробно разберем, почему так происходит, и рассмотрим три надежных способа решения этой проблемы.
Когда мы загружаем картинку в HTML-макет в конфигураторе 1С, платформа сохраняет ее во внутренней структуре временных файлов макета. В самом HTML-коде генерируется относительный путь, который выглядит примерно так: <img src="8eb4fad1-1fa6-403e-970f-2c12dbb43e23_files/1.png" />.
Когда мы считываем текст макета методом ПолучитьТекст() и передаем его в свойство HTML-текста письма, этот относительный путь уходит получателю без изменений. Естественно, почтовая программа на стороне получателя ничего не знает о файловой системе нашего сервера 1С или о структуре метаданных конфигурации. Она пытается найти картинку по указанному пути локально на компьютере пользователя или на своем сервере и, не найдя её, отображает пустой квадрат.
Существует несколько ошибочных подходов к решению этой проблемы, которые часто выбирают начинающие разработчики:
src="https://mycompany.com/images/logo.png". Это рабочий метод, но у него есть существенный минус: большинство современных почтовых клиентов по умолчанию блокируют загрузку внешних изображений в целях конфиденциальности (чтобы отправитель не мог отследить факт открытия письма). Получателю придется вручную нажимать кнопку «Разрешить загрузку картинок», что портит внешний вид письма.src="data:image/png;base64,iVBORw...". В обычном браузере это работает превосходно. Однако многие почтовые сервисы (например, Outlook и Gmail) полностью вырезают или блокируют Base64-код из соображений безопасности (в него можно внедрить вредоносный скрипт) и для предотвращения раздувания размера писем.Единственным общепринятым мировым стандартом отправки писем с изображениями является технология Content-ID (CID). Картинка прикрепляется к письму как скрытое вложение (MIME-part), а в HTML-коде мы ссылаемся на нее с помощью конструкции src="cid:ИдентификаторКартинки". Разберем три практических способа реализации этого механизма в 1С.
Разработчики платформы 1С предусмотрели встроенный интеллектуальный механизм, который может самостоятельно проанализировать HTML-код письма, найти в нем ссылки на локальные файлы, автоматически упаковать их во вложения и связать через cid.
Давайте разберем этот процесс по шагам. Главное условие для работы этого метода: в HTML-коде письма пути к картинкам должны быть указаны как абсолютные локальные пути на сервере 1С (начиная с префикса file:///).
Рассмотрим пример программного кода, реализующий этот подход:
// Шаг 1. Получаем текст HTML из макета
МакетХТМЛ = УправлениеОтчетами.ПолучитьМакет("НашМакетПисьма");
ТекстHTML = МакетХТМЛ.ПолучитьТекст();
// Шаг 2. Сохраняем картинки из макета на диск сервера во временную папку
// Предположим, мы программно выгрузили картинку во временный файл
ПутьККартинкеНаДиске = ПолучитьИмяВременногоФайла("png");
ДвоичныеДанныеКартинки = ПолучитьКартинкуИзБазы(); // Ваша функция получения данных
ДвоичныеДанныеКартинки.Записать(ПутьККартинкеНаДиске);
// Шаг 3. Заменяем относительный путь в HTML-тексте на абсолютный файловый путь
ПутьДляHTML = "file:///" + СтрЗаменить(ПутьККартинкеНаДиске, "\", "/");
ТекстHTML = СтрЗаменить(ТекстHTML, "8eb4fad1-1fa6-403e-970f-2c12dbb43e23_files/1.png", ПутьДляHTML);
// Шаг 4. Формируем интернет-почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Тестовое письмо с картинками";
Письмо.Отправитель.Адрес = "sender@company.com";
Письмо.Получатели.Добавить("recipient@client.com");
// Важно: добавляем текст именно с указанием типа HTML
Письмо.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);
// Шаг 5. Запускаем автоматическую обработку текстов
Письмо.ОбработатьТексты();
// Платформа сама найдет файл по пути "file:///", прикрепит его во вложения,
// сгенерирует уникальный CID и заменит путь в HTML на "cid:..."
Использование метода ОбработатьТексты() избавляет разработчика от ручной рутины, связанной с парсингом тегов <img> и генерацией уникальных идентификаторов. Платформа делает все операции под капотом.
Бывают ситуации, когда сохранять файлы на диск сервера нежелательно (например, из соображений производительности при массовых рассылках или из-за ограничений прав доступа в облачных кластерах). В этом случае мы можем связать HTML-код и картинки полностью в оперативной памяти.
Для этого в HTML-макете мы сразу прописываем статический идентификатор в теге картинки. Посмотрим на пример разметки в макете:
<p>Здравствуйте! Благодарим за покупку в нашем магазине.</p>
<img src="cid:CompanyLogo" alt="Наш Логотип" style="width: 200px; height: auto;" />
<p>С уважением, отдел продаж.</p>
Обратите внимание на значение атрибута src="cid:CompanyLogo". Нам не нужно динамически менять эту строчку в коде 1С. Все, что нам требуется — это добавить картинку во вложения письма и явно назначить ей этот же идентификатор.
Проанализируем пример кода на стороне 1С:
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Ваш заказ успешно оформлен!";
Письмо.Отправитель.Адрес = "sales@company.com";
Письмо.Получатели.Добавить("customer@email.com");
// Устанавливаем готовый HTML-текст со статичным cid
Письмо.Тексты.Добавить(ПолучитьТекстHTMLМакета(), ТипТекстаПочтовогоСообщения.HTML);
// Получаем двоичные данные картинки (например, из макета или из хранилища значений)
ДвоичныеДанныеЛоготипа = ПолучитьДвоичныеДанныеЛоготипа();
// Добавляем двоичные данные во вложения сообщения
ВложениеЛоготип = Письмо.Вложения.Добавить(ДвоичныеДанныеЛоготипа, "logo.png");
// Ключевой момент: связываем вложение с HTML-кодом по идентификатору!
ВложениеЛоготип.Идентификатор = "CompanyLogo";
Этот способ работает невероятно быстро, надежно и поддерживается абсолютно всеми почтовыми клиентами. Главное — следить за уникальностью идентификаторов, если в письме используется несколько разных картинок.
Если ваши пользователи самостоятельно создают письма во встроенном текстовом редакторе 1С (в режиме Предприятия), вставляют туда картинки из буфера обмена или загружают файлы с локального компьютера, то структура HTML формируется динамически. Для работы с такими данными в платформе 1С существует специальный объект — ФорматированныйДокумент.
Данный объект обладает встроенным методом ПолучитьHTML(), который умеет разделять визуальное представление документа на чистый HTML-код и структуру картинок. Разберем по шагам, как это запрограммировать:
// Предположим, у нас на форме есть реквизит "ТекстПисьма" с типом ФорматированныйДокумент
ПереданныйТекстHTML = "";
СтруктураКартинок = Новый Структура;
// Метод разделяет текст и изображения
ТекстПисьма.ПолучитьHTML(ПереданныйТекстHTML, СтруктураКартинок);
// Создаем почтовое сообщение
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Письмо из редактора";
Письмо.Отправитель.Адрес = "info@company.com";
Письмо.Получатели.Добавить("client@domain.com");
// Записываем полученный HTML в тело письма
Письмо.Тексты.Добавить(ПереданныйТекстHTML, ТипТекстаПочтовогоСообщения.HTML);
// Обходим коллекцию выделенных картинок и прикрепляем их во вложения
Для Каждого ЭлементСтруктуры Из СтруктураКартинок Цикл
// Получаем двоичные данные картинки
ДанныеКартинки = ЭлементСтруктуры.Значение.ПолучитьДвоичныеДанные();
// Имя ключа структуры является сгенерированным cid в полученном HTML
ИдентификаторКартинки = ЭлементСтруктуры.Ключ;
// Добавляем вложение в письмо
НовоеВложение = Письмо.Вложения.Добавить(ДанныеКартинки, ИдентификаторКартинки + ".png");
НовоеВложение.Идентификатор = ИдентификаторКартинки;
КонецЦикла;
Этот способ идеален для создания гибких почтовых рассылок, новостных дайджестов или индивидуальных ответов клиентам непосредственно из интерфейса учетной системы.
Чтобы ваши письма выглядели профессионально и не ломались в различных почтовых клиентах, помните о следующих правилах верстки:
<style> в заголовке HTML-документа. Все стили оформления (шрифты, цвета, отступы картинок) необходимо прописывать непосредственно внутри самих тегов с помощью атрибута style. Например: <p style="font-family: Arial, sans-serif; color: #333333; margin-bottom: 15px;">.width самого тега img и дублируйте в style="width: ..."). Это предотвратит «растягивание» и деформацию шаблона письма на экранах мобильных телефонов.alt для изображений. Если у пользователя совсем отключена загрузка вложений из-за экономии трафика или медленного интернета, он должен понять, что находилось на месте картинки (например, alt="Логотип нашей компании").Применяя описанные методы связывания картинок через Content-ID (cid), вы гарантируете корректное отображение ваших фирменных стилей, логотипов и товарных карточек в любых почтовых сервисах ваших клиентов.