2021-06-06 11:48:48 +02:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# pylint: disable=C0116,W0613
|
|
|
|
# This program is dedicated to the public domain under the CC0 license.
|
|
|
|
|
|
|
|
"""This example showcases how PTBs "arbitrary callback data" feature can be used.
|
|
|
|
|
|
|
|
For detailed info on arbitrary callback data, see the wiki page at https://git.io/JGBDI
|
|
|
|
"""
|
|
|
|
import logging
|
|
|
|
from typing import List, Tuple, cast
|
|
|
|
|
|
|
|
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
|
|
|
from telegram.ext import (
|
|
|
|
Updater,
|
|
|
|
CommandHandler,
|
|
|
|
CallbackQueryHandler,
|
|
|
|
CallbackContext,
|
|
|
|
InvalidCallbackData,
|
|
|
|
PicklePersistence,
|
|
|
|
)
|
|
|
|
|
|
|
|
logging.basicConfig(
|
|
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
|
|
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
def start(update: Update, context: CallbackContext) -> None:
|
|
|
|
"""Sends a message with 5 inline buttons attached."""
|
|
|
|
number_list: List[int] = []
|
|
|
|
update.message.reply_text('Please choose:', reply_markup=build_keyboard(number_list))
|
|
|
|
|
|
|
|
|
|
|
|
def help_command(update: Update, context: CallbackContext) -> None:
|
|
|
|
"""Displays info on how to use the bot."""
|
|
|
|
update.message.reply_text(
|
|
|
|
"Use /start to test this bot. Use /clear to clear the stored data so that you can see "
|
|
|
|
"what happens, if the button data is not available. "
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def clear(update: Update, context: CallbackContext) -> None:
|
|
|
|
"""Clears the callback data cache"""
|
|
|
|
context.bot.callback_data_cache.clear_callback_data() # type: ignore[attr-defined]
|
|
|
|
context.bot.callback_data_cache.clear_callback_queries() # type: ignore[attr-defined]
|
|
|
|
update.effective_message.reply_text('All clear!')
|
|
|
|
|
|
|
|
|
|
|
|
def build_keyboard(current_list: List[int]) -> InlineKeyboardMarkup:
|
|
|
|
"""Helper function to build the next inline keyboard."""
|
|
|
|
return InlineKeyboardMarkup.from_column(
|
|
|
|
[InlineKeyboardButton(str(i), callback_data=(i, current_list)) for i in range(1, 6)]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def list_button(update: Update, context: CallbackContext) -> None:
|
|
|
|
"""Parses the CallbackQuery and updates the message text."""
|
|
|
|
query = update.callback_query
|
|
|
|
query.answer()
|
|
|
|
# Get the data from the callback_data.
|
|
|
|
# If you're using a type checker like MyPy, you'll have to use typing.cast
|
|
|
|
# to make the checker get the expected type of the callback_data
|
|
|
|
number, number_list = cast(Tuple[int, List[int]], query.data)
|
|
|
|
# append the number to the list
|
|
|
|
number_list.append(number)
|
|
|
|
|
|
|
|
query.edit_message_text(
|
|
|
|
text=f"So far you've selected {number_list}. Choose the next item:",
|
|
|
|
reply_markup=build_keyboard(number_list),
|
|
|
|
)
|
|
|
|
|
|
|
|
# we can delete the data stored for the query, because we've replaced the buttons
|
|
|
|
context.drop_callback_data(query)
|
|
|
|
|
|
|
|
|
|
|
|
def handle_invalid_button(update: Update, context: CallbackContext) -> None:
|
|
|
|
"""Informs the user that the button is no longer available."""
|
|
|
|
update.callback_query.answer()
|
|
|
|
update.effective_message.edit_text(
|
|
|
|
'Sorry, I could not process this button click 😕 Please send /start to get a new keyboard.'
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
|
|
|
"""Run the bot."""
|
|
|
|
# We use persistence to demonstrate how buttons can still work after the bot was restarted
|
2021-08-13 16:18:42 +02:00
|
|
|
persistence = PicklePersistence(filename='arbitrarycallbackdatabot.pickle')
|
2021-06-06 11:48:48 +02:00
|
|
|
# Create the Updater and pass it your bot's token.
|
|
|
|
updater = Updater("TOKEN", persistence=persistence, arbitrary_callback_data=True)
|
|
|
|
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('start', start))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('help', help_command))
|
|
|
|
updater.dispatcher.add_handler(CommandHandler('clear', clear))
|
|
|
|
updater.dispatcher.add_handler(
|
|
|
|
CallbackQueryHandler(handle_invalid_button, pattern=InvalidCallbackData)
|
|
|
|
)
|
|
|
|
updater.dispatcher.add_handler(CallbackQueryHandler(list_button))
|
|
|
|
|
|
|
|
# Start the Bot
|
|
|
|
updater.start_polling()
|
|
|
|
|
|
|
|
# Run the bot until the user presses Ctrl-C or the process receives SIGINT,
|
|
|
|
# SIGTERM or SIGABRT
|
|
|
|
updater.idle()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|