В этом посте рассмотрим одну фичу, которая может быть полезна дорогому читателю Недавно встал вопрос с множественным выбором. Бот предлагает пользователю список возможных вариантов, а пользователь в свою очередь имеет возможность выбрать несколько из этих вариантов. При том реализовано это через инлайн-клавиатуру Ожидаемый результат работы флагов будет примерно следующий: Краткая вводная дана, переходим к порядку реализации. Создаем бота через @BotFather, создаем новую ГТ и открываем AppsScripts (подробнее про создание ботов можно почитать тут. Как правило, я делю скрипт на несколько логических кусочков и сохраняю в разные файлы Настоятельно рекомендую поступать также. В файл Global записываю глобальные переменные или константы.  Здесь API бота; ссылка на текущий гугл док; лист этого дока, с которым мы будем непосредственно работать. Ссылка на гугл док расположена в адресной строке браузера В файле Keyboards создадим нашу клавиатуру. Клавиатуру я записываю в отдельную переменную (в данном случае FLAGS) Моя клава выглядит так: Сейчас самое интересное… Какая логика? Мы отправляем клаву в чат по запросу пользователя, по команде, например. Далее пользователь кликает на один из вариантов (кнопку), который хочет выбрать. Мы запоминаем его выбор и отправляем новую клавиатуру, где в тексте выбранной кнопки будет изменен флаг. Внимательный читатель заметил, что в названиях кнопок есть смайлики. Они-то и будут нашими флагами, которые отражают одно из значений true/false, 1/0, да/нет. Так как мы записываем клаву в таблицу, сначала будем проверять, есть ли уже эта клава в таблице и в какой именно ячейке она записана. Искать будем по ключу chat_id Функция выше возвращает id строки таблицы, в которой записан искомый ид чата. Id строки в таблице и номер строки - не одно и то же. Когда мы забираем все значения из таблицы и записываем их в массив (методом getValues()), значения в массиве начинаются с 0, тогда как в таблице отсчет ведется с 1. Просто помним об этом) Следующая функция ищет chat_id в таблице и возвращает соответствующую этому ид клаву. В ином случае возвращает дефолтную клаву. И разумеется, нужна функция для сохранения клавиатуры в таблице гугл Здесь я сначала разделяю текст кнопки, которая была нажата, по пробелам, получая массив. Далее изменяю первый элемент (смайлик) на противоположное значение. Объединяю все снова в один текст для этой кнопки и записываю в таблицу. Сохраненная в таблице клавиатура будет выглядеть так Соответственно, если ботом пользуются несколько человек в разных чатах, то для каждого чата будет выделена строка в таблице под свою клавиатуру. Идентификатор является ид чата (первая колонка) Также запилю функцию для отправки клавы пользователя в виде сообщения Бот будет общаться с пользователем с помощью двух функций send() и send_key(). С первой из них уже было знакомство в этой статье, вторую рассмотрим здесь. Функция отправляет инлайн-клавиатуру в чат вместе с сообщением. Соответственно на входе нам нужны текст сообщения, ид чата, куда мы эти сообщение и клаву отправляем, апи бота и сама клава. Вызываем функции send() и send_key() из тела  функции doPost(). Стандартная функция doPost() для коммуникации с ботом получает от нас одну из двух команд и выполняет два соотвутствующих этим командам действия: отправляет клаву в чат; отправляет сообщение, текст которого содержит выбор пользователя В функции выше у нас имеются два условия update.hasOwnProperty('message') update.hasOwnProperty('callback_query') В первый if мы попадаем при условии, что пользователь написал боту сообщение, а во второй, - когда пользователь нажал на нопку. В переменную vote я записываю значение callback_data нажатой кнопки. callback_data мы указали в переменной FLAGS для каждой кнопки, и эти значения - числа от 0 до 10. Эти же числа выполняют роль номера элемента массива при работе c кнопками в функции setKeyboard(). Сохраняем и деплоим Создадим файл Api connector и запишем сюда функцию установки вебхука Укажем App_link (ссылка появляется в окне после деплоя) и запустим функцию api_connector. Я отправила боту сообщение "/getkeyboard",  на что он мне вернул клаву без галочек Далее результат клика по одной из кнопок Я бы еще удаляла предыдущую клаву, чтобы у нас оставалась только одна активная. К списку функций в файл functions допишем следующую функцию И добавим вызов этой функции в doPost() Проверяем работу бота снова Предыдущая клава успешна удалена. По команде "/save" мы получаем от бота нашу клаву в виде сообщения Я описала функционал, который может быть полезен в тех или иных ботах. Его конечно можно модифицировать или усовершенствовать и допилить под ваши нужды. Но, надеюсь, общая идея ясна.