Part 1 - Create New project
console.cloud.google -(google cloud platform)
01
Go to the console.cloud google and create a new project
https://developers.google.com/gmail/api/guides
Create a new project name mygmaildata
02
Select the project go to Library
or Enable APIs & Services
,
search for gmail api
, and ENABLE
it.
03
Enable The Gmail API
04
Go to CREATE CREDENTIALS
in the api.
05
You might also be able to do it on the Credential
pages

Part 2 - Create Credentials - Credential Type & Scopes
Credential types and Scopes
Part 4 add Test user
01
Go to OAuth consent screen
to add ADD USERS
and add your email to the User

04
Enter the email you wish to use

Part 5 Create a VENV & Install Libraries
01
Go to jieJenn 00-GetStartGmailApi-Python for review, and install a venv in the directory of the project, and install the libraries
python -m venv venv
./venv/bin/activate

02
If ./venv/bin/activate
Does Not Work
run
source ./venv/bin/activate

03
Go to https://developers.google.com/gmail/api/quickstart/python , and install the client libraries
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

04
To deactivate and exit the venv type,
deactivate

Part 6 - Gmail Api -> Quickstarts -> python -> (token.json
)
01
To get started quick copy and paste the code into your script from the Gmail Api -> Quickstarts -> python page
https://developers.google.com/gmail/api/quickstart/python

02
Make sure you change the name of credentials.json
to your client_secret
file name, and Keep creds
= to None
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/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(
"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:
# Call the Gmail API
service = build("gmail", "v1", credentials=creds)
results = service.users().labels().list(userId="me").execute()
labels = results.get("labels", [])
if not labels:
print("No labels found.")
return
print("Labels:")
for label in labels:
print(label["name"])
except HttpError as error:
# TODO(developer) - Handle errors from gmail API.
print(f"An error occurred: {error}")
if __name__ == "__main__":
main()

03
Run the python script and the browser will open to this page showing gmail accounts, **Only test users assigned in part 4 - add Test user

04
Click Continue

05
Click Continue

06
When you see this page, you can now use the data in your script

07
A token.json
will be downloaded into the same directory as the script

Part 7 - Project - Python Code get token.json
- ( step 1 )
01
Fix tabindexes for images only step-col & and img-4-container img sizes
Import the client libraies and add the scope
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 SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]

02
(this code doesn't not work alone)
Write the function myEmails()
1. First, check if os.path
exist between script and api, And,
if there is a token.json
(which right now there is no token.json
) **this code will do nothing
creds
's value will be assigned
a Credentials
object with a from_authorized_user_file
method and token.json
and SCOPES
as arguments.
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 SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"] def myEmails(): creds = None if os.path.exists('token.json'):creds
= Credentials.from_authorized_user_file
('token.js',SCOPES)

03
(this code doesn't not work alone)
The next conditional checks if creds
does not
and if creds
is not
valid.
If So,
the nested condition checks if creds
exist
,
expired
, and
for a
refresh_token
which will be in the token.json, and refreshes creds
with a Request()
function in the refresh
method
Otherwise if everything exists, the else
statement assignes the InstallAppFlow
class
with the from_client_secrets_file
method to flow
(this makes the request)
and assigns flow
with a run_local_server
method with port=0
to
creds
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 SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"] def myEmails(): creds = None if os.path.exists('token.json'):creds
= Credentials.from_authorized_user_file('token.json',SCOPES) ifnot
or
creds not
creds
.valid: if creds and creds.expired
and creds.refresh_token
: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file
('client_secret.json',SCOPES) creds = flow.run_local_server
(port=0
)

04
Working code
(This will not work if token.js
already exists)
Write the creds
to a file called token.js,
The first time the script runs, the token.json
file will be created. Therefore after that, we can use the data from the api
Run the script and the browser will open with emails ( ** Remember ) you can only use emails assigned as Test Users as seen in part 4
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 SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"] def myEmails(): creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) 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) cred = flow.run_local_server(port=0) with open ('token.json ','w') as token: token.write(creds.to_json()) myEmails()

05
Select the email and hit continues on each page, until the page tells you can close the window.
Fix these images




06
The token.js
file will appear in the same directory as the script

Part 8 - Python Code - service = build('gmail','v1',Credentials=creds)
- (step 2)
01
The build
function from googleapiclient.discovery
will check if
creds
exists, and connect to the api, here we can print out the first message
Go to https://developers.google.com/gmail/api/reference/rest
for more details on users()
,messages()
,list()
and the get()
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
SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]
def myEmails():
creds = None
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
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)
cred = flow.run_local_server(port=0)
with open ('token.json ','w') as token:
token.write(creds.to_json())
try:
service = build('gmail','v1',credentials=creds)
result = service.users().messages().list(userId='me').execute()
messages = result.get('messages')
print(messages[0])
except HttpError as error:
print('err',error)
myEmails()

02
Within try:
we can loop through the messages
try: service = build('gmail','v1',credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: print(i) except HttpError as error: print('err',error)

03
As we are loopin throught the messages, we can use the 'id'
's
in the get()
function to retrieve the
payload
,
Figure out what a payload means
try: service = build('gmail','v1',credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: txt = service.users().messages().get(userId='me',id=i['id']).execute() payload = txt['payload'] print(payload) except HttpError as error: print('err',error)
You can see at the bottom of the video the console in vs code, printing all the contents of the
payload
04
The 'payload'
contains the headers
which contains the 'subjects'
and 'senders'
for each messages in gmail.
try:
service = build('gmail','v1',credentials=creds)
result = service.users().messages().list(userId='me').execute()
messages = result.get('messages')
for i in messages:
txt = service.users().messages().get(userId='me',id=i['id']).execute()
payload = txt['payload']
headers = payload['headers']
print(headers)
except HttpError as error:
print('err',error)
This shows the content in headers
being printed out
05
We can query the 'headers'
and search for the attribute
'name'
to find email's 'senders' 'From'
and 'subjects' 'Subject
to get their 'value'

06
Create 3 empty list to add to for
subject
senders
body
and add to the list for each loop
subjects = [] senders = [] body = []

07
Loop through 'headers'
and Query with a conditional and search for name
for 'Subject'
, append to subjects
and From
, append to
senders
try: service = build('gmail','v1',credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: txt = service.users().messages().get(userId='me',id=i['id']).execute() payload = txt['payload'] headers = payload['headers'] for i in headers: if i['name'] == 'Subject': subjects.append(i['value']) if i ['name'] == 'From': senders.append(i['value']) print(subjects[0]) print(senders[0])

08
The body of the email is the email itself, It is located in
parts
which is located back in payload
try: service = build('gmail','v1',credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: txt = service.users().messages().get(userId='me',id=i['id']).execute() payload = txt.get('payload') headers = payload.get('headers') for i in headers: if i['name'] == 'Subject': subjects.append(i['value']) if i['name'] == 'From': senders.append(i['value']) parts = payload.get('parts') print(parts)
The parts
is very long because it contains the email, if you scroll up you
can see the 'body
with the data
attribute which contains the email content.

10
** This code will cause an error because empty messages with have a
Nonetype
We must replact and Decode the body.'data' attribute,
using the library base64
seen at the top of script.
import base64
try: service = build('gmail','v1',credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: txt = service.users().messages().get(userId='me',id=i['id']).execute() payload = txt['payload'] headers = payload['headers'] for i in headers: if i['name'] == 'Subject': subjects.append(i['value']) if i['name'] == 'From': senders.append(i['value']) parts = payload.get('parts')[0] data = parts['body']['data'] data = data.replace('-','+').replace('_','/') decode_data = base64.b64decode(data) body.append(decode_data) print(data)

10
Check for a none type, and here is the full code
This code doesn't work entirely you can print each message but, if none it breaks
Move on to jieJenn to find new approach, jieJenn-01-gettingStarted
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 import base64 import email SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"] subjects = [] senders = [] body = [] def myEmails(): creds = None if os.path.exists('token.json'): creds = Credentials.from_authorized_user_file('token.json', SCOPES) 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) with open('token.json', 'w') as token: token.write(creds.to_json()) try: service = build('gmail', 'v1', credentials=creds) result = service.users().messages().list(userId='me').execute() messages = result.get('messages') for i in messages: txt = service.users().messages().get(userId='me', id=i['id']).execute() payload = txt['payload'] headers = payload['headers'] for i in headers: if i['name'] == 'Subject': subjects.append(i['value']) if i['name'] == 'From': senders.append(i['value']) parts = payload.get('parts') if parts: parts = parts[0] data = parts['body']['data'] data = data.replace('-', '+').replace('_', '/') decode_data = base64.b64decode(data) print(decode_data) body.append(decode_data) if body: print(body[0].decode('utf-8')) # Decode the bytes to string # print(body[2]) # Decode the bytes to string except HttpError as error: print('err', error) myEmails()
