Передача аргументов в клавиатуру Telebot

Абстрактная клавиатура (кнопка):

def button():
    keyboard = types.InlineKeyboardMarkup()
    btn = types.InlineKeyboardButton(text="В начало", callback_data="В начало")
    keyboard.add(btn)
    return keyboard

Мне нужно, чтобы действие от нажатия кнопки зависело от аргумента, поступившего в клавиатуру, и обработчик колбека вёл себя по разному в одной и той же клавиатуре в зависимости от этого аргумента, либо просто, чтобы этот аргумент, например, был записан в БД. Вот что приходит в голову:

def button(x):
    keyboard = types.InlineKeyboardMarkup()
    btn = types.InlineKeyboardButton(text="В начало", callback_data=f"В начало {x}")
    keyboard.add(btn)
    return keyboard 

И потом в обработчике этот "x" мы находим и используем для логики: call.data.split()[-1]. Но выглядит всё это костыльно.

Может быть, есть красивое решение?


Ответы (1 шт):

Автор решения: Amgarak

Можно через сериализацию в json сделать:

import json
import telebot
from telebot import types

bot = telebot.TeleBot('Token')

def button(action, x):
    keyboard = types.InlineKeyboardMarkup()
    callback_data = json.dumps({"action": action, "value": x})
    btn = types.InlineKeyboardButton(text=f"Кнопка для {action}", callback_data=callback_data)
    keyboard.add(btn)
    return keyboard

@bot.callback_query_handler(func=lambda call: json.loads(call.data).get('action') == "to_start")
def to_start_handler(call):
    data = json.loads(call.data)
    x = data.get("value")
    bot.send_message(call.message.chat.id, f"Действие 1: {x}")
    bot.answer_callback_query(call.id)

@bot.callback_query_handler(func=lambda call: json.loads(call.data).get('action') == "to_end")
def to_end_handler(call):
    data = json.loads(call.data)
    x = data.get("value")
    bot.send_message(call.message.chat.id, f"Действие 2: {x}")
    bot.answer_callback_query(call.id)

@bot.message_handler(commands=['start'])
def start_message(message):
    bot.send_message(message.chat.id, " Действие 1:",
                     reply_markup=button("to_start", 42))  
    bot.send_message(message.chat.id, "Действие 2:",
                     reply_markup=button("to_end", 100))  

bot.polling()
→ Ссылка