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 197 forks source link

How do I get logged in user email id? #347

Closed himangipatel closed 4 years ago

himangipatel commented 4 years ago

I have an access token of user which I got as below, const accessToken = req.body.originalDetectIntentRequest.payload.user.accessToken; how can I get logged in user emailid,name and user's other details?

Fleker commented 4 years ago

You should use the conv.user object.

himangipatel commented 4 years ago

@Fleker but there is only access token in conv.user object

"user": { "accessToken": "w8S-ffdFLBCiddyxfsFxKPp3y4FJJoLD2", "locale": "en-US", "lastSeen": "2019-08-05T12:54:38Z", "userVerificationStatus": "VERIFIED" }

himangipatel commented 4 years ago

Screenshot from 2019-08-06 10-29-01

I have tried this code...but email is always undefined.

Screenshot from 2019-08-06 10-43-36

himangipatel commented 4 years ago

got all information though this API http://{YOUR_AUTH0_DOMAIN}/userinfo

Just We need to pass access token in header : authorization:Bearer accessToken

Also change JsonWebToken Signature Algorithm to HS256 and add openid and profile scopes---> This works for me to get userinfo

raftheunis87 commented 4 years ago

Having the same issue here. I was using the userId first, but since it is deprecated, I'm looking for an alternative. I have changed the Account Linking to OAuth & Google Sign In. The user starts his/her dialog and then bumps into this piece of code:

app.intent('Give Color', async (conv, { color }) => {
  conv.data[Fields.COLOR] = color;
  if (conv.user.ref) {
    await conv.user.ref.set({ [Fields.COLOR]: color });
    conv.close(`I got ${color} as your favorite color.`);
    return conv.close('Since you are signed in, I\'ll remember it next time.');
  }
  return conv.ask(new SignIn(`To save ${color} as your favorite color for next time`));
});

The SignIn modal is shown on the phone where I select my Google account. Then my /token endpoint is called on the OAuth server containing the Google Token (assertion) which holds all the users data. I decode it, check in the database if the "sub" is already present, and I throw the following exception:

return res.status(401).send({ error: 'user_not_found' });

Then the normal OAuth procedure kicks in, where I deliver a token to google.

After token delivery, I get a new request on my action:

app.intent('Get Sign In', async (conv, params, signin) => {
  if (signin.status !== 'OK') {
    return conv.close('Let\'s try again next time.');
  }
  const color = conv.data[Fields.COLOR];
  await conv.user.ref.set({ [Fields.COLOR]: color });
  return conv.close(`I saved ${color} as your favorite color. `
    + 'Since you are signed in, I\'ll remember it next time.');
});

But the value of signin.status is always ERROR.

Anyone can help me out on this one?

himangipatel commented 4 years ago

did you set account linking though https://auth0.com ?

raftheunis87 commented 4 years ago

No, I have setup my own Authorization Server using NodeJS.

raftheunis87 commented 4 years ago

Ok got a bit further. Something was wrong in the OAuth Server.

So now I got this:

app.intent('Get Sign In', async (conv, params, signin) => {
  if (signin.status !== 'OK') {
    return conv.close('Let\'s try again next time.');
  }
  const color = conv.data[Fields.COLOR];
  await conv.user.ref.set({ [Fields.COLOR]: color });
  return conv.close(`I saved ${color} as your favorite color. `
    + 'Since you are signed in, I\'ll remember it next time.');
});

Took the following line straight from the debug console of VSCode:

signin.status
"OK"
conv.user
User {raw: Object, storage: Object, _id: undefined, locale: "en-BE", verification: "VERIFIED", …}
_id: undefined
[[StableObjectId]]: 7
access: Access {token: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB"}
entitlements: Array(0) []
id: undefined
last: Last {seen: Thu Aug 08 2019 10:53:17 GMT+0200 (Central Europea…}
locale: "en-BE"
name: Name {display: undefined, family: undefined, given: undefined}
permissions: Array(0) []
profile: Profile {token: undefined}
raw: Object {accessToken: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB", locale: "en-BE", lastSeen: "2019-08-08T08:53:17Z", …}
storage: Object {}
verification: "VERIFIED"
__proto__: Object {constructor: , _serialize: , _verifyProfile: , …}
conv.user.id is *DEPRECATED*: Use conv.user.storage to store data instead

So the last question I have: Why isn't the Google ID Token send in this request? So how can I link this accesstoken to this specific google user in my database?