Lambda Function < API Gateway < Conversational Action AccessToken

google-assistant

#1

Hi everyone,

This is kind of a follow up question to this one: Conversational Action AccessToken

If I use the jovo webhook in my action console and run the action on my computer I can access the token with:

this.$host.headers[‘authorization’]

But after loading the zip file into my AWS lambda function and configure an AWS API Gateway, the headers are always undefined:

Cannot read property ‘authorization’ of undefined

Do you have an idea why the token is missing here? And how I can access it?

this.$request?.getAccessToken(); // returns also undefined

That’s what I get for this.$host:

{
    "isApiGateway": false,
    "responseHeaders": {
        "Content-Type": "application/json; charset=utf-8"
    },
    "hasWriteFileAccess": false,
    "event": {
        "handler": {
            "name": "Jovo"
        },
        "intent": {
            "name": "actions.intent.MAIN",
            "params": {},
            "query": "Talk to launcher"
        },
        "scene": {
            "name": "actions.scene.START_CONVERSATION",
            "slotFillingStatus": "UNSPECIFIED",
            "slots": {},
            "next": {
                "name": "MainMenuScene"
            }
        },
        "session": {
            "id": "ABwp...sw",
            "params": {},
            "typeOverrides": [],
            "languageCode": ""
        },
        "user": {
            "locale": "en-US",
            "params": {},
            "accountLinkingStatus": "LINKED",
            "verificationStatus": "GUEST",
            "packageEntitlements": [],
            "gaiamint": "",
            "permissions": [],
            "lastSeenTime": "2021-08-24T06:19:50Z"
        },
        "home": {
            "params": {}
        },
        "device": {
            "capabilities": [
                "SPEECH",
                "RICH_RESPONSE",
                "LONG_FORM_AUDIO"
            ],
            "timeZone": {
                "id": "Europe/Zurich",
                "version": ""
            }
        }
    },
    "context": {
        "callbackWaitsForEmptyEventLoop": true,
        "functionVersion": "$LATEST",
        "functionName": "LaunchSpeechApp",
        "memoryLimitInMB": "128",
        "logGroupName": "/aws/lambda/LaunchSpeechApp",
        "logStreamName": "2021/08/24/[$LATEST]ec7...6d74",
        "invokedFunctionArn": "arn:aw...eechApp",
        "awsRequestId": "df3a6...3010"
    },
    "$request": {
        "handler": {
            "name": "Jovo"
        },
        "intent": {
            "name": "actions.intent.MAIN",
            "params": {},
            "query": "Talk to launcher"
        },
        "scene": {
            "name": "actions.scene.START_CONVERSATION",
            "slotFillingStatus": "UNSPECIFIED",
            "slots": {},
            "next": {
                "name": "MainMenuScene"
            }
        },
        "session": {
            "id": "ABwp...sw",
            "params": {},
            "typeOverrides": [],
            "languageCode": ""
        },
        "user": {
            "locale": "en-US",
            "params": {},
            "accountLinkingStatus": "LINKED",
            "verificationStatus": "GUEST",
            "packageEntitlements": [],
            "gaiamint": "",
            "permissions": [],
            "lastSeenTime": "2021-08-24T06:19:50Z"
        },
        "home": {
            "params": {}
        },
        "device": {
            "capabilities": [
                "SPEECH",
                "RICH_RESPONSE",
                "LONG_FORM_AUDIO"
            ],
            "timeZone": {
                "id": "Europe/Zurich",
                "version": ""
            }
        }
    }
}

thank you!

EDIT 31.08.2021:
I just tried to host the code on Google Cloud Platform and tested the action from the google action console. There I get a host object with headers and also the authorization token. So it has maybe something to do with the API Gateway and Conversational Actions?
Another Action I made, but with dialogflow, works with the API Gateway.


#2

I’m currently on vacation and on a ferry with little to no internet bandwidth, but is it possible that you need to configure AWS API Gateway to proxy the headers? I think I wrote a tutorial for the setup somewhere, let me have a look.


#3

I can’t test it right now, but iirc you can add your headers by going to the API method dashboard and click on Method Request. In there you can add HTTP Request Headers.


#4

Hi @rubenaeg,

thank you for your help! I’ll try this and will give feedback after.


#5

Hi @rubenaeg

I just found one jovo tutorial for using the API Gateway: Tutorial
But I didn’t find anything about the headers.

I tried in the method request to add authorization and Authorization but with no success.

If I use in the “integration request” (top right in the image above) this predefined Mapping Template…

…the headers are in the request but the format isn’t recognized by jovo anymore. That’s the error I got:
image

and here is the format of the request. As you can see, the token is there but the structure with “body-json” and “params” is probably the problem:

{
  "body-json": {
    "handler": {
      "name": "Jovo"
    },
    "intent": {
      ...
    },
    "scene": {
      ...
    },
    "session": {
     ...
    },
    "user": {
      ...
    },
    "home": {
      ...
    },
    "device": {
      ...
    }
  },
  "params": {
    "path": {},
    "querystring": {},
    "header": {
      "Accept-Encoding": "gzip, deflate, br",
      "Authorization": "Bearer eyJ0eXAJhbG...ugw1rEkdYRw",
      "Content-Type": "application/json;charset=UTF-8",
      ...
    }
  },
  "stage-variables": {},
  "context": {
    ....
  }
}

#6

Hey @Simon

How did you set up the API Gateway for your Lambda?

Can’t reproduce with this configuration. The Bearer token is in the headers object.


#7

hi @AlexSwe

I see you used HTTP as API type. I can try that tomorrow morning.
My configuration right now is like in the tutorial. But maybe that’s only correct if used with dialogflow? Because the same setup worked for my old google actions.
image


#8

That’s the problem here.
I tried the REST type a few months ago. I couldn’t make it work either.


#9

Hi @AlexSwe,

Thank you!
Fortunately, you always know the secret path to the solution. :wink: