0

我正在 Python 中的 AWS Lambda 中开发一个 Amazon Lex 聊天机器人,它将进行 API 发布调用并获得 JSON 字符串中的响应,如下所示

'{"_id":"598045d12e1f98980a00001e","unique_id":"ed7e4e17c7db499caee576a7761512","cerebro":{"_id":"59451b239db9fa8b0a000004","acc_id":"533a9f0d2eda783019000002","name":"cerebro","access_id":"g01n0XTwoYfEWSIP","access_token":"3Yxw8ZiUlfSPsbEVLI6Z93vZyKyBFFIV"},"bot":{"_id":"59452f42dbd13ad867000001","name":"helloword"},"rundata":{"arguments":"","target":"local"},"state":"created","queue_id":null,"s_ts":null,"e_ts":null,"response":{},"responses":[],"summary":null,"resolve_incident":false,"err":null}'

但我只对 id 值感兴趣,所以我将 json 转换为字典,如下所示并获取 id 值

res = requests.post(botrun_api, json=botrun_payload, headers=headers)
data = json.loads(res.content)
new_id=json_data.get('_id', None)
return new_id

如果我在 Lambda 控制台中测试代码,我会得到输出

AWS Lambda 控制台中的输出

但我在我的聊天机器人中得到如下输出

I was unable to process your message. DependencyFailedException: Invalid Lambda Response: Received invalid response from Lambda: Can not construct instance of IntentResponse: no String-argument constructor/factory method to deserialize from String value ('59832ba22e1f98980a00009b') at [Source: "59832ba22e1f98980a00009b"; line: 1, column: 1]

我的源代码如下:

import math
import dateutil.parser
import datetime
import time
import os
import logging
import requests
import uuid

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


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


def get_slots(intent_request):
    return intent_request['currentIntent']['slots']


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


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
        }
    }


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


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


def build_validation_result(is_valid, violated_slot, message_content):
    if message_content is None:
        return {
            "isValid": is_valid,
            "violatedSlot": violated_slot,
        }

    return {
        'isValid': is_valid,
        'violatedSlot': violated_slot,
        'message': {'contentType': 'PlainText', 'content': message_content}
    }



def APIbot(intent_request):
    """
    Performs dialog management and fulfillment for cluster configuration input arguments.
    Beyond fulfillment, the implementation of this intent demonstrates the use of the elicitSlot dialog action
    in slot validation and re-prompting.
    """

    value1 = get_slots(intent_request)["myval1"]
    value2 = get_slots(intent_request)["myval2"]
    intense_type = get_slots(intent_request)["Instance"]
    source = intent_request['invocationSource'] 
    api_endpoint = 'url'
    api_creds = {
    'apiuser': 'user',
    'apikey': 'key'
    }

    #trigger a bot run
    botrun_api = api_endpoint + '/botruns'

    botrun_payload = {
        "botname":"helloword",
        "arguments":"",
        "target":"local",
        "unique_id": uuid.uuid4().hex[:30] #unique run id - 30 chars max
    }

    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Key apiuser=%(apiuser)s apikey=%(apikey)s' % api_creds
    }

    res = requests.post(botrun_api, json=botrun_payload, headers=headers)
    data = json.loads(res.content)  
    new_id=json_data.get('_id', None)   
    return new_id



    # Instiate a cluster setup, and rely on the goodbye message of the bot to define the message to the end user.
    # In a real bot, this would likely involve a call to a backend service.
    return close(intent_request['sessionAttributes'],
                 'Fulfilled',
                 {'contentType': 'PlainText',
                  'content': 'Thanks, your values are {} and {} '.format(value1, value2)})


""" --- 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 == 'my_Values':
        return APIbot(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)

请帮助我提前解决这个问题:)

4

1 回答 1

1

Lambda 仅在new_id返回时显示您的函数成功,因为它不关心响应的格式。

连接到 AWS Lex 时,响应必须采用 AWS 定义的响应格式

在上面的示例中,您可以通过new_id方法中的传递close,以通过 Lex 输出响应:

return close(intent_request['sessionAttributes'],
             'Fulfilled',
             {'contentType': 'PlainText',
              'content': str(new_id)}

您还需要删除该return new_id语句。

于 2017-08-07T19:02:57.337 回答