Beispiel #1
0
 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)
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
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