Cant seem to authenticate to read gmail via Gmail API - google-api

I have dug through most of stackoverflow posts to find an answer but still unable to solve this problem. This is just a simple matter of authing into the gmail api but I want to do it in a server so I need to follow the server-server (OAuth2.0 2 legged procedure). Anyways
I have gone through all the oauth docs in google api .
This one is spot on but it does no good.
https://developers.google.com/gmail/api/auth/web-server.
I have a service account and I do have the creds file.
here is my code snippet.
def call_gmail():
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
SERVICE_ACCOUNT_FILE = '<creds_file>'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
print(credentials)
service = build('gmail', 'v1', credentials=credentials)
messages = ListMessagesMatchingQuery(service, "me", "<Some email address>")
message_id = messages[0]['id']
I keep getting this error:
An error occurred: <HttpError 400 when requesting https://www.googleapis.com/gmail/v1/users/me/history?startHistoryId=2547406&alt=json returned "Bad Request">
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
Would be very grateful if someone can help me solve this. thanks.

The gmail api only works with service accounts if its a Gsuite account and you have set up domain-wide delegation. Contact your Gsuite admin and make sure that they have setup delegation properly.
delegating authority

Related

What does a 404 mean in the context of a Google Calendar API?

I am trying to programatically access a calendar I own using the Google Calendar API list:
r = requests.get(
url="https://www.googleapis.com/calendar/v3/calendars/<the ID of my calendar which looks like mydomain_randomstuff#group.calendar.google.com>/events",
params={
'key': <the key from the API console>,
'singleEvents': True,
'orderBy': 'startTime'
}
This call fails with a 404:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "Not Found"
}
],
"code": 404,
"message": "Not Found"
}
}
What does that error actually mean, in the context of this API?
Note:
the calendar does exist and it has events
the API limits are not even close to be reached
{
"error": {
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "Not Found"
}
],
"code": 404,
"message": "Not Found"
}
}
Can mean one of two things. Either the calendar Id you have typed is in correct or the user who you are authenticated with does not have access to that calendar. Make sure you are logging in with the correct user with access to that calendar. Optionally you can do a calendar.list which will return a list of the calendars that the user currently has access to. That way you wont have to worry about possibly miss typing the calendar id.
authorization
The method you are using events.list requires authorization (permission from the user) in order to access their calendar. Which can be seen in the documentation page
You need to authncate your user using Oauth2 and one of the scopes above. You will then have an access token you can use to access this calendar.
apikey
Api keys are used for accessing public data. Unless your calendar is set to public you will not be able to use it to see events. Also remember that api keys do not have access to update public calendars you still need to be authenticated to make changes to them.
Service account
If this is a server to server application you should use a service account not an API key. All you need to do is add the service account as a user on the google calendar like you would any other user. It will then have access to your calendar.

Getting 401 response in google developer api only when query GET subscriptions

I'm using Google Play Android Developer API. I access it from server with service account. I have private key and got access token with it.
I use scope https://www.googleapis.com/auth/androidpublisher. And when I ask subscription info, I got 401 error:
"error": {
"errors": [
{
"domain": "androidpublisher",
"reason": "permissionDenied",
"message": "The current user has insufficient permissions to perform the requested operation."
}
],
"code": 401,
"message": "The current user has insufficient permissions to perform the requested operation."
}
But when I use other queries with the same token and with the same scope, I got successfull responses. For example, I can successful get voided purchases list or info about inapp product:
200 OK
{
"packageName": "com.myapp.exapmle",
"sku": "subscr_month",
"status": "active",
"purchaseType": "subscription",
"defaultPrice": {
"priceMicros": "149000000",
"currency": "RUB"
}
What could be the cause of the problem? I added this service account to developer console and provided all permissions (administrator access).

Adsense API getting 'Error: Login Required'

I'm using the API Explorer tool to create some request urls for google adsense. Here is the request url that the explorer tool generated that gives a response of today's earnings: https://www.googleapis.com/adsense/v1.4/reports?startDate=today&endDate=today&accountId=MY_ACCOUNT_ID&metric=EARNINGS&key=MY_API_KEY
However, when I try to use this url in the browser or in my code it gives this response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
I am not sure what I am missing it use this url. I have activated adsense apis on my google developer console.
The key parameter is the public API key for accessing public data.
The access_token parameter is used for accessing private user data.
In your case you are trying to access your private account and should be using an access token.
To obtain an access token you need to authentication your application using either Oauth2 or a service account. Once you have obtained an access token and send that with your request as so:
https://www.googleapis.com/adsense/v1.4/reports?startDate=today&endDate=today&accountId=MY_ACCOUNT_ID&metric=EARNINGS&access_token=YourAccessToken
You need to replace MY_API_KEY with your API key, and MY_ACCOUNT_ID in same fashion.

Google Reports API with a service account

I'm trying to make a call to Google Reports API with a service account.
I follow this code example : https://godoc.org/golang.org/x/oauth2/google#JWTConfigFromJSON
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Access denied. You are not authorized to read activity records."
,
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Access denied. You are not authorized to read activity records."
}
}
I'm pretty sure it is on Google configuration side but :
I created the service account
I downloaded the JWT
I authorized the needed scopes
Then I try to call this URL : https://www.googleapis.com/admin/reports/v1/activity/users/all/applications/login
What could I have forget ?
Thanks for helping me.
Fixed it. Needed to explicitly specify the subject value.
I now follow the Service Account example : https://godoc.org/golang.org/x/oauth2/google

Google Simple API Access - Authorization required, but how?

I'm trying write a standalone perl app that list all my tasks stored in Google Tasks. I'm led to believe I can use what Google call "Simple API Access" because it's just my tasks and it's read only.
So I did the following:
#!perl
use LWP;
my $browser = LWP::UserAgent->new;
my $list = "Iyrhxu8sRTVOhE4hUBr4W1kwNTI6MDow";
my $key = "<api key removed>";
my $url = "https://www.googleapis.com/tasks/v1/lists/$list/tasks?pp=1&key=$key";
print $browser->get($url)->content;
In return, I get:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
Unfortunately I've no idea what authorization it wants at this point. I tried replacing the last line with:
my $auth = "...";
print $browser->get($url, "Authorization", $auth)->content;
and using the Google listed Client ID, Email address and Client Secret listed in the API Console - but they all gave Invalid Credentials.
Can anyone help?
Doesn't seem to work, they seem to have disabled it in favor of oauth2, and just haven't updated the apply-for-an-api-key page. Use Oauth2 instead:
https://developers.google.com/oauthplayground/
If you need an api key, you can get it here:
https://code.google.com/apis/console

Resources