Как собрать массив из выборки запроса для клавиатуры Telegram-бота в 1С

Программист IT и автоматизация бизнеса
← На главную

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

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

Базовый алгоритм формирования структуры клавиатуры

Для начала проанализируем базовую структуру inline_keyboard. Telegram ожидает получить массив массивов (массив строк, где каждая строка — это массив кнопок-структур). Рассмотрим типичный код формирования такой клавиатуры внутри цикла обхода выборки запроса.

Допустим, у нас есть результат запроса, содержащий поля ТекстКнопки и Идентификатор. Нам необходимо создать массив строк МассивСтрок, внутри которого будет находиться массив МассивКнопокСтроки.


// Выполняем запрос и получаем выборку
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

// Инициализируем основные контейнеры
МассивСтрок = Новый Массив; // Это общий контейнер для всех рядов кнопок
МассивКнопокСтроки = Новый Массив; // Это контейнер для одного ряда

Пока Выборка.Следующий() Цикл
    
    // Создаем структуру конкретной кнопки
    Кнопка = Новый Структура;
    Кнопка.Вставить("text", Выборка.ТекстКнопки);
    Кнопка.Вставить("callback_data", Выборка.Идентификатор);
    
    // Добавляем кнопку в текущий ряд
    МассивКнопокСтроки.Добавить(Кнопка);
    
КонецЦикла;

// После завершения цикла добавляем сформированный ряд в основной массив
МассивСтрок.Добавить(МассивКнопокСтроки);

// Формируем итоговую структуру клавиатуры
Клавиатура = Новый Структура;
Клавиатура.Вставить("inline_keyboard", МассивСтрок);

В данном примере мы получим все кнопки в один горизонтальный ряд. Если кнопок много, они просто не поместятся на экране смартфона или будут сильно обрезаны.

Распределение кнопок по рядам (сетка кнопок)

Чтобы интерфейс бота выглядел профессионально, кнопки следует распределять по рядам (например, по 2 или 3 кнопки в ряд). Давайте модифицируем наш код, добавив счетчик и логику переноса строки.

Рассмотрим, как реализовать автоматическую разбивку на ряды:


КнопкиВРяду = 2; // Задаем желаемое количество кнопок в одной строке
МассивСтрок = Новый Массив;
МассивКнопокСтроки = Новый Массив;

Пока Выборка.Следующий() Цикл
    
    // Создаем структуру кнопки одной строкой для компактности
    Кнопка = Новый Структура("text, callback_data", Выборка.ТекстКнопки, Выборка.Идентификатор);
    МассивКнопокСтроки.Добавить(Кнопка);
    
    // Если текущий ряд заполнен, переносим его в основной массив и создаем новый ряд
    Если МассивКнопокСтроки.Количество() = КнопкиВРяду Тогда
        МассивСтрок.Добавить(МассивКнопокСтроки);
        МассивКнопокСтроки = Новый Массив;
    КонецЕсли;
    
КонецЦикла;

// Важный момент: проверяем, не остались ли "хвосты" после завершения цикла
Если МассивКнопокСтроки.Количество() > 0 Тогда
    МассивСтрок.Добавить(МассивКнопокСтроки);
КонецЕсли;

Клавиатура = Новый Структура("inline_keyboard", МассивСтрок);

Используя объект Массив и метод Количество(), мы легко управляем геометрией нашей клавиатуры. Обратите внимание на переинициализацию МассивКнопокСтроки = Новый Массив внутри условия — это необходимо, чтобы не очищать старые данные (так как массивы в 1С передаются по ссылке), а создавать новый контейнер для следующей строки.

Преобразование в JSON и отправка

Telegram принимает клавиатуру в формате JSON-строки в параметре reply_markup. Для преобразования структуры 1С в JSON воспользуемся встроенными средствами платформы.

Разберем функцию преобразования:


Функция ПолучитьJSONКлавиатуры(СтруктураКлавиатуры)
    ЗаписьJSON = Новый ЗаписьJSON;
    ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
    ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
    
    ЗаписатьJSON(ЗаписьJSON, СтруктураКлавиатуры);
    
    Результат = ЗаписьJSON.Закрыть();
    Возврат Результат;
КонецФункции

Важный нюанс: Если вы отправляете данные через GET-запрос, строку JSON обязательно нужно закодировать для URL, иначе спецсимволы (кавычки, скобки) приведут к ошибке сервера. Используйте функцию КодироватьСтроку(ТекстJSON, СпособКодированияСтроки.URL).

Критические ограничения Telegram API

Проанализируем технические лимиты, несоблюдение которых часто становится причиной того, что клавиатура "не работает" или сообщение не уходит:

  1. Лимит callback_data: Это самое частое ограничение. Длина значения в поле callback_data не может превышать 64 байта. Если вы передаете туда УникальныйИдентификатор ссылки 1С (36 символов) и добавляете префикс команды, вы вплотную приближаетесь к лимиту. Рекомендуется использовать сокращенные идентификаторы.
  2. Общее количество кнопок: В одном сообщении может быть не более 100 кнопок.
  3. Пустые значения: Если в Выборка.ТекстКнопки придет NULL или пустая строка, Telegram вернет ошибку 400 Bad Request. Всегда используйте проверку ЗначениеЗаполнено() или функцию Строка().
  4. Кодировка: Telegram ожидает UTF-8. Платформа 1С при формировании JSON и использовании HTTPСоединение делает это автоматически, но при ручной сборке строк об этом стоит помнить.

Оптимизация работы с большими выборками

Вместо последовательного обхода Выборка, иногда эффективнее выгрузить результат запроса в таблицу значений методом Выгрузить(). Рассмотрим преимущества такого подхода:

Выясним причину частых ошибок: если код написан верно, но клавиатура не появляется, проверьте права бота и правильность chat_id. Также помните, что inline_keyboard (кнопки под сообщением) и reply_keyboard (кнопки вместо основной клавиатуры) имеют разную структуру и параметры настройки (например, resize_keyboard или one_time_keyboard актуальны только для reply_keyboard).

Таким образом, мы рассмотрели полный цикл создания клавиатуры: от обхода выборки Запрос до формирования вложенных массивов и сериализации в JSON. Использование счетчиков для разбивки на ряды и контроль лимитов callback_data сделают вашу интеграцию надежной и удобной для пользователя.

← На главную