如何解决Telegram Python Bot 内联菜单和字典
Click Here to see the flowchart 我的 Telegram 机器人需要一些帮助。我正在尝试创建一个机器人,它允许我修改一组选定的字典值并在其末尾以某种方式显示字典键和值。如代码所示,现在我无法弄清楚如何找出用户单击了哪个按钮并将其反映在该键的相应值中。 (例如,(KEY)Shop A - (VALUE)Low Crowd,Compliant...等对于此选定区域中的其他商店)。请注意,我目前仅编写了区域 1 的代码作为示例 -> 它还必须能够为其他选定区域使用它们自己的一组带有空值的预定义字典键。请参阅图片以更好地理解
#!/usr/bin/env python
# pylint: disable=C0116
import logging
from telegram import Update,ForceReply,InlineKeyboardButton,InlineKeyboardMarkup
from telegram.ext import Updater,CommandHandler,MessageHandler,Filters,CallbackContext,CallbackQueryHandler
# Enable logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',level=logging.INFO
)
logger = logging.getLogger(__name__)
############################ Keyboards #########################################
def main_area_selection_kb():
keyboard = [
[
InlineKeyboardButton("Area 1",callback_data='main_1'),],[
InlineKeyboardButton("Area 2",callback_data='main_2'),[
InlineKeyboardButton("Area 3",callback_data='main_3'),[
InlineKeyboardButton("Area 4",callback_data='main_4'),[
InlineKeyboardButton("Area 5",callback_data='main_5'),[
InlineKeyboardButton("Area 6",callback_data='main_6'),]
return InlineKeyboardMarkup(keyboard)
def crowd_level_selection_kb():
keyboard = [
[
InlineKeyboardButton("Low",callback_data='clvl_1'),InlineKeyboardButton("Moderate",callback_data='clvl_2'),InlineKeyboardButton("High",callback_data='clvl_3'),InlineKeyboardButton("Closed",callback_data='clvl_4'),]
]
return InlineKeyboardMarkup(keyboard)
def compliance_kb():
keyboard = [
[
InlineKeyboardButton("Compliant",callback_data='com_1'),InlineKeyboardButton("Not Compliant",callback_data='com_2'),]
]
return InlineKeyboardMarkup(keyboard)
############################ Selection #########################################
def compliance_selection(update,_: CallbackContext) -> None:
query = update.callback_query
query.answer()
if query.data == 'com_1':
query.message.reply_text('Compliant')
elif query.data == 'com_2':
query.message.reply_text('Not Compliant')
def crowd_level_selection(update,_: CallbackContext) -> None:
query = update.callback_query
query.answer() # How do I "pass" the dictionary in/return the value of the user selection back into the respective dictionary's key value?)
if query.data == 'clvl_1':
query.message.reply_text('You choose Low Crowd')
elif query.data == 'clvl_2':
query.message.reply_text('You choose Moderate Crowd')
elif query.data == 'clvl_3':
query.message.reply_text('You choose High Crowd')
elif query.data == 'clvl_4':
query.message.reply_text('You choose Closed')
def main_area_selection(update,_: CallbackContext) -> None:
query = update.callback_query
query.answer()
# query.edit_message_text(text=f"Selected option: {query.data}")
if query.data == 'main_1':
query.message.reply_text('You choose Area 1')
areamain(query)
elif query.data == 'main_2':
query.message.reply_text('You choose Area 2')
elif query.data == 'main_3':
query.message.reply_text('You choose Area 3')
elif query.data == 'main_4':
query.message.reply_text('You choose Area 4')
elif query.data == 'main_5':
query.message.reply_text('You choose Area 5')
elif query.data == 'main_6':
query.message.reply_text('You choose Area 6')
else:
query.message.reply_text('Error')
############################ Functions #########################################
def start(update,context):
"""Send a message when the command /start is issued."""
update.message.reply_text('Please Choose an Area',reply_markup=main_area_selection_kb())
def areamain(update):
areamaindict = {'Shop A': '','Shop B': '','Shop C': '','Shop D': '','Shop E': ''}
for i in areamaindict:
update.message.reply_text(f"{i} Crowd Level:",reply_markup=crowd_level_selection_kb())
#Next step: Add in menu for compliance
#Following that,Set this i value to <High/Medium/Low> Crowd and <Compliant/Not Compliant> once user selected both respective buttons
############################ Main #########################################
def main():
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")
# Get the dispatcher to register handlers
dispatcher = updater.dispatcher
# on different commands - answer in Telegram
dispatcher.add_handler(CommandHandler("start",start))
############################# Handlers #########################################
updater.dispatcher.add_handler(CallbackQueryHandler(main_area_selection,pattern='main'))
updater.dispatcher.add_handler(CallbackQueryHandler(crowd_level_selection,pattern='clvl'))
updater.dispatcher.add_handler(CallbackQueryHandler(compliance_selection,pattern='com'))
# Start the Bot/Listen for user input/messages
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,# SIGTERM or SIGABRT. This should be used most of the time,since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()
解决方法
注意投诉没有实现,希望你能用同样的设计思路来实现。
#!/usr/bin/env python
# pylint: disable=C0116
import logging
from typing import Dict
from telegram import InlineKeyboardButton,InlineKeyboardMarkup
from telegram.ext import (
Updater,CommandHandler,CallbackContext,CallbackQueryHandler,)
# Enable logging
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",level=logging.INFO
)
logger = logging.getLogger(__name__)
temporary_data: Dict[int,dict] = {}
def compliance_kb():
return InlineKeyboardMarkup(
[
[
InlineKeyboardButton("Compliant",callback_data="com_1"),InlineKeyboardButton("Not Compliant",callback_data="com_2"),]
]
)
# ########################### Selection #########################################
def compliance_selection(update,_: CallbackContext) -> None:
query = update.callback_query
query.answer()
if query.data == "com_1":
query.message.reply_text("Compliant")
elif query.data == "com_2":
query.message.reply_text("Not Compliant")
def crowd_level_selection(update,_: CallbackContext) -> None:
global temporary_data
query = update.callback_query
query.answer()
main_area_number = query.data.split("_")[-1]
# we need to identify the shop right? for that we can take the message for example Shop C Crowd Level:
# so taking the first 6 charachter from the message we got the key
shop_level = update.effective_message.text[:6]
update.effective_message.delete()
if "clvl_1" in query.data:
query.message.reply_text(
f"You choose Low Crowd of main area {main_area_number}"
)
temporary_data[query.from_user.id]["shop_data"][shop_level][
"crowd_level"
] = "Low"
elif "clvl_2" in query.data:
query.message.reply_text(
f"You choose Moderate Crowd of main area {main_area_number}"
)
temporary_data[query.from_user.id]["shop_data"][shop_level][
"crowd_level"
] = "Moderate"
elif "clvl_3" in query.data:
query.message.reply_text(
f"You choose High Crowd of main area {main_area_number}"
)
temporary_data[query.from_user.id]["shop_data"][shop_level][
"crowd_level"
] = "High"
elif "clvl_4" in query.data:
query.message.reply_text(f"You choose Closed of main area {main_area_number}")
temporary_data[query.from_user.id]["shop_data"][shop_level][
"crowd_level"
] = "Closed"
from pprint import pprint
print(shop_level)
pprint(temporary_data)
def main_area_selection(update,_: CallbackContext) -> None:
global temporary_data
temporary_data[update.effective_chat.id] = {}
query = update.callback_query
query.answer()
each_shop_dict = {
"Shop A": {"crowd_level": "null","compliant": "null"},"Shop B": {"crowd_level": "null","Shop C": {"crowd_level": "null","Shop D": {"crowd_level": "null","Shop E": {"crowd_level": "null",} # or {f"Shop {k}":{"crowd_level": "null","compliant": "null"} for k in ["A","B","C","D","E"]} but this makes confusion.
update.effective_message.delete()
if "main" in query.data:
number = query.data.split("_")[-1]
query.message.reply_text(f"You choose Area {number}")
temporary_data[query.from_user.id].update(
dict(main_area_number=int(number),shop_data=each_shop_dict)
)
for i in each_shop_dict:
main_area_number = query.data.split("_")[-1]
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"Low",callback_data=f"clvl_1_{main_area_number}"
),InlineKeyboardButton(
"Moderate",callback_data=f"clvl_2_{main_area_number}"
),InlineKeyboardButton(
"High",callback_data=f"clvl_3_{main_area_number}"
),InlineKeyboardButton(
"Closed",callback_data=f"clvl_4_{main_area_number}"
),]
]
)
query.message.reply_text(f"{i} Crowd Level:",reply_markup=markup)
# ########################### Functions #########################################
def start(update,context):
"""Send a message when the command /start is issued."""
print(temporary_data.get(update.effective_chat.id,None))
update.message.reply_text(
"Please Choose an Area",reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton("Area 1",callback_data="main_1"),],[
InlineKeyboardButton("Area 2",callback_data="main_2"),[
InlineKeyboardButton("Area 3",callback_data="main_3"),[
InlineKeyboardButton("Area 4",callback_data="main_4"),[
InlineKeyboardButton("Area 5",callback_data="main_5"),[
InlineKeyboardButton("Area 6",callback_data="main_6"),]
),)
# ########################### Main #########################################
def main():
# Create the Updater and pass it your bot's token.
updater = Updater("TOKEN")
# Get the dispatcher to register handlers
dispatcher = updater.dispatcher
# on different commands - answer in Telegram
dispatcher.add_handler(CommandHandler("start",start))
# ############################ Handlers #########################################
updater.dispatcher.add_handler(
CallbackQueryHandler(main_area_selection,pattern="main")
)
updater.dispatcher.add_handler(
CallbackQueryHandler(crowd_level_selection,pattern="clvl")
)
updater.dispatcher.add_handler(
CallbackQueryHandler(compliance_selection,pattern="com")
)
# Start the Bot/Listen for user input/messages
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,# SIGTERM or SIGABRT. This should be used most of the time,since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == "__main__":
main()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。