'How do I transfer button values to a variable?

Good evening, can you tell me how to pass a variable value from a button? I tried to implement something like that, but unfortunately I couldn't. Are there any other solutions to this problem?

Code:

variable = 0

@dp.callback_query_handler(text="buy ticket")
async def buyit(query: CallbackQuery):
    keycheck = InlineKeyboardMarkup(row_width=2).add(
        InlineKeyboardButton(text="Privacy", url="http://2.pdf"),
        InlineKeyboardButton(text="Offer", url="http://1.pdf"),
        InlineKeyboardButton(text="Yes", callback_data="check:1"),
        InlineKeyboardButton(text="No", callback_data="check:2"),
    )
    await query.message.edit_text("Before you buy a ticket, please read the privacy policy and the public offer", reply_markup=keycheck)
    global variable
    variable = int(query.data.split(":")[1])
    if variable == 1:
        print(1)
    elif variable ==2:
        print(2)


Solution 1:[1]

For example, if you want to handle this variables in next function, you could use callback_query handler with text_contains filter:

@dp.callback_query_handler(text="buy ticket")
async def buyit(query: types.CallbackQuery):
    keycheck = InlineKeyboardMarkup(row_width=2).add(
        InlineKeyboardButton(text="Privacy", url="http://2.pdf"),
        InlineKeyboardButton(text="Offer", url="http://1.pdf"),
        InlineKeyboardButton(text="Yes", callback_data="check:1"),
        InlineKeyboardButton(text="No", callback_data="check:2"),
    )
    await query.message.edit_text("Before you buy a ticket, please read the privacy policy and the public offer", reply_markup=keycheck)


@dp.callback_query_handler(text_contains='check:')
async def callback_contains_check(query: types.CallbackQuery):
    variable = int(query.data[6:])
    if variable == 1:
        print(1)
    elif variable ==2:
        print(2)

or you can use aiogram's CallbackData factory (for me looks better):

from aiogram.utils.callback_data import CallbackData
 
check_cb = CallbackData('check','value')  # check:<value>
    
@dp.callback_query_handler(text="buy ticket")
async def buyit(query: types.CallbackQuery):
    keycheck = InlineKeyboardMarkup(row_width=2).add(
        InlineKeyboardButton(text="Privacy", url="http://2.pdf"),
        InlineKeyboardButton(text="Offer", url="http://1.pdf"),
        InlineKeyboardButton(text="Yes", callback_data=check_cb.new(val="1")), # check is prefix, value is 1 same as next
        InlineKeyboardButton(text="No", callback_data="check:2"), # check is prefix, value is 2
    )
    await query.message.edit_text("Before you buy a ticket, please read the privacy policy and the public offer", reply_markup=keycheck)
    
    
@dp.callback_query_handler(check_cb.filter())
async def check_callback_filter(query: types.CallbackQuery, callback_data: dict): 
# callback_data - dictionary for check_cb lools like: 
# {'@': 'check', 'val': '1'} , you could get values by keys
    variable = int(callback_data.get('val'))
    if variable == 1:
        print(1)
    elif variable ==2:
        print(2)

CallbackData factory allows you to have different callback_data's and filter them in different handlers.

example:

  • vote:up:1 or vote:down:1
  • buy:apple:1
  • check:2
  • etc.

vote_cb = CallbackData('vote','action','qty') # vote is prefix

InlineKeyboardButton(text="?", callback_data=vote_cb.new(action="up", qty="1")

@dp.callback_query_handler(vote_cb.filter(action='up')) # filter by action

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1