Как правильно настроить JSON-запрос и Basic-авторизацию для интеграции с SMS-шлюзом Kcell в 1С

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

Интеграция 1С с внешними веб-сервисами через REST API — одна из самых частых задач современного разработчика. Однако при реализации протокола HTTP часто возникают ошибки, которые трудно диагностировать без понимания нюансов работы протоколов и спецификаций конкретного провайдера. В данной статье мы разберем процесс отправки SMS через шлюз Kcell (api.kcell.kz), проанализируем типичные ошибки 400 Bad Request и 401 Unauthorized, а также приведем эталонный код для стабильной работы.

Разбор первой ошибки: почему сервер возвращает 400 Bad Request?

Когда при отправке запроса вы получаете ответ 400 Bad Request, это означает, что сервер (в данном случае nginx) не смог корректно интерпретировать ваш запрос. Рассмотрим основные причины этой проблемы в контексте 1С:

  1. Некорректная структура JSON: Сервер ожидает строго определенный формат. Например, если вы отправляете массив сообщений на адрес, предназначенный для одиночного сообщения, или наоборот.
  2. Наличие Byte Order Mark (BOM): 1С по умолчанию может добавлять невидимые символы в начало строки при записи в UTF-8. Многие веб-серверы на Linux (включая nginx) не понимают эти символы и прерывают обработку запроса.
  3. Отсутствие обязательных заголовков: Для POST-запросов критически важно указывать Content-Length (длину тела запроса в байтах).

Проанализируем метод установки тела запроса. Чтобы избежать проблем с кодировкой, всегда используйте параметр ИспользованиеByteOrderMark.НеИспользовать в методе УстановитьТелоИзСтроки.

Формирование структуры JSON для одиночных и пакетных сообщений

При работе с SMS-шлюзом важно различать методы отправки. Для одиночного сообщения на адрес /messages структура должна быть простой, без лишних вложений. Разберем на примере:


// Пример формирования JSON для одного сообщения
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("client_message_id");
ЗаписьJSON.ЗаписатьЗначение("123456789");
ЗаписьJSON.ЗаписатьИмяСвойства("sender");
ЗаписьJSON.ЗаписатьЗначение("SMSGW");
ЗаписьJSON.ЗаписатьИмяСвойства("recipient");
ЗаписьJSON.ЗаписатьЗначение("77010000000");
ЗаписьJSON.ЗаписатьИмяСвойства("message_text");
ЗаписьJSON.ЗаписатьЗначение("Текст сообщения");
ЗаписьJSON.ЗаписатьКонецОбъекта();
ТелоЗапроса = ЗаписьJSON.Закрыть();

Если же стоит задача отправить пакет сообщений (метод /batches), структура меняется — появляется корневой массив messages. Посмотрим на этот формат подробнее:


{
  "messages": [
    {
      "client_message_id": "id1",
      "recipient": "77010000001",
      "message_text": "Привет 1"
    },
    {
      "client_message_id": "id2",
      "recipient": "77010000002",
      "message_text": "Привет 2"
    }
  ]
}

Секреты Basic-авторизации в 1С: исправляем ошибку 401

Ошибка 401 Unauthorized сигнализирует о том, что логин или пароль не приняты сервером. В стандарте Basic Authentication есть важный нюанс, который часто упускают: логин и пароль должны быть соединены через двоеточие перед кодированием в Base64.

Проанализируем правильный алгоритм формирования заголовка авторизации:


ИмяПользователя = "ВашЛогин";
ПарольПользователя = "ВашПароль";

// Ключевой момент: соединение через двоеточие
СтрокаДляКодирования = ИмяПользователя + ":" + ПарольПользователя;

// Получаем двоичные данные в UTF-8
ДД = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляКодирования, КодировкаТекста.UTF8, Ложь);

// Кодируем в Base64
ХешАвторизации = Base64Строка(ДД);
ХешАвторизации = СтрЗаменить(ХешАвторизации, Символы.ПС, ""); // Убираем переносы строк
ХешАвторизации = СтрЗаменить(ХешАвторизации, Символы.ВК, "");

ЗаголовокАвторизации = "Basic " + ХешАвторизации;

Важно: Если в пароле используются специальные символы, убедитесь, что кодировка при получении двоичных данных установлена именно в UTF8.

Полный пример кода для отправки SMS через HTTPСоединение

Соберем все полученные знания в единую процедуру. Мы будем использовать объекты HTTPСоединение, HTTPЗапрос и ЗащищенноеСоединениеOpenSSL для работы по защищенному протоколу HTTPS.


Процедура ОтправитьSMS_Kcell()
    
    Сервер = "api.kcell.kz";
    Ресурс = "/app/smsgw/rest/v2/messages";
    
    // 1. Настройка защищенного соединения
    SSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
    
    // 2. Создание соединения
    // Не забывайте указывать прокси, если сервер 1С находится за корпоративным экраном
    Соединение = Новый HTTPСоединение(Сервер, 443, , , , 60, SSL);
    
    // 3. Формирование тела запроса (JSON)
    СтрокаJSON = "{
    |""client_message_id"" : """ + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "") + """,
    |""sender"" : ""SMSGW"",
    |""recipient"" : ""77010000000"",
    |""message_text"" : ""Тестовое сообщение из 1С""
    |}";
    
    // 4. Подготовка запроса и заголовков
    ЗапросHTTP = Новый HTTPЗапрос(Ресурс);
    
    // Авторизация
    Логин = "MyLogin";
    Пароль = "MyPassword";
    ДД_Auth = ПолучитьДвоичныеДанныеИзСтроки(Логин + ":" + Пароль, КодировкаТекста.UTF8, Ложь);
    Хеш = Base64Строка(ДД_Auth);
    
    ЗапросHTTP.Заголовки.Вставить("Authorization", "Basic " + Хеш);
    ЗапросHTTP.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    ЗапросHTTP.Заголовки.Вставить("Accept", "application/json");
    
    // Установка тела и расчет Content-Length (1С сделает это автоматически при УстановитьТелоИзСтроки)
    ЗапросHTTP.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    
    // 5. Отправка и обработка результата
    Попытка
        Ответ = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
        
        Если Ответ.КодСостояния = 200 ИЛИ Ответ.КодСостояния = 201 Тогда
            Сообщить("SMS успешно отправлено!");
        Иначе
            // Если возникла ошибка, читаем тело ответа, чтобы понять причину
            ТекстОшибки = Ответ.ПолучитьТелоКакСтроку();
            Сообщить("Ошибка при отправке! Код: " + Ответ.КодСостояния);
            Сообщить("Ответ сервера: " + ТекстОшибки);
        КонецЕсли;
    Исключение
        Сообщить("Не удалось связаться с сервером: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Как отлаживать HTTP-запросы?

Если код выше все равно выдает ошибку, проанализируем ситуацию с помощью инструментов мониторинга трафика. Рекомендуем использовать Fiddler или Postman.

Дополнительные рекомендации по работе с API

При интеграции с Kcell или любым другим SMS-шлюзом, обратите внимание на следующие важные моменты:

Белые списки IP-адресов: Многие провайдеры блокируют запросы, если IP-адрес вашего сервера не внесен в доверенный список в личном кабинете. Даже при правильном логине и пароле вы можете получить 403 Forbidden.

Ограничения по количеству символов: Помните, что длина одного SMS сообщения на кириллице составляет 70 символов. Если ваш message_text длиннее, шлюз разобьет его на несколько частей, что повлияет на тарификацию. Убедитесь, что ваш алгоритм в 1С учитывает это при рассылках.

Имя отправителя (Sender ID): Параметр sender не может быть произвольным. Он должен быть предварительно согласован с оператором связи. Использование незарегистрированного имени — самая частая причина 400 Bad Request после того, как технические ошибки в коде уже исправлены.

Следуя этим инструкциям и используя проверенный код, мы обеспечим надежную интеграцию 1С с сервисами рассылок, минимизируя время на отладку и поиск скрытых ошибок в HTTP-заголовках.

← На главную