Google People API not returning any data - google-api

I am using this url:
https://people.googleapis.com/v1/people/me?personFields=emailAddresses&access_token=XYZ...
The access token is valid, I have requested scope userinfo.profile. The call returns with http code 200, however all the data I get is:
{
"resourceName": "people/106663430887168632038",
"etag": "%EgUBCT43LhoEAQIFBw=="
}
Why am I not getting the email address?

Nevermind I found this API that retrieves the email address I want:
https://gmail.googleapis.com/gmail/v1/users/{userId}/profile
I guess the People API retrieves some other stored email addresses.

Related

How to configure authentication from Azure data factory to Google Sheets

I am trying to fetch data from Google Sheets via the Azure Data Factory. I have a data flow configured, and a Google Sheets Linked Service configured as well. The Google Sheets Linked Service is using an API key that has no Application Restrictions, and for API restrictions, it is restricted to Google Sheets. When I test the connection, it is successful. However, when I try to fetch a spreadsheet using the data flow in debug mode, I get the error:
at Source 'GoogleSheetsOutput': Failure to read most recent page request: DF-REST_001 - Error response from server: Some({
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}), Status code: 403. Please check your request url and body. (url:https://sheets.googleapis.com/v4/spreadsheets/<my_spreadsheet_id>/values/Sheet1!A2:B3,request body: None, request method: GET)
I made a service account, and shared the google sheet with the service account e-mail, and I also shared it with the admin on the account, which is where the API Key was made.
Any ideas what I need to do here? I would also prefer to use oauth / service account instead if possible, so I am happy to go down that route if there is some documentation I can follow.
"error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" }
I tried to repro this and got the same error.
To solve this, I changed access of my google sheets from restricted to Anyone with the link
It worked and data is previewed without error.

Tracing HTTP Request to Lambda Function Invocation

The frontend developers at my company want to be able to see the lambda function logs of their requests.
Is there a way to pass something like a user created unique id in a header in an http request that will be passed from api gateway to the lambda function so that it easy to find the logs for that particular request?
It is an environment where there could be many requests happening simultaneously.
API Gateway will attach a unique ID to each request and this will filter through into Lambda. Each request should return a header with its response x-amzn-RequestId containing the request ID. In Lambda, you can access this request ID through the context object.
You're also free to create your own headers, x-correlation-id for example. In Lambda, you can access this header via the event.
Once you have you're value, you can attach that to your logs, directly as part of the log message or as metadata — depending on what logger you're using. If you're using CloudWatch, you might want to construct an object:
{ "requestId": "abc", "message": "This is a log entry." }
However you choose to do it, you should end up with a correlation ID which you can use to query your log entries.

Youtube Data Api Search Endpoint 401 Error

I'm trying to use the Youtube search endpoint, which does not seem to require an OAuth token. I've read a few tutorials and they only pass an API key. I'm getting a "Failed to load resource: the server responded with a status of 401 ()" error in my console in Chrome Dev Tools. Specifically, looking at the Network tab I get this:
I notice it says that there is an error: "invalid_token" but I pass the api key so they must be talking about the OAuth token? I'm confused because it shouldn't need one, especially because I'm just doing a query for public data. Even the Try This API portion of the endpoint documentation does not need one. Most importantly, my call in Postman works and just pasting the endpoint in my browser directly works. Why doesn't it work? This is using an axios call from a ReactJS frontend.
const apiKey = 'MY_API_KEY';
const url = 'https://www.googleapis.com/youtube/v3/search';
const response = await axios.get(url, {
params: {
part: 'snippet',
maxResults: 5,
q: songName,
key: apiKey
}
});
What was happening was that I was using axios.defaults.headers.common['Authorization'] =Bearer ${params.access_token}; in other calls for another API. This causes default everything to have this access token! So what I did for now is delete axios.defaults.headers.common["Authorization"]; -- the solution is pretty obvious, just make sure you have no extra headers because Search is not a OAuth endpoint!

Google HomeGraph API: PERMISSION_DENIED error

I am making a smart home app using Actions On Google. I currently have a Firebase cloud function that calls the HomeGraph API with a Request Sync request.
Here's the contents of the function:
const {smarthome} = require('actions-on-google');
const app = smarthome({
key: "(My Key)"
});
//Assume UID is the id of the user that we are requesting a sync for
app.requestSync(uid).then((res) => {
return;
}, (e) => {
console.error(e);
});
In the logs for this function, I am getting the error:
{ "error": { "code": 403, "message": "The caller does not have permission", "status": "PERMISSION_DENIED" } }
This error seems like a standard Google API permission denied error response, but when would it happen in a Request Sync HomeGraph API call?
I was having this problem for quite a long time, and I decided to post the question and answer here so others don't have to spend wasted time troubleshooting.
There are two potential causes for this error to occur.
The most logical cause: make sure you provide a valid API key in the data passed in to the smarthome constructor. The example in the question is correct (of course, replace (my key) with the key you made in the console.
This was the cause of the error that I ran in to: make sure the uid you pass in to requestSync() is a valid user ID. There was a flaw in my SYNC code, therefore the user did not get created. I struggled so much on diagnosing this problem because the error message does not make sense.
Hope this helps to anyone with this problem.

Google OAuth: "invalid_grant" still a thing

I've been stuck for hours getting the Google OAuth2 flow going in my Node/Express application. The basics are fairly straight-forward:
Create Google application credentials
Redirect users to consent screen
Receive a code value
Exchange code for access_token and refresh_token
Store refresh_token for the future
For whatever reason, I cannot pass Step 4 above and always get the following response:
{
"error": "invalid_grant",
"description": "Bad Request"
}
There are a ton of other solutions asking about the above, and no solution has yet worked for me:
Don't use the same code regardless of result
Wait a while after adding new Authorized Redirect URIs
Include http://localhost:3000 as an Authorized Redirect URI
Include all variants with/without protocol, port, trailing-slash
Set access_type to offline previously if needed (and it is)
Use Request instead of Axios
Include a null scope parameter like the OAuth Playground
Encode parameters using Querystring
Confirm application/x-www-urlencoded is the Content-Type
Log out of all Google accounts when retrying
Be aware of Google's token creation limit
With the above stated, here's the specifics of my plight:
Host: http://localhost:3000
Callback #1: http://localhost:3000/auth/google/callback (where code is sent and exchange action below is run)
Callback #2: http://localhost:3000/auth/google/callbacktwo (where access_token and refresh_token should be returned)
Exchange Action: Adjusted for Request module
{
method: 'POST',
uri: 'https://www.googleapis.com/oauth2/v4/token',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
body: {
'code': req.query.code,
'redirect_uri': 'http://localhost:3000/auth/google/callbacktwo',
'client_id': '***.apps.googleusercontent.com',
'client_secret': '***',
'scope': null,
'grant_type': 'authorization_code'
}
}
Authorized Redirect URIs: Visible in Application > Credentials > OAuth 2.0 client IDs
See screenshot
All-in-all, I'm stuck. There's either something fundamentally wrong with my setup/approach or I'm the first developer encountering this bug (the latter can't be true). Can pay for assistance too.
In a shocking turn of events, I resolved this within minutes of posting above with the changes below:
Change #1
Added 'http://127.0.0.1' variants to my Authorized Redirect URIs list
Since '127.0.0.1' equates to 'localhost', thought I'd give it a try. Read this elsewhere.
Change #2
Changed the Exchange Action's redirect_uri to Callback #1, which is where the code was sent.
I thought "what if Google isn't liking the redirect URI not being where it sent the code?".
Change #3
Removed the Exchange Action's scope parameter
Though it's clearly visible in the OAuth Playground, it's not in the documentation.
And the result? Received the object I've been seeking for hours and hours:
{
"access_token": "****",
"expires_in": 3600,
"refresh_token": "***",
"scope": "https://www.googleapis.com/auth/userinfo.profile",
"token_type": "Bearer",
"id_token": "*****"
}
Disclaimer: This does not mean the above will work for you, but it did for me and I'll take it.

Resources