def wrapper(bot, update): """ Check return the passed function if linked chat_id is currently in cache. Else, return cancel message and take system to raw state. :param bot: :param update: :return: """ chat_id = None print(type(update)) print(update) if update.message is not None: print('got message') chat_id = update.message.chat.id elif update.callback_query is not None: print('update using callback_query') chat_id = update.callback_query.from_user.id else: print('got nothing') print('Found chat id: ' + str(chat_id)) u_info = fetch_from_cache(chat_id=chat_id) if u_info is not None: return func(bot, update) else: return conversation_expired(bot, update)
def add_remarks(bot, update): """ Add remarks to a user's booking. :param bot: :param update: :return: """ user_remarks = update.message.text user_info = fetch_from_cache(update.message.chat.id) user_info['remarks'] = user_remarks update_cache(update.message.chat.id, user_info) num_people = user_info['num_people'] time = user_info['time'] date = user_info['date'].strftime("%A, %b %d, %Y") extras = user_remarks table = user_info['tables'] if table == 'autoselect': table = 'Auto-Select' reply_keyboard = [[InlineKeyboardButton('Yes', callback_data='Yes')], [InlineKeyboardButton('No', callback_data='No')]] update.message.reply_text( 'Thanks. We\'ll keep that in mind.\n' 'Booking Summary:\n' 'Making a reservation for {0} people at {1} on {2}.\n' 'Table: {4}\n' 'Extras: {3}'.format(num_people, time, date, extras, table), reply_markup=InlineKeyboardMarkup(reply_keyboard)) return settings.SHOW_CONFIRMATION_DIALOG
def set_visit_time(bot, update): """ Set customer's visiting time. :param bot: :param update: :return: """ reply_keyboard = [ ['1', '2'], ['3', '4'], ['5', '6'], ['7', '8'], ['9', '10'], ['11', '12'], ['13', '14'], ['15', '16'], ['17', '18'], ['19', '20'], ] user_info = fetch_from_cache(update.message.chat.id) visiting_time = update.message.text user_info['time'] = visiting_time update_cache(update.message.chat.id, user_info) update.message.reply_text( 'Great. How many guests?\n' 'We allow bulk bookings for up to 12 people at once.\n', reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)) print('new state: ' + str(settings.INPUT_NUM_PEOPLE)) return settings.INPUT_NUM_PEOPLE
def input_num_people(bot, update): """ Set number of people for reservation. :return: """ user_info = fetch_from_cache(update.message.chat.id) user_info['num_people'] = update.message.text date = user_info['date'] time = user_info['time'] start_time, end_time = get_duration(date, time) if int(user_info['num_people']) < 12: update_cache(update.message.chat.id, user_info) tables = Table.get_available_tables(start_time, end_time, user_info['num_people']) if len(tables) != 0: keyboard = create_inline_keyboard(tables) update.message.reply_text( 'Please select a table.\n', reply_markup=InlineKeyboardMarkup(keyboard)) # if no email is present in data store for this user, take system to email input state. return settings.INPUT_TABLE_NUMBER else: keyboard = [[ InlineKeyboardButton('Try Again', callback_data='restart') ], [InlineKeyboardButton('Contact Us', callback_data='contact')]] update.message.reply_text( 'Sorry. No tables available at ' + user_info['time'] + ' on ' + date.strftime("%A, %b %d, %Y") + '.\n' 'Please try again for a different time or contact us for more information.\n', reply_markup=InlineKeyboardMarkup(keyboard)) # if no email is present in data store for this user, take system to email input state. return settings.NO_TABLES_AVAILABLE else: user_info['tables'] = 'autoselect' update_cache(update.message.chat.id, user_info) user = User.get_user(update.message.chat.id) if user.email in [None, '']: update.message.reply_text( 'Please enter email address for confirmation.\n') return settings.INPUT_EMAIL else: update.message.reply_text( 'Confirmation email will be sent to the following email address: {}' '\n Press OK to Confirm and Change to update email address.'. format(user.email), reply_markup=InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton('Confirm', callback_data='confirm') ], [InlineKeyboardButton('Change', callback_data='change')]])) return settings.EMAIL_OPTIONS
def set_user_email(bot, update): """ This should only be asked in case user is a new user. In case an old user is returning, this must be skipped. :return: """ chat_id = update.message.chat.id user_info = fetch_from_cache(chat_id) user_info['email'] = update.message.text update_cache(chat_id, user_info) # This is a fire and forget call. # Should be responsive enough. User.set_email_address(chat_id, update.message.text) update.message.reply_text( text='Anything else you want us to know about the reservation?' 'Press None for No Extras.', reply_markup=InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton('None', callback_data='No'), InlineKeyboardButton('Yes', callback_data='Yes') ]])) return settings.ANY_REMARKS
def any_remarks_handler(bot, update): """ Whether or not any remarks are to be added by a user. 1. If yes, go to INPUT_REMARKS state. 2. If no, go to CONFIRMATION STATE. :param bot: :param update: :return: """ to_add = update.callback_query.data if str(to_add) == 'Yes': bot.edit_message_text( text= 'Please enter anything else that you\'d like us to keep in mind.', chat_id=update.callback_query.from_user.id, message_id=update.callback_query.message.message_id) return settings.INPUT_REMARKS else: user_info = fetch_from_cache(update.callback_query.from_user.id) update_cache(update.callback_query.from_user.id, user_info) num_people = user_info['num_people'] time = user_info['time'] date = user_info['date'].strftime("%A, %b %d, %Y") table = user_info['tables'] if table == 'autoselect': table = 'Auto-Select' reply_keyboard = [[InlineKeyboardButton('Yes', callback_data='Yes')], [InlineKeyboardButton('No', callback_data='No')]] bot.edit_message_text( chat_id=update.callback_query.from_user.id, message_id=update.callback_query.message.message_id, text='Skipping extras..') bot.send_message(chat_id=update.callback_query.from_user.id, text='Booking Summary:\n' 'Making a reservation for {0} people at {1} on {2}.\n' 'Table: {4}\n' 'Extras: {3}'.format(num_people, time, date, 'None', table), reply_markup=InlineKeyboardMarkup(reply_keyboard)) return settings.SHOW_CONFIRMATION_DIALOG
def input_table(bot, update): """ Set table to be used. :param bot: :param update: :return: """ chat_id = update.callback_query.from_user.id user_info = fetch_from_cache(chat_id) try: tables = int(update.callback_query.data) except (ValueError, Exception) as ex: tables = 'autoselect' user_info['tables'] = tables update_cache(chat_id, user_info) bot.edit_message_text(chat_id=chat_id, text='You\'ve selected Table: ' + str(tables) + "\n", message_id=update.callback_query.message.message_id) sleep(0.25) user = User.get_user(chat_id) if user is not None and user.email not in [None, '']: email = user.email bot.send_message( chat_id=chat_id, text= 'Confirmation email will be sent to the following email address: {}' '\nPress Confirm to Proceed or Change to update email address.'. format(email), reply_markup=InlineKeyboardMarkup(inline_keyboard=[[ InlineKeyboardButton('Confirm', callback_data='confirm') ], [InlineKeyboardButton('Change', callback_data='change')]])) return settings.EMAIL_OPTIONS else: bot.send_message( chat_id=chat_id, text='Please enter email address for confirmation.\n', ) return settings.INPUT_EMAIL
def show_confirmation_dialog(bot, update): """ CallbackQueryHandler that decides Whether or not to show confirmation dialog to user stating all details entered and ask them to confirm. TODO: [LATER] Allow the user to go back to a particular stage and re enter information from there onwards. :return: """ # Get reservation information from cache. chat_id = update.callback_query.from_user.id if update.callback_query.data == 'Yes': bot.edit_message_text( text='Please wait while we confirm your reservation.', chat_id=chat_id, message_id=update.callback_query.message.message_id) # Generate booking id, save reservation info in datastore, update reservation record and send email. # If booking fails, show user a message and ask them to start again at a different time. user_info = fetch_from_cache(chat_id=chat_id) time = user_info['time'] date = user_info['date'] num_people = user_info['num_people'] table = user_info['tables'] email = None if 'email' in user_info: email = user_info['email'] try: first_name = update.effective_user.first_name except Exception as ex: first_name = '' try: last_name = update.effective_user.last_name except Exception as ex: last_name = '' start_time, end_time = get_duration(date, time) if isinstance(table, int): # check again that the selected table is available. # Assuming some time has elapsed since the user selected the table and the table might've been booked by # someone else during that time. if Table.is_available(table, start_time, end_time): user = User.get_user(chat_id) was_successful, reservation_id, tables = make_reservation( email, first_name, last_name, chat_id, num_people, table, start_time, end_time, user) if was_successful: send_confirmation_message(bot, chat_id, num_people, time, date, reservation_id, update, tables) else: bot.send_message( chat_id=chat_id, text="Sorry, Table " + str(table) + ' is no longer available. Please start again.') return ConversationHandler.END else: bot.send_message( chat_id=chat_id, text="Sorry, Table " + str(table) + ' is no longer available. Please start again.') return ConversationHandler.END else: # Select tables automatically. user = User.get_user(chat_id) was_successful, reservation_id, tables = make_reservation( email, first_name, last_name, chat_id, num_people, table, start_time, end_time, user) if not was_successful: bot.send_message( chat_id=chat_id, text="Could not find sufficient tables for your reservation." "\nPlease contact us for further assistance." "\nType /contact for more details.") else: send_confirmation_message(bot, chat_id, num_people, time, date, reservation_id, update, tables) return ConversationHandler.END else: bot.edit_message_text( text='Reservation Cancelled. See you again.', chat_id=chat_id, message_id=update.callback_query.message.message_id) return ConversationHandler.END