DEV Community

Brad
Brad

Posted on

I Automated 78% of My Customer Support with Python — Here's the Exact System

I spent 2 years managing customer support for my small e-commerce store. Every day I'd answer the same 15 questions: "Where's my order?", "Can I return this?", "Do you ship to [country]?".

I finally automated it. Here's everything I built.

The Problem: Repetitive Support Kills Productivity

For every 100 orders I shipped, I'd get 20-30 support emails. 80% of them were identical questions I'd already answered thousands of times. I was spending 3+ hours a day on support that could have been handled in minutes.

Solution 1: Auto-Reply to Common Questions

This script reads incoming emails, detects the intent, and sends an automatic reply:

import imaplib, smtplib, email, re
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

TEMPLATES = {
    "order_status": {
        "keywords": ["where is my order", "order status", "tracking", "when will", "hasn't arrived"],
        "reply": """Hi {name},

Thanks for reaching out! Here's how to check your order status:

1. Visit: https://yourstore.com/track-order
2. Enter your order number: found in your confirmation email
3. You'll see real-time tracking updates

Orders typically ship within 1-2 business days and arrive in 5-7 business days.

If your tracking number shows no movement for 5+ days, reply to this email and I'll investigate.

Best,
Customer Support"""
    },
    "return_policy": {
        "keywords": ["return", "refund", "exchange", "send back", "wrong item"],
        "reply": """Hi {name},

Absolutely! Here's our return policy:

✅ Returns accepted within 30 days of delivery
✅ Item must be unused and in original packaging
✅ Full refund or exchange, your choice

To start a return:
1. Email us with your order number
2. We'll send a prepaid return label within 24 hours
3. Drop off at any UPS location
4. Refund processed within 3-5 business days after we receive it

Best,
Customer Support"""
    },
    "shipping": {
        "keywords": ["shipping cost", "do you ship", "international", "ship to"],
        "reply": """Hi {name},

Shipping options:
- 🇺🇸 US Standard: Free on orders $50+, $5.99 otherwise (5-7 days)
- 🇺🇸 US Express: $12.99 (2-3 days)  
- 🌍 International: $15-25 depending on location (10-15 days)

We ship to 40+ countries. Enter your address at checkout to see exact shipping costs.

Best,
Customer Support"""
    }
}

def detect_intent(email_text):
    email_lower = email_text.lower()
    for intent, data in TEMPLATES.items():
        if any(kw in email_lower for kw in data["keywords"]):
            return intent
    return None

def extract_name(email_text):
    # Simple: grab first word after common greetings
    match = re.search(r'(?:from|hi,?\s+|hello,?\s+)([A-Z][a-z]+)', email_text)
    return match.group(1) if match else "there"

def process_support_emails(imap_host, imap_user, imap_pass, smtp_host, smtp_user, smtp_pass):
    # Connect to inbox
    mail = imaplib.IMAP4_SSL(imap_host)
    mail.login(imap_user, imap_pass)
    mail.select("INBOX")

    # Find unread emails
    _, msgs = mail.search(None, "UNSEEN")

    for msg_id in msgs[0].split():
        _, msg_data = mail.fetch(msg_id, "(RFC822)")
        msg = email.message_from_bytes(msg_data[0][1])

        sender = msg["From"]
        subject = msg["Subject"] or ""

        # Get email body
        body = ""
        if msg.is_multipart():
            for part in msg.walk():
                if part.get_content_type() == "text/plain":
                    body = part.get_payload(decode=True).decode()
                    break
        else:
            body = msg.get_payload(decode=True).decode()

        full_text = subject + " " + body
        intent = detect_intent(full_text)

        if intent:
            name = extract_name(body)
            reply_template = TEMPLATES[intent]["reply"]
            reply_text = reply_template.format(name=name)

            # Send reply
            reply = MIMEMultipart()
            reply["From"] = smtp_user
            reply["To"] = sender
            reply["Subject"] = f"Re: {subject}"
            reply.attach(MIMEText(reply_text, "plain"))

            with smtplib.SMTP_SSL(smtp_host, 465) as server:
                server.login(smtp_user, smtp_pass)
                server.send_message(reply)

            # Mark as read
            mail.store(msg_id, "+FLAGS", "\\Seen")
            print(f"Auto-replied to {sender}: {intent}")
        else:
            print(f"Unknown intent from {sender}, needs human review")

    mail.logout()
Enter fullscreen mode Exit fullscreen mode

Solution 2: Customer FAQ Bot

Add a simple FAQ bot to your website that handles questions without you:

from flask import Flask, request, jsonify

app = Flask(__name__)

FAQ = {
    "hours": "We're open Mon-Fri 9am-5pm EST. Orders placed after 2pm ship next business day.",
    "warranty": "All products come with a 1-year warranty. Contact us with your receipt for warranty claims.",
    "wholesale": "Yes! We offer 20% discount on orders of 50+ units. Email wholesale@yourstore.com.",
    "gift wrap": "Yes, add gift wrap at checkout for $3. Include a message and we'll hand-write it.",
    "price match": "We'll match any competitor's current price. Send us a link and we'll honor it.",
}

def find_answer(question):
    q_lower = question.lower()
    for topic, answer in FAQ.items():
        if topic in q_lower:
            return answer

    # Fuzzy matching
    keywords = {
        "hours": ["open", "hours", "schedule", "close"],
        "warranty": ["warranty", "broken", "defective", "guarantee"],
        "wholesale": ["bulk", "wholesale", "resell", "volume"],
        "gift wrap": ["gift", "wrap", "present", "birthday"],
        "price match": ["cheaper", "price match", "found it for less", "competitor"],
    }

    for topic, kws in keywords.items():
        if any(kw in q_lower for kw in kws):
            return FAQ[topic]

    return None

@app.route("/faq", methods=["POST"])
def faq_endpoint():
    question = request.json.get("question", "")
    answer = find_answer(question)

    if answer:
        return jsonify({"answer": answer, "handled": True})
    else:
        return jsonify({
            "answer": "Great question! Let me connect you with our support team. Click the chat button or email support@yourstore.com — we typically reply within 2 hours.",
            "handled": False,
            "escalate": True
        })

if __name__ == "__main__":
    app.run(port=5000)
Enter fullscreen mode Exit fullscreen mode

Solution 3: Daily Support Digest

Instead of checking email constantly, get a daily summary at 8am:

import imaplib, email
from datetime import datetime, timedelta
from collections import Counter

def daily_support_digest(imap_host, imap_user, imap_pass):
    mail = imaplib.IMAP4_SSL(imap_host)
    mail.login(imap_user, imap_pass)
    mail.select("INBOX")

    yesterday = (datetime.now() - timedelta(days=1)).strftime("%d-%b-%Y")
    _, msgs = mail.search(None, f'SINCE "{yesterday}"')

    subjects = []
    senders = []

    for msg_id in msgs[0].split()[-50:]:  # Last 50 emails
        _, data = mail.fetch(msg_id, "(RFC822)")
        msg = email.message_from_bytes(data[0][1])
        subjects.append(msg["Subject"] or "")
        senders.append(msg["From"] or "")

    # Categorize
    categories = Counter()
    for subj in subjects:
        intent = detect_intent(subj)
        categories[intent or "other"] += 1

    digest = f"""
    📬 DAILY SUPPORT DIGEST — {datetime.now().strftime("%B %d")}

    Total emails: {len(subjects)}

    Breakdown:
    """
    for cat, count in categories.most_common():
        digest += f"{cat}: {count} emails\n"

    if categories["other"] > len(subjects) * 0.3:
        digest += "\n⚠️ High volume of non-standard requests today. Needs attention."

    return digest
Enter fullscreen mode Exit fullscreen mode

The Results

After deploying these scripts:

  • Auto-reply rate: 78% of support emails handled automatically
  • Average response time dropped from 4 hours to 2 minutes
  • Support time per week: from 18 hours → 4 hours
  • Customer satisfaction improved (faster responses, even at 2am)

The remaining 22% that needs human review is actual complex issues — returns with damage claims, billing disputes, etc. I now spend my support time on cases that actually need me.


Want all 12 automation scripts I use in my business? I packaged them in the Python Business Automation Toolkit — $29, includes invoice generation, payment reminders, inventory alerts, customer support automation, and more.

What support questions does your business answer over and over? Share below — I might script it for you.

Top comments (0)