Инструкции Salebot

Динамическое меню. Изменяемые кнопки. В Telegram боте

2022-11-26 23:17 Инструкции
Динамическое меню / изменяемые кнопки!

Очень частый вопрос "А как сделать, чтобы кнопки в боте были чем-то вроде переключателей, типо Вкл/Выкл?" или "А как сделать множественный выбор в кнопках?".

И теперь перед тобой инструкция к применению.

  • Как обычно пример масштабируемый под любое количество кнопок
  • Реализован вывод результата в зависимости от выбранных вариантов

Приступим ...

О типах данных. В salebot, так же как и в программировании существует несколько типов данных: строковые и числовые.
Подробно о типах данных можно почитать здесь
Я всегда рекомендую активно использовать в переменных и call_back числовые данных, так как они поддаются математическим операциям и имеют четкий, предсказуемый порядок и иерархию.

В это уроке я так же активно использую числа.

Стартовый блок


  • Создадим блок "Начало диалога" с обычным условием /start
  • В настройках проекта зададим переменную bot_token и укажем в ней api token вашего Telegram бота
  • С первого же блока мы будем использовать Telegram Bot Api, так что указываем в нём следующие настройки. Ниже я дам пояснения по используемым переменным
  • - Тип запроса - POST-data
  • - URL запроса - https://api.telegram.org/bot#{bot_token}/sendMessage
  • - Сохраняемые значения - result|message_id -> message_id
  • - JSON параметры:
{
  "chat_id":"#{platform_id}",
  "text":"Здесь написан какой-то супер умный текст, ну или не очень умный 🤪",
  "reply_markup":"{\"inline_keyboard\":[[{\"text\":\"Кнопка 1 - #{checkpoint_1}\",\"callback_data\":1}],[{\"text\":\"Кнопка 2 - #{checkpoint_2}\",\"callback_data\":2}],[{\"text\":\"Кнопка 3 - #{checkpoint_3}\",\"callback_data\":3}]]}"
}
  • В калькуляторе укажем следующие переменные, так мы задаём стартовые значения наших "переключателей":
  • checkpoint_1 = "❌"
  • checkpoint_2 = "❌"
  • checkpoint_3 = "❌"

Как добавить кнопки и на каких этапах для этого нужно сделать изменения я расскажу в конце статьи. Пока разберём пример с тремя кнопками


Обрати внимание на написание текста кнопок и callback_data!


В тексте каждой кнопки указана переменная вида #{checkpoint_1}.
Эти переменные являются изменяемыми значениями. Весь текст кнопки может быть прописан в каждой из этих переменных.
Цифра в каждой из этих переменных соответствует номеру кнопки. У тебя наверняка текст в кнопке будет другой, но в переменной обязательно прописывай ее порядковый номер.
В callbak_data каждой кнопки также указан порядковый номер кнопки и он совпадает с соответствующим номером в переменной #{checkpoint_...}.

Блок "Изменение кнопок"


  • От стартового блока протягиваем стрелку и создаём новый блок "Изменение кнопок"
  • В стрелке указываем следующие параметры:
  • - Условие, здесь указываем каждый callback_data из кнопок предыдущего блока. Т.е. сколько было кнопок столько цифр прописываем по порядку, в примере три кнопки - 1;2;3
  • - Выбор соответствия - Полное совпадение
  • - Отображать как кнопку - выключить
  • - Пользователь вводит данные - включить
  • - Задаём переменную для пользовательского ввода - click


  • В блоке "Изменение кнопок" указываем следующие настройки:
- Тип запроса - POST-data
- URL запроса - https://api.telegram.org/bot#{bot_token}/editMessageText
- Сохраняемые значения - result|message_id -> message_id
- JSON параметры:
{
  "chat_id":"#{platform_id}",
  "message_id":"#{message_id}",
  "text":"Здесь написан какой-то супер умный текст, ну или не очень умный 🤪",
  "reply_markup":"{\"inline_keyboard\":[[{\"text\":\"Кнопка 1 - #{checkpoint_1}\",\"callback_data\":1}],[{\"text\":\"Кнопка 2 - #{checkpoint_2}\",\"callback_data\":2}],[{\"text\":\"Кнопка 3 - #{checkpoint_3}\",\"callback_data\":3}],[{\"text\":\"✅ Подтвердить ✅\",\"callback_data\":\"done\"}]]}"
}

Здесь изменился метод в URL запроса и соответственно в JSON параметрах добавился параметр message_id изменяемого сообщения.
А также на этом этапе мы добавляем кнопку "✅ Подтвердить ✅" с callback_data - done. Ведь один клик пользователем в предыдущем блоке уже произошёл.
И главная магия происходит в калькуляторе, благодаря указанным цифрам в переменных и callback_data

В калькуляторе указываем следующие функции:
  • checkpoint_#{click} = if(checkpoint_#{click} == "✅", "❌", if(checkpoint_#{click} == "❌","✅", 0))
Здесь с помощью переменной #{click}, в которую помещен порядковый номер нажатой кнопки, мы указываем калькулятору в какой именно кнопке нужно произвести изменение. А с помощью функции if и вложенности в ней меняем одно значение на другое.
  • num = 1
Этот порядковый номер нам понадобится далее для вывода результата выбора
  • result = []
Здесь мы создаём пустой массив он также понадобится далее для вывода результата выбора


  • Теперь создаём петлю для блока "Изменение кнопок" нажав соответствующую кнопку в нём или вручную протянув от него к нему же стрелку.


  • В стрелке указываем точно такие же значения, как и в предыдущей стрелке.
  • Это позволит нам зациклить "переключение" кнопок и изменять одно и тоже сообщения, так как нам надо. При этом не нужно создавать дополнительного блока


Выдаём результат выбора


Результат выбора можно выдавать "топорно" просто показав значения всех кнопок, где-то будет стоят галочка, а где-то крестик. Но нам же не нужен простой результат :)
В моё примере бот выдаёт только выбранные значения в пронумерованном списке. Так же гораздо нагляднее.


А сам значения кнопок можно использовать в дальнейшей логике для формирования заказа, разветвления или чего ты там себе придумаешь.

  • От блока "Изменение кнопок" протянем стрелку и создадим новый блок "Формирование Итога"
  • В стрелке укажем следующие параметры:
  • - Задержка перед ответом - 0 секунд
  • - Условие - done
  • Это callback_data кнопки "✅ Подтвердить ✅".
  • - Отображать как кнопку - выключить
  • - Выбор соответствия - Полное совпадение


  • В блоке "Формирование Итога" в калькуляторе пропишем функцию
result = if(checkpoint_#{num} == "✅", append(result, "Кнопка #{num} - #{checkpoint_#{num}}"),append(result, "1"))

Пояснение к функции.


В предыдущем блоке мы создали пустой массив result. В этом блоке мы начнём его заполнять.
Также в предыдущем блоке мы задали значение счётчику num = 1, здесь мы начнём его использовать для прохождения по всем кнопкам и записи значений всех кнопок в массив result.
Как здесь работает функция if. Если значение переменной checkpoint_1, цифра меняется по счётчику num, равна "✅", то мы добавляем с помощью функции append в ранее созданный массив значение соответствующей кнопки.
При значении num = 1 это будет "Кнопка 1 - ✅"
Если же checkpoint_1 не равно "✅", то добавляем в массив цифру "1".
Далее мы сделаем цикл и с помощью него проверим значение каждой кнопки, добавив в массив нужные данные.
  • Протягиваем от блока "Формирование Итога" стрелку и создаём новый блок "Цикл". В настройках стрелки указываем:
  • - Задержка перед ответом - 0 секунд
  • - Переменная для сравнения - num <= 3
  • Здесь мы указываем количество имеющихся у нас кнопок, т.е. сейчас это 3 кнопки. Чтобы ограничить количество тактов цикла.
  • Также сразу от блока "Цикл" протянем стрелку обратно к блоку "Формирование Итога" указав в настройках стрелки:
  • - Задержка перед ответом - 0 секунд


  • В блоке "Цикл" в калькуляторе прописываем функции:
result = remove(result,"1")
С помощью этой функции мы удаляем из итогового массива не нужные нам "1". Которые были записаны в блоке "Формирование Итога", если в кнопке не было значения "✅"
num = num + 1
Повышаем счётчик на 1, для перехода проверки на следующую кнопку.
Далее цикл сам проходит по всем имеющимся кнопкам.
  • От блока "Формирование Итога" протягиваем еще одну стрелку и создаём последний блок "Итог". В стрелке указыаем следующие параметры:
  • - Задержка перед ответом - 0 секунд
  • - Переменная для сравнения - num > 3
Здесь также указано количество используемых кнопок. Когда цикл пройдёт по всем кнопкам, то он перейдёт в блок "Итог".


  • В блоке "Итог" указываем следующие настройки:
  • - Текст сообщения - #{result}
  • - Функции калькулятора:
result = remove(result,"1")
Так мы удаляем последнюю единицу из массива с конечным результатом.
result = massive_to_text(result, "Вы выбрали:", 1)
Здесь мы приводим массив в удобочитаемый пронумерованный список.
В функцию massive_to_text передаём обрабатываемый массив, затем текстовый Заголовок, и с помощью "1" указываем функции, что список нужно пронумеровать.
Получаем вот такой результат


Как добавить кнопки?


Напишу в какие местах и что нужно изменить.
  • Добавить сами кнопки в JSON параметры в блоках: Стартовый и Изменение кнопок.
  • При добавлении новых кнопок обязательно прописывать следующие по порядку цифры в переменной #{checkpoint_...} и в callback_data новых кнопок.



  • Добавить в Условие двух стрелок через точка с запятой callback_data новых кнопок. Т.е. добавить новые цифры по порядку


  • Заменить цифру в сравнении переменной num в двух стрелках на самую большую цифру, которая есть в копках. Т.е. если кнопок 5, то прописать 5, если кнопок 10, то прописать 10


  • Всё тестануть! :)

ЕСЛИ У ВАС ПРОБЛЕМЫ С ОТРАБОТКОЙ ЦИКЛА И ВЫВОДОМ РЕЗУЛЬТАТОВ, КАК ПОКАЗАНО ВЫШЕ


В salebot бывают проблемы в отработкой циклов. Я же не могу вас оставить в беде :)
В идеале описанный выше цикл написать на Python, тогда он 100% рабочий.
Но не все пишут на Python, так что есть совсем простой вариант: просто выводить значения всех кнопок.


На скрине выше, я создал еще один блок "Формирование результата" и протянул к нему стрелку с Условием "done". Блоке прописаны по порядку все кнопки с конечными значения и вот такой результат получает польщователь