Telegram Python Bot 内联菜单和词典
Telegram Python Bot Inline Menu and Dictionary
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", "compliant": "null"},
"Shop C": {"crowd_level": "null", "compliant": "null"},
"Shop D": {"crowd_level": "null", "compliant": "null"},
"Shop E": {"crowd_level": "null", "compliant": "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()
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", "compliant": "null"},
"Shop C": {"crowd_level": "null", "compliant": "null"},
"Shop D": {"crowd_level": "null", "compliant": "null"},
"Shop E": {"crowd_level": "null", "compliant": "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()