При разработке интеграции 1С с Telegram одной из наиболее частых задач является формирование динамических меню. В отличие от статических кнопок, динамические меню строятся на основе данных из информационной базы: это могут быть списки номенклатуры, статусы заказов или перечень доступных команд. Основная сложность заключается в том, чтобы правильно перенести результат выполнения запроса в специфическую вложенную структуру, которую ожидает Telegram API.
В этой статье мы разберем, как пройти путь от выполнения запроса до получения готовой JSON-строки, рассмотрим правила распределения кнопок по рядам и обсудим технические ограничения, которые важно учитывать, чтобы сообщения успешно доставлялись пользователям.
Для начала проанализируем базовую структуру inline_keyboard. Telegram ожидает получить массив массивов (массив строк, где каждая строка — это массив кнопок-структур). Рассмотрим типичный код формирования такой клавиатуры внутри цикла обхода выборки запроса.
Допустим, у нас есть результат запроса, содержащий поля ТекстКнопки и Идентификатор. Нам необходимо создать массив строк МассивСтрок, внутри которого будет находиться массив МассивКнопокСтроки.
// Выполняем запрос и получаем выборку
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
// Инициализируем основные контейнеры
МассивСтрок = Новый Массив; // Это общий контейнер для всех рядов кнопок
МассивКнопокСтроки = Новый Массив; // Это контейнер для одного ряда
Пока Выборка.Следующий() Цикл
// Создаем структуру конкретной кнопки
Кнопка = Новый Структура;
Кнопка.Вставить("text", Выборка.ТекстКнопки);
Кнопка.Вставить("callback_data", Выборка.Идентификатор);
// Добавляем кнопку в текущий ряд
МассивКнопокСтроки.Добавить(Кнопка);
КонецЦикла;
// После завершения цикла добавляем сформированный ряд в основной массив
МассивСтрок.Добавить(МассивКнопокСтроки);
// Формируем итоговую структуру клавиатуры
Клавиатура = Новый Структура;
Клавиатура.Вставить("inline_keyboard", МассивСтрок);
В данном примере мы получим все кнопки в один горизонтальный ряд. Если кнопок много, они просто не поместятся на экране смартфона или будут сильно обрезаны.
Чтобы интерфейс бота выглядел профессионально, кнопки следует распределять по рядам (например, по 2 или 3 кнопки в ряд). Давайте модифицируем наш код, добавив счетчик и логику переноса строки.
Рассмотрим, как реализовать автоматическую разбивку на ряды:
КнопкиВРяду = 2; // Задаем желаемое количество кнопок в одной строке
МассивСтрок = Новый Массив;
МассивКнопокСтроки = Новый Массив;
Пока Выборка.Следующий() Цикл
// Создаем структуру кнопки одной строкой для компактности
Кнопка = Новый Структура("text, callback_data", Выборка.ТекстКнопки, Выборка.Идентификатор);
МассивКнопокСтроки.Добавить(Кнопка);
// Если текущий ряд заполнен, переносим его в основной массив и создаем новый ряд
Если МассивКнопокСтроки.Количество() = КнопкиВРяду Тогда
МассивСтрок.Добавить(МассивКнопокСтроки);
МассивКнопокСтроки = Новый Массив;
КонецЕсли;
КонецЦикла;
// Важный момент: проверяем, не остались ли "хвосты" после завершения цикла
Если МассивКнопокСтроки.Количество() > 0 Тогда
МассивСтрок.Добавить(МассивКнопокСтроки);
КонецЕсли;
Клавиатура = Новый Структура("inline_keyboard", МассивСтрок);
Используя объект Массив и метод Количество(), мы легко управляем геометрией нашей клавиатуры. Обратите внимание на переинициализацию МассивКнопокСтроки = Новый Массив внутри условия — это необходимо, чтобы не очищать старые данные (так как массивы в 1С передаются по ссылке), а создавать новый контейнер для следующей строки.
Telegram принимает клавиатуру в формате JSON-строки в параметре reply_markup. Для преобразования структуры 1С в JSON воспользуемся встроенными средствами платформы.
Разберем функцию преобразования:
Функция ПолучитьJSONКлавиатуры(СтруктураКлавиатуры)
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, СтруктураКлавиатуры);
Результат = ЗаписьJSON.Закрыть();
Возврат Результат;
КонецФункции
Важный нюанс: Если вы отправляете данные через GET-запрос, строку JSON обязательно нужно закодировать для URL, иначе спецсимволы (кавычки, скобки) приведут к ошибке сервера. Используйте функцию КодироватьСтроку(ТекстJSON, СпособКодированияСтроки.URL).
Проанализируем технические лимиты, несоблюдение которых часто становится причиной того, что клавиатура "не работает" или сообщение не уходит:
callback_data не может превышать 64 байта. Если вы передаете туда УникальныйИдентификатор ссылки 1С (36 символов) и добавляете префикс команды, вы вплотную приближаетесь к лимиту. Рекомендуется использовать сокращенные идентификаторы.Выборка.ТекстКнопки придет NULL или пустая строка, Telegram вернет ошибку 400 Bad Request. Всегда используйте проверку ЗначениеЗаполнено() или функцию Строка().HTTPСоединение делает это автоматически, но при ручной сборке строк об этом стоит помнить.Вместо последовательного обхода Выборка, иногда эффективнее выгрузить результат запроса в таблицу значений методом Выгрузить(). Рассмотрим преимущества такого подхода:
Таблица.Количество() и рассчитать количество рядов.ВыгрузитьКолонку() для получения плоского массива значений, если структура кнопок максимально простая.Выясним причину частых ошибок: если код написан верно, но клавиатура не появляется, проверьте права бота и правильность chat_id. Также помните, что inline_keyboard (кнопки под сообщением) и reply_keyboard (кнопки вместо основной клавиатуры) имеют разную структуру и параметры настройки (например, resize_keyboard или one_time_keyboard актуальны только для reply_keyboard).
Таким образом, мы рассмотрели полный цикл создания клавиатуры: от обхода выборки Запрос до формирования вложенных массивов и сериализации в JSON. Использование счетчиков для разбивки на ряды и контроль лимитов callback_data сделают вашу интеграцию надежной и удобной для пользователя.