[英]Telethon (bot), how to work with commands, buttons and anwers
我想實現類似 BotFather 的東西。 它發送按鈕,你 select 你的選項,如果選項需要答案,你必須回答正確的答案。
例如,如果我想添加/編輯命令,我按“編輯命令”,命令必須是格式command - description
如果格式無效,它將回復錯誤。 它怎么知道我的消息是對“編輯命令”的回答而不是對“編輯關於”的回答(例如,因為“編輯關於”沒有這種格式)? 我知道如果我想聽按鈕中的動作,必須使用@client.on(events.CallbackQuery(pattern=...))
但這不會“等待”用戶對特定回調的回答,是嗎? 我試過了,但沒有用。
# client pre-configuration...
@client.on(events.NewMessage(pattern=r"\/new"))
async def handler(event):
keyboard = [
[
Button.inline("New Command", "edit_command"),
Button.inline("Anything", "any"),
],
]
await client.send_message(event.sender_id, "Hey, There!", buttons=keyboard)
@client.on(events.CallbackQuery(pattern="edit_command"))
async def call_handler(event):
await client.send_message(event.sender_id, "Please send command in format:\ncommand - description")
我是否必須實施event.NewMessage()
,如果先前的消息是“請以格式發送命令:\n命令 - 描述”,則驗證消息是否具有“X”格式? 否則忽略消息?
示例想法:
處理來自用戶的所有消息,或使用模式^[az- ]+$
,並閱讀以前的消息....
@client.on(events.NewMessage())
async def handler(event):
if "send command in format" in previous_message or "Command format is invalid" in previous_message:
if ensure_command_message_format(event.raw_text):
# Hey! Nice!....
else:
await client.send_message(event.sender_id, "Command format is invalid, please try again.")
if anything_else in previous_message:
if ensure_anything_else_format(event.raw_text):
# etc...
這是最好的方法嗎?
是的,你所做的並沒有錯,但這不是最好的方法,當我說這不是最好的方法時,我的意思是在可維護性方面,如果你幾個月后回來更新你的代碼,你可能會遇到困難,但你做得很好,對於這樣的系統,有一個名為“ STATE DESIGN PATTERN ”的模式,我在這里提到它只是為了以防你想進一步閱讀,確保理解它的概念,所以基本上,復制 state 設計模式的一些部分,我建議你得到一個STATE變量,它將存儲狀態列表中的 state,你的狀態列表可能如下所示 ' ["edit_name", "edit_description", " edit_menu", "main_menu", "start"] ' 那么每個 state 的含義以及每個 state 的命名由您來定義,對我來說,“edit_name” state 意味着我們目前正在嘗試編輯某物的名稱,所以我應該期待一些文本,“main_menu”state 意味着我們有來自主菜單的響應,所以每個 state 系統都有一個開始 state,對我來說,我的開始 state 是“開始”,所以我的代碼看起來像這樣:
#DEFINE YOUR STATES AND SET THE START STATE
STATE = "start"
@client.on(events.NewMessage()):
if STATE == "start":
#send main menu stuff to user
#Change state to main menu
new_STATE = "main_menu"
if STATE == "main_menu":
#here i am only interested in responded suited for main therefore
if response in state_responses[STATE]:
#This is a valid main menu response, maybe the response was "EDIT"
#so we need to switch to edit state now
#DO YOUR EDIT CODE HERE, probably sending edit options, Name or Description
#Edit State Change
new_STATE = "edit_menu"
if STATE == "edit_menu":
#ok so we are in an editing mood, and we know what we are expecting, in response
#either name or description
if response in state_responses[STATE]:
if "response_is_name":
#ok name has been chosen so next input we are expecting pure
#text so we will put state to "edit_name"
new_STATE = "edit_name"
#<.... am gonna skip some codes and jump to edit_name state ....>
if STATE == "edit_name":
#well then whatever input we get, we will use it to edit the name,
#maybe the name of the bot or something, make sure to validate the name
#people can create some weird names so create some name validation
set_name(response)
#OK so now that we are done changing the name where do we want to do
#Maybe we will send a "name change successful" message and go back to the
#main menu, ok so we will send our message
send.message("name change successful")
#Now which state sends the main menu to the user ? ... if you remember it was
#the start state, so we will set the state to start, to start the entire loop
new_STATE = "start"
#SET STATE = new_STATE
STATE = new_STATE
以上只是一個例子:
是的,所以它與您擁有的 if-else 相同,但它更具可讀性,並且感覺更有條理,有一種方法可以在沒有 if-else 的情況下實現它,而是使用類,但我只建議您在 state 會議開始時這樣做超過 20 左右的巨大數字,長話短說,你有正確的想法,但你缺乏結構,我強烈建議你觀看 state 設計模式上的視頻,注意設計模式是解決問題的工具,因此取決於您的問題您可以修改設計模式以滿足您的需要,通常在 state 設計模式視頻中,他們會教您實現它的“類”方式,但對於小型項目,“if-else”方式很好
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.