Как перенести PHP-код для отправки SMS в 1С: реализация HTTP-запросов и Digest-авторизации

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

Перенос кода с одного языка программирования на другой — задача частая, особенно когда речь идет об интеграции 1С с внешними веб-сервисами. Одной из наиболее популярных задач является отправка SMS-сообщений через сторонние шлюзы, которые предоставляют примеры кода на PHP с использованием библиотеки CURL. В этой статье мы подробно разберем, как интерпретировать PHP-код и написать его аналог на платформе 1С:Предприятие 8.3.

Анализ исходного PHP-кода

Для начала проанализируем, что именно делает PHP-функция. Основные моменты, на которые стоит обратить внимание:

  1. Инициализация CURL: создание сессии для работы с определенным URL.
  2. Формирование тела запроса: параметры (телефон, текст, отправитель) кодируются функцией urlencode и объединяются в строку.
  3. Метод POST: данные передаются не в строке адреса, а в теле сообщения (CURLOPT_POST).
  4. Авторизация: используется тип CURLAUTH_DIGEST. Это важный момент, так как Digest-авторизация сложнее обычной Basic-авторизации и требует особого подхода в 1С.
  5. Возврат результата: получение ответа от сервера в виде строки.

Рассмотрим, как реализовать аналогичную логику в 1С, используя объект HTTPСоединение.

Способ 1: Реализация через стандартные средства HTTPСоединение

В простейшем случае, если API сервиса позволяет использовать встроенные механизмы авторизации платформы, код будет выглядеть следующим образом. Разберем его по шагам.

Сначала подготовим данные. В 1С для работы с HTTP-запросами используются объекты HTTPСоединение и HTTPЗапрос. Важно помнить, что в 1С адрес сервера и путь к ресурсу разделяются.


Функция ОтправитьСМС_ПростойВариант(АдресСервера, Логин, Пароль, Отправитель, Телефон, Текст)
    
    // Проверяем заполнение обязательных полей
    Если ПустаяСтрока(Логин) Или ПустаяСтрока(Пароль) Или ПустаяСтрока(Телефон) Тогда
        Возврат "FAILED";
    КонецЕсли;

    // 1. Создаем соединение. Платформа 8.3 автоматически поддерживает Digest-авторизацию,
    // если передать логин и пароль в конструктор соединения.
    Соединение = Новый HTTPСоединение(АдресСервера, , Логин, Пароль);

    // 2. Формируем тело запроса (аналог CURLOPT_POSTFIELDS)
    // Внимание: в исходном примере был символ "телефон", заменяем его на корректный "&"
    ТелоЗапроса = "email=" + КодироватьСтроку(Отправитель, СпособКодированияСтроки.КодировкаURL)
                + "&phone=" + КодироватьСтроку(Телефон, СпособКодированияСтроки.КодировкаURL)
                + "&text=" + КодироватьСтроку(Текст, СпособКодированияСтроки.КодировкаURL);

    // 3. Создаем запрос к конкретному ресурсу (скрипту на сервере)
    Запрос = Новый HTTPЗапрос("/sendsms");
    Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
    Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);

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

КонецФункции

Разбор нюансов кодирования и передачи параметров

Проанализируем критические отличия между PHP и 1С, которые могут привести к ошибкам:

URL Encoding: В PHP функция urlencode преобразует пробелы в символ "+". В 1С метод КодироватьСтроку со значением СпособКодированияСтроки.КодировкаURL заменяет пробел на "%20". Большинство современных сервисов понимают оба варианта, но если ваш SMS-шлюз специфичен, может потребоваться ручная замена: Результат = СтрЗаменить(КодированнаяСтрока, "%20", "+").

Digest-авторизация: Это метод "вызов-ответ". Сервер сначала возвращает ошибку 401 с уникальным числом (nonce), а клиент должен отправить хеш от пароля и этого числа. 1С в объекте HTTPСоединение берет эту работу на себя. Однако, если сервер требует специфический алгоритм (например, SHA-256), стандартное соединение 1С может не сработать. В этом случае придется формировать заголовок Authorization вручную.

Способ 2: Универсальная функция с разбором URL и поддержкой HTTPS

Часто разработчик получает полный URL (например, https://api.sms-service.com/v1/sendsms). Для 1С его нужно разбить на "Сервер" и "Путь к ресурсу". Также важно предусмотреть работу через защищенное соединение (SSL/TLS).

Рассмотрим более продвинутый пример кода, который учитывает эти факторы:


Функция ОтправитьSMS_Расширенный(ПолныйURL, Пользователь, Пароль, Отправитель, Номер, Сообщение)
    
    // Парсим URL
    Схема = ""; Сервер = ""; Путь = "";
    Если СтрНайти(ПолныйURL, "://") > 0 Тогда
        ЧастиURL = СтрРазделить(ПолныйURL, "://");
        Схема = НРег(ЧастиURL[0]);
        Остаток = ЧастиURL[1];
    Иначе
        Остаток = ПолныйURL;
    КонецЕсли;
    
    ПозСлэша = СтрНайти(Остаток, "/");
    Если ПозСлэша > 0 Тогда
        Сервер = Лев(Остаток, ПозСлэша - 1);
        Путь = Сред(Остаток, ПозСлэша);
    Иначе
        Сервер = Остаток;
        Путь = "/";
    КонецЕсли;

    // Настройка защищенного соединения для HTTPS
    Защита = Неопределено;
    Если Схема = "https" Тогда
        Защита = Новый ЗащищенноеСоединениеOpenSSL();
    КонецЕсли;

    // Инициализация соединения
    HTTPСоединение = Новый HTTPСоединение(Сервер, , Пользователь, Пароль, , , Защита);

    // Формирование структуры параметров
    Параметры = Новый Массив;
    Параметры.Добавить("email=" + КодироватьСтроку(Отправитель, СпособКодированияСтроки.КодировкаURL));
    Параметры.Добавить("phone=" + КодироватьСтроку(Номер, СпособКодированияСтроки.КодировкаURL));
    Параметры.Добавить("text=" + КодироватьСтроку(Сообщение, СпособКодированияСтроки.КодировкаURL));
    
    СтрокаЗапроса = СтрСоединить(Параметры, "&");

    // Создание запроса
    HTTPЗапрос = Новый HTTPЗапрос(Путь);
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
    HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаЗапроса);

    Попытка
        Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
        Возврат Ответ.ПолучитьТелоКакСтроку();
    Исключение
        Возврат "FAILED";
    КонецПопытки;

КонецФункции

Рекомендации по отладке

Выясним причину возможных проблем при реализации интеграции:

Использование объекта HTTPСоединение является наиболее "правильным" и производительным способом для современных конфигураций 1С. В отличие от старых методов через COM-объекты (вроде WinHttp), встроенные средства кроссплатформенны и корректно работают как в Windows, так и в Linux-версиях сервера 1С.

← На главную