Почему символ «+» пропадает при отправке сообщения в Telegram бот из 1С?

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

При разработке интеграции 1С с мессенджером Telegram программисты часто сталкиваются с ситуацией, когда текстовые сообщения или команды доходят до адресата в искаженном виде. Одной из наиболее типичных проблем является исчезновение символа «+» (плюс). Например, вместо ожидаемой команды /+ 1 пользователь видит в чате / 1. Рассмотрим подробно, почему это происходит, и разберем способы исправления этой ошибки.

Выясним причину: почему пропадает плюс?

Проблема кроется не в самом Telegram и не в платформе 1С как таковой, а в стандартах передачи данных по протоколу HTTP. Чаще всего для взаимодействия с Telegram API разработчики используют метод GET, передавая параметры сообщения прямо в строке адреса (URL).

Согласно спецификации RFC 1738, символ + в строке запроса является зарезервированным. Он интерпретируется веб-сервером (в данном случае сервером Telegram) как пробел. Именно поэтому, когда вы отправляете строку "/+ 1", принимающая сторона «справедливо» заменяет плюс на пробел, и на выходе получается "/ 1". Для того чтобы передать плюс именно как символ, его необходимо подвергнуть специальному преобразованию — URL-кодированию (Percent-encoding).

Решение №1: Использование функции URL-кодирования в 1С

Самый простой способ заставить Telegram корректно отображать спецсимволы при использовании GET-запросов — это закодировать строку перед отправкой. В платформе 1С для этого предусмотрена встроенная функция КодироватьСтроку().

Разберем ситуацию на примере кода, предоставленного автором темы. Вместо прямой склейки строк, применим кодирование:


// Исходный текст сообщения
ТекстСообщения = "/+ 1 - выполняется установка начала рабочего дня" + Символы.ПС + "/- 1 - выполняется установка конца рабочего дня";

// Неправильный способ формирования URL (плюс превратится в пробел)
// Ресурс = "sendMessage?chat_id=" + Идентификатор + "&text=" + ТекстСообщения;

// Правильный способ с использованием кодирования
ЗакодированныйТекст = КодироватьСтроку(ТекстСообщения, СпособКодированияСтроки.КодировкаURL);
Ресурс = "sendMessage?chat_id=" + Формат(ИдентификаторЧат, "ЧГ=0") + "&text=" + ЗакодированныйТекст;

При использовании СпособКодированияСтроки.КодировкаURL символ + будет заменен на шестнадцатеричную последовательность %2B. Когда сервер Telegram получит такой запрос, он выполнит обратное декодирование и отобразит пользователю исходный символ +.

Важный нюанс: при кодировании всей строки целиком символ / (слэш) может превратиться в %2F. В большинстве случаев Telegram корректно распознает это как команду, но если вы хотите сохранить структуру URL-параметров максимально «чистой», кодируйте только те части строки, которые содержат пользовательский ввод или спецсимволы.

Решение №2: Переход на метод POST и использование JSON

Использование метода GET для передачи длинных текстовых сообщений считается плохой практикой (bad practice). Существуют ограничения на длину URL-строки, а проблемы с кодировкой спецсимволов (не только плюса, но и &, #, ?) будут возникать постоянно. Проанализируем более надежный подход — отправку данных методом POST с телом в формате JSON.

При передаче данных в теле POST-запроса необходимость в URL-кодировании текстовых параметров отпадает, так как данные передаются не в заголовке запроса, а в его теле. Посмотрим на пример реализации:


// Формируем структуру данных для Telegram
ДанныеЗапроса = Новый Структура;
ДанныеЗапроса.Вставить("chat_id", ИдентификаторЧат);
ДанныеЗапроса.Вставить("text", "/+ 1 - установка начала дня");

// Сериализуем структуру в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеЗапроса);
СтрокаJSON = ЗаписьJSON.Закрыть();

// Настройка HTTP-запроса
Запрос = Новый HTTPЗапрос("sendMessage");
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Отправка через HTTPСоединение
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

В данном случае 1С передает данные в чистом виде UTF-8. Это исключает любые искажения символов +, кириллицы и эмодзи. Кроме того, использование POST позволяет отправлять сообщения практически неограниченной длины.

Решение №3: Учет особенностей разметки (MarkdownV2)

Если в вашем коде используется параметр parse_mode = 'MarkdownV2', то символ + может пропадать или вызывать ошибку Bad Request по другой причине. В синтаксисе MarkdownV2 плюс является служебным символом.

Проанализируем правила экранирования: в режиме MarkdownV2 любые символы с кодами от 1 до 126, которые используются как спецсимволы (включая _, *, [, ], (, ), ~, `, >, #, +, -, =, |, {, }, ., !), должны быть экранированы обратным слэшем \.

Пример правильной строки для MarkdownV2:

СтрокаСообщения = "/\+ 1 - выполняется установка";

Если вы не планируете использовать жирный шрифт или курсив, рекомендуем использовать parse_mode = 'HTML' или вовсе не указывать этот параметр. В HTML-режиме плюс не требует экранирования, нужно будет следить только за символами <, > и &.

Ограничения Telegram на имена команд

Важно помнить о техническом ограничении самого Telegram: командой (клиentities) считается только то слово, которое начинается со слэша и содержит только латинские буквы, цифры и подчеркивания. Символ + технически не может быть частью «синей кликабельной ссылки» команды.

  1. Если вы отправите /+команда, Telegram не подсветит это как команду.
  2. Пользователю придется вводить это вручную или копировать.
  3. Для удобства взаимодействия лучше использовать текстовые алиасы, например /add_work_day вместо /+ 1.

Если же использование плюса — это требование интерфейса, то ваш бот на стороне 1С должен обрабатывать входящее сообщение не как команду (Command), а как обычный текст, анализируя первые символы строки самостоятельно.

Резюме и рекомендации

Разберем по шагам алгоритм действий, если у вас пропадают символы при работе с ботом:

  1. Проверьте метод отправки. Если используется GET, обязательно применяйте КодироватьСтроку(Текст, СпособКодированияСтроки.КодировкаURL).
  2. Проверьте кодировку. Убедитесь, что данные отправляются в UTF-8 без BOM (Byte Order Mark).
  3. Используйте POST. Это избавит вас от большинства проблем с кодированием URL-адресов и спецсимволов.
  4. Следите за parse_mode. Если используете MarkdownV2, не забывайте экранировать плюс обратным слэшем \+.
  5. Очистка строки. Убедитесь, что между слэшем и плюсом нет невидимых символов (например, неразрывных пробелов), скопированных из текстовых редакторов. Лучше переписать строку вручную непосредственно в конфигураторе 1С.

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

← На главную