How Email Works and Programming Guide

Hello everyone! The person we are chatting with today is the "living fossil" on the Internet - email. It predates the World Wide Web by more than 20 years and is still the cornerstone of corporate communication, service notifications, and marketing outreach. Almost all modern programming languages ​​have built-in email support, or there are mature third-party libraries to help you quickly complete sending and receiving. This article starts with the principles and then provides ready-to-use Python practical code to help you thoroughly master email development.


1. Understand the flow of mails from “surface mail”

The flow logic of email is actually exactly the same as sending a traditional ordinary letter. We use the following analogy diagram to get the core link in one second.

Steps for traditional ordinary mail

  1. Write the content, put it in the envelope, fill in the recipient's address, and affix the stamp.
  2. Put it into the mailbox downstairs or the inbox of the community post office
  3. China Post/Express Company’s multi-level transshipment center relay transportation
  4. The regional post office in the destination city sorts into specific delivery groups according to streets and communities.
  5. The postman puts the letter in the mailbox at your door or in the company mailroom, and you can pick it up yourself.

Replace the physical role with a computer program or server, compress the time from "days" to "milliseconds/second", and the entire flow becomes the classic arrow diagram below:

flowchart LR
    A[发件人] --> B(MUA 邮件用户代理)
    B --> C(MTA 邮件传输代理 发件方)
    C -->|DNS MX 记录寻址| D(多个中继MTA)
    D --> E(MDA 邮件投递代理 收件方)
    E <-.-|同步/下载| F(MUA 邮件用户代理)
    F <-.- G[收件人]

The benefit of process visualization is: when debugging email problems (such as why it cannot be received), you can quickly locate whether the MTA is stuck or the MDA has not delivered.


The English abbreviations in the picture above are basic vocabulary for email development and must be remembered.

1. MUA (Mail User Agent, Mail User Agent)

The client you deal with directly is responsible for writing, reading, displaying emails, and transferring your operations (send/receive) to the MTA or MDA.

  • Common tools: Outlook, Thunderbird, Foxmail, and web and mobile apps such as Gmail/Outlook/QQ
  • Programmed MUA: email alert module and crawler exception notification script written in Python

2. MTA (Mail Transfer Agent, Mail Transfer Agent)

The "Express Company + Transshipment Center" in the mail industry, its only responsibility is to relay forward the mail, from the sender's MTA all the way to the recipient's MDA.

  • Traditional service providers: Gmail, Outlook.com, NetEase/QQ’s own sending server
  • Modern cloud alternatives: AWS SES, SendGrid, Alibaba Cloud email push, etc., specially designed for business emails, supporting high concurrency, bounce management, and anti-spam optimization

3. MDA (Mail Delivery Agent, mail delivery agent)

Equivalent to your personal mailbox/company mailroom, it is the place where emails are ultimately stored. The recipient's MUA will pick up the letter from here.

  • Modern trend: It is no longer a single server, but a distributed high-availability storage system relying on various service providers (such as GFS used by Gmail and its subsequent evolution)

3. Two protocols for sending and receiving emails

There needs to be a "unified language" between components, that is, a protocol.

🔒 Sending only: SMTP protocol

(Simple Mail Transfer Protocol, Simple Mail Transfer Protocol)

  • Port changes:
    • 25: The traditional clear text port is now blocked by almost all operators to prevent spam abuse.
    • 587: Modern encrypted submission port, preferred
    • 465: SMTPS encrypted port, some old services are still in use
  • Security requirements: STARTTLS or SSL/TLS encryption must be enabled; SPF/DKIM/DMARC anti-forgery must be configured; mainstream service providers have abandoned PLAIN/LOGIN and used OAuth2 instead

📥 Special for receiving: POP3 vs IMAP4

ProtocolEncrypted portCore featuresApplicable scenarios
POP3995 (POP3S)Download emails to local, default Delete from server (can be set to retain)Single device with small storage space
IMAP4993 (IMAPS)Two-way synchronization of server and local status (read/unread/tab/mobile)Multi-device (mobile phone + computer + tablet) office
  • Modern plus points for IMAP4: supports IDLE push (no manual refresh required, instant reminder of new emails), server-side search and tags

4. Three-piece security set that you must know for modern email development

In the early years, you could send emails with just an email account and password, but that’s no longer possible – spam is rampant and all major service providers are very strict. For business emails, these three security measures must be fully configured:

  1. SPF(Sender Policy Framework)
    Declare in DNS which IPs or MTAs are authorized to send emails on your behalf so that recipients can verify the source.
  2. DKIM(DomainKeys Identified Mail)
    By adding a digital signature to the email content, the recipient can verify whether the email has been tampered with during transmission.
  3. DMARC(Domain-based Message Authentication)
    Tell the recipient what to do with the message (reject/trash/deliver normally) if SPF or DKIM verification fails.

5. Three steps of preparation before development (super important!)

If the preparation work is not in place, the code will definitely not work. Please complete it one by one.

1. Prepare test account

Prepare at least two mailboxes from different service providers (to avoid cross-domain problems being invisible to the same user). Recommended combinations:

  • International: Gmail + Outlook
  • Domestic: 163 + QQ email

2. Remember the configuration information of commonly used service providers

Save the following configuration and copy it directly when writing code:

Service ProviderSMTP ServerIMAP ServerEncrypted SMTP PortEncrypted IMAP Port
Gmailsmtp.gmail.comimap.gmail.com587 / 465993
Outlooksmtp.office365.comoutlook.office365.com587993
163smtp.163.comimap.163.com465993
QQsmtp.qq.comimap.qq.com465993

3. Start the service and obtain the authorization code

⚠️ **Highlights! ** Almost all major mailboxes have disabled common password login to SMTP/IMAP. You must:

  1. Manually enable the "SMTP / POP3 / IMAP" function in the email settings
  2. After verifying the mobile phone number, obtain the application-specific password (163 is called "authorization code", QQ is called "IMAP/SMTP service password")

6. Practical practice of quickly sending and receiving emails in Python

Python built-insmtplibimaplibemailThe library can handle basic sending and receiving without installing third-party dependencies, which is especially suitable for novices to get started.

Example 1: Send "dual format email" using SMTP + SSL

Dual format = plain text + HTML to avoid being intercepted or displaying garbled characters by clients that do not support HTML.

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

# ------------------- 配置区(替换为你自己的信息) -------------------
SMTP_SERVER = "smtp.163.com"
SMTP_PORT = 465
SENDER_EMAIL = "你的163邮箱@163.com"
SENDER_PASSWORD = "你的163授权码"      # 不是邮箱登录密码!
RECEIVER_EMAIL = "收件人邮箱@qq.com"
SUBJECT = "Python测试双格式邮件"
# -------------------------------------------------------------

def send_modern_email():
    # 1. 创建多部分邮件容器(用于承载纯文本 + HTML)
    msg = MIMEMultipart("alternative")
    msg["From"] = formataddr(("发件人昵称", SENDER_EMAIL))
    msg["To"] = formataddr(("收件人昵称", RECEIVER_EMAIL))
    msg["Subject"] = SUBJECT

    # 2. 准备纯文本与 HTML 内容
    plain_text = "这是Python测试的纯文本内容,如果客户端不支持HTML会显示这个。"
    html_content = """
    <html>
        <body>
            <h2>Python测试成功🎉</h2>
            <p>这是一封带HTML格式的邮件,支持图片、链接、样式~</p>
            <a href="https://www.rspress.dev/" target="_blank">点击跳转到Rspress官网</a>
        </body>
    </html>
    """

    # 3. 将内容加入容器(注意顺序:纯文本在前,HTML 在后,客户端会优先选择支持的)
    msg.attach(MIMEText(plain_text, "plain", "utf-8"))
    msg.attach(MIMEText(html_content, "html", "utf-8"))

    # 4. 建立 SSL 加密连接并登录发送
    try:
        with smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) as server:
            server.login(SENDER_EMAIL, SENDER_PASSWORD)
            server.send_message(msg)
        print("✅ 邮件发送成功!")
    except Exception as e:
        print(f"❌ 邮件发送失败:{e}")

if __name__ == "__main__":
    send_modern_email()

Example 2: Read unread emails using IMAP + SSL

The following demonstrates basic reading, and recommended combinations for complex emails (attachments, HTML parsing, etc.)beautifulsoup4andemailused together with the library.

import imaplib
import email
from email.header import decode_header

# ------------------- 配置区(替换为你自己的信息) -------------------
IMAP_SERVER = "imap.qq.com"
IMAP_PORT = 993
EMAIL = "你的QQ邮箱@qq.com"
PASSWORD = "你的QQ授权码"            # 不是邮箱登录密码!
# -------------------------------------------------------------

def fetch_unread_emails():
    # 1. 建立 SSL 加密连接并登录
    try:
        with imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT) as imap:
            imap.login(EMAIL, PASSWORD)
            imap.select("INBOX")  # 选择收件箱(也可以指定其他文件夹)

            # 2. 搜索未读邮件
            status, messages = imap.search(None, "UNSEEN")
            if status != "OK" or not messages[0]:
                print("📭 没有未读邮件~")
                return

            # 3. 遍历未读邮件编号并获取内容
            print(f"📬 找到 {len(messages[0].split())} 封未读邮件:")
            for num in messages[0].split():
                status, data = imap.fetch(num, "(RFC822)")
                if status != "OK":
                    continue

                raw_email = data[0][1]
                msg = email.message_from_bytes(raw_email)

                # 解码主题与发件人
                subject, encoding = decode_header(msg["Subject"])[0]
                if isinstance(subject, bytes):
                    subject = subject.decode(encoding or "utf-8")
                from_addr = decode_header(msg["From"])[0][0]
                if isinstance(from_addr, bytes):
                    from_addr = from_addr.decode(decode_header(msg["From"])[0][1] or "utf-8")

                print(f"\n--- 未读邮件 {num.decode()} ---")
                print(f"📧 发件人:{from_addr}")
                print(f"📝 主题:{subject}")
    except Exception as e:
        print(f"❌ 读取邮件失败:{e}")

if __name__ == "__main__":
    fetch_unread_emails()

7. Four best practices for business email development

If you are doing commercial emails such as user registration verification and order notification, it is recommended to keep the following practices in mind on top of the basic code:

  1. Priority to use the official API of the service provider For example, Gmail API, Alibaba Cloud Email Push API. Compared with traditional SMTP/IMAP, they are more stable and have more complete functions (with built-in bounce analysis, open rate statistics, batch sending, etc.).
  2. Strictly control the sending rate All mainstream service providers have day/hour/minute level limits. If the limit is exceeded, the IP or account will be blocked. Be sure to implement exponential backoff retry logic.
  3. Optimize email content to prevent accidental entry into the trash
  • Avoid sensitive words such as "free, winning, click to claim"
  • Ensure correct MIME structure
  • Legal requirement: Must include a "one-click unsubscribe" button
  1. Establish a closed loop of monitoring and feedback
  • Processing bounces: Hard bounces (address does not exist) are removed directly, soft bounces (temporarily unreachable) are delayed and retried.
  • With user permission, you can track open rates, link click rates, and perform A/B test optimization

Summarize

Although modern email systems continue to use the protocol framework more than thirty years ago, they have evolved into complex services with high security, high availability, and high concurrency. As a developer, you will have a solid foundation for email development by mastering the following three points:

  • Keep in mind the three core components of MUA, MTA, and MDA and the basic principles of the two protocols SMTP / IMAP
  • Complete the email configuration before starting (turn on the service, obtain the authorization code)
  • Business-grade emails give priority to official APIs, and follow best practices such as sending rate, content optimization, and monitoring bounces.

I hope this article can help you get started with email development quickly. If you encounter any questions during practice, please feel free to communicate in the comment area!