# 邮件服务
yuanboot Python 提供 SMTP 客户端,支持文本、HTML、附件以及 STARTTLS / SSL。应用需要准备可访问的 SMTP 服务和发送账号。
# 配置 SMTP
在项目 config.yml 中添加:
yuanboot:
email:
host: "${SMTP_HOST}"
port: 587
username: "${SMTP_USERNAME}"
password: "${SMTP_PASSWORD}"
starttls: true
ssl: false
timeout: 10
mail:
sender: "${SMTP_SENDER}"
587 端口通常使用 STARTTLS;465 端口通常配置 ssl: true、starttls: false。两种 TLS 方式不能同时启用,具体以邮件服务商要求为准。
构建宿主时调用 use_components() 会按邮件配置注册 SmtpClient;也可显式调用 use_email():
from yuanboot import ConfigurationBuilder
from yuanboot.web import WebHostBuilder
configuration = ConfigurationBuilder().add_yaml_file().add_environment().build()
builder = WebHostBuilder(configuration).use_email()
# 继续注册 Startup / 业务服务和路由,再调用 builder.build()。
# 注入业务服务
在业务服务中通过构造器注入 SmtpClient 与 Configuration:
from yuanboot import Configuration
from yuanboot.components.email import SmtpClient
class NotificationService:
def __init__(self, smtp: SmtpClient, configuration: Configuration):
self.smtp = smtp
self.sender = configuration.get_string("mail.sender")
def send_order_created(self, recipient: str, order_id: str):
return self.smtp.send(
sender=self.sender,
recipients=[recipient],
subject=f"订单 {order_id} 已创建",
body=f"您的订单 {order_id} 已创建成功。",
)
在 Startup.configure_services 中注册 services.add_scoped(NotificationService),再向控制器注入该服务。
send 为同步调用,适合普通 def 动作或后台工作线程;从异步动作调用时可使用 await asyncio.to_thread(service.send_order_created, recipient, order_id)。
# HTML 与附件
以下代码在已注入 SmtpClient 的业务方法中使用:
self.smtp.send(
sender=self.sender,
recipients=["customer@example.com"],
subject="订单明细",
body="<p>订单已创建,明细请见附件。</p>",
html=True,
attachments={"order.txt": "订单明细".encode("utf-8")},
)
recipients 支持地址列表,也支持分号分隔的字符串;附件为文件名到字节内容的字典。
发送失败会抛出异常,业务应记录失败并根据需要重试。返回值为 SMTP 拒收地址信息,空字典表示 SMTP 服务接受了全部收件人,不代表邮件已送达收件箱。
需要定时发送或把发送从接口响应中移出时,可结合后台服务;需要跨进程可靠投递时,由业务队列或任务表保存待发送消息。