Build a Daily Task Emailer with Python and Gmail API

Build a Daily Task Emailer with Python and Gmail API

Build a Daily Task Emailer with Python and Gmail API

 

In our always-on digital world, staying organized can be a challenge. What if you could receive a neatly formatted summary of your tasks each morning, sent automatically to your inbox? In this post, we’ll walk through the process of building a Python-based daily task emailer using the Gmail API. You’ll learn how to send formatted emails, manage OAuth2 credentials, schedule your script via cron, and structure your code for flexibility.

1. Setting Up the Gmail API

To securely send emails through Gmail using Python, we need to use Google’s Gmail API with OAuth 2.0 authentication.

Step 1: Create a Google Cloud project

  • Go to the Google Cloud Console.
  • Create a new project or select an existing one.
  • Enable the Gmail API in the API Library.
  • Navigate to “Credentials” and create OAuth 2.0 client IDs for a desktop application.

Download your credentials file as credentials.json.

Step 2: Install Google client libraries

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

Step 3: Authenticating with Gmail

from __future__ import print_function
import os.path
from google.auth.transport.requests import Request
from google_auth_oauthlib.flow import InstalledAppFlow
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

# Gmail API scopes
SCOPES = ['https://www.googleapis.com/auth/gmail.send']

def get_gmail_service():
    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())
    return build('gmail', 'v1', credentials=creds)

This function handles authentication and returns an authorized Gmail API service object.

2. Formatting and Sending the Email

Now let’s define a function that creates and sends a formatted task email. We’ll use the MIME library to craft the message.

from email.mime.text import MIMEText
import base64

def send_email(task_list):
    service = get_gmail_service()
    message_text = "

Today's Tasks

    " + ''.join(f"
  • {task}
  • " for task in task_list) + "
" message = MIMEText(message_text, 'html') message['to'] = "youremail@example.com" message['subject'] = "Daily Task Reminder" raw = base64.urlsafe_b64encode(message.as_bytes()).decode() body = {'raw': raw} sent_message = service.users().messages().send(userId="me", body=body).execute() print(f"Email sent with id: {sent_message['id']}")

Using HTML format makes the email clean, user-friendly, and mobile-optimized. The MIMEText library handles message construction, and Gmail API’s send method performs the actual dispatch.

3. Organizing Tasks for Email

Since task data typically comes from various sources—databases, scripts, APIs—let’s keep our task generation logic modular. For demonstration, we’ll use a static list:

def get_daily_tasks():
    return [
        "Reply to client emails",
        "Review pull requests",
        "Team standup at 10 AM",
        "Plan next sprint backlog",
        "Update project documentation"
    ]

This abstraction allows you to swap data sources later: JSON files, Trello boards, JIRA, Google Sheets, etc.

4. Scheduling with Cron

To automate this daily, use a cron job (Linux/macOS) or Task Scheduler (Windows). Open your crontab:

crontab -e

Add the following line to run the script every weekday at 8:00 AM:

0 8 * * 1-5 /usr/bin/python3 /home/username/scripts/task_emailer.py

Ensure that your script includes a main guard and executes the job as intended:

if __name__ == '__main__':
    tasks = get_daily_tasks()
    send_email(tasks)

Tip: Always use absolute paths in cron scripts and consider logging output to a file for debugging.

5. Security, Performance, and Best Practices

Here are a few tips to improve performance and security:

  • Use service accounts for non-interactive scripts or investigate delegated domain-wide access.
  • Limit scopes to essentials—gmail.send is enough here.
  • Store tokens securely: Use environment variables or secure credential storage (e.g., AWS Secrets Manager, HashiCorp Vault).
  • Error handling: Wrap Gmail API calls in try-except blocks for better error visibility.
try:
    send_email(tasks)
except Exception as e:
    print(f"Failed to send email: {str(e)}")

Conclusion

With just a bit of Python scripting and Gmail API integration, we created a highly useful and flexible tool that sends daily task digests directly to your inbox. Whether for personal productivity or team-wide updates, automating reports this way saves time and keeps everyone aligned. Extend this by pulling data from a task management system or visualizing calendar events. Happy automating!

 

Useful links: