""""""fromdatetimeimportdatetimefromtimeimporttimefromtypingimportAnyfromtypingimportListfromtypingimportOptionalfromtypingimportSetfromtypingimportTYPE_CHECKINGfrompyrogram.typesimportInlineKeyboardMarkupfrompyrogram.typesimportMessagefrompyrogram.typesimportReplyKeyboardMarkupfromtgintegration.containersimportInlineKeyboardfromtgintegration.containersimportReplyKeyboardfromtgintegration.update_recorderimportMessageRecorderifTYPE_CHECKING:fromtgintegration.botcontrollerimportBotControllerclassResponse:def__init__(self,controller:"BotController",recorder:MessageRecorder):self._controller=controllerself._recorder=recorderself.started:Optional[float]=Noneself.action_result:Any=None# cached propertiesself.__reply_keyboard:Optional[ReplyKeyboard]=Noneself.__inline_keyboards:List[InlineKeyboard]=[]@propertydefmessages(self)->List[Message]:returnself._recorder.messages@propertydefis_empty(self)->bool:returnnotself.messages@propertydefnum_messages(self)->int:returnlen(self.messages)@propertydeffull_text(self)->str:return"\n".join(x.textforxinself.messagesifx.text)or""@propertydefreply_keyboard(self)->Optional[ReplyKeyboard]:ifself.__reply_keyboard:returnself.__reply_keyboardifself.is_empty:returnNone# Contingent upon the way Telegram works,# only the *last* message with buttons in a response object mattersmessages=reversed(self.messages)forminmessages:ifisinstance(m.reply_markup,ReplyKeyboardMarkup):last_kb_msg=mbreakelse:returnNone# No message with a keyboard foundreply_keyboard=ReplyKeyboard(controller=self._controller,chat_id=last_kb_msg.chat.id,message_id=last_kb_msg.message_id,button_rows=last_kb_msg.reply_markup.keyboard,)self.__reply_keyboard=reply_keyboardreturnreply_keyboard@propertydefinline_keyboards(self)->Optional[List[InlineKeyboard]]:ifself.__inline_keyboards:returnself.__inline_keyboardsifself.is_empty:returnNoneinline_keyboards=[InlineKeyboard(controller=self._controller,chat_id=message.chat.id,message_id=message.message_id,button_rows=message.reply_markup.inline_keyboard,)formessageinself.messagesifisinstance(message.reply_markup,InlineKeyboardMarkup)]self.__inline_keyboards=inline_keyboardsreturninline_keyboards@propertydefkeyboard_buttons(self)->Set[str]:all_buttons=set()forminself.messages:markup=m.reply_markupifmarkupandhasattr(markup,"keyboard"):forrowinmarkup.keyboard:forbuttoninrow:all_buttons.add(button)returnall_buttons@propertydeflast_message_datetime(self)->Optional[datetime]:ifself.is_empty:returnNonereturndatetime.fromtimestamp(self.messages[-1].date)@propertydeflast_message_timestamp(self)->Optional[time]:ifself.is_empty:returnNonereturnself.messages[-1].date@propertydefcommands(self)->Set[str]:all_commands=set()forminself.messages:entity_commands=[xforxinm.entitiesifx.type=="bot_command"]foreinentity_commands:all_commands.add(m.text[e.offset,len(m.text)-e.length])caption_entity_commands=[xforxinm.entitiesifx.type=="bot_command"]foreincaption_entity_commands:all_commands.add(m.caption[e.offset,len(m.caption)-e.length])returnall_commandsasyncdefdelete_all_messages(self,revoke:bool=True):peer_id=self.messages[0].chat.idawaitself._controller.client.delete_messages(peer_id,[x.message_idforxinself.messages],revoke=revoke)def__eq__(self,other):ifnotisinstance(other,Response):returnFalsereturn(self.full_text==other.full_textandself.inline_keyboards==other.inline_keyboards# TODO: self.keyboard == other.keyboard)def__getitem__(self,item):returnself.messages[item]def__str__(self):ifself.is_empty:return"Empty response"return"\nthen\n".join(['"{}"'.format(m.text)forminself.messages])classInvalidResponseError(Exception):DOCS""" Raised when peer's response did not match the [expectation](tgintegration.expectation.Expectation). """