Почему 1С всегда кодирует тему письма и как отправить незакодированный Subject

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При отправке электронной почты из платформы 1С разработчики часто сталкиваются с особенностью: даже если тема письма состоит исключительно из латинских букв (например, abc), в исходном коде отправленного письма заголовок темы принимает следующий вид:

Subject: =?utf-8?B?YWJj?=

Обычные почтовые клиенты при передаче чистого латинского текста оставляют заголовок открытым: Subject: abc. Однако встроенные объекты 1С всегда кодируют тему. Разберем, почему так происходит, с какими проблемами это связано при работе с Email2SMS-шлюзами и какими способами можно передать письмо с незакодированным заголовком.

Причина поведения платформы 1С

Проанализируем работу штатных объектов ИнтернетПочта и ИнтернетПочтовоеСообщение. Платформа 1С строго придерживается стандарта RFC 2047 (MIME Part Three: Message Header Extensions for Non-ASCII Text). Согласно внутренним алгоритмам платформы, текстовые заголовки писем автоматически упаковываются в формат Base64 или Quoted-Printable с явным указанием кодировки (по умолчанию UTF-8).

В объекте ИнтернетПочтовоеСообщение отсутствуют специальные настройки или флаги, позволяющие отключить RFC 2047 для заголовка Subject. Для большинства почтовых серверов и почтовых клиентов это не является проблемой, так как они корректно декодируют такие сообщения. Однако некоторые сторонние сервисы (например, устаревшие шлюзы пересылки e-mail в SMS) не умеют разбирать заголовки по стандарту RFC 2047. Их парсеры ищут ключевые слова или префиксы команд прямо в сыром тексте сообщения и, не найдя совпадений, отклоняют письмо.

Стандартный метод отправки из 1С и его особенности

Посмотрим на типовой пример кода отправки письма через штатный почтовый клиент 1С:


Профиль = Новый ИнтернетПочтовыйПрофиль; 
Профиль.АдресСервераSMTP = "smtp.yourserver.com";
Профиль.ПортSMTP = 25;
Профиль.Пользователь = "user@yourserver.com";
Профиль.ПользовательSMTP = "user@yourserver.com";
Профиль.Пароль = "secret_password";

Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Получатели.Добавить("gate@sms-service.com");
Сообщение.Отправитель.Адрес = "user@yourserver.com";    
Сообщение.Тема = "abc";

Почта = Новый ИнтернетПочта; 
Почта.Подключиться(Профиль); 
Почта.Послать(Сообщение); 
Почта.Отключиться();

При выполнении этого кода в поле Subject на сервер уходит строка =?utf-8?B?YWJj?=. Если приемный сервис не поддерживает автоматическое декодирование Base64, отправка SMS не состоится. Рассмотрим альтернативные способы решения этой задачи без изменения логики платформы.

Способ 1. Использование COM-объекта CDO.Message (для ОС Windows)

Выясним, как обойти ограничение платформы средствами операционной системы. Объект CDO.Message при работе с латинскими символами не кодирует заголовок Subject в Base64 и передает его в открытом виде.

Разберем пример реализации отправки через CDO.Message:


Письмо = Новый COMОбъект("CDO.Message");
Конфигурация = Письмо.Configuration;

// Настройка параметров SMTP-сервера
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing").Value = 2; // Отправка по сети через SMTP
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver").Value = "smtp.yourserver.com";
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport").Value = 25;
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate").Value = 1; // Базовая аутентификация
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername").Value = "user@yourserver.com";
Конфигурация.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword").Value = "secret_password";
Конфигурация.Fields.Update();

// Формирование сообщения
Письмо.From = "user@yourserver.com";
Письмо.To = "gate@sms-service.com";
Письмо.Subject = "abc"; // Текст на латинице передается в чистом виде
Письмо.TextBody = "Текст сообщения для СМС";

Попытка
    Письмо.Send();
    Сообщить("Сообщение успешно отправлено!");
Исключение
    Сообщить("Ошибка при отправке почты: " + ОписаниеОшибки());
КонецПопытки;

Способ 2. Переход на HTTP API сервиса рассылки

Наиболее надежным архитектурным решением при работе с СМС-сервисами является отказ от отправки сообщений через E-mail в пользу REST/HTTP API. Большинство современных шлюзов предоставляют готовые HTTP-интерфейсы для отправки сообщений.

Рассмотрим пример отправки запроса с использованием встроенных объектов HTTPСоединение и HTTPЗапрос:


Сервер = "api.sms-service.com";
Соединение = Новый HTTPСоединение(Сервер, 443, , , , Истина); // HTTPS-соединение

Ресурс = "/v1/send_sms?phone=79991112233&text=" + КодироватьСтроку("Текст СМС", СпособКодированияСтроки.URL_Encoding);
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Authorization", "Bearer YOUR_API_TOKEN");

Попытка
    Ответ = Соединение.Получить(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        Сообщить("СМС успешно отправлено!");
    Иначе
        Сообщить(" Ошибка сервиса. Код ответа: " + Ответ.КодСостояния);
    КонецЕсли;
Исключение
    Сообщить("Ошибка соединения с HTTP-сервисом: " + ОписаниеОшибки());
КонецПопытки;

Способ 3. Использование внешних утилит или скриптов

Если требуется сохранить отправку именно по почте, но без использования COM-объектов (например, при работе сервера 1С на ОС Linux), можно использовать сторонние утилиты консоли (например, cURL или утилиту Postie), вызываемые через команду ЗапуститьПриложение.

Разберем порядок действий при использовании cURL:

  1. Сформируем файл с сырым текстом письма email.txt, где явно пропишем заголовки без кодирования:
    
    From: user@yourserver.com
    To: gate@sms-service.com
    Subject: abc
    
    Текст сообщения СМС
    
  2. Вызовем отправку через системную команду:
    
    Команда = "curl --url ""smtp://smtp.yourserver.com:25"" --mail-from ""user@yourserver.com"" --mail-rcpt ""gate@sms-service.com"" --upload-file ""C:\temp\email.txt"" --user ""user@yourserver.com:secret_password""";
    ЗапуститьПриложение(Команда, , Истина);
    

Подведение итогов

Мы проанализировали причины, по которым встроенная почта 1С кодирует заголовок Subject в Base64. Это стандартное поведение платформы 1С для соблюдения спецификации RFC 2047. Для корректного взаимодействия с сервисами, не поддерживающими данный стандарт, рекомендуется использовать интеграцию через HTTP API, отправку через CDO.Message или вызов внешних сетевых утилит.

← На главную