From 97ece953f6b5f9ecf8c77d8dc83c98109de06729 Mon Sep 17 00:00:00 2001 From: Yariv Menachem Date: Thu, 2 Jan 2025 17:33:14 +0200 Subject: [PATCH] full flow works with no saving to db --- .../telegram_start_handler.py | 127 +++++++++++------- 1 file changed, 78 insertions(+), 49 deletions(-) diff --git a/src/telegram_handler/telegram_start_handler.py b/src/telegram_handler/telegram_start_handler.py index 67f3de6..8af02c3 100644 --- a/src/telegram_handler/telegram_start_handler.py +++ b/src/telegram_handler/telegram_start_handler.py @@ -18,20 +18,23 @@ class Flow(Enum): ADDRESS = 1 FILTERS = 2 EXPERIENCE = 3 - RETRY = 4 + VERIFY_ADDRESS = 4 + VERIFY_FILTERS = 5 + SKIP_FILTERS = 6 class TelegramStartHandler(TelegramHandler): def __init__(self): + self.filters = None self.telegram_bot = TelegramBot() self.user_repository = UserRepository() self.logger = create_logger("TelegramStartHandler") self.positions = position_repository.find_all() self.temp_user = None - self.last_state = None + self.cities = None - async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> Flow: + async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Starts the conversation and asks the user about their position.""" chat: Chat = update.message.chat user = User(full_name=chat.full_name, username=chat.username, chat_id=chat.id) @@ -47,64 +50,55 @@ class TelegramStartHandler(TelegramHandler): reply_markup=reply_markup, ) - return Flow.POSITION + return Flow.POSITION.value - async def position(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> Flow: + async def position(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Stores the selected position and asks for a photo.""" - self.last_state = Flow.POSITION user = update.message.from_user self.logger.info("Position of %s: %s", user.first_name, update.message.text) position = next((p for p in self.positions if p.name == update.message.text), None) if not position: await update.message.reply_text("Position not found") - buttons2 = [[KeyboardButton(position.name)] for position in self.positions] - reply_markup = ReplyKeyboardMarkup(buttons2, one_time_keyboard=True, + buttons = [[KeyboardButton(position.name)] for position in self.positions] + reply_markup = ReplyKeyboardMarkup(buttons, one_time_keyboard=True, input_field_placeholder=Flow.POSITION.name) await update.message.reply_text( "What Position are you looking for?", reply_markup=reply_markup, ) - return Flow.POSITION + return Flow.POSITION.value await update.message.reply_text( - "I see! Please send me a photo of yourself, " - "so I know what you look like, or send /skip if you don't want to.", - reply_markup=ReplyKeyboardRemove(), + "Gorgeous! Now, send me cites you want to search for\n" + "Example: Rishon Lezion,Petah Tikva,..." ) - return Flow.ADDRESS + return Flow.ADDRESS.value async def address(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Stores the photo and asks for a location.""" user = update.message.from_user - photo_file = await update.message.photo[-1].get_file() - await photo_file.download_to_drive("user_photo.jpg") - self.logger.info("Photo of %s: %s", user.first_name, "user_photo.jpg") + self.cities = update.message.text.split(",") + reply_markup = ReplyKeyboardMarkup([[KeyboardButton("Yes"), KeyboardButton("No")]], one_time_keyboard=True, + input_field_placeholder=Flow.VERIFY_ADDRESS.name) + await update.message.reply_text(f"Did you choose: {self.cities} ?", reply_markup=reply_markup) + + return Flow.VERIFY_ADDRESS.value + + async def verify_address(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + if update.message.text == "No": + await update.message.reply_text( + "Please send the cities\n" + "Example: Rishon Lezion,Petah Tikva,..." + ) + return Flow.ADDRESS.value + + reply_markup = ReplyKeyboardMarkup([["1", "2"]], one_time_keyboard=True, + input_field_placeholder=Flow.VERIFY_ADDRESS.name) await update.message.reply_text( - "Gorgeous! Now, send me your location please, or send /skip if you don't want to." - ) - - return Flow.FILTERS.value - - async def filter(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - """Stores the location and asks for some info about the user.""" - user = update.message.from_user - user_location = update.message.location - self.logger.info( - "Location of %s: %f / %f", user.first_name, user_location.latitude, user_location.longitude - ) - await update.message.reply_text( - "Maybe I can visit you sometime! At last, tell me something about yourself." - ) - - return Flow.EXPERIENCE.value - - async def skip_filter(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: - """Skips the location and asks for info about the user.""" - user = update.message.from_user - self.logger.info("User %s did not send a location.", user.first_name) - await update.message.reply_text( - "You seem a bit paranoid! At last, tell me something about yourself." + "Maybe I can visit you sometime!\n" + "Tell Your experience", + reply_markup=reply_markup ) return Flow.EXPERIENCE.value @@ -112,7 +106,44 @@ class TelegramStartHandler(TelegramHandler): async def experience(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: """Stores the info about the user and ends the conversation.""" user = update.message.from_user - self.logger.info("Bio of %s: %s", user.first_name, update.message.text) + self.logger.info("Experience of %s: %s", user.first_name, update.message.text) + + await update.message.reply_text( + "Gorgeous!\n" + "Now, send me keywords to filter out positions based on title\n" + "Example: Data,QA,..." + ) + return Flow.FILTERS.value + + async def filters_flow(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Stores the location and asks for some info about the user.""" + user = update.message.from_user + self.logger.info( + "Filters of %s: %f / %f", user.first_name, update.message.text + ) + self.filters = update.message.text.split(",") + reply_markup = ReplyKeyboardMarkup([[KeyboardButton("Yes"), KeyboardButton("No")]], one_time_keyboard=True, + input_field_placeholder=Flow.VERIFY_FILTERS.name) + await update.message.reply_text(f"Did you choose: {self.filters} ?", reply_markup=reply_markup) + + return Flow.VERIFY_FILTERS.value + + async def verify_filter(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + if update.message.text == "No": + await update.message.reply_text( + "Please send the filters\n" + "Example: QA ,DATA,..." + ) + return Flow.FILTERS.value + + await update.message.reply_text("Thank you! I hope we can talk again some day.") + + return ConversationHandler.END + + async def skip_filter(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: + """Skips the location and asks for info about the user.""" + user = update.message.from_user + self.logger.info("User %s did not send a filters.", user.first_name) await update.message.reply_text("Thank you! I hope we can talk again some day.") return ConversationHandler.END @@ -161,14 +192,12 @@ start_handler = TelegramStartHandler() start_conv_handler = ConversationHandler( entry_points=[CommandHandler("start", start_handler.start)], states={ - Flow.POSITION: [MessageHandler(filters.TEXT, start_handler.position)] - # Flow.SAVE_POSITION: [MessageHandler(filters.TEXT, start_handler.position)] - # Flow.ADDRESS: [MessageHandler(filters.PHOTO, photo), CommandHandler("skip", skip_photo)], - # Flow.FILTERS: [ - # MessageHandler(filters.LOCATION, location), - # CommandHandler("skip", skip_location), - # ], - # Flow.EXPERIENCE: [MessageHandler(filters.TEXT & ~filters.COMMAND, bio)], + Flow.POSITION.value: [MessageHandler(filters.TEXT, start_handler.position)], + Flow.ADDRESS.value: [MessageHandler(filters.TEXT, start_handler.address)], + Flow.VERIFY_ADDRESS.value: [MessageHandler(filters.TEXT, start_handler.verify_address)], + Flow.EXPERIENCE.value: [MessageHandler(filters.TEXT, start_handler.experience)], + Flow.FILTERS.value: [MessageHandler(filters.TEXT, start_handler.filters_flow)], + Flow.VERIFY_FILTERS.value: [MessageHandler(filters.TEXT, start_handler.verify_filter)], }, fallbacks=[CommandHandler("cancel", start_handler.cancel)], )