actions-on-google-nodejs icon indicating copy to clipboard operation
actions-on-google-nodejs copied to clipboard

AWS Lambda with API Gateway

Open valhus opened this issue 5 years ago • 2 comments

I'm having a issue with AWS that I really can't understand. My app starts correct, using the simulator that will trigger an intent results in an error that I really don't understand.

Code in AWS:

const { dialogflow, Table, Image } = require('actions-on-google');
const df = dialogflow({debug: true});

df.intent('nextdeparture', async (conv, params) => {
  conv.close('aws test');
});

exports.fulfillment = df;

From the logs in aws I can see a simpleResponse

{
    "status": 200,
    "headers": {
        "content-type": "application/json;charset=utf-8"
    },
    "body": {
        "payload": {
            "google": {
                "expectUserResponse": false,
                "richResponse": {
                    "items": [
                        {
                            "simpleResponse": {
                                "textToSpeech": "aws test"
                            }
                        }
                    ]
                }
            }
        }
    }
}

But this is what I'm getting in the simulator:

MalformedResponse Failed to parse Dialogflow response into AppResponse because of invalid platform response: Could not find a RichResponse or SystemIntent in the platform response for agentId: 0da3cbb2-f7db-4297-bb2c-4bbf18a73db1 and intentId: 9aa705a5-6984-4905-859e-9307d4af625e.

valhus avatar Nov 01 '19 00:11 valhus

I'm seeing the same thing. Did you find a resolution?

JBaczuk avatar Nov 27 '19 21:11 JBaczuk

It appears the sdk does not support Lambda + Api Gateway out of the box, like the docs suggest, it returns an object with additional properties (status, body, etc.). You have to create your own custom handler and only send the body, see https://github.com/actions-on-google/actions-on-google-nodejs/issues/219#issuecomment-466573394

module.exports.handler = (event: any, context: any, callback: any) => {
  const body = event.body || event;
  const headers = event.headers || context.request.headers || [];
  return app.handler(body, headers).then(res =>
    if (res.status != 200) {
        callback(null, {"fulfillmentText": `I got status code: ${res.status}`});
    } else {
        callback(null, res.body);
    }
  };
};

I also had to forward the headers from API Gateway using this guide: https://aws.amazon.com/premiumsupport/knowledge-center/custom-headers-api-gateway-lambda/

JBaczuk avatar Nov 27 '19 23:11 JBaczuk