actions-on-google / actions-on-google-nodejs

Node.js client library for Actions on Google
https://actions-on-google.github.io/actions-on-google-nodejs
Apache License 2.0
900 stars 193 forks source link

Actions SDK - How to Get Session and Project ID on Fulfillment Request? #301

Open rafapetter opened 5 years ago

rafapetter commented 5 years ago

I'm handling Fulfillments on Actions SDK. Is there a way to get the Project ID or any Session or Context information, during a Fulfillment Request?

I know that I can get on DialogFlow requests, but I can't find a way to get that on Actions SDK.

Thanks

Canain commented 5 years ago

I don't think there's a way to get the Project ID for Actions SDK as it's not exposed in the request.

But there is a conversation id you can get for the request which is basically a session id.

In the library you can access it with:

conv.id

If you want to track project id, you possibly can pass it as a parameter in your fulfillment url. So for example, if your webhook url was https://example.com/webhook, then you set a different url for each project like https://example.com/webhook?project=abc123.

From then, you can read the query parameters from Express or whatever framework you like using either framework metadata in the Actions on Google library middleware or fulfill to a different app instance before hitting the client library via a routing library like express.

rafapetter commented 5 years ago

Hey @Canain, thanks for the quick response.

The conv.id definitely can be used as the session ID. I was just hoping the JSON request from Actions SDK would have the same info as DialogFlow has.

I was trying to avoid the query params on the webhook url, but I guess that's the only way out.

Canain commented 5 years ago

Actually, it turns out there is a way but involves reading the headers not the request body.

In headers, there should be key which in lowercase is authorization. This header is mainly used for verifying the request comes from Google but in order to do that it also contains an aud or audience value which is the project id.

If you decode this token with a library like jwt-decode, then you can extract out aud to get the project id.

So something like this could work if you are using Express or Firebase Functions:

npm install jwt-decode
const { actionssdk } = require('actions-on-google')
const jwtDecode = require('jwt-decode')

const app = actionssdk()

app.middleware((conv, framework) => {
  if (framework.express) {
    const token = framework.express.request.headers['authentication']
    const decoded = jwtDecode(token)
    conv.projectId = decoded.aud
  }
})

app.intent('actions.intent.MAIN', conv => {
  conv.ask(`Hello ${conv.projectId}`)
})
rafapetter commented 5 years ago

@Canain Nice, it worked for me. Thanks.

I'm actually using AWS Lambda. But I'm facing another issue now: I'm trying to create/update Actions projects through an AWS Lambda and an EC2. The reason: My app provides a way to publish actions projects for third parties, so I need to automate the process of creating actions, but I couldn't find another way without using the "gactions CLI". So far I'm struggling connecting to EC2 through Lambda. Would you have idea if there's an API for that?

igilham commented 5 years ago

It's also worth knowing that you can get this from the environment variables on Google Cloud if running on Cloud Functions or App Engine. This is a benefit of the integration between Actions Projects and GCP Projects: they exist under the same GCP Project ID.

Fleker commented 5 years ago

There is no public API for project management, so you'd need to use gactions.

rafapetter commented 5 years ago

Ok, and if I'm using the Actions SDK, is there a way to update the Fulfillment Url directly on the web console? Or I'm always dependent on the gactions CLI?

igilham commented 5 years ago

You have to use the gactions tool for that. The SDK is only a client library for the webhook APIs.

rafapetter commented 5 years ago

@igilham Ok =\ Let's hope they have API's to better manage the actions in the future.

zeuslawyer commented 5 years ago

I just accidentally discovered another way to get the project Id, but from the credentials JSON.

go to https://dialogflow.com/docs/reference/v2-auth-setup, follow the instructions but be careful to choose choose 'API Admin' instead of 'API Client'

when you've got the JSON, add it to your config and read in the ['project_id'] property.

const projectId = credentials['project_id'];

That seems to work for me, and I hope i've not misunderstood your question~