【问题标题】:Did i migrate from the default code to my testing one properly?我是否正确地从默认代码迁移到我的测试代码?
【发布时间】:2018-01-09 10:31:26
【问题描述】:

我想使用 Lex 的界面创建一个聊天机器人,作为第一步,我找到了一个 ScheduleAppointment 默认机器人,所以我决定对其进行调整。此机器人中的默认提示是datetimeappointmenttype。作为第一步,我开始使用蓝图 lex-make-appointment-python https://console.aws.amazon.com/lambda/home?region=us-east-1#/create/new?bp=lex-make-appointment-python 并且不得不在那里更改许多默认内容,例如它有一个确切的约会时间和日期等,而我想在进一步开发之前使用的版本在lambda 中是需要ANY TIMEANY DAY 的,例如,如果我要求安排约会tomorrow,但如果机器人询问日期并且我输入hfujdhfu 之类的内容,我不会出错或banana 我应该再次询问what is the date?

所有这些都是我调整后的代码版本:

import json
import dateutil.parser
import datetime
import time
import os
import math
import random
import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


""" --- Helpers to build responses which match the structure of the necessary dialog actions --- """


def elicit_slot(session_attributes, intent_name, slots, slot_to_elicit, message, response_card):
    return {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'ElicitSlot',
            'intentName': intent_name,
            'slots': slots,
            'slotToElicit': slot_to_elicit,
            'message': message,
            'responseCard': response_card
        }
    }


def confirm_intent(session_attributes, intent_name, slots, message, response_card):
    return {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'ConfirmIntent',
            'intentName': intent_name,
            'slots': slots,
            'message': message,
            'responseCard': response_card
        }
    }


def close(session_attributes, fulfillment_state, message):
    response = {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'Close',
            'fulfillmentState': fulfillment_state,
            'message': message
        }
    }

    return response


def delegate(session_attributes, slots):
    return {
        'sessionAttributes': session_attributes,
        'dialogAction': {
            'type': 'Delegate',
            'slots': slots
        }
    }


def build_response_card(title, subtitle, options):
    """
    Build a responseCard with a title, subtitle, and an optional set of options which should be displayed as buttons.
    """
    buttons = None
    if options is not None:
        buttons = []
        for i in range(min(5, len(options))):
            buttons.append(options[i])

    return {
        'contentType': 'application/vnd.amazonaws.card.generic',
        'version': 1,
        'genericAttachments': [{
            'title': title,
            'subTitle': subtitle,
            'buttons': buttons
        }]
    }


""" --- Helper Functions --- """


def parse_int(n):
    try:
        return int(n)
    except ValueError:
        return float('nan')


def try_ex(func):
    """
    Call passed in function in try block. If KeyError is encountered return None.
    This function is intended to be used to safely access dictionary.

    Note that this function would have negative impact on performance.
    """

    try:
        return func()
    except KeyError:
        return None
def isvalid_date(date):
    try:
        dateutil.parser.parse(date)
        return True
    except ValueError:
        return False
def build_time_output_string(appointment_time):
    hour, minute = appointment_time.split(':')  # no conversion to int in order to have original string form. for eg) 10:00 instead of 10:0
    if int(hour) > 12:
        return '{}:{} p.m.'.format((int(hour) - 12), minute)
    elif int(hour) == 12:
        return '12:{} p.m.'.format(minute)
    elif int(hour) == 0:
        return '12:{} a.m.'.format(minute)

    return '{}:{} a.m.'.format(hour, minute)
def make_appointment(intent_request):
    """
    Performs dialog management and fulfillment for booking a dentists appointment.

    Beyond fulfillment, the implementation for this intent demonstrates the following:
    1) Use of elicitSlot in slot validation and re-prompting
    2) Use of confirmIntent to support the confirmation of inferred slot values, when confirmation is required
    on the bot model and the inferred slot values fully specify the intent.
    """
    appointment_type = intent_request['currentIntent']['slots']['AppointmentType']
    date = intent_request['currentIntent']['slots']['Date']
    appointment_time = intent_request['currentIntent']['slots']['Time']
    source = intent_request['invocationSource']
    output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
    booking_map = json.loads(try_ex(lambda: output_session_attributes['bookingMap']) or '{}')

    if source == 'DialogCodeHook':
        # Perform basic validation on the supplied input slots.
        slots = intent_request['currentIntent']['slots']
 if not appointment_type:
            return elicit_slot(
                output_session_attributes,
                intent_request['currentIntent']['name'],
                intent_request['currentIntent']['slots'],
                'AppointmentType',
                {'contentType': 'PlainText', 'content': 'What type of appointment would you like to schedule?'},
                build_response_card(
                    'Specify Appointment Type', 'What type of appointment would you like to schedule?',
                    build_options('AppointmentType', appointment_type, date, None)
                )
            )

        if appointment_type and not date:
            return elicit_slot(
                output_session_attributes,
                intent_request['currentIntent']['name'],
                intent_request['currentIntent']['slots'],
                'Date',
                {'contentType': 'PlainText', 'content': 'When would you like to schedule your {}?'.format(appointment_type)},
                build_response_card(
                    'Specify Date',
                    'When would you like to schedule your {}?'.format(appointment_type),
                    build_options('Date', appointment_type, date, None)
                )
            )
)
message_content = 'What time on {} works for you? '.format(date)
            if appointment_time:
                output_session_attributes['formattedTime'] = build_time_output_string(appointment_time)
 )

            available_time_string = build_available_time_string(appointment_type_availabilities)
            return elicit_slot(
                output_session_attributes,
                intent_request['currentIntent']['name'],
                slots,
                'Time',
                {'contentType': 'PlainText', 'content': '{}{}'.format(message_content, available_time_string)},
                build_response_card(
                    'Specify Time',
                    'What time works best for you?',
                    build_options('Time', appointment_type, date, booking_map)
                )
            )

        return delegate(output_session_attributes, slots)
duration = get_duration(appointment_type)
""" --- Intents --- """


def dispatch(intent_request):
    """
    Called when the user specifies an intent for this bot.
    """

    logger.debug('dispatch userId={}, intentName={}'.format(intent_request['userId'], intent_request['currentIntent']['name']))

    intent_name = intent_request['currentIntent']['name']

    # Dispatch to your bot's intent handlers
    if intent_name == 'MakeAppointment':
        return make_appointment(intent_request)
    raise Exception('Intent with name ' + intent_name + ' not supported')


""" --- Main handler --- """


def lambda_handler(event, context):
    """
    Route the incoming request based on intent.
    The JSON body of the request is provided in the event slot.
    """
    # By default, treat the user request as coming from the America/New_York time zone.
    os.environ['TZ'] = 'America/New_York'
    time.tzset()
    logger.debug('event.bot.name={}'.format(event['bot']['name']))

    return dispatch(event)

【问题讨论】:

  • 您是否遇到任何错误?是否按预期工作?
  • 没有,保存时出现“模块'lambda_function'中的语法错误”。
  • 调试它并发现错误,您可以在Cloudwatch中看到日志。我在第 171 行和第 175 行看到),没有任何(,这一定会导致语法错误。许多代码行无法访问,因为您在它们之前编码return,但不会导致语法错误。
  • @sid8491 正确这些已调整,您认为您可以找到阻止其正常工作和调整的问题
  • 正如我之前所说的,在了解基础知识之前,您会试图跳到进步。这就是你面临问题的原因。

标签: python aws-lambda chatbot amazon-lex


【解决方案1】:

在第 171 行和第 175 行有 ),但没有任何 (,这一定会导致语法错误。许多代码行无法访问,因为您在它们之前编码return,但不会导致语法错误。

您可以在Cloudwatch 上查看日志。

您使用的蓝图非常复杂,对初学者不友好。你真的应该使用this 蓝图来启动。这是我的建议。

另外,由于您使用的是response_card,因此请注意,响应卡不会显示在 Lex 控制台窗口中。不过,它可以在 Facebook 和 Slack 中使用。

【讨论】:

  • 我纠正了这两个错误,当我用 lex 运行它时,我得到了以下错误An error has occurred: Invalid Lambda Response: Received error response from Lambda: Unhandled
  • 没有日志,没有人可以帮助您。 cloudwatch 将成为您的救星。
  • 尚未完全完成,但您的调试建议和链接非常有帮助。
  • 酷,尝试理解 CLoudwatch 日志,并在您有疑问的地方使用 logger.debug(object) 添加日志语句。如果觉得有用,请点赞并标记接受。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
相关资源
最近更新 更多