Build an Email Reminder Bot in Python That Reads From Google Sheets
Sending reminder emails is a common task in many domains, from managing team tasks to sending payment reminders or event notifications. In this tutorial, you’ll learn how to create a Python automation bot that integrates Google Sheets and Gmail to send customized reminder emails based on spreadsheet data.
This bot will use the Google Sheets API to read recipient data and message content, and the Gmail API to send the emails. Let’s break this down step-by-step and build a clean, data-driven reminder solution in Python.
1. Setting Up Google API Access
Before we can access Google Sheets or Gmail, we need to set up access through Google Cloud Console.
- Go to Google Cloud Console.
- Create a project and enable the Google Sheets API and Gmail API.
- Under “APIs & Services” > “Credentials,” create OAuth 2.0 credentials for a desktop app and download the
credentials.json
.
Install the required Python packages:
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Now, authenticate and obtain access and refresh tokens using this code snippet:
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
import os.path
import pickle
SCOPES = ['https://www.googleapis.com/auth/gmail.send',
'https://www.googleapis.com/auth/spreadsheets.readonly']
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
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.pickle', 'wb') as token:
pickle.dump(creds, token)
This code handles OAuth2 authorization and caches credentials for future use.
2. Reading Data From Google Sheets
Use your spreadsheet to manage recipients. A common layout might include columns like: Email
, Name
, Task
, Due Date
.
Example Google Sheet URL: https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit
Use the Google Sheets API to read rows:
from googleapiclient.discovery import build
def read_sheet(creds):
service = build('sheets', 'v4', credentials=creds)
SPREADSHEET_ID = 'your_spreadsheet_id_here'
RANGE_NAME = 'Sheet1!A2:D'
result = service.spreadsheets().values().get(
spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute()
rows = result.get('values', [])
return rows
Each row will contain the email data we’ll use to construct reminders dynamically.
3. Sending Emails with Gmail API
Now that we can get data, let’s send emails through Gmail API. The method uses MIME messages plus base64 encoding.
import base64
from email.mime.text import MIMEText
def create_message(to, subject, body):
message = MIMEText(body)
message['to'] = to
message['subject'] = subject
raw = base64.urlsafe_b64encode(message.as_bytes())
return {'raw': raw.decode()}
def send_message(creds, message):
service = build('gmail', 'v1', credentials=creds)
sent_msg = service.users().messages().send(userId='me', body=message).execute()
print(f"Email sent to {message['to']} (ID: {sent_msg['id']})")
This approach allows total customization. You can also add HTML formatting or attachments using different MIME types if needed.
4. Assembling the Reminder Bot
Now let’s combine everything into a workflow. We’ll loop through rows in the sheet and send a formatted reminder to each recipient.
def run_bot():
rows = read_sheet(creds)
for row in rows:
if len(row) < 4:
continue # Skip incomplete rows
email, name, task, due_date = row
subject = f"Reminder: {task} due by {due_date}"
body = f"Hi {name},\n\nJust a reminder that '{task}' is due by {due_date}. Please take necessary action.\n\nBest,\nYour Friendly Bot"
msg = create_message(email, subject, body)
send_message(creds, msg)
This bot can now be scheduled using a cron job or Windows Task Scheduler to run periodically and check the sheet.
5. Tips for Automation and Scalability
- Rate Limiting: Gmail API has quota limits of ~500 emails/day per account. Consider spreading out emails or using a service account (for G Suite domains).
- HTML Content: Switching from
MIMEText(body)
toMIMEText(html_body, 'html')
allows rich formatting. - Dry Run Mode: Add a flag to preview messages without sending, useful for testing layouts.
- Error Handling: Wrap API calls in try/except blocks to handle network errors or bad data gracefully.
- Security: Never commit
credentials.json
ortoken.pickle
to version control.
This bot can easily be extended to add features like conditional reminders, smart scheduling, and group messages. It’s a lightweight but powerful way to enable communication automation using data you already manage in spreadsheets.
Conclusion
We’ve successfully created a working end-to-end solution to send customized email reminders by integrating Google Sheets and Gmail APIs using Python. This kind of automation proves incredibly useful in a wide variety of projects and teams who want to eliminate repetitive manual tasks. With just basic spreadsheet data and Python code, you have now built an effective reminder bot that can run from anywhere — local machines, servers, or even serverless platforms.
Try running this daily and watch your productivity increase while your inbox gets smarter.
Useful links: