使用 Mail API 接收邮件

本指南介绍如何使用 Mail API 接收邮件。

发送到应用的电子邮件是作为包含 MIME 数据的 HTTP 请求实现的。要处理传入电子邮件,需将电子邮件地址与应用配置中的脚本处理程序关联起来,然后将处理程序添加到应用的代码中。

传入电子邮件会生成 HTTP 请求,这些请求将传递至相应的脚本。处理传入电子邮件的脚本必须位于默认服务中。

如需详细了解邮件服务,请参阅 Mail API 概览

准备工作

您必须将您的发件人电子邮件注册为已获授权的发件人。如需了解详情,请参阅谁可以发送电子邮件

配置应用以接收电子邮件

在您创建新应用时,系统会默认停用传入电子邮件。要启用传入电子邮件服务,您必须在默认服务中修改 app.yaml 文件。

  1. 添加 inbound_services 部分,用于启用传入电子邮件服务。 例如:

    inbound_services:
    - mail

    如果您未通过在配置文件中添加此部分来启用传入电子邮件服务,则系统会停用传入电子邮件服务,并忽略发送到应用的电子邮件。

  2. 添加映射,使通过网址映射的电子邮件地址与脚本处理程序关联起来。

    对于默认服务,接收电子邮件的电子邮件地址采用以下格式:

    [STRING]@[Google Cloud project ID].appspotmail.com
    

    对于非默认服务,电子邮件地址采用以下格式:

    [STRING]@[servicename]-dot-[Google Cloud project ID].appspotmail.com
    

    电子邮件将通过以下网址,以 HTTP POST 请求形式发送到应用,其中 [ADDRESS] 是完整电子邮件地址(包含域名):

    /_ah/mail/[ADDRESS]
    

    要处理应用中的传入电子邮件,请将电子邮件网址映射到 app.yaml 文件中的处理程序:

    - url: /_ah/mail/.+
      script: handle_incoming_email.app
      login: admin

    在上述示例中,/_ah/mail/.+ 匹配的是发送到应用的所有电子邮件。如果您愿意,可以对不同电子邮件地址设置多个处理程序,如以下示例所示:

    - url: /_ah/mail/owner@.*your_app_id\.appspotmail\.com
      script: handle_owner.app
      login: admin
    - url: /_ah/mail/support@.*your_app_id\.appspotmail\.com
      script: handle_support.app
      login: admin
    - url: /_ah/mail/.+
      script: handle_catchall.app
      login: admin

    系统会按此列表中从第一项到最后一项的顺序匹配传入电子邮件的网址。因此,如果电子邮件网址与多个模式匹配,则系统将执行第一个匹配处理程序。这样,您便能够将“catchall”处理程序作为最后一个映射包含在内。处理程序在默认模块(或应用版本)中运行。

处理传入电子邮件

使用 Python 网络框架时,InboundEmailMessage 构造函数会接收 HTTP 请求正文的字节。您可以使用多种方法在 Python 中创建 InboundEmailMessage 对象。在 Flask 中,request.get_data() 提供请求字节数。 InboundEmailMessage 对象包含电子邮件。其 bodies() 方法返回邮件中的正文。如果在不使用任何参数的情况下调用 bodies(),该方法将返回一个依次生成 HTML 正文和纯文本正文的迭代器。如果只需要 HTML 或纯文本,可以将参数传递给 bodies()

@app.route("/_ah/mail/<path>", methods=["POST"])
def receive_mail(path):
    message = mail.InboundEmailMessage(request.get_data())

    # Do something with the message
    print(
        f"Received greeting for {escape(message.to)} at {escape(message.date)} from {escape(message.sender)}"
    )
    for content_type, payload in message.bodies("text/plain"):
        print(f"Text/plain body: {payload.decode()}")
        break

    return "OK", 200

InboundEmailMessage 对象包含用于访问其他邮件字段的属性:

  • subject 包含邮件主题。
  • sender 是发件人的地址,例如 "Nobody <nobody@example.com>"
  • to 是以英文逗号分隔的邮件主要收件人列表,例如 "Joe <joe@example.com>, Bill <bill@example.com>"
  • cc 包含以英文逗号分隔的抄送收件人列表,例如 "Joe <joe@example.com>, Bill <bill@example.com>"
  • date 将返回邮件日期。
  • attachments 是一系列 Attachment 对象(可能为空)。
  • original 是完整邮件,包括其他字段(如电子邮件标头)未公开的数据,如 Python email.message.Message

使用本地开发服务器模拟传入邮件

将您的应用设置为处理传入电子邮件后,您可以使用开发服务器控制台模拟传入电子邮件:

  1. 以管理员身份访问开发服务器,方法是转到 http://localhost:8080/console,然后选择以管理员身份登录 (Sign in as administrator)。
  2. 在开发服务器中,点击导航栏中的入站邮件 (Inbound Mail)。
  3. 填写显示的表单,然后点击发送电子邮件 (Send Email)。

    如需运行开发服务器,请参阅本地开发服务器

请参阅邮件处理程序指南,详细了解 Mail API 的迁移注意事项。