Systems Library / Sales Automation / How to Automate Contact Record Updates from Email
Sales Automation crm pipeline

How to Automate Contact Record Updates from Email

Update CRM contact records automatically based on email interactions.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Your CRM is only as good as the data in it. This system automates crm contact updates from email activity so your team works from current records without manual entry. I run this for every CRM I touch.

What You Need Before Starting

Step 1: Connect to Email

Use the Gmail API to read recent emails. Filter to business domains only.

from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build

def get_recent_emails(creds_path, hours_back=24):
    creds = Credentials.from_authorized_user_file(creds_path)
    service = build("gmail", "v1", credentials=creds)

    results = service.users().messages().list(
        userId="me", q=f"newer_than:{hours_back}h"
    ).execute()

    emails = []
    for msg in results.get("messages", []):
        detail = service.users().messages().get(
            userId="me", id=msg["id"]
        ).execute()
        headers = {h["name"]: h["value"] for h in detail["payload"]["headers"]}
        emails.append({
            "from": headers.get("From", ""),
            "to": headers.get("To", ""),
            "subject": headers.get("Subject", ""),
            "date": headers.get("Date", ""),
        })
    return emails

Step 2: Match Emails to Contacts

Look up each email address in your CRM. If the contact exists, queue an update. If not, flag it for review.

def match_to_crm(emails, crm_client):
    matched = []
    unmatched = []
    for email in emails:
        address = extract_email_address(email["from"])
        contact = crm_client.search_contacts(email=address)
        if contact:
            matched.append({"contact": contact, "email": email})
        else:
            unmatched.append(email)
    return matched, unmatched

Step 3: Update Contact Records

Push activity data back into the CRM. Log the email date, subject, and direction.

def update_crm_activity(crm_client, matched_emails):
    for item in matched_emails:
        contact_id = item["contact"]["id"]
        email = item["email"]
        crm_client.create_activity(
            contact_id=contact_id,
            activity_type="email",
            subject=email["subject"],
            timestamp=email["date"],
            direction="inbound"
        )
    print(f"Updated {len(matched_emails)} contact records")

Step 4: Handle New Contacts

When an email comes from an unknown address, check if it belongs to an existing company.

def handle_unmatched(crm_client, unmatched_emails):
    for email in unmatched_emails:
        address = extract_email_address(email["from"])
        domain = address.split("@")[1]
        company = crm_client.search_companies(domain=domain)
        if company:
            crm_client.create_contact(
                email=address,
                company_id=company["id"],
                source="email_auto_detected"
            )

Step 5: Schedule Hourly Sync

Run this every hour during business hours. Email-to-CRM sync should feel instant to reps.

0 * * * * cd /root/email-sync && python sync_emails.py >> /var/log/email-sync.log 2>&1

What to Build Next

Add sentiment analysis to incoming emails. Flag contacts who sound frustrated so reps can prioritize their responses.

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems