Google Assistant Smart Home : agentUserId definition may be incorrect - google-home

As per Google Assistant documentation for Smart Home, the agentUserId used in action.devices.QUERY is defined to 'Reflects the unique (and immutable) user ID on the agent's platform. The string is opaque to Google, so if there's an immutable form vs a mutable form on the agent side, use the immutable form (e.g. an account number rather than email)'
However there can be cases where the same device (with same agent user id) is attached to multiple Google Assistant accounts and in such cases a DISCONNECT request may result is ceasing report state for all accounts. The solution will be to add some unique ID corresponding to the Google Assistant account, however such information is not available in any request.
Has anyone seen similar issue and is my understanding incorrect?

The agentUserId is meant to be the user account on the smart home platform. SHP user '1234' may have a vacuum and two lights, but could be linked to multiple Google accounts.
During the account linking process, you would be expected to give a refresh and access tokens to allow for Google to have authorized control over these devices. If you assign unique access tokens for each Google account that signs in, you'd be able to determine which Google account the request is coming from.
At that point, once the user disconnects, you can use the access token in the request header to associate that with a specific Google account and only disable reporting for that account while not affecting other accounts.
So, yes the solution is to have a unique ID connecting to the account. While this is not passed in the agent ID, there is already a mechanism to make this association through the authorization system.
Alternatively, you could append a key in the agentUserId, ie. '1234-user#gmail.com'. However, this may have unintended impacts in the Home Graph. In a multi-user home, you may end up seeing the devices duplicated because Google doesn't have the right information to deduplicate.

Related

How to request Domain-wide Delegation through a consent screen, on G Suite

I need to have access to Calendar information from a company's G Suite accounts, to synchronize data with the company system through a API.
When I need to provide access to my own data, there is a fairly simple way to do it. Using Oauth2, through a login window the user allows the API to access the requested data.
But in the G Suite documentation, the path indicated when involving the administrator and company data, involves the administrator accessing admin.google.com, go to the security-related session, and manually register my API, listing the scopes that he wants to grant me access.
To make a parallel, in Microsoft Graph there is a way to request consent from the domain administrator, where only a user consent / admin consent screen is displayed using Oauth2.
I wonder if there is a way to get this type of access in G Suite without requiring the end user to take such complicated steps to make my API work properly.
UPDATE:
This question was originally posted in 2019, does anyone aware if something was changes since then?
You should use the Marketplace SDK for this. This allows you to publish an application to the Google Workspace Marketplace where company admins can choose to install it for their domain.
There are a couple things to keep in mind:
There's an expectation that your application will have some sort of user facing presence (e.g. add-on, link to web app, etc).
Google will review your app before publishing. Since you're not using Gmail or Drive scopes (for these, Google requires a 3rd party security review), this process should not be too difficult. But plan for it to take some time, and follow the best practices so it's done right the first time.
You also mentioned synchronizing calendars. If that means mainly reading, no problem, but if you're writing (a lot at once), be mindful of calendar use limits. These are per user and for all activity by that user (not just your app).

How to uniquely identity a pipedrive account?

We are trying to integrate our platform with Pipedrive. As far as we have researched, in a pipedrive account, there is one admin and he can add multiple users. And the users later can login in their respective accounts.
What we are trying to make sure is that once a Pipedrive account is integrated with our platform, the same account should not be integrated twice. So, I need a unique identifier, that lets me know whether the account has already been integrated.
My initial approach was to check the api key. But it was not successful, since every users in an account have different API Keys.
After a bit of research, I found out that there is an identifier called company_id which is common for all the users in an account. But I could not find anything regarding it in documentation. So, I am not 100% confident to go ahead and implement it in our code.
Does anyone have an idea about this?
Pipedrive support rep here.
The most sure-fire way to ensure this is to make a GET request against http://api.pipedrive.com/v1/users?api_token=your_token_here.
You are correct in assuming the company_id in the additional_data object in the response is static and won't change across any users on the account.
Note that a Pipedrive account may have more than one admin, and that non-admins (regular users) might have visibility (and editing) restrictions in place, which may cause some of your GET, PUT and DELETE requests to fail.
In case you're not doing this already, I'd thus advise filtering the data array from the abovementioned endpoint for user.is_you to equal true and check whether the is_admin property is set to 1 during "registration" to ensure the user setting up the integration is an admin.
Hope this helps!
I'm not quite sure what you're asking for. Are you looking for a unique identifier for each user?
Each user has an id, you can get all users by calling
https://api.pipedrive.com/v1/users?api_token=____
This will return a JSON Object with data on your users, including their names and associated IDs. Admins are just users with different privilege levels. All admins are users, but not all users are admins. All users are part of a company, the company is identified by the first part of the Pipedrive account url ie.
https://FooCompany.pipedrive.com
Are you trying to see if a certain company has been integrated already?

Errors accessing Shared/Room Calendars through Microsoft Graph API

I'm making an application that requires access to the shared/room-resource calendars in an Office 365 instance, using non-admin accounts. I've registered an app (in the Microsoft Application Registration Portal) using the V2 endpoint and Auth Code Grant. This successfully allows me to log in, and gives me a functional token with the Calendars.ReadWrite.Shared scope. With this token, I can retrieve my own calendars, and calendars that have been explicitly shared with me (and therefore added to my list of calendars). All of this is doable with just the normal Calendars.ReadWrite scope.
However, I get errors when requesting access to any other shared calendars, like the room calendars. Here's an example. If I make a GET call to https://graph.microsoft.com/beta/users/my-own-email#business.com/calendars it successfully returns a list of my calendars. If I make a GET call to https://graph.microsoft.com/beta/users/meetingroom1.4#business.com/calendars I get a 404 (Not Found) Error. The same error occurs for any other user, not just meeting rooms. Note that I can see these calendars when I'm logged into Office 365 online with the same account.
A different error occurs if I ask for events not calendars. If I make a GET call to https://graph.microsoft.com/beta/users/meetingroom1.4#business.com/events, I get a 500 (Internal Server) Error.
I've checked all the other threads I can find on the issue, and this one from November How to access shared calendars from Office REST API? says there's some kind of blocking issue on Microsoft's end. It's using the Office REST API rather than Graph, but on the back-end the APIs call the same stuff. Is this issue still about? Alternatively, am I missing some further permissions? I tried adding quite a few different permissions on top of Calendars.ReadWrite.Shared, but none of them fixed it. Is there a correct combination?
Thanks so much for any help, and let me know if any other info would be useful for diagnosis.
So if anyone else happens to be interested in this, I figured out a way to access room resource calendars without using the Calendars.ReadWrite.Shared permission. This allows you to use just the Calendars.ReadWrite permission to access the room resources, by moving them into the list of calendars of the email you're authenticating with. However, it will only work for specific accounts that you share the calendars with, so won't be usable in apps that have to work for any account. This is good enough for my use-case, but may not be for yours.
First, find or make an account that is a delegate to, and has full access to, the room resource calendar you want to use. On that account click 'Open another mailbox' in the dropdown list under your profile image.
Open another mailbox location
In the pop-up that follows, put in the email address of the room resource calendar that you want to use.
Then, on the new page that opens (which should be the Office account of the room resource calendar):
Navigate to the calendar page
Click 'Share'
Share the default calendar with the account you plan to authenticate with.
Then log into that 'authentication' account, check its email for the notification of the shared calendar, and click 'accept'. What this will do is move the calendar into the authenticated account's list of calendars, meaning you can access it with just a call to the https://graph.microsoft.com/v1.0/me/calendars endpoint. You'll have to repeat it for every calendar you want to be able to access, sadly.

Using googlecl with a non-Gmail address

I am trying to build a small toolbox of scripts such that I can automate some tasks involving Google contacts, calendar and so on. Most of the work is already done by means of the googlecl project, which looks very promising.
As far as I understand the process, googlecl needs to request an authentication ticket from Google by means of OAuth. Admittedly, I have only a sketchy notion of what is going on there, but that’s something that Wikipedia will help me solve.
Here’s the catch: My Google account uses a non-Gmail address (let it be vucar#example.invalid for the sake of this discussion). The account was created back in the old days when Google didn’t force GMail down people’s throats who have no use for it. googlecl will direct me to https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=…&hd=example.invalid to complete the OAuth handshake. Google will then tell me that ‘the domain name has not been signed up for Google Apps’. Which is correct.
If I don’t supply my user ID to googlecl, then the URL reads …&hd=default. Google will accept the OAuth request, granting whichever permissions needed to my locally running googlecl, but then googlecl will complain that the token was issued to a different user ID than for the user ID that was requested. Which of course is also correct.
I’ve read through https://support.google.com/a/answer/33419, which in turn redirects me to http://www.google.com/a in order to ‘to sign up your domain for Google Apps’. Apparently, if my Google account uses a domain different from #gmail.com, then I am a business user and need to purchase Google Apps for my domain—to get, amonst a truckload of other stuff, my domain connected to GMail, the polar opposite of what I wanted to have by having that ‘foreign’ domain in the first place.
I have to admit that I am stymied. I understand what OAuth in this case is used for, but I fail to grasp the byzantine reasoning at Google’s. I do not believe that I want Google Apps for my domain, and I especially do not want to hand over my emails or anything else to Google. I merely want to access and modify my data at Google’s, with my user ID happening not to end in #gmail.com.
Is it strictly required that I purchase Google Apps for Work for such a configuration? The contacts, calendars and so forth is already at Google’s, and used from both Google’s web site and Android clients. The only thing new to the mix is API access.

How can I setup Google Oauth to allow login using an alternate Google account?

I made a members-only site that uses Google oauth2 to authorise users. The site is built with the Laravel framework and Artdarek's oath library.
When the authorization callback comes from Google, I lookup the user record in the DB by email and proceed to the protected page if the record exists, otherwise to a register page.
The problem is some of our members use two Google accounts. One user registered via his primary account (e.ge. a#gmail.com). The next day he returned and mistakenly tried to login with b#gmail.com. Naturally the system showed him the registration page. From that time on each time he visits the site the authentication mechanism sees him using his second (unwanted) set of credentials.
To resolve this one case I instructed him to logout of all accounts (on both sides), clear cookies and start from scratch but this is not a practical solution for all users. In same cases even this measure does not seem to correct the problem.
How can I solve this case? What is the right way to request oauth authentication and get them back from the right account? Can I force Google to ask the user with which account to proceed?
Google will automatically ask the user which account they want on an oauth request if they enable the account chooser.
I have logged into my Google Apps and my Google account, so for me on an oauth request, I get the following prompt:
In order to do the same for your user, they have to click "Stay signed in", but of course this is not advisable for public computers.
Beyond the above, I'm afraid not much can be done. - if they logged in with a#gmail.com at that time, these are the credentials you will receive.
They way I solve this problem is to have a field where the customer can add additional emails, and select one that is primary. I will then inspect against these emails when a request comes in to avoid duplicate user accounts.

Resources