Как получить почту из MS Exchange через EWS в 1С, если POP3 и SMTP заблокированы

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

В современных корпоративных средах службы безопасности часто блокируют стандартные протоколы передачи почты, такие как POP3 и SMTP, из-за их потенциальной уязвимости. В таких случаях основным инструментом взаимодействия с сервером Microsoft Exchange становится протокол Exchange Web Services (EWS). Это API, основанное на SOAP и работающее через HTTP(S), что позволяет обходить ограничения и интегрироваться с почтовым сервером напрямую. Разберем подробно, как реализовать получение почты через EWS в среде 1С:Предприятие.

Проблема использования COM-объектов и системных библиотек

Часто разработчики пытаются использовать MSXML2.XMLHTTP через COM-соединение. Однако, как показывает практика, это часто приводит к ошибкам в системных библиотеках, таких как msxml3.dll, особенно при работе с современными протоколами шифрования TLS. Проанализируем, почему лучше отказаться от этого метода в пользу встроенных средств платформы 1С.

При использовании COMОбъект("MSXML2.XMLHTTP") вы зависите от настроек операционной системы и версии установленных библиотек. Вместо этого рассмотрим использование объекта HTTPСоединение, который является кроссплатформенным и более стабильным.

Подготовка защищенного соединения

Поскольку работа с EWS практически всегда идет через HTTPS, первым шагом нам необходимо настроить защищенное соединение. Проигнорировав этот этап, мы получим ошибку при попытке установить связь с сервером.


ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
СерверExchange = "your-exchange-server.com";
Пользователь = "domain\user";
Пароль = "password";

Соединение = Новый HTTPСоединение(СерверExchange, , Пользователь, Пароль, , 30, ЗащищенноеСоединение);

Формирование SOAP-запроса для поиска писем (FindItem)

Для получения списка писем используется метод FindItem. Важно понимать структуру XML-пакета, который ожидает сервер. Выясним причину, по которой многие запросы возвращают ошибку: часто это отсутствие пространства имен или некорректная версия схемы. Проанализируем структуру запроса на поиск непрочитанных сообщений в папке "Входящие".

Обратите внимание на заголовок RequestServerVersion. Без указания версии сервера Exchange может не понять структуру запроса.


ТекстЗапроса = 
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""
|               xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types""
|               xmlns:m=""http://schemas.microsoft.com/exchange/services/2006/messages"">
|  <soap:Header>
|    <t:RequestServerVersion Version=""Exchange2013"" />
|  </soap:Header>
|  <soap:Body>
|    <m:FindItem Traversal=""Shallow"">
|      <m:ItemShape>
|        <t:BaseShape>IdOnly</t:BaseShape>
|        <t:AdditionalProperties>
|          <t:FieldURI FieldURI=""item:Subject""/>
|          <t:FieldURI FieldURI=""item:DateTimeReceived""/>
|        </t:AdditionalProperties>
|      </m:ItemShape>
|      <m:ParentFolderIds>
|        <t:DistinguishedFolderId Id=""inbox""/>
|      </m:ParentFolderIds>
|    </m:FindItem>
|  </soap:Body>
|</soap:Envelope>";

Отправка запроса через HTTPСоединение

Рассмотрим процесс отправки сформированного XML на сервер. Для работы с EWS адрес ресурса обычно выглядит как /ews/exchange.asmx. Посмотрим на пример настройки заголовков и отправки POST-запроса.


Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");

Запрос = Новый HTTPЗапрос("/ews/exchange.asmx", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса, КодировкаТекста.UTF8);

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

Получение содержимого письма (GetItem)

Метод FindItem возвращает только идентификаторы (ItemId). Чтобы прочитать текст письма или скачать вложения, нам необходимо выполнить второй шаг — запрос GetItem. Разберем по шагам, как это сделать, используя полученный ранее Id и ChangeKey.


ТекстЗапросаПолучения = 
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""
|               xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"">
|  <soap:Body>
|    <GetItem xmlns=""http://schemas.microsoft.com/exchange/services/2006/messages"">
|      <ItemShape>
|        <t:BaseShape>Default</t:BaseShape>
|        <t:IncludeMimeContent>true</t:IncludeMimeContent>
|      </ItemShape>
|      <ItemIds>
|        <t:ItemId Id=""ИДЕНТИФИКАТОР_ПИСЬМА"" ChangeKey=""КЛЮЧ_ИЗМЕНЕНИЙ""/>
|      </ItemIds>
|    </GetItem>
|  </soap:Body>
|</soap:Envelope>";

Важный момент: использование свойства IncludeMimeContent позволяет получить письмо целиком в формате EML, что удобно для последующего разбора библиотеками 1С или сохранения в файл.

Использование WS-определений: плюсы и минусы

Рассмотрим альтернативный вариант — использование объекта WSОпределения. Этот метод кажется более "правильным" для 1С, так как он позволяет работать с объектами XDTO. Однако выясним, с какими сложностями вы можете столкнуться:

  1. Огромный размер WSDL: Файл описания сервисов Exchange (Services.wsdl) весит несколько мегабайт и ссылается на множество схем.
  2. Потребление памяти: Инициализация WSПрокси на основе такого WSDL может занимать значительное время и требовать до нескольких гигабайт оперативной памяти в момент разбора.
  3. Сложность авторизации: При использовании WSПрокси иногда возникают трудности с пробросом NTLM-авторизации в некоторых версиях платформы.

Поэтому для простых задач получения почты ручное формирование XML через HTTPСоединение часто оказывается более быстрым и надежным решением.

Современная аутентификация (OAuth 2.0)

Проанализируем современную ситуацию: Microsoft постепенно отключает базовую аутентификацию (логин/пароль) в Exchange Online (Office 365). Если ваша почта находится в облаке, вам потребуется:

Обработка результатов

Для разбора ответа от сервера рекомендуем использовать объект ЧтениеXML или ПостроительDOM. Поскольку XML от Exchange очень многословен, ПостроительDOM позволит вам быстро находить нужные узлы с помощью XPath-запросов, не перебирая все дерево вручную. Например, вы можете быстро извлечь все t:ItemId из ответа FindItem, чтобы затем в цикле запросить содержимое каждого письма.

Таким образом, мы проанализировали основные подходы к работе с MS Exchange через EWS. Несмотря на кажущуюся сложность по сравнению с POP3, данный метод предоставляет гораздо более широкие возможности по управлению почтовыми ящиками, календарями и задачами напрямую из 1С.

← На главную