I'm trying to write a telegram bot, that uses inline keyboards to make criteria for selection in a step by step way. And I want the last step of this to be a message telling me what are the criteria selected. Normally I would return the string value from one function and pass it into another, but I'm new to telegram bots and don't know how to do it correctly here. So i thought if i could somehow modify a variable inside a function and then make use of it inside another function that would solve my problem, but unfortunately I didn't manage to find anything that worked for me.
from aiogram import Bot, Dispatcher, executor, types
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
button1 = InlineKeyboardButton(text="Criteria1", callback_data="Never")
button2 = InlineKeyboardButton(text="Criteria2", callback_data="Gonna")
button3 = InlineKeyboardButton(text="Criteria3", callback_data="Give")
button4 = InlineKeyboardButton(text="Selected Criteria", callback_data="You")
keyboard_inline = InlineKeyboardMarkup().add(button1, button4)
keyboard_inline2 = InlineKeyboardMarkup().add(button2, button4)
keyboard_inline3 = InlineKeyboardMarkup().add(button3, button4)
keyboard_inline4 = InlineKeyboardMarkup().add(button4)
bot = Bot(token="")
dp = Dispatcher(bot)
selected_criteria = ""
@dp.message_handler(commands=['start', 'help'])
async def welcome(message: types.Message):
selected_criteria = "Nothing was selected"
await message.reply("Welcome Choose 1st Criteria", reply_markup=keyboard_inline)
@dp.callback_query_handler(text=["Never", "Gonna", "Give", "You"])
async def criteria_selection(call: types.CallbackQuery):
if call.data == "Never":
selected_criteria = "Criteria1 was selected"
await call.message.reply("Choose 2nd Criteria", reply_markup=keyboard_inline2)
if call.data == "Gonna":
selected_criteria = "Criteria2 was selected"
await call.message.reply("Choose 3rd Criteria", reply_markup=keyboard_inline3)
if call.data == "Give":
selected_criteria = "Criteria3 was selected"
await call.message.reply("End Selection", reply_markup=keyboard_inline4)
if call.data == "You":
await call.message.reply(selected_criteria)
await call.answer()
executor.start_polling(dp)
Basically i want to know if there is some way for me to save changes to variable "selected_criteria" and make use of those changes in other functions.
selected_criteria = ""
def function1():
selected_criteria = "criteria1"
def function2():
selected_criteria = "criteria2"
function1()
function2()
print(selected_criteria)
Maybe there is a more natural way to do it with telegram bots if so please tell me.
CodePudding user response:
Not sure if this is a standard pattern, but it seems like you could make these handler functions instance methods (so they can share instance attributes) and register them in __init__
:
class Handler:
def __init__(self):
self.bot = Bot(token="")
self.dp = Dispatcher(bot)
self.selected_criteria = ""
self.dp.message_handler(
commands=['start', 'help']
)(self.welcome)
self.dp.callback_query_handler(
text=["Never", "Gonna", "Give", "You"]
)(self.criteria_selection)
async def welcome(self, message: types.Message):
self.selected_criteria = "Nothing was selected"
await message.reply("Welcome Choose 1st Criteria", reply_markup=keyboard_inline)
async def criteria_selection(self, call: types.CallbackQuery):
if call.data == "Never":
self.selected_criteria = "Criteria1 was selected"
await call.message.reply("Choose 2nd Criteria", reply_markup=keyboard_inline2)
if call.data == "Gonna":
self.selected_criteria = "Criteria2 was selected"
await call.message.reply("Choose 3rd Criteria", reply_markup=keyboard_inline3)
if call.data == "Give":
self.selected_criteria = "Criteria3 was selected"
await call.message.reply("End Selection", reply_markup=keyboard_inline4)
if call.data == "You":
await call.message.reply(self.selected_criteria)
await call.answer()
handler = Handler()