Как прикрепить кнопки к посту? Как записать параметр, значением которого является объект? Что такое JSON-серилизованный массив или список? Ответим на эти и другие вопросы.
В жизни нас окружают объекты, которые имеют свойства со значениями. Для их записи и передачи в понятном для человека текстовом виде используются разные форматы. В JSON это выглядит так.
Пустой объект:
{}
Объект с одним свойством:
{ "chat_id": 123456 }
, где chat_id - имя свойства, 123456 - значение свойства типа Integer
Б ТГ используются следующие простые типы:
Помимо простых типов также используются и сложные - объект и массив.
{ "web_app":{ "url":"URL" } }
Здесь значением свойства web_app является объект со свойством url.
Массив (список) объектов записывается так:
{ "commands": [ { "command": "/start", "description": "Старт" }, { "command": "/help", "description": "Помощь" } ] }
Список массивов (массив массивов):
{ "inline_keyboard": [ [ { "text": "Копировать", "callback_data" : "copy", }, { "text": "Поиск", "callback_data" : "find", } ], [ { "text": "Предыдущий", "callback_data" : "prev", }, { "text": "Следующий", "callback_data" : "next", } ] ] }
Подведём итог и выпишем шаблоны, которые помогут понять какие скобки использовать и где:
А вот такое типа "объект массива" {[]} или "объект в объекте" {{}} уже не пройдёт.
Для проверки корректности записи в JSON-формате существуют онлайн валидаторы. Нередко программный код не работает из-за того, что есть ошибка в формате данных - где-то лишняя запятая, где-то её нет, где-то внутри строки неэкранированный символ и т.д. Валидатор поможет их найти.
Список массивов используется там, где нужно получить два измерения (X и Y), например, для описания кнопок клавиатур. Каждая строка кнопок - это список, каждая кнопка в строке - тоже список.
В Bot Api мы имеем дело с запросами и методами. По этой причине терминология немного меняется. Вместо "свойства объекта" будем говорить параметры (Parameters) метода и поля (fields) объекта.
Рассмотрим метод sendMessage и необязательный параметр entities, который имеет тип массива объектов MessageEntity. Массив объектов - это шаблон вида [{},{}]. В описании написано, что это JSON-серилизованный список. Сериализация в данном контексте означает преобразование в формат, который требуется для передачи данных. Мы не можем передать массив или объект, но можем передать строку. Сериализация как раз и производит их преобразование в строку.
Щёлкем по ссылке MessageEntity и видим, что это объект с тремя обязательными полями - type, offset и length. Теперь можно завершить описание параметра:
{ "entities":[ { "type":"bold", "offset":0, "length":3 } ] }
Если в эту запись добавить параметры chat_id канала и text, то успешное выполнение метода sendMessage создаст сообщение, первые три символа текста которого будут выделены жирным начертанием.
Немного сложнее разобраться с клавиатурами. Для уменьшения числа ошибок имеет смысл последовательно выписывать параметры и поля. Проще говоря, мы выписываем только то, что нам известно к текущему моменту времени.
За вывод или скрытие клавиатуры отвечает параметр reply_markup. Выпишем его:
{ "reply_markup": }
Почему за двоеточием ничего нет? Потому что мы пока не знаем тип этого значения. Можно, конечно, поставить там кавычки. Но, если параметром является объект, а в этот момент что-то отвлекло, то можно элементарно забыть убрать кавычки и получить ошибку.
Значением reply_markup является один из указанных JSON-сериализованных объектов. Теперь мы знаем, что значение является какой-то объект и можем это указать:
{ "reply_markup":{} }
Допустим, нужно создать кнопки под сообщением. Тогда выбираем объект InlineKeyboardMarkup, у которого одно обязательное поле inline_keyboard. Выписываем его:
{ "reply_markup":{ "inline_keyboard": } }
Почему мы выписали inline_keyboard, а не InlineKeyboardMarkup? Потому что объект в JSON - это список его полей, а имена объектов не указываются. В качестве аналогии можно посмотреть путь к файлу, например, С:\Мои документы\Отличные фотки\котик.jpg. Мы же не указываем, что вот это папки, а вот это файл. И так понятно. Так же и в JSON.
Если где-то в явном виде не указано, что значением свойства является объект, то понять это можно по косвенным признакам. Например, если где-то рядом используется слово "поле". Поле без футболистов бывает, а без объекта - нет. Можно пойти от противного и посмотреть, похоже значение свойства на простой тип - строку, число, булев или нет. Если нет, то скорее всего, речь идёт об объекте.
Смотрим тип свойства inline_keyboard. Это массив массивов InlineKeyboardButton. Что такое InlineKeyboardButton? Пока не знаем. Выпишем то, что знаем - массив массивов:
{ "reply_markup":{ "inline_keyboard":[ [ ], [ ] ] } }
Смотрим, что такое InlineKeyboardButton - это объект с обязательным полем text и любым одним обязательным полем из опциональных. Выберем опциональное поле url и завершим вывод структуры, подставив какие-нибудь значения URL:
Ниже дан пример поста с HTML-форматированием текста и кнопками:
Если большая часть показанного понятна, то можно сказать, что сложное осталось позади и впереди нас ждёт только интересное, но в следующий раз.