Интеграция 1С с внешними веб-сервисами через REST API — одна из самых частых задач современного разработчика. Однако при реализации протокола HTTP часто возникают ошибки, которые трудно диагностировать без понимания нюансов работы протоколов и спецификаций конкретного провайдера. В данной статье мы разберем процесс отправки SMS через шлюз Kcell (api.kcell.kz), проанализируем типичные ошибки 400 Bad Request и 401 Unauthorized, а также приведем эталонный код для стабильной работы.
Когда при отправке запроса вы получаете ответ 400 Bad Request, это означает, что сервер (в данном случае nginx) не смог корректно интерпретировать ваш запрос. Рассмотрим основные причины этой проблемы в контексте 1С:
Content-Length (длину тела запроса в байтах).Проанализируем метод установки тела запроса. Чтобы избежать проблем с кодировкой, всегда используйте параметр ИспользованиеByteOrderMark.НеИспользовать в методе УстановитьТелоИзСтроки.
При работе с 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"
}
]
}
Ошибка 401 Unauthorized сигнализирует о том, что логин или пароль не приняты сервером. В стандарте Basic Authentication есть важный нюанс, который часто упускают: логин и пароль должны быть соединены через двоеточие перед кодированием в Base64.
Проанализируем правильный алгоритм формирования заголовка авторизации:
ИмяПользователя = "ВашЛогин";
ПарольПользователя = "ВашПароль";
// Ключевой момент: соединение через двоеточие
СтрокаДляКодирования = ИмяПользователя + ":" + ПарольПользователя;
// Получаем двоичные данные в UTF-8
ДД = ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляКодирования, КодировкаТекста.UTF8, Ложь);
// Кодируем в Base64
ХешАвторизации = Base64Строка(ДД);
ХешАвторизации = СтрЗаменить(ХешАвторизации, Символы.ПС, ""); // Убираем переносы строк
ХешАвторизации = СтрЗаменить(ХешАвторизации, Символы.ВК, "");
ЗаголовокАвторизации = "Basic " + ХешАвторизации;
Важно: Если в пароле используются специальные символы, убедитесь, что кодировка при получении двоичных данных установлена именно в UTF8.
Соберем все полученные знания в единую процедуру. Мы будем использовать объекты 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 успешно отправлено!");
Иначе
// Если возникла ошибка, читаем тело ответа, чтобы понять причину
ТекстОшибки = Ответ.ПолучитьТелоКакСтроку();
Сообщить("Ошибка при отправке! Код: " + Ответ.КодСостояния);
Сообщить("Ответ сервера: " + ТекстОшибки);
КонецЕсли;
Исключение
Сообщить("Не удалось связаться с сервером: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если код выше все равно выдает ошибку, проанализируем ситуацию с помощью инструментов мониторинга трафика. Рекомендуем использовать Fiddler или Postman.
Ответ.ПолучитьТелоКакСтроку(). Часто провайдеры возвращают детальное описание ошибки в формате JSON (например: "Invalid sender name").При интеграции с Kcell или любым другим SMS-шлюзом, обратите внимание на следующие важные моменты:
Белые списки IP-адресов: Многие провайдеры блокируют запросы, если IP-адрес вашего сервера не внесен в доверенный список в личном кабинете. Даже при правильном логине и пароле вы можете получить 403 Forbidden.
Ограничения по количеству символов: Помните, что длина одного SMS сообщения на кириллице составляет 70 символов. Если ваш message_text длиннее, шлюз разобьет его на несколько частей, что повлияет на тарификацию. Убедитесь, что ваш алгоритм в 1С учитывает это при рассылках.
Имя отправителя (Sender ID): Параметр sender не может быть произвольным. Он должен быть предварительно согласован с оператором связи. Использование незарегистрированного имени — самая частая причина 400 Bad Request после того, как технические ошибки в коде уже исправлены.
Следуя этим инструкциям и используя проверенный код, мы обеспечим надежную интеграцию 1С с сервисами рассылок, минимизируя время на отладку и поиск скрытых ошибок в HTTP-заголовках.