Интеграция 1С с мессенджером Telegram открывает огромные возможности для автоматизации бизнеса: от оперативного получения отчетов до оформления заказов прямо из чата. Одной из ключевых задач при разработке бота является создание удобного интерфейса взаимодействия с пользователем. В этой статье мы подробно разберем, как программно выводить клавиатуры разных типов (Inline и Reply) средствами 1С, как обрабатывать нажатия на кнопки и как динамически управлять их расположением.
Для начала проанализируем ситуацию: Telegram принимает команды через HTTP-запросы. Чтобы отправить пользователю клавиатуру, необходимо в методе sendMessage заполнить необязательный параметр reply_markup. Этот параметр должен содержать строку в формате JSON, описывающую структуру кнопок. Выясним причину, по которой у многих разработчиков возникают сложности на начальном этапе: Telegram ожидает не просто плоский список кнопок, а «массив массивов». Каждый вложенный массив представляет собой отдельный ряд кнопок в интерфейсе мессенджера.
Рассмотрим основные типы клавиатур, которые мы можем использовать:
Прежде чем формировать саму клавиатуру, нам понадобится надежная функция для работы с методом sendMessage. Рассмотрим пример реализации, где мы передаем параметры запроса. Обратите внимание, что сложные структуры, такие как клавиатура, лучше передавать через тело POST-запроса, чтобы избежать проблем с длиной URL и спецсимволами.
Функция sendMessage(chat_id, text, reply_markup = Неопределено) Экспорт
Если НЕ ЗначениеЗаполнено(chat_id) ИЛИ НЕ ЗначениеЗаполнено(text) Тогда
Возврат Неопределено;
КонецЕсли;
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("chat_id", chat_id);
ПараметрыЗапроса.Вставить("text", text);
Если reply_markup <> Неопределено Тогда
ПараметрыЗапроса.Вставить("reply_markup", reply_markup);
КонецЕсли;
// Рекомендуется использовать POST запрос с передачей JSON в теле
ТекстJSON = СформироватьJSON(ПараметрыЗапроса);
Результат = ОтправитьHTTPЗапрос("sendMessage", ТекстJSON);
Возврат Результат;
КонецФункции
Разберем по шагам процесс создания инлайн-кнопок. Каждая кнопка — это объект Структура, содержащий обязательные поля text (то, что видит пользователь) и callback_data (скрытый идентификатор, который вернется в 1С при нажатии).
Посмотрим на пример формирования клавиатуры с двумя кнопками в одном ряду:
// 1. Создаем массив, который будет содержать строки кнопок
СтрокиКнопок = Новый Массив;
// 2. Создаем массив для первого ряда кнопок
ПервыйРяд = Новый Массив;
// 3. Описываем кнопки и добавляем их в ряд
Кнопка1 = Новый Структура("text, callback_data", "Прайс-лист", "get_price");
Кнопка2 = Новый Структура("text, callback_data", "Оформить заказ", "create_order");
ПервыйРяд.Добавить(Кнопка1);
ПервыйРяд.Добавить(Кнопка2);
// 4. Добавляем ряд в общую структуру клавиатуры
СтрокиКнопок.Добавить(ПервыйРяд);
// 5. Оборачиваем в структуру inline_keyboard
КлавиатураОбъект = Новый Структура("inline_keyboard", СтрокиКнопок);
// 6. Сериализуем в JSON
КлавиатураJSON = СформироватьJSON(КлавиатураОбъект);
// 7. Отправляем сообщение
sendMessage(IDПользователя, "Выберите интересующий вас раздел:", КлавиатураJSON);
Часто возникает вопрос: как сделать так, чтобы кнопки располагались одна под другой? Для этого нужно проанализировать структуру вложенности. Чтобы каждая кнопка была на новой строке, нам необходимо каждую кнопку помещать в свой собственный отдельный массив (ряд).
Рассмотрим пример динамического формирования вертикального списка из справочника или таблицы значений:
СтрокиКнопок = Новый Массив;
Для Каждого СтрТЗ Из ТаблицаТоваров Цикл
НовыйРяд = Новый Массив;
Кнопка = Новый Структура;
Кнопка.Вставить("text", СтрТЗ.Наименование);
// Важно: callback_data ограничен 64 байтами!
Кнопка.Вставить("callback_data", "id_" + СтрТЗ.Код);
НовыйРяд.Добавить(Кнопка);
СтрокиКнопок.Добавить(НовыйРяд);
КонецЦикла;
КлавиатураОбъект = Новый Структура("inline_keyboard", СтрокиКнопок);
Принцип создания reply_keyboard практически идентичен, но вместо callback_data в структуре кнопки обычно используется только text. При нажатии на такую кнопку пользователь просто «отправляет» боту сообщение с этим текстом. Проанализируем дополнительные параметры, такие как resize_keyboard, который делает кнопки компактными (по умолчанию они огромные).
СтрокиКнопок = Новый Массив;
Ряд1 = Новый Массив;
Ряд1.Добавить(Новый Структура("text", "Главное меню"));
Ряд1.Добавить(Новый Структура("text", "Помощь"));
СтрокиКнопок.Добавить(Ряд1);
КлавиатураОбъект = Новый Структура;
КлавиатураОбъект.Вставить("keyboard", СтрокиКнопок);
КлавиатураОбъект.Вставить("resize_keyboard", Истина);
КлавиатураОбъект.Вставить("one_time_keyboard", Истина); // Скроет клавиатуру после нажатия
КлавиатураJSON = СформироватьJSON(КлавиатураОбъект);
Когда пользователь нажимает инлайн-кнопку, 1С получает входящее обновление (через getUpdates или Webhook), содержащее объект callback_query. Важно понимать, что в этом случае текстовое поле message.text может быть пустым, а данные нужно искать в callback_query.data.
Важный нюанс: После получения callback_query бот обязан вызвать метод answerCallbackQuery. Если этого не сделать, на кнопке у пользователя будет продолжать крутиться индикатор загрузки. С помощью этого метода можно также вывести всплывающее уведомление.
Если НС.Свойство("callback_query") Тогда
IDЗапроса = НС.callback_query.id;
ДанныеКнопки = НС.callback_query.data;
Если ДанныеКнопки = "get_price" Тогда
// Логика вывода прайса
ОтправитьПрайс(НС.callback_query.message.chat.id);
КонецЕсли;
// Обязательное подтверждение получения запроса
ПодтвердитьНажатиеКнопки(IDЗапроса, "Запрос обрабатывается...");
КонецЕсли;
Для корректной работы с Telegram API крайне важно правильно преобразовывать объекты 1С (Структуры и Массивы) в строку JSON. Рассмотрим наиболее надежный способ с использованием встроенных средств платформы 8.3:
Функция СформироватьJSON(Объект)
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет,,, ЭкранированиеСимволовJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, Объект);
Результат = ЗаписьJSON.Закрыть();
Возврат Результат;
КонецФункции
Использование параметра ЭкранированиеСимволовJSON.Нет особенно важно, если в названиях кнопок используются кириллические символы или спецзнаки, так как это предотвращает появление лишних обратных слэшей в JSON-строке, которые Telegram может не распознать.
Таким образом, мы рассмотрели полный цикл работы с клавиатурами: от проектирования вложенных массивов до отправки и обработки обратной связи. Помните о лимитах Telegram (например, ограничение в 64 байта для callback_data) и всегда подтверждайте действия пользователя через answerCallbackQuery для обеспечения лучшего пользовательского опыта.