Toggle table of contents sidebar
inlinekeyboard2.py
ΒΆ
1#!/usr/bin/env python 2# pylint: disable=unused-argument 3# This program is dedicated to the public domain under the CC0 license. 4 5"""Simple inline keyboard bot with multiple CallbackQueryHandlers. 6 7This Bot uses the Application class to handle the bot. 8First, a few callback functions are defined as callback query handler. Then, those functions are 9passed to the Application and registered at their respective places. 10Then, the bot is started and runs until we press Ctrl-C on the command line. 11Usage: 12Example of a bot that uses inline keyboard that has multiple CallbackQueryHandlers arranged in a 13ConversationHandler. 14Send /start to initiate the conversation. 15Press Ctrl-C on the command line to stop the bot. 16""" 17import logging 18 19from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update 20from telegram.ext import ( 21 Application, 22 CallbackQueryHandler, 23 CommandHandler, 24 ContextTypes, 25 ConversationHandler, 26) 27 28# Enable logging 29logging.basicConfig( 30 format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO 31) 32# set higher logging level for httpx to avoid all GET and POST requests being logged 33logging.getLogger("httpx").setLevel(logging.WARNING) 34 35logger = logging.getLogger(__name__) 36 37# Stages 38START_ROUTES, END_ROUTES = range(2) 39# Callback data 40ONE, TWO, THREE, FOUR = range(4) 41 42 43async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 44 """Send message on `/start`.""" 45 # Get user that sent /start and log his name 46 user = update.message.from_user 47 logger.info("User %s started the conversation.", user.first_name) 48 # Build InlineKeyboard where each button has a displayed text 49 # and a string as callback_data 50 # The keyboard is a list of button rows, where each row is in turn 51 # a list (hence `[[...]]`). 52 keyboard = [ 53 [ 54 InlineKeyboardButton("1", callback_data=str(ONE)), 55 InlineKeyboardButton("2", callback_data=str(TWO)), 56 ] 57 ] 58 reply_markup = InlineKeyboardMarkup(keyboard) 59 # Send message with text and appended InlineKeyboard 60 await update.message.reply_text("Start handler, Choose a route", reply_markup=reply_markup) 61 # Tell ConversationHandler that we're in state `FIRST` now 62 return START_ROUTES 63 64 65async def start_over(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 66 """Prompt same text & keyboard as `start` does but not as new message""" 67 # Get CallbackQuery from Update 68 query = update.callback_query 69 # CallbackQueries need to be answered, even if no notification to the user is needed 70 # Some clients may have trouble otherwise. See https://core.telegram.org/bots/api#callbackquery 71 await query.answer() 72 keyboard = [ 73 [ 74 InlineKeyboardButton("1", callback_data=str(ONE)), 75 InlineKeyboardButton("2", callback_data=str(TWO)), 76 ] 77 ] 78 reply_markup = InlineKeyboardMarkup(keyboard) 79 # Instead of sending a new message, edit the message that 80 # originated the CallbackQuery. This gives the feeling of an 81 # interactive menu. 82 await query.edit_message_text(text="Start handler, Choose a route", reply_markup=reply_markup) 83 return START_ROUTES 84 85 86async def one(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 87 """Show new choice of buttons""" 88 query = update.callback_query 89 await query.answer() 90 keyboard = [ 91 [ 92 InlineKeyboardButton("3", callback_data=str(THREE)), 93 InlineKeyboardButton("4", callback_data=str(FOUR)), 94 ] 95 ] 96 reply_markup = InlineKeyboardMarkup(keyboard) 97 await query.edit_message_text( 98 text="First CallbackQueryHandler, Choose a route", reply_markup=reply_markup 99 ) 100 return START_ROUTES 101 102 103async def two(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 104 """Show new choice of buttons""" 105 query = update.callback_query 106 await query.answer() 107 keyboard = [ 108 [ 109 InlineKeyboardButton("1", callback_data=str(ONE)), 110 InlineKeyboardButton("3", callback_data=str(THREE)), 111 ] 112 ] 113 reply_markup = InlineKeyboardMarkup(keyboard) 114 await query.edit_message_text( 115 text="Second CallbackQueryHandler, Choose a route", reply_markup=reply_markup 116 ) 117 return START_ROUTES 118 119 120async def three(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 121 """Show new choice of buttons. This is the end point of the conversation.""" 122 query = update.callback_query 123 await query.answer() 124 keyboard = [ 125 [ 126 InlineKeyboardButton("Yes, let's do it again!", callback_data=str(ONE)), 127 InlineKeyboardButton("Nah, I've had enough ...", callback_data=str(TWO)), 128 ] 129 ] 130 reply_markup = InlineKeyboardMarkup(keyboard) 131 await query.edit_message_text( 132 text="Third CallbackQueryHandler. Do want to start over?", reply_markup=reply_markup 133 ) 134 # Transfer to conversation state `SECOND` 135 return END_ROUTES 136 137 138async def four(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 139 """Show new choice of buttons""" 140 query = update.callback_query 141 await query.answer() 142 keyboard = [ 143 [ 144 InlineKeyboardButton("2", callback_data=str(TWO)), 145 InlineKeyboardButton("3", callback_data=str(THREE)), 146 ] 147 ] 148 reply_markup = InlineKeyboardMarkup(keyboard) 149 await query.edit_message_text( 150 text="Fourth CallbackQueryHandler, Choose a route", reply_markup=reply_markup 151 ) 152 return START_ROUTES 153 154 155async def end(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: 156 """Returns `ConversationHandler.END`, which tells the 157 ConversationHandler that the conversation is over. 158 """ 159 query = update.callback_query 160 await query.answer() 161 await query.edit_message_text(text="See you next time!") 162 return ConversationHandler.END 163 164 165def main() -> None: 166 """Run the bot.""" 167 # Create the Application and pass it your bot's token. 168 application = Application.builder().token("TOKEN").build() 169 170 # Setup conversation handler with the states FIRST and SECOND 171 # Use the pattern parameter to pass CallbackQueries with specific 172 # data pattern to the corresponding handlers. 173 # ^ means "start of line/string" 174 # $ means "end of line/string" 175 # So ^ABC$ will only allow 'ABC' 176 conv_handler = ConversationHandler( 177 entry_points=[CommandHandler("start", start)], 178 states={ 179 START_ROUTES: [ 180 CallbackQueryHandler(one, pattern="^" + str(ONE) + "$"), 181 CallbackQueryHandler(two, pattern="^" + str(TWO) + "$"), 182 CallbackQueryHandler(three, pattern="^" + str(THREE) + "$"), 183 CallbackQueryHandler(four, pattern="^" + str(FOUR) + "$"), 184 ], 185 END_ROUTES: [ 186 CallbackQueryHandler(start_over, pattern="^" + str(ONE) + "$"), 187 CallbackQueryHandler(end, pattern="^" + str(TWO) + "$"), 188 ], 189 }, 190 fallbacks=[CommandHandler("start", start)], 191 ) 192 193 # Add ConversationHandler to application that will be used for handling updates 194 application.add_handler(conv_handler) 195 196 # Run the bot until the user presses Ctrl-C 197 application.run_polling(allowed_updates=Update.ALL_TYPES) 198 199 200if __name__ == "__main__": 201 main()
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4