Want to code faster? Our Python Code Generator lets you create Python scripts with just a few clicks. Try it now!
Gmail is by far the most popular mail service nowadays. Individuals and organizations use it. Many of its features are enhanced with AI, including its security (and detection of fraudulent emails) and its suggestions when writing emails.
In the previous tutorials, we explained how you could send emails and read emails with Python. If you didn't read them yet, I highly recommend you check them out.
While the previous tutorials were on using the IMAP/SMTP protocols directly, in this one, we will be using Google's API to send and read emails; by doing so, we can use features that are specific to Google Mail, for example; add labels to some emails, mark emails as unread/read and so on.
For this guide, we will explore some of the main features of the Gmail API, and we will write several Python scripts that can send emails, search for emails, delete, and mark them as read or unread. They'll be used as follows:
Here is the table of contents:
To get started, let's install the necessary dependencies:
To use the Gmail API, we need a token to connect to Gmail's API. We can get one from the Google APIs' dashboard.
We first enable the Google mail API, head to the dashboard, and use the search bar to search for Gmail API, click on it, and then enable:
We then create an OAuth 2.0 client ID by creating credentials (by heading to the Create Credentials button):
Click on Create Credentials, and then choose OAuth client ID from the dropdown menu:
You'll be headed to this page:
Select Desktop App as the Application type and proceed. You'll see a window like this:
Go ahead and click on DOWNLOAD JSON; it will download a long-named JSON file. Rename it to credentials.json
and put it in the current directory of the project.
Alternatively, if you missed that window, you can click on that download icon button at the right of the page:
Note: If this is the first time you use Google APIs, you may need to simply create an OAuth Consent screen and add your email as a testing user.
Now we're done with setting up the API, let's start by importing the necessary modules:
Obviously, you need to change our_email
to your address. Make sure you use the email you created the API auth with.
First of all, let's make a function that loads the credentials.json
, does the authentication with Gmail API and returns a service object that can be used later in all of our upcoming functions:
You should see this familiar if you have already used a Google API before, such as Google Drive API; it is basically reading the credentials.json
and saving it to token.pickle
file after authenticating with Google in your browser, we save the token, so the second time we run the code, we shouldn't authenticate again.
This will prompt you in your default browser to accept the permissions required for this app. If you see a window that indicates the app isn't verified, you may just want to head to Advanced and click on go to Gmail API Python (unsafe):
First, let's start with the function that sends emails; we know that emails can contain attachments, so we will define a function that adds an attachment to a message. A message is an instance of MIMEMultipart
(or MIMEText
, if it doesn't contain attachments):
Second, we write a function that takes some message parameters, builds, and returns an email message:
And finally, we make a function that takes message parameters, and uses the Google mail API to send a message constructed with the build_message()
we previously defined:
That's it for sending messages. Let's use the function to send an example email:
Put your email as the destination address and real paths to files, and you'll see that the message is indeed sent!
Learn also: How to Send Emails in Python using smtplib.
We had to retrieve the messages page by page because they are paginated. This function would return the IDs of the emails that match the query. We will use it for the delete, mark as read, mark as unread, and search features. The good news is that you can use Gmail search operators such as from
, to
, subject
, filename
, before
and after
(for dates), and many more. Check this page for more info.
In this section, we'll make Python code that takes a search query as input and reads all the matched emails; printing email basic information (To
, From
addresses, Subject
and Date
) and plain/text
parts.
We'll also create a folder for each email based on the subject and download text/html
content as well as any file that is attached to the email and saves it in the folder created.
Before we dive into the function that reads emails given a search query, we gonna define two utility functions that we'll use:
The get_size_format()
function will just print bytes in a nice format (grabbed from this tutorial), and we gonna need the clean()
function to make a folder name that doesn't contain spaces and special characters.
Next, let's define a function that parses the content of an email partition:
Now, let's write our main function for reading an email:
Since the previously defined function search_messages()
returns a list of IDs of matched emails, the read_message()
downloads the content of the email and does what's already mentioned above.
The read_message()
function uses parse_parts()
to parse different email partitions, if it's a text/plain
, then we just decode it and print it to the screen; if it's a text/html
, then we simply save it in that folder created with the name index.html
, and if it's a file (attachment), then we download the attachment by its attachment_id
and save it under the created folder.
Also, if two emails have the same Subject
, then we need to add a simple counter to the name of the folder, and that's what we did with folder_counter
.
Let's use this in action:
This will download and parse all emails that contain the Python Code keyword. Here is a part of the output:
You'll also see folders created in your current directory for each email matched:
Inside each folder is its corresponding HTML version of the email and any attachments, if available.
You can use advanced filters in the search_messages()
function. For example, if you want to get emails that contain a PDF attachment, you can use search_messages(service, "filename: pdf")
. Again, check this page for advanced filtering.
Related: How to Read Emails in Python using imaplib.
We use the batchModify()
method, and we set removeLabelIds
to ["UNREAD"]
in the body
parameter to remove the unread label from the matched emails.
For example, let's mark all Google emails as read:
Marking messages as unread can be done in a similar manner, this time by adding the label ["UNREAD"]
:
Example run:
Now, for the deleting messages feature:
This time we use the batchDelete()
method to delete all matched emails, let's, for example, delete all Google Alerts emails:
Related: How to Delete Emails in Python using imaplib.
Gmail queries support filters that can be used to select specific messages. Some of these filters are shown below, and this is a dialog that is shown when searching for emails; we can fill it and get the corresponding search query:
Gmail not only offers a great and friendly user interface, with many features for demanding users, but it also offers a powerful API for developers to use and interact with Gmail. We conclude that manipulating emails from Google mail programmatically is very straightforward.
If you want to know more about the API, I encourage you to check the official Gmail API page.
Finally, I've created Python scripts for each task we did in this tutorial; please check this page for the full code.
Below are some of the Google API tutorials:
Happy Coding ♥
Finished reading? Keep the learning going with our AI-powered Code Explainer. Try it now!
View Full Code Assist My Coding
Got a coding query or need some guidance before you comment? Check out this Python Code Assistant for expert advice and handy tips. It's like having a coding tutor right in your fingertips!