EZGmail and Python — Managing Your Emails Programmatically

Hey Finxters! Among the many daily tasks you can achieve with Python, there is one Siri-like task that comes quite handy: managing your emails in a programmatic way

Of course, many emails need your human understanding to be processed properly, and this article is not about implementing a neural network to fine-tune every single email action. 

However, it is about learning a key asset: how to implement a code to manage simple tasks on a Gmail account, with the ezgmail module, such as:  

  • receiving and reading your unread messages 
  • sending emails, including attachments 
  • downloading attachments 
  • viewing your recent messages 

Building on these simple tasks, you will then be able to endlessly tailor your mailbox according to your personal needs, such as for example: 

  • trigger automatic replies based on specific strings found in an email body and/or subject,
  • block a sender by throwing to the bin emails based on sender email address, or
  • albeit more elaborate, make your very own spam detector by injecting an NLP algorithm in your program.

Lets get started! 

Setting It Up

For this project to work, you need two things: 

  • installing the right module
  • enabling the Gmail API

Install the ezgmail Module

The module well be working with is called ezgmail, and you can install it with the usual command: 

pip install ezgmail

or

pip3 install ezgmail

Alternatively, you may run

pip install --user -upgrade ezgmail

on Windows, to make sure you get the latest version. 

To check it installed correctly, you can then check the version with the following command line argument: 

pip show ezgmail 

Note that this module is not produced by or affiliated with Google. It was developed by software programer Al Sweigart and you can find all the details here: https://github.com/asweigart/ezgmail 

Enabling the Gmail API 

First of all, I highly recommend you setup a separate Gmail account for this project. This will prevent any unexpected event from altering your mailbox in any unwanted way. 

So, start out by signing up for a new Gmail account, then visit this page: https://developers.google.com/gmail/api/quickstart/python 

Click Enable the Gmail API button, then fill in the form, after which you’ll see a link to a credentials.json file, which you’ll have to download and place in the same directory as your Python file. This is a requirement for the code to work. (For those who don’t know, basically, json is a popular and widespread format that looks like a dictionary in Python.) 

Consider this file content the same as your Gmail password, so keep it secret. 

When you will run your Python code to manage your Gmail account, the code will first visit the json file directory in order to fetch your credentials from the credentials.json file. 

This provides additional security as unlike other modules, with ezgmail you do NOT have to type in plain text your credentials in the program. 

Time to start: enter the following code: 

import ezgmail, os
# change dir to the one where json credentials are saved:
os.chdir(r'C:/path_to_credentials_json_file')
ezgmail.init()

As a side remark, notice that you could have achieved what the second line does (i.e., changing the current working directory to the directory containing the file credentials.json) with the Python exec() function!

Something like:

exec(import os; os.system(cd path_to_credentials_json_file))  

The .init() method will open your browser towards a Google page where you can login. Type your credentials, you may then see This app isn’t verified: this is OK (believe me, I did it before you and I’m fine!), click Advanced, then Go to quickstart (unsafe)

When the next page prompts you with Quickstart wants to access your Google account, allow it, then close the browser. 

You’re almost done with the setup phase.  

What just happened is a token.json file was created, and this will be used to provide your Python code access to the Gmail account you created for this project. Keep this one safe, too. 

So from now on, you will no longer need to manually type your credentials. 

You’re good to go! Starting now, the .init() method should no longer be necessary.  

Sending emails 

The method is quite straightforward: ezgmail.send() 

ezgmail.send('recipient@gmail.com', 'test', 'hello world!')

Here are the arguments that you can pass: 

Mandatory args are: 

  • recipient 
  • subject 
  • body 

Optional, kwargs are: 

  • attachment (you can pass a list if there are several) 
  • sender 
  • cc (might not work at the moment, as per the github page) 
  • bcc (might not work at the moment, as per the github page) 

Forgot the email address the token.json was setup for? 

Just check the attribute ezgmail.EMAIL_ADDRESS 🙂 

ezgmail.EMAIL_ADDRESS

Receiving emails 

There are two steps involved:

  • Reading the email, and
  • Downloading its attachments.

Reading mail 

The ezgmail package structures emails just like the GUI email client does: it organizes them into threads, that can in turn contain multiple messages. 

Hence the method .unread() lists the GmailThread objects. 

print(ezgmail.unread())

Want to read a specific email within a thread? 

The .messages attribute is just what you need. It is subscriptable: 

unreadThreads = ezgmail.unread()
print(unreadThreads[0].messages[0].body)

It comes with a bunch of attributes such as sender, recipient, body, timestamp etc. 

Also check the .recent() method: it yields the 25 most recent threads of your Gmail account. 

recentThreads = ezgmail.recent()
print(ezgmail.summary(recentThreads))

Downloading attachments 

A GmailMessage object carries an attachments attribute that’s a list of filenames. 

Pass any combination of these filenames in the .downloadAttachment() method to download the files, or if you want all of them, use the .downloadAllAttachments() method, which even has an argument enabling  you to specify where to download the files (default the current working directory). 

Searching mail 

You guessed it use the ezgmail.search() method! 

Enter a string in this method just like you would in a GUI mailbox. 

resultThreads = ezgmail.search('json')
ezgmail.summary(resultThreads)

This returns a list of threads (remember the GmailThreads objects?) 

You can then pass the above mentioned attributes to retrieve specific info about a message. 

Where to go from here? 

Try it yourself! 

And do discover the other features provided by this efficient and user-friendly module! 

  • Maybe you need it to automate a newsletter? 
  • Or to setup email reminders for your personal need? 
  • Or at work? 

Let us know! 

A few concluding remarks: 

  • in general, for this to work the email account needs to be configured with the lowest level of security, else the email will end-up either blocked or in the spams 
  • you may not be able to send repeated emails with the exact same text (as these probably are spams) nor with .exe attachments (since these are probably viruses) 
  • please use this technology responsibly 
  • thanks to Al Sweigart for creating and maintaining this awesome module 
  • just because it currently works doesn’t mean it will forever; it is reliant on Googles choices among other things, and this module behaviour through time cannot be guaranteed 

Last, if you need to process emails from an account other than Gmail, you should check the right modules to send and receive emails from any account, respectively using SMTP and IMAP protocols.