RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Business Automation with Local AI
  6. /Ch. 2
Business Automation with Local AI

02. Email Processing Pipeline

Chapter 2 of 18 · 15 min
KEY INSIGHT

A processing pipeline is fetch → prepare → infer → act. Build reusable components for each stage.

An email processing pipeline retrieves emails, prepares them for analysis, runs AI inference, and takes action based on results. The pipeline pattern appears in every automation chapter because the components transfer across use cases.

The basic pipeline structure:

import imaplib
import email
from email.header import decode_header
import json
from ollama import chat

def fetch_unread_emails(mail_server, username, password, mailbox='INBOX'):
    """Connect to IMAP and fetch unread emails."""
    mail = imaplib.IMAP4_SSL(mail_server)
    mail.login(username, password)
    mail.select(mailbox)
    status, messages = mail.search(None, 'UNSEEN')
    email_ids = messages[0].split()
    
    emails = []
    for email_id in email_ids:
        status, msg_data = mail.fetch(email_id, '(RFC822)')
        raw_email = msg_data[0][1]
        msg = email.message_from_bytes(raw_email)
        emails.append({
            'id': email_id,
            'from': msg['From'],
            'subject': msg['Subject'],
            'body': get_email_body(msg)
        })
    
    mail.logout()
    return emails

def get_email_body(msg):
    """Extract text body from email message."""
    body = None
    if msg.is_multipart():
        for part in msg.walk():
            content_type = part.get_content_type()
            if content_type == 'text/plain':
                try:
                    body = part.get_payload(decode=True).decode()
                except:
                    body = str(part.get_payload())
                break
    else:
        body = msg.get_payload(decode=True)
    return body if body else ""

This script connects to any IMAP-compatible email server, retrieves unread messages, and extracts their content. Gmail, Outlook, Exchange, and most email providers support IMAP.

The next step is choosing a model for processing. Smaller models like llama3.2:1b or 3b handle high-volume classification tasks where speed matters. Larger models like llama3.1:8b handle nuanced tasks requiring better comprehension. The choice depends on your hardware and the complexity of the required understanding.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Configure this script for your email provider. Run it once manually to confirm it retrieves emails. Store credentials in environment variables, not in the script.

← Chapter 1
Business Automation Landscape
Chapter 3 →
Email Classification