Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the user name/id of a google account linked with Dialog flow

I have integrated google assistant with my dialogflow agent. I need to get the user who is invoking the intent.

For eg, If an user account "ABC" have access to invoke my agent via Google assistant app, on the welcome intent I have to send a response like "Welcome ABC". How do I achieve this with google assistant app is my endpoint.

Thanks in Advance.

like image 848
Arun Avatar asked Dec 17 '22 22:12

Arun


2 Answers

You have two questions here: How to get the user's name and how to get their id.

The first thing to realize is that this information is considered personally identifiable information (PII), so Google doesn't give it to you without the permission of the user. How you ask for that permission, and how it is delivered to you, depends on some of your exact needs.

User ID

Historically, you could get an anonymous user ID for the Assistant account. This would be different than the Google User ID that is available below and was meant to be a persistent identifier so you could keep track of returning users.

This has been deprecated, and if this is all you need, then you can create your own identifier and save it as part of the userStorage.

Requesting user information

The traditional way of getting their name is to request the user for permission to access their information. If you're using the actions-on-google library, you do this using the Permission object with something like this:

  const options = {
    // We just want permission to get their name
    permissions: ['NAME'],

    // Prompt them why we want the information
    context: 'To address you by name'
  };
  conv.ask(new Permission(options));

If the user grants permission, the results will be available in conv.user.name. You should save this in the userStorage, since the permission is not persistent. So this might look something like:

var userStorageStr = conv.user.userStorage || '{}';
var userStorage = JSON.parse( userStorageStr );
var name = conv.user.name || userStorage.name;
userStorage.name = name;

// ...

conv.user.userStorage = JSON.stringify( userStorage );

With the multivocal library, you would indicate that the User/Name environment property is one of the Requirements for the action or intent you want. So this might be in your configuration as

Local: {
  en: {
    Requirements: {
      "Action.multivocal.welcome": "User/Name"
    }
  }
}

The name will be available in the environment under User/Name.

If you're using JSON, then you need to use the user information helper. For Dialogflow, this would be under the payload.google.systemIntent property, while for the Actions SDK this would be in expectedInputs[0].possibleIntents[0]. You might specify something like this:

    {
      "intent": "actions.intent.PERMISSION",
      "inputValueData": {
        "@type": "type.googleapis.com/google.actions.v2.PermissionValueSpec",
        "optContext": "To address you by name",
        "permissions": [
          "NAME"
        ]
      }
    }

The name will be under the originalDetectIntentRequest.payload.user.profile field if you are using Dialogflow and user.profile for the Action SDK.

All of this seems like a lot, just to get a name. And you can't get the email address if you want that in addition. But there are other options.

Requesting their Google Profile

Their Google Profile contains both their unique Google ID, their full name (in the "name" field, given_name, last_name, and typically some other information such as their email address (the email address isn't guaranteed since they can omit this from their profile, but is typically there). You would use Google Sign-In for the Assistant to request this information. There is some configuration required in the Action console, and then you would request permission to get it using the sign-in helper.

With the actions-on-google library, the line would be something like:

conv.ask(new SignIn());

Once the user granted it, you can get their profile in

conv.user.profile.payload

their name in

conv.user.profile.payload.name

and their email in, you guessed it,

conv.user.profile.payload.email

Note that unlike asking for the user information, the profile will be available in all future activity with you. You don't need to store it.

With multivocal, you would say that the User/IsAuthenticated environment setting is one of the Requirements for the action or intent you want. So this might be in your configuration as

Local: {
  en: {
    Requirements: {
      "Action.multivocal.welcome": "User/IsAuthenticated"
    }
  }
}

The profile will be available in the environment under User/Profile, the name would be in User/Profile/name, and the email in User/Profile/email.

If you're using JSON, then you need to use the sign-in helper. For Dialogflow, this would be under the payload.google.systemIntent property, while for the Actions SDK this would be in expectedInputs[0].possibleIntents[0]. You might specify something like this:

    {
      "intent": "actions.intent.SIGN_IN",
      "inputValueData": {}
    }

You will get an identity token for the user in the originalDetectIntentRequest.payload.user.idToken field if you are using Dialogflow and user.idToken for the Action SDK. You will need to validate and decode this JWT. (The actions-on-google and multivocal libraries handle this step for you.)

like image 191
Prisoner Avatar answered May 14 '23 04:05

Prisoner


The easiest would be to use Google Sign-In for the Assistant: https://developers.google.com/actions/identity/google-sign-in

like image 42
Leon Nicholls Avatar answered May 14 '23 05:05

Leon Nicholls