В процессе автоматизации документооборота в 1С:Комплексная автоматизация 2.4 или ERP часто возникает задача пересылки входящей корреспонденции. Стандартная пересылка текста не всегда удобна, особенно если исходное письмо содержит сложную структуру, встроенные изображения и собственные вложения. В таких случаях идеальным решением является вложение «письма в письмо», аналогично тому, как это реализовано в почтовых клиентах вроде Microsoft Outlook. Разберем подробно, как реализовать этот механизм программно.
Наиболее надежным и «промышленным» способом является сохранение исходного сообщения в файл формата .eml и его последующее прикрепление к новому письму. Формат EML является стандартом (RFC822) и распознается практически всеми почтовыми серверами и клиентами. Рассмотрим, как это реализовать.
Для начала нам необходимо получить данные исходного письма. В 1С объект ИнтернетПочтовоеСообщение нельзя конвертировать в двоичные данные одной командой. Проанализируем алгоритм формирования такого вложения:
Критически важным моментом здесь является установка свойства ТипСодержимого. Если мы просто прикрепим файл, получатель увидит его как обычный текстовый документ. Чтобы почтовый клиент открыл его именно как письмо, используем следующий код:
НовоеПисьмо = Новый ИнтернетПочтовоеСообщение;
НовоеПисьмо.Тема = "Пересылка: " + ИсходноеПисьмо.Тема;
// Путь к предварительно сформированному файлу письма
ПутьКФайлуЭМЛ = ПолучитьИмяВременногоФайла("eml");
// ... здесь логика сохранения исходного письма в файл ...
Вложение = НовоеПисьмо.Вложения.Добавить(Новый ДвоичныеДанные(ПутьКФайлуЭМЛ), "OriginalMessage.eml");
Вложение.ТипСодержимого = "message/rfc822";
Установка типа message/rfc822 дает сигнал почтовому приложению (Outlook, Gmail, Thunderbird), что внутри находится полноценное сообщение с сохранением всей структуры переписки.
Платформа 1С позволяет манипулировать коллекциями вложений. Рассмотрим ситуацию, когда мы получаем почту и хотим перенаправить вложения из одного письма в другое. Проанализируем рекурсивный метод обхода, который позволяет «добраться» до писем, которые уже были вложены в исходное сообщение:
Процедура ОбработатьВложения(ИсходныеВложения, ПисьмоПолучатель)
Для каждого Вложение Из ИсходныеВложения Цикл
Данные = Вложение.Данные;
Если ТипЗнч(Данные) = Тип("ДвоичныеДанные") Тогда
// Обычный файл (фото, документ)
ПисьмоПолучатель.Вложения.Добавить(Данные, Вложение.Имя);
ИначеЕсли ТипЗнч(Данные) = Тип("ИнтернетПочтовоеСообщение") Тогда
// Вложенное письмо — обрабатываем рекурсивно или добавляем целиком
НовоеВложение = ПисьмоПолучатель.Вложения.Добавить(Данные);
НовоеВложение.Имя = "Вложенное_письмо.eml";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот подход удобен тем, что нам не всегда нужно сохранять данные на диск, если платформа корректно распознает вложенный объект ИнтернетПочтовоеСообщение. Однако стоит помнить, что при отправке через защищенные SMTP-серверы может потребоваться явная сериализация в поток данных.
Если решение запускается на клиенте, где установлен Microsoft Outlook, можно использовать его мощную объектную модель. Это самый простой способ «вложить письмо в письмо» в визуальном стиле Outlook, однако он имеет ограничения (не работает в Linux, требует наличия установленного офисного пакета и прав доступа).
Разберем пример кода для создания такого сообщения:
Outlook = Новый COMОбъект("Outlook.Application");
НовоеПисьмо = Outlook.CreateItem(0); // 0 = olMailItem
НовоеПисьмо.Subject = "Тема письма";
// Добавление вложения типа "вложенный элемент"
// Здесь 4 — это константа olEmbeddeditem
Вложение = НовоеПисьмо.Attachments.Add(ИсходноеПисьмоOutlook, 4);
НовоеПисьмо.Display(); // Отобразить пользователю для ввода комментария
Этот метод позволяет диспетчеру в «Комплексной автоматизации» сразу увидеть привычный интерфейс Outlook с уже прикрепленным «первичным» письмом.
Если задача стоит «сделать попроще» и нет жесткого требования именно к формату .eml, можно использовать метод визуального цитирования. Мы не вкладываем файл, а вставляем содержимое старого письма в новое, визуально отделяя его. Выясним, как это реализовать через HTML.
Для этого мы берем HTMLТекст исходного письма и оборачиваем его в стандартный для почтовых систем блок цитирования blockquote. Посмотрим на пример формирования тела сообщения:
ТекстДиспетчера = "Проблема принята, направляю на исполнение.";
ИсходныйТекст = ИсходноеПисьмо.ТекстHTML;
ПолныйТекстHTML = "<p>" + ТекстДиспетчера + "</p>"
+ "<blockquote style=""margin:0 0 0 0.8ex; border-left:1px #ccc solid; padding-left:1ex"">"
+ ИсходныйТекст
+ "</blockquote>";
НовоеПисьмо.ТекстHTML = ПолныйТекстHTML;
Важный нюанс: при таком подходе фотографии, которые были прикреплены к исходному письму, необходимо также программно перенести в коллекцию Вложения нового письма, иначе получатель увидит только текст без изображений «проблемы».
Поскольку работа ведется в КА 2.4, рекомендуем обратить внимание на программный интерфейс Библиотеки стандартных подсистем (БСП). В модуле РаботаСПочтовымиСообщениями реализованы функции, которые берут на себя часть рутины по подготовке писем. При формировании пересылки через механизмы БСП можно использовать параметр ПересылаемоеСообщение, который в некоторых версиях конфигураций автоматически обрабатывает структуру вложений.
Подведем итог: если вам нужно строгое соответствие стандартам — используйте метод с формированием .eml и типом message/rfc822. Если важна простота реализации и читаемость сотрудником — используйте HTML-цитирование с копированием коллекции вложений.