Automating emails and integrating to gmail can be done fairly easily with Python 3 giving you a range of things that can make your applications richer. This will enable you to link email to one of your applications for things like weekly notifications, alerts, or even the logon confirmation. We will go through how to send emails using Gmail using Python 3 step by step.
How to access Gmail API
If this is you first time trying to use the Gmail API, we recommend you take a look into the our “How to access Gmail through API with Python 3” Blog in which we had learned how to use this API, it’s requirements and we have code sample in which we printed all email subjects. Either way, we will take a brief summary just to refresh
Pre-requisites
On our blog ” How to access Gmail through API with Python 3 ” we touched this topic in depth, so please refer to this blog if you get stuck setting the following pre-requisites
- Python 2.6 or greater
- The pip package management tool
- A Google account with Gmail API enabled
- OAuth 2.0 Client IDs credentials from Google API console
- Google Client Libraries
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Now that everything has been set and we know how to use the API we are going to dive a little bit more dipper, now we are going to learn how to write and send emails directly from our code. This will be very useful if we are going for example to automatize some alerts, or maybe some automatic replays with the customization that you want, your mind is your limit here
Gmail Access Scope
The scope within Gmail API dictates what permissions our application have, in other words, what is going to be able to perform with this API. As we are going to a reading and sending emails we are going to need the scope: compose
Scope Code | Description | Usage |
https://www.googleapis.com/auth/gmail.compose | Create, read, update, and delete drafts. Send messages and drafts. | Restricted |
Creating an email
Emails are sent as base64url encoded strings within the raw property of a message resource. The high-level workflow to send an email is:
- Create the email content in some convenient way and encode it as a base64url string.
- Create a new message resource and set its
raw
property to the base64url string you just created. - Call
messages.send
, or, if sending a draft,drafts.send
to send the message.
Importing the necessary libraries for processing gmail
In order to create emails, we are going to need at least tow libraries. These are intended to handle the respective format of the content in different points of the process.
- base64
This module provides functions for encoding binary data to printable ASCII characters and decoding such encodings back to binary data - MIMEText
A subclass ofMIMENonMultipart
, theMIMEText
class is used to create MIME objects of major type text.
#import base64 lib in order to encode and decode
import base64
# Import MIMEText in order to cast str into MIMEText object
from email.mime.text import MIMEText
Creating email messages
In the following code, we are going to define a method that is going to receive all the parameters needed to build an email and will return an object which contains the message of the email.
Within our method, we create a variable called “message” which is a MIMEtext object, which contains our messages in plain text, and we add som values to handle the other parameters as the sender, to and the subject
Args:
- sender: Email address of the sender.
- to: Email address of the receiver.
- subject: The subject of the email message.
- message_text: The text of the email message.
Returns:
- A string containing an email.
def create_message(sender, to, subject, message_text):
message = MIMEText(message_text,'plain')
message['to'] = to
message['from'] = sender
message['subject'] = subject
email = base64.urlsafe_b64encode(message.as_bytes()).decode()
return email
Before sending an email let’s understand a little bit the functions that we are going to use.
Sending an email through Gmail
Once we have a method that will create an object which will contain our different parameters of the email, we are ready to create another method which will be in charge of sending it.
This new method will receive and returns the following:
- Args:
- service: Authorized Gmail API service instance.
- user_id: User’s email address. The special value “me” can be used to indicate the authenticated user.
- message: Message to be sent.
- Returns:
- Array with sent message information.
In addition to this, we are going to execute the send() method and store the returning value into a variable called message. This variable is going to be used to check if the email was sent, and identify the email’s id
def send_message(service, user_id, message):
message = (service.users().messages().send( userId=user_id, body={'raw':message}).execute())
return message
Now that we have the two methods that we are going to need to send emails through Gmail API, we need to include some additional functions to complete the process.
Common functions for preparing the API calls for Gmail
If you are not familiar with the following code we encourage you to go to our ” How to access Gmail through API with Python 3 ” blog in which we explain everything in depth. These are helper functions that help to determine the security controls of access the emails.
# Import all needed libraries to use Gmail API
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import base64
from email.mime.text import MIMEText
# Defines the permissions that are going to be requested to the end-user
# These permissions defines what our application can performe
SCOPES = ['https://www.googleapis.com/auth/gmail.compose']
def main():
# Checking credentials
creds = get_permissions()
#Declare Gmail API service
service = build('gmail', 'v1', credentials=creds)
# returns permissions granted by the end-user
def get_permissions():
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 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.pickle', 'wb') as token:
pickle.dump(creds, token)
return creds
Complete script to send emails with gmail using python 3
And finally, after all the work is done, we are ready to execute our code and send emails from our application. All the code snippets seen above is merged to the below script
Here are the steps performed by the main function:
- Stores credential’s data into the ‘creds’ variable executing the get_permissions() method.
- Then use our ‘creds variable to initialize the Gmail API, and store it at the service variable.
- At the following step, you will need to change the parameters to the ones needed, accordingly with the applications requirements, in this case, we are going to use test parameters .
- Once the message is stored in our ‘msg’ variable we just call our send_message() so it sends the email, and at the same time we print the result so we know it has been sent successfully.
# Import all needed libraries to use Gmail API
from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import base64
from email.mime.text import MIMEText
SCOPES = ['https://www.googleapis.com/auth/gmail.compose']
def main():
# Checking credentials
creds = get_permissions()
#Declare Gmail API service
service = build('gmail', 'v1', credentials=creds)
msg = (create_message('test@gmail.com','test@gmail.com','test','test_body'))
print (send_message(service,"me",msg))
def get_permissions():
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# 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.pickle', 'wb') as token:
pickle.dump(creds, token)
return creds
def create_message(sender, to, subject, message_text):
message = MIMEText(message_text,'plain')
message['to'] = to
message['from'] = sender
message['subject'] = subject
email = base64.urlsafe_b64encode(message.as_bytes()).decode()
return email
def send_message(service, user_id, message):
message = (service.users().messages().send( userId=user_id, body={'raw':message}).execute())
return message
if __name__ == '__main__':
main()
Running the code
Congrats! Everything has been done, now we are ready to run our script and check the Gmail client to check our new incoming Email has been sent from our script. Just open a console/terminal an execute the script type:
# Replace script.py with the name given to your file
python script.py
After the code has been executed, you will get two results, one at the console/terminal and the other at your Gmail client account, your results will look similar to the following images


Get Notified Automatically Of New Articles
Error SendFox Connection: