接收电子邮件

发送到应用的电子邮件是作为包含 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 SDK 定义了 InboundMailHandler,这是一个用于处理传入电子邮件的网页应用类。InboundMailHandler 位于 google.appengine.ext.webapp.mail_handlers 包中。

使用 InboundMailHandler

  1. InboundMailHandler 创建一个子类并替换 receive() 方法。
  2. 使用 Python SDK 所定义 InboundEmailMessage 类的参数调用 receive() 方法。

例如,您可以创建一个 InboundEmailMessage 实例,如下所示:

import logging

from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
import webapp2


class LogSenderHandler(InboundMailHandler):
    def receive(self, mail_message):
        logging.info("Received a message from: " + mail_message.sender)

InboundMailHandler 包含一个 mapping() 辅助类方法,该方法向邮件处理程序返回匹配所有传入电子邮件地址的一个地址对,当然,您可以对所编码的 InboundMailHandler 任何子类调用此方法:

app = webapp2.WSGIApplication([LogSenderHandler.mapping()], debug=True)

InboundEmailMessage 对象(在本例中为 mail_message)包含电子邮件。其 bodies() 方法返回邮件中的正文。如果在不使用任何参数的情况下调用 bodies(),该方法将返回一个依次生成 HTML 正文和纯文本正文的迭代器。如果只需要 HTML 或纯文本,可以将参数传递给 bodies()

plaintext_bodies = mail_message.bodies('text/plain')
html_bodies = mail_message.bodies('text/html')

for content_type, body in html_bodies:
    decoded_html = body.decode()
    # ...

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)。

    如需了解详情(包括如何运行开发服务器),请参阅 Python 开发服务器