gmailapi - JWalshe86/career GitHub Wiki
Google Gmail API Anthony Brunson
Go to career project
xdg-open https://console.cloud.google.com/home/dashboard?project=career-429216
- Search
gmail api
in the search bar - Click enable
- Go back to
gmail api
and click ontutorials & documentation
- Click on
quickstarts
andpython
- Install the Google client library for python:
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Error:
touch quickstart.py
Insert:
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()
838028a
To filter unread Gmail messages by excluding specific senders and categories, you update the query string in the Gmail API request. Construct the query with is:unread -category:social -category:promotions and append exclusions for specific senders using -from:{sender}. Extract email metadata like sender and subject from the headers. This approach helps you filter out unwanted emails and retrieve relevant unread messages efficiently.
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 os.path
# Define the scope and initialize other necessary variables
SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]
def get_unread_emails():
"""Fetch unread emails excluding specific senders and categories."""
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)
# List of senders to exclude
excluded_senders = [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
]
# Construct the query string
query = "is:unread -category:social -category:promotions"
for sender in excluded_senders:
query += f" -from:{sender}"
results = service.users().messages().list(userId="me", q=query).execute()
messages = results.get('messages', [])
if not messages:
print("No unread messages found.")
return []
unread_emails = []
for message in messages:
msg = service.users().messages().get(userId="me", id=message['id']).execute()
email_data = {
'id': message['id'],
'snippet': msg['snippet'],
'sender': next(header['value'] for header in msg['payload']['headers'] if header['name'] == 'From'),
'subject': next(header['value'] for header in msg['payload']['headers'] if header['name'] == 'Subject')
}
unread_emails.append(email_data)
return unread_emails
except HttpError as error:
print(f"An error occurred: {error}")
return []
if __name__ == "__main__":
unread_emails = get_unread_emails()
for email in unread_emails:
print(f"Email ID: {email['id']}, From: {email['sender']}, Subject: {email['subject']}, Snippet: {email['snippet']}")
c652d311 If content of email has 'unfortunately' text turn red
def get_unread_emails():
"""Fetch unread emails excluding specific senders and categories."""
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)
# List of senders to exclude
excluded_senders = [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
]
query = "is:unread -category:social -category:promotions"
for sender in excluded_senders:
query += f" -from:{sender}"
results = service.users().messages().list(userId="me", q=query).execute()
messages = results.get('messages', [])
unread_emails = []
for message in messages:
msg = service.users().messages().get(userId="me", id=message['id']).execute()
snippet = msg['snippet']
email_data = {
'id': message['id'],
'snippet': snippet,
'sender': next(header['value'] for header in msg['payload']['headers'] if header['name'] == 'From'),
'subject': next(header['value'] for header in msg['payload']['headers'] if header['name'] == 'Subject'),
'highlight': 'highlight' if 'unfortunately' in snippet.lower() else ''
}
unread_emails.append(email_data)
return unread_emails
except HttpError as error:
print(f"An error occurred: {error}")
return []
Highlight Logic: For each email, the snippet (text preview) is checked for the word "unfortunately". If found, a highlight flag is set to 'highlight'
{% extends 'base.html' %}
{% block content %}
<div class='container'>
<!-- Display unread email subjects and senders -->
<div class="row mb-2">
<div class="col">
<h2>Unread Emails</h2>
<ul>
{% for email in email_subjects %}
<li class="{{ email.highlight }}">
<strong>From:</strong> {{ email.sender }}<br>
<strong>Subject:</strong> {{ email.subject }}<br>
<strong>Snippet:</strong> {{ email.snippet }}
</li>
{% empty %}
<li>No unread emails</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<style>
.highlight {
color: red;
}
</style>
{% endblock %}
Explanation Conditional Class Application: Each email list item (
Navbar display unread email count
Base.html
<!doctype html>
{% load static %}
<html lang="en" itemscope itemtype="http://schema.org/WebPage">
<head>
<meta charset="UTF-8">
<title>Job Searches</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{% static 'css/main.css'%}">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body data-bs-spy="scroll" data-bs-target=".navbar">
<!-- NAVBAR -->
<nav class="navbar2 navbar-expand-lg navbar-dark static-top">
<div class="container">
<button class="navbar-toggler text-white" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav text-lg-center">
<li class="nav-item">
<a class="nav-link text-white" href="http://127.0.0.1:8000/">Home</a>
</li>
</ul>
<!-- Unread Emails Count -->
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link text-white" href="{% url 'jobs_dashboard_with_emails' %}">
<i class="bi bi-envelope"></i>
Unread Messages: <span class="badge bg-danger">{{ unread_email_count }}</span>
</a>
</li>
</ul>
<!-- Add more nav items as needed -->
</div>
</div>
</nav>
<!-- NAVBAR END -->
<!-- Your page content -->
{% block content %} {% endblock %}
<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<script src='{% static 'js/main.js' %}'></script>
{% block postloadjs %} {% endblock %}
</body>
</html>
jobs_dashboard_with_emails view
def jobs_dashboard_with_emails(request):
key = settings.GOOGLE_API_KEY
eligible_locations = Jobsearch.objects.filter(place_id__isnull=False)
locations = []
for a in eligible_locations:
data = {
'lat': float(a.lat),
'lng': float(a.lng),
'name': a.name
}
locations.append(data)
email_subjects = get_unread_emails()
unread_email_count = len(email_subjects) # Calculate the number of unread emails
return render(request, "jobs/jobs_dashboard.html", context={
'key': key,
'locations': locations,
'email_subjects': email_subjects,
'unread_email_count': unread_email_count, # Pass the unread email count to the template
})
HTML Template Changes: Added a new ul element in the navbar to display the unread messages count. The count is displayed using a badge element next to an envelope icon for visual indication.
View Changes: Updated the view to calculate the number of unread emails and passed this count to the template. This count is used in the template to show how many unread messages are present.