Why is this necessary in 2025? 🕒
Mail is still the main channel of communication with customers and partners. In fact, 60–80% of incoming emails are routine: confirmations, repetitive questions, "good afternoon, could you tell me...". The bot frees up hours per week, speeds up the response to the user and reduces the likelihood of "depositing" emails.

What we will build ⚙️
Mini-bot on IMAP + SMTP for basic auto-reply.
Routing by keywords (e.g., "payment", "cooperation").
Abstract "how to switch" to Gmail API (OAuth 2.0) for reliability.
Deployment plan: cron / APScheduler, logging, Docker.
Security minimum: .env, App Password, frequency limitation.
Below is the minimum working version.
# pip install python-dotenv
import os, imaplib, smtplib, email
from email.mime.text import MIMEText
from dotenv import load_dotenv
load_dotenv()
IMAP = os.getenv("IMAP_SERVER", "imap.gmail.com")
SMTP = os.getenv("SMTP_SERVER", "smtp.gmail.com")
EMAIL = os.getenv("EMAIL_ADDRESS")
PASS = os.getenv("EMAIL_PASSWORD") # App Password for Gmail
def send_reply(to_addr:str, subject:str):
msg = MIMEText("Thank you! We have received your letter and will reply as soon as possible.")
msg["Subject"] = f"Re: {subject or ''}".strip()
msg["From"] = EMAIL
msg["To"] = to_addr
with smtplib.SMTP_SSL(SMTP, 465) as smtp:
smtp.login(EMAIL, PASS)
smtp.sendmail(EMAIL, [to_addr], msg.as_string())
with imaplib.IMAP4_SSL(IMAP) as imap:
imap.login(EMAIL, PASS)
imap.select("INBOX")
status, data = imap.search(None, '(UNSEEN)')
ids = data[0].split()
for msg_id in ids:
_, raw = imap.fetch(msg_id, "(RFC822)")
msg = email.message_from_bytes(raw[0][1])
sender = email.utils.parseaddr(msg.get("From",""))[1]
subj = msg.get("Subject","")
if sender:
send_reply(sender, subj)
# mark as read
imap.store(msg_id, '+FLAGS', '\\Seen')💡 Tip: During tests, add "dry-run" to log actions instead of actually sending.
Smarter: answers by keywords 🧭
The simplest logic: we look at the subject and body of the letter, we choose a template for the answer.
KEYMAP = {
"payment": "Regarding payment: the invoice has been sent, the terms are 1-2 banking days. If you need an act, please reply to this letter.",
"cooperation": "Thank you for your interest! Please write briefly about your audience and format, and we will get back to you with a proposal.",
"Technical support": "Describe the playback steps and send screenshots/logs — we will help you promptly."
}
DEFAULT = "Thank you for your letter! We are in touch and will get back to you as soon as possible."
def choose_reply(subject:str, body:str) -> str:
text = f"{subject} {body}".lower()
for key, template in KEYMAP.items():
if key in text:
return template
return DEFAULTIt can be expanded to a simple "intent": search for several keys, count the "weight" of matches and choose the best template.
Deployment and operation 🚀
Scheduler: cron,
APScheduleror systemd-timer.Docker: pin the Python version and dependencies, connect
.envas a secret.Logs: INFO level for normal operation and WARNING/ERROR for failures; send errors to Telegram/Slack.
Frequency limitation: do not reply more than once a day to the address; keep a cache of "replies in the last 24 hours".
A/B: test the texts of auto-replies and the subject of the letter — it affects further communication.
Safety and ethics 🔒
Keep secrets in
.env, use App Password or OAuth 2.0, do not commit tokens to the repository.Add "you received an auto-reply" and a way to contact the person to the response.
Whitelist domains/addresses for automatic actions; leave controversial emails for manual parsing.
Follow the email provider's policy and the law on personal data.
📊 What a Python mail bot can do
Scenario | What the bot does | Benefits |
|---|---|---|
Auto Reply | "Thank you, we received the letter" + waiting for the deadline | Removes routine, speeds up first response |
Filtration | Puts in folders: "payment", "cooperation", "support" | Inbox without chaos |
Forwarding | Sends questions about payment to the accountant, and about integration to technical support | Fast routing |
Keywords | Selects a template based on the content of the letter | More relevant answers |
CRM integration | Creates a lead/deal, pulls up a contact | Transparent funnel |
AI response | Generates text via LLM from a brief summary of the letter | Human tone, less manual work |

Upgrade ideas 💡
Summary of the letter: extract a brief summary and substitute it in the answer.
Templates with variables: sender's name, order number, deadline.
Anti-loop: do not reply to auto-replies/no-reply, check the headers
Auto-Submitted.Multilingualism: define the language of the letter and select a template.
📎 Store templates in JSON/YAML and roll out changes without code release.
In Codice we make programming training fun and easy to understand: we have interesting courses with tasks that help you improve your skills step by step.
And we also have an active Telegram channel, where we discuss cool ideas, share experiences and analyze tasks together — learning becomes not only useful, but also fun.
Leave a comment: which auto-reply scenario do you need - "payment", "support", "cooperation" or something else?
