Я измучился, да, буквально измучился при разработке собственного Telegram-бота для своего радио. Проблема возникла при составлении корректного ответа на запрос WebHook, который должен был отобразить кнопочку, нажатие на которую вызывает открытие ссылки у пользователя. Проблема была в том, что я никак не мог понять, как должен выглядеть ответ в формате JSON и как описывать поле inline_markup. Поиск в Google по запросу типа «telegram bot inline_markup request example» выдавал только примеры кода на PHP и Python, причём все использовали какие-то мудрёные фреймворки, компоненты которых разбросаны по файлам так, что отпало всякое желание в них разбираться.

Итак, делюсь с вами полным ответом, который вызовет Inline URL Button у пользователя в ответ на его команду:

{
	"text": "Няяши говорят няя",
	"chat_id": 313371488228,
	"reply_markup": {
		"inline_keyboard": [
			[{
				"text": "Текст на кнопке",
				"url": "https:\/\/example.com\/ya3bal\/nus\/sus"
			}]
		]
	}
}

Обратите внимание на два вложенных одномерных массива. Этот нюанс недостаточно очевидно описан в документации Telegram (особенно в отношении ответов JSON на прилетевший запрос WebHook). Туда можно посылать как JSON-строку, так и вложенный JSON-объект, но там два одномерных массива. Возможно, для многих это было очевидно, однако я промучился с этим достаточно долго. При запросе по HTTP в это поле записывается сериализованный объект в виде строки.