Amazon web services 如何解决从AmazonLex获得的424(失败的依赖项)(python)?

Amazon web services 如何解决从AmazonLex获得的424(失败的依赖项)(python)?,amazon-web-services,aws-lambda,amazon-lex,Amazon Web Services,Aws Lambda,Amazon Lex,我已经编写了lambda函数,它工作得很好,但是当我尝试从Lex与它通信时,我得到了依赖项异常。我如何调试或解决这个问题?已定义变量REST\u END\u POINT。下面是我的代码,请看一下,告诉我我可能做错了什么 我在Amazon Lex doc上研究了这个问题。并提到以下内容: DependencyFailedException 1.其中一个依赖项(如AWS Lambda或Amazon Polly)引发了异常。比如说, 如果Amazon Lex没有足够的权限调用Lambda函数 如果L

我已经编写了lambda函数,它工作得很好,但是当我尝试从Lex与它通信时,我得到了依赖项异常。我如何调试或解决这个问题?已定义变量REST\u END\u POINT。下面是我的代码,请看一下,告诉我我可能做错了什么

我在Amazon Lex doc上研究了这个问题。并提到以下内容:

DependencyFailedException 1.其中一个依赖项(如AWS Lambda或Amazon Polly)引发了异常。比如说,

  • 如果Amazon Lex没有足够的权限调用Lambda函数

  • 如果Lambda函数的执行时间超过30秒

  • 如果函数返回委托对话框操作而不删除任何插槽值

HTTP状态代码:424

以下是我采取的行动:

  • 我已检查lambda函数的执行时间不超过30秒
  • Amazon Lex有权调用我的lambda函数
第三点我不太明白,但我认为它也解决了从我提供的代码,请纠正我,如果我错了

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_validation_result(is_valid, violated_slot, message_content):
    return {
        'isValid': is_valid,
        'violatedSlot': violated_slot,
        'message': {'contentType': 'PlainText', 'content': message_content}
    }


def validate_oms_count(oms_type, date):
    if oms_type:
        if len(oms_type) == 0 or (oms_type != 'transport' and oms_type != 'overtime'):
            return build_validation_result(False, 'OmsType', 'I did not recognize that, can I make an overtime request?')

    if date:
        if not isvalid_date(date):
            return build_validation_result(False, 'Date', 'I did not understand that, what date works best for you?')

    return build_validation_result(True, None, None)


def validate_menu_date(date):
    if date:
        if not isvalid_date(date):
            return build_validation_result(False, 'Date', 'I did not understand that, what date works best for you?')

    return build_validation_result(True, None, None)


def get_token(output_session_attributes):
    token = json.loads(try_ex(lambda: output_session_attributes['token']) or '{}')

    if not token:
        try:
            data = bytes(json.dumps({"username": "admin","password": "Oms2017@","rememberMe": "false"}), 'utf-8')
            f = urllib.request.urlopen(urllib.request.Request(REST_END_POINT+'/authenticate', data, {'Content-Type': 'application/json'}))
            result = json.loads(f.read().decode())
            output_session_attributes['token'] = result['id_token']

            logger.debug('Token {}'.format(result['id_token']))

            return result['id_token']
        except Exception as e:
            logger.debug('An error occurred at the backend1 {}'.format(e)) 
    else:
        return token


def build_options(slot, oms_type):
    """
    Build a list of potential options for a given slot, to be used in responseCard generation.
    """

    if slot == 'OmsType':
        return [
            {'text': 'Transport', 'value': 'transport'},
            {'text': 'Overtime', 'value': 'overtime'}
        ]


""" --- Functions that control the bot's behavior --- """


def get_menu_of_day(intent_request):
    """
    Performs dialog management and fulfillment for getting the menu of the day.

    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.
    """
    date = intent_request['currentIntent']['slots']['Date']
    source = intent_request['invocationSource']
    output_session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
    data_map = json.loads(try_ex(lambda: output_session_attributes['dataMap']) or '{}')

    if source == 'DialogCodeHook':
        # Perform basic validation on the supplied input slots.
        slots = intent_request['currentIntent']['slots']
        validation_result = validate_menu_date(date)
        if not validation_result['isValid']:
            slots[validation_result['violatedSlot']] = None
            return elicit_slot(
                output_session_attributes,
                intent_request['currentIntent']['name'],
                slots,
                validation_result['violatedSlot'],
                validation_result['message'],
                build_response_card(
                    'Specify {}'.format(validation_result['violatedSlot']),
                    validation_result['message']['content'],
                    build_options(validation_result['violatedSlot'], None)
                )
            )

        if not date:
            slots['Date'] = None
            return elicit_slot(
                output_session_attributes,
                intent_request['currentIntent']['name'],
                intent_request['currentIntent']['slots'],
                'Date',
                {'contentType': 'PlainText', 'content': 'What date works for you?'},
                build_response_card(
                    'Specify Date', 'What date works for you?',
                    build_options('Date', None)
                )
            )

        if date:
            get_token(output_session_attributes)
            data_map['date'] = date
            output_session_attributes['dataMap'] = json.dumps(data_map)

        return delegate(output_session_attributes, slots)

    # Send request to the backend service to perform user action.
    token = get_token(output_session_attributes)
    extractedMenu = []
    try:
        data_map['date'] = date
        output_session_attributes['dataMap'] = json.dumps(data_map)
        params = urllib.parse.urlencode({'day':date})
        response = urllib.request.urlopen(urllib.request.Request(REST_END_POINT+'/menuOfdays?'+ params, headers={'Authorization': 'Bearer '+token}))
        convertedResponse = json.loads(response.read().decode())
        extractedMenu = [item['menu']['name'] for item in convertedResponse]
        logger.debug(extractedMenu)
    except Exception as e:
        logger.debug('An error occurred at the backend2 {}'.format(e))

    return close(
        output_session_attributes,
        'Fulfilled',
        {
            'contentType': 'PlainText',
            'content': 'Menu of the day include: {} '.format(extractedMenu)
        }
    )


""" --- 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 == 'GetMenuOfDay':
        return get_menu_of_day(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)

如果一切正常,当询问{Date}的菜单是什么时,回答是:当天的菜单包括
菜单项列表

检查Lex是否有Polly权限提供TTS响应。或者,您可以将AWS托管策略“LexBotPolicy”附加到Lex角色