При отправке электронной почты из платформы 1С разработчики часто сталкиваются с особенностью: даже если тема письма состоит исключительно из латинских букв (например, abc), в исходном коде отправленного письма заголовок темы принимает следующий вид:
Subject: =?utf-8?B?YWJj?=
Обычные почтовые клиенты при передаче чистого латинского текста оставляют заголовок открытым: Subject: abc. Однако встроенные объекты 1С всегда кодируют тему. Разберем, почему так происходит, с какими проблемами это связано при работе с Email2SMS-шлюзами и какими способами можно передать письмо с незакодированным заголовком.
Проанализируем работу штатных объектов ИнтернетПочта и ИнтернетПочтовоеСообщение. Платформа 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С:
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервера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 не состоится. Рассмотрим альтернативные способы решения этой задачи без изменения логики платформы.
Выясним, как обойти ограничение платформы средствами операционной системы. Объект 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();
Сообщить("Сообщение успешно отправлено!");
Исключение
Сообщить("Ошибка при отправке почты: " + ОписаниеОшибки());
КонецПопытки;
Наиболее надежным архитектурным решением при работе с СМС-сервисами является отказ от отправки сообщений через 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-сервисом: " + ОписаниеОшибки());
КонецПопытки;
Если требуется сохранить отправку именно по почте, но без использования COM-объектов (например, при работе сервера 1С на ОС Linux), можно использовать сторонние утилиты консоли (например, cURL или утилиту Postie), вызываемые через команду ЗапуститьПриложение.
Разберем порядок действий при использовании cURL:
email.txt, где явно пропишем заголовки без кодирования:
From: user@yourserver.com
To: gate@sms-service.com
Subject: abc
Текст сообщения СМС
Команда = "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 или вызов внешних сетевых утилит.