Python Email Automation: Beyond Basic Scripts

Python Email Automation: Beyond Basic Scripts

Advanced Python Email Automation: Send, Receive, and Process at Scale

Email remains critical for business communication, but managing it manually doesn't scale. Python lets you automate everything from sending personalized campaigns to parsing incoming messages and extracting data. Here's how to build sophisticated email automation.

Email Automation Capabilities

Sending:

  • Personalized email campaigns
  • Transactional notifications
  • Report distribution
  • Automated follow-ups

Receiving/Processing:

  • Parse incoming emails
  • Extract attachments
  • Route to appropriate systems
  • Auto-respond to inquiries

Sending Emails with Python

Basic SMTP Sending

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

def send_email(to, subject, body, html_body=None):
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = 'sender@company.com'
    msg['To'] = to

    msg.attach(MIMEText(body, 'plain'))
    if html_body:
        msg.attach(MIMEText(html_body, 'html'))

    with smtplib.SMTP('smtp.gmail.com', 587) as server:
        server.starttls()
        server.login('sender@company.com', 'app_password')
        server.send_message(msg)

Using Email Services (SendGrid, Mailgun)

import sendgrid
from sendgrid.helpers.mail import Mail

def send_via_sendgrid(to, subject, content):
    sg = sendgrid.SendGridAPIClient(api_key='your-api-key')

    message = Mail(
        from_email='sender@company.com',
        to_emails=to,
        subject=subject,
        html_content=content
    )

    response = sg.send(message)
    return response.status_code

Personalized Mass Emails

import pandas as pd
from jinja2 import Template

def send_personalized_campaign(template_path, recipients_csv):
    # Load template
    with open(template_path) as f:
        template = Template(f.read())

    # Load recipients
    recipients = pd.read_csv(recipients_csv)

    for _, row in recipients.iterrows():
        # Personalize content
        html_content = template.render(
            name=row['first_name'],
            company=row['company'],
            custom_offer=row['offer_code']
        )

        send_email(
            to=row['email'],
            subject=f"Special offer for {row['company']}",
            body="",
            html_body=html_content
        )

        time.sleep(1)  # Rate limiting

Reading and Parsing Emails

IMAP Email Reading

import imaplib
import email
from email.header import decode_header

def read_unread_emails():
    mail = imaplib.IMAP4_SSL('imap.gmail.com')
    mail.login('your@email.com', 'app_password')
    mail.select('inbox')

    # Search for unread emails
    status, messages = mail.search(None, 'UNSEEN')
    email_ids = messages[0].split()

    emails = []
    for eid in email_ids:
        status, msg_data = mail.fetch(eid, '(RFC822)')
        msg = email.message_from_bytes(msg_data[0][1])

        emails.append({
            'from': msg['from'],
            'subject': decode_header(msg['subject'])[0][0],
            'date': msg['date'],
            'body': get_email_body(msg)
        })

    mail.logout()
    return emails

Extract Attachments

def save_attachments(msg, output_dir):
    for part in msg.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue

        filename = part.get_filename()
        if filename:
            filepath = os.path.join(output_dir, filename)
            with open(filepath, 'wb') as f:
                f.write(part.get_payload(decode=True))
            return filepath

Email-Based Workflows

Auto-Process Incoming Invoices

def process_invoice_emails():
    emails = read_unread_emails()

    for email_data in emails:
        if 'invoice' in email_data['subject'].lower():
            # Save attachment
            attachment_path = save_attachments(email_data['msg'], '/tmp')

            # Extract invoice data
            if attachment_path.endswith('.pdf'):
                invoice_data = extract_invoice_data(attachment_path)

                # Add to accounting system
                create_bill_in_quickbooks(invoice_data)

                # Mark email as processed
                move_to_folder(email_data['id'], 'Processed')

Auto-Respond to Inquiries

def auto_respond_to_inquiries():
    emails = read_unread_emails()

    for email_data in emails:
        category = classify_email(email_data['body'])  # Use AI

        if category == 'pricing_inquiry':
            send_email(
                to=email_data['from'],
                subject=f"Re: {email_data['subject']}",
                body=load_template('pricing_response.txt')
            )
        elif category == 'support_request':
            create_support_ticket(email_data)
            send_email(
                to=email_data['from'],
                subject=f"Re: {email_data['subject']}",
                body=load_template('support_acknowledgment.txt')
            )

Best Practices

Sending:

  • Use email service providers for bulk sending
  • Implement rate limiting
  • Handle bounces and unsubscribes
  • Use proper authentication (SPF, DKIM, DMARC)

Processing:

  • Use app passwords, not main passwords
  • Handle different email formats gracefully
  • Log all automated actions
  • Implement error handling

Integration with n8n/Make

For many email workflows, combining Python with no-code tools is ideal:

  • n8n/Make for orchestration and simple logic
  • Python for complex parsing and processing
  • Call Python via HTTP endpoints

Need Email Automation Help?

Our Python automation team builds custom email processing solutions that integrate with your business systems.

Contact us for email automation consulting.

0 comments

Leave a comment

Please note, comments need to be approved before they are published.