# Telegram Bot API: telegram.ext.ConversationHandler ###### tags: `telegram` `bot` `API` >[name=shaoe.chen][time=Fri, Mar 5, 2020] :::danger [官方文件](https://python-telegram-bot.readthedocs.io/en/stable/telegram.ext.conversationhandler.html) ::: ## 說明 :::info classtelegram.ext.ConversationHandler(entry_points, states, fallbacks, allow_reentry=False, per_chat=True, per_user=True, per_message=False, conversation_timeout=None, name=None, persistent=False, map_to_parent=None) ::: Bases: telegram.ext.handler.Handler 一個透過管理四個其它處理程序的集合來保持與單一用戶對話的處理程序。 第一個集合,名為`entry_points`的list,用來初始化對話,舉例來說,使用`telegram.ext.CommandHandler`或`telegram.ext.RegexHandler` 第二個集合,名為`states`的dict,包含不同的對話階段,以及一個或多個相關的處理程序,如果用戶在與他們對話的當下是處理該狀態時發送訊息,那就會使用該處理程序。這邊你還可以為`TIMEOUT`定義狀態,定義當超過`conversation_timeout`時候的行為,還有為`WAITING`定義狀態,定義當接收到一個新的更新而前一個裝飾器`@run_async`處理程序未完成時的行為。 第三個集合,名為`fallbacks`的list,如果用戶當下正處於對話中,但是該狀態既沒有相關的處理程序,或者與該狀態相關的處理程序也不適合更新,舉例來說,如果更新包含一個命令(command),但需要的是普通的簡訊,那就使用該list。 要改變對話的狀態,那處理程序的callback function在響應用戶之後必須回傳新的狀態。如果沒有回傳任何東西(預設回傳None),那狀態將不會改變。如果entry point callback function回傳None,那就會在執行完這個callback function直接結束對話。要結束對話,callback function必須回傳`END`或`-1`。要處理對話的timeout,可以使用處理程序`TIMEOUT`或`-2` :::info 上述的每個處理程序集合中,處理程序也可以是`ConversationHandler`。那種情況下,巢狀的`ConversationHandler`應該有屬性`map_to_parent`,這屬性允許在巢狀對話中的指定狀態回傳到父對話(parent conversation)。 注意到,`map_to_parent`的key不能出現在狀態屬性的keys~(應該是指命令不能重覆)~,否則將被忽略。你也許會映射`END`到父狀態的其中一個狀態,以便在結束之後繼續父對話,甚至映射一個狀態到`END`以便從巢狀對話中結束父對話。關於巢狀ConversationHandler的範例,請見我們的[examples](https://github.com/python-telegram-bot/python-telegram-bot/blob/master/examples)。 ::: ## 參數 * `entry_points` * `Handler`物件的list,可以觸發對話的開始。 * Type: List\[`telegram.ext.Handler`\] * `states` * dict,定義用戶可以處於的不同的對話狀態,以及在該狀態下使用的一個或多個`Handler`物件。 * Type: Dict\[object, List\[ telegram.ext.Handler\]\] * `fallbacks` * 如果用戶處於對話中,可能會使用的處理程序的list,但是它們的當前狀態的每個處理程序都會在`check_update`上回傳`False`。 * Type: List\[telegram.ext.Handler\] * `allow_reentry` * 確認用戶是否可以以entry point重新啟動一個對話 * Type: bool * `per_chat` * 對話的金鑰是否應該包含聊天室的ID * Type: bool * `per_user` * 對話的金鑰是否應該包含用戶的ID * Type: bool * `per_message` * 對話的金鑰是否應該包含訊息的ID * Type: bool * `conversation_timeout` * 可選。當這個處理程序沒有動作超過這個timeout設置(秒),它將自動地結束。如果該值為0(預設),那就是沒有timeout。當它被觸發,最後一個接收到的更新將被狀態處於`ConversationHandler.TIMEOUT`的所有處理程序(其`check_update`方法回傳True)所處理。 * Type: float`|:obj:`datetime.timedelta * `name` * 可選。這個conversationhandler的名稱。持久性所需求(背景執行?)。 * Type: str * `persistent` * 可選。如果這個處理程序的conversations dict應該被保存。`name`是必要的,而且必需在`telegram.ext.Updater`設置持久性。 * Type: bool * `map_to_parent` * 可選。dict,用於指示巢狀的conversationhandler轉換到其parnet conversationhandler的映射狀態,以代替指定的巢狀狀態。 * Type: Dict\[object, object\] * `END=-1` * 用來做為結束對話時所回傳的常數。 * Type: int * `TIMEOUT= -2` * 用來做為對話超時的時候處理狀態的常數。 * Type: int * `WAITING= -3` * 用來做為對話仍在等待前一個裝飾器`@run_sync`所執行的處理程序完成時處理狀態的常數。 * Type: int * `check_update(update)` * 確定這個conversationhandler的更新是否應該被處理,如果是,那就確定當前的對話狀態。 * Parameters: update (telegram.Update) – Incoming telegram update. * Returns: bool * `handle_update(update, dispatcher, check_result, context=None)` * 將更新發送到當前狀態與處理程序的callback * Parameters: * check_result – 來自check_update的結果。關於這個處理程序,它是由key,handler與handler的check result所組成的tuple。 * update (telegram.Update) – 傳入telegram的更新。 * dispatcher (telegram.ext.Dispatcher) – 發起更新的dispatcher。