Get mail from gmail using service account - python

I'm using google service account for access all mail from gmail account without UI interface but When I execute my code it giving me error
googleapiclient.errors.HttpError: https://www.googleapis.com/gmail/v1/users/me/labels?alt=json returned
"Bad Request">
But when i check Quotas from https://console.developers.google.com/apis/api/gmail.googleapis.com/quotas
there is showing all request that I did using my python code but it always return Bad request when I execute below code.
import httplib2
from apiclient import discovery
from oauth2client.service_account import ServiceAccountCredentials
def get_credentials():
scopes = ['https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.metadata',
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/gmail.labels',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.metadata',
'https://www.googleapis.com/auth/gmail.settings.basic']
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'client_secret.json', scopes=scopes)
return credentials
def main():
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
print('No labels found.')
else:
print('Labels:')
for label in labels:
print(label['name'])
if __name__ == '__main__':
main()

Much has changed since this post was first written,
If anyone else is still looking for an answer. This is my initialization process for the Gmail API today.
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
def main():
# Setup for the Gmail API
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('gmail', 'v1', http=creds.authorize(Http()))
# Call the Gmail API to fetch INBOX
results = service.users().labels().list().execute()
A major difference is the use of access tokens along with credentials in my code.

Related

I can't authorize gmail api application in google colaboratory

I'm running the quickstart code from https://developers.google.com/people/quickstart/python in a colab notebook.
# \[START people_quickstart\]
from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = \['https://www.googleapis.com/auth/contacts.readonly'\]
def main():
"""Shows basic usage of the People API.
Prints the name of the first 10 connections.
"""
creds = None
\# The file token.json stores the user's access and refresh tokens, and is
\# created automatically when the authorization flow completes for the first
\# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
\# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
\# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('people', 'v1', credentials=creds)
# Call the People API
print('List 10 connection names')
results = service.people().connections().list(
resourceName='people/me',
pageSize=10,
personFields='names,emailAddresses').execute()
connections = results.get('connections', [])
for person in connections:
names = person.get('names', [])
if names:
name = names[0].get('displayName')
print(name)
except HttpError as err:
print(err)
if __name__ == '__main__':
main()
# \[END people_quickstart\]
but it fails the authentication at this stage:
http://localhost:52591/?state=K8nzFjxOrWJkPEqjeG1AZiGpsT5DSx&code=4/0ARtbsJoAH2rD9UYgHOKJ__UdJcq87d2vuFjEAqcI3aKJpj1rLJ-93TXR0_v-LnBR4Fytsg&scope=https://www.googleapis.com/auth/gmail.readonly
why is it redirected to localhost?
There is a simple way to send e-mail at google colab? with or without using gmail?
i'm using the google colab at opera browser.
Can anyone help me how i can send a simple e-mail at google colab without lowing the gmail security level?
T.T
There is something wrong with the way you are loading the run_local_server if you are getting a 404 error.
The code below is my standard QuickStart for People api. I just tested it and it works fine. I am not getting a 404 error.
# To install the Google client library for Python, run the following command:
# pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
from __future__ import print_function
import os.path
import google.auth.exceptions
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/contacts']
def main():
"""Shows basic usage of the People API.
Prints a list of user contacts.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
try:
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
creds.refresh(Request())
except google.auth.exceptions.RefreshError as error:
# if refresh token fails, reset creds to none.
creds = None
print(f'An error occurred: {error}')
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'C:\YouTube\dev\credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('people', 'v1', credentials=creds)
# Call the People API
print('List 10 connection names')
results = service.people().connections().list(
resourceName='people/me',
pageSize=10,
personFields='names,emailAddresses').execute()
connections = results.get('connections', [])
for person in connections:
names = person.get('names', [])
if names:
name = names[0].get('displayName')
print(name)
except HttpError as err:
print(err)
if __name__ == '__main__':
main()

problems with my Python code connecting with google docs api

I'm coding a Python app to automatize invoices via a google docs API but I'm having errors with the code and I don't know how to solve it
# [START docs_quickstart]
from __future__ import print_function
import os.path
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/documents.readonly','https://www.googleapis.com/auth/documents','https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.readonly']
def main():
"""Shows basic usage of the Docs API.
Prints the title of a sample document.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
service = build('docs', 'v1', credentials=creds)
title = 'My Document'
body = {
'title': title
}
document = service.documents().create(body=body).execute()
print('Created document with title: {0}'.format(
document.get('title')))
except HttpError as err:
print(err)
if __name__ == '__main__':
main()
# [END docs_quickstart]
and this is the error code that I'm having
PS D:\Universidad\Proyectos de Programacion Propia\python\googledocsinvoice.restapi> python quickstart.py
<HttpError 403 when requesting https://docs.googleapis.com/v1/documents?alt=json returned "Request had insufficient authentication scopes.". Details: "[{'#type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', 'domain': 'googleapis.com', 'metadata': {'service': 'docs.googleapis.com', 'method': 'google.apps.docs.v1.DocumentsService.CreateDocument'}}]">
if you know some guide or complete tutorial to Automate Document Creation with the Google Docs API like invoices and replace encapsulation values like {{productID}} I will be very grateful
I saw the Automate document creation of google channel but it wasn't very helpful https://youtu.be/-dX-fWb3ogE
Best Regards
Make sure you also enable the Docs API in your Developers Console.
Delete the credential file ~/.credentials.json and token.json (if you ran the code before
Change the scope variable used for reading docs
var SCOPES = ['https://www.googleapis.com/auth/documents.readonly'];
to
var SCOPES = ['https://www.googleapis.com/auth/documents'];
Check more info on https://developers.google.com/docs/api/reference/rest/v1/documents/create#authorization-scopes and https://developers.google.com/docs/api/how-tos/authorizing
After the execution of code, API will authenticate again and then the issue should be resolved.

I can't authorize gmail api application in google colab

I'm learning gmail api through google colab.
I'm running the quickstart code in colab and my browser is edge.
from __future__ import print_function
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly']
def main():
"""Shows basic usage of the Gmail API.
Lists the user's Gmail labels.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'/content/drive/MyDrive/Colab Notebooks/credentials for gmail api.json', SCOPES) #使用檔案要上傳
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.json', 'w') as token:
token.write(creds.to_json())
service = build('gmail', 'v1', credentials=creds)
# Call the Gmail API
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
if not labels:
print('No labels found.')
else:
print('Labels:')
for label in labels:
print(label['name'])
if __name__ == '__main__':
main()
after I click the authoritize steps, it pops out
it can't find the local host.
I have no idea what to do, and this quickstart can run successful in jupyter.

Google Api + List members of a group with python

Well, basicaly I'm lost with this task. I need to get all members of a group with the api google privedes. I'm starting with gmail quickstart example, first I have configure Api project and the OAuth client.
My first test was to see all the messages I have in my inbox, all ok. But to do the same with groups members I'm lost, I can't find the way to do it.
Any idea?
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
import json
import requests
SCOPES = 'https://www.googleapis.com/auth/admin.directory.group.member'
def main():
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('gmail', 'v1', http=creds.authorize(Http()))
response = requests.get("https://www.googleapis.com/admin/directory/v1/groups/example#test.com/members")
print(response)
The response is a:
<Response [401]>
Looks like you started with the gmail example and then modified to access the admin/group function
Check the admin docs here https://developers.google.com/admin-sdk/directory/v1/quickstart/python
here is the function, it will retrieve all groups email addressess
def retrieving_groups():
response_group = service.groups().list(customer='my_customer').execute()
for group in response_group['groups']:
print(group['email'])

How to get the email-address of the sender of an email using Gmail Python API

Using the Google API python client, I want to find the email address/ name of the sender of an email.
So far, I have extracted details about the message but I am having trouble finding a way to extract the finder's information.
Here is the code snippet:
from __future__ import print_function
import httplib2
import os
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
try:
import argparse
flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
flags = None
# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/gmail-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/gmail.readonly'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Quickstart'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
home_dir = os.path.expanduser('~')
credential_dir = os.path.join(home_dir, '.credentials')
if not os.path.exists(credential_dir):
os.makedirs(credential_dir)
credential_path = os.path.join(credential_dir,
'gmail-python-quickstart.json')
store = Storage(credential_path)
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else: # Needed only for compatibility with Python 2.6
credentials = tools.run(flow, store)
print('Storing credentials to ' + credential_path)
return credentials
def main():
"""Shows basic usage of the Gmail API.
Creates a Gmail API service object and outputs a list of label names
of the user's Gmail account.
"""
credentials = get_credentials()
http = credentials.authorize(httplib2.Http())
service = discovery.build('gmail', 'v1', http=http)
results = service.users().messages().list(userId='me').execute()
messages = results['messages']
mail = service.users().messages().get(userId='me', id=messages[0]['id'], format='minimal').execute()
# I have other formats(RAW, METADATA and FULL) but I cannot parse them.
print(mail)
if __name__ == '__main__':
main()
I am looking for some method(either built-in or third-party library) to parse the email object returned by the API to return a more readable information. Some ad-hoc method will also work for the time-being.
I got an ad-hoc way to extract the basic information about an email.
Here is the snippet:
metadata = mail['payload']['headers']
# This list contains information about To, From and Subject among other gibberish.
for d in metadata:
# for sender's information
if d['name'] == 'From':
print(d['value'])
# for subject of the mail
if d['name'] == 'Subject':
print(d['value'])

Categories