电子邮件(Email)

页面摘要: 邮件功能通过本地 SMTP 或 SendGrid 等外部提供方发送事务性消息。本文档中的设置指南涵盖提供方配置,以及如何通过控制器或钩子扩展发送能力。

邮件(Email)功能使 Strapi 应用程序能够从服务器或外部提供方发送邮件。

  • Plan:免费功能
  • Role & permission:用户通过后端服务器发送邮件需具备 Email > "send" 权限
  • Activation:默认可用
  • Environment:在开发与生产环境中均可用

配置

邮件功能的大部分配置选项通过你的 Strapi 项目代码处理。管理面板提供当前配置的只读视图、连接状态、提供方能力,并允许用户发送测试邮件。

提供方 vs. 主机
  • 邮件提供方指的是 Strapi 调用以发送邮件的包(例如官方提供方如 Sendgrid,或社区包如 @strapi/provider-email-nodemailer)。提供方在 Strapi 调用它们时实现发送邮件的逻辑。
  • 提供方主机(或服务器)指的是提供方暴露的连接细节(例如 SMTP 主机名、端口或 REST API 端点)。某些提供方通过 API 密钥隐藏这些细节,而其他提供方则要求你在配置中提供与主机相关的选项。

邮件功能仅处理出站发送。接收或解析传入消息超出了内置插件的范围,必须通过你的邮件提供方的入站 webhook 或自定义集成来实现。

管理面板设置

配置该功能的路径: Settings > Email feature > Configuration

邮件配置

配置界面对于大多数字段是只读的。它显示当前的提供方配置,并允许用户测试连接。

配置面板中显示以下信息:

  • Default sender email(默认发件人邮箱),以及如果配置的 defaultFrom 地址包含显示名称,则还有 Default sender name(默认发件人名称)。
  • Default response email(默认回复邮箱),以及如果配置的 defaultReplyTo 地址包含显示名称,则还有 Default reply-to name(默认回复名称)。
  • Email provider(邮件提供方):当前使用的提供方。
NOTE

如果当前提供方支持 SMTP 连接验证(例如 Nodemailer 提供方),还会显示一个 Connection status(连接状态) 字段和一个 Test connection(测试连接) 按钮。点击它会在不发送消息的情况下验证 SMTP 连接。根据结果,按钮会显示 Connected(已连接) 或 Error(错误) 标记。

当当前提供方暴露 SMTP 元数据时,主配置下方会出现一张 Provider capabilities(提供方能力) 卡片。它显示 SMTP 服务器地址、加密协议(TLS、STARTTLS 或 None)、身份验证类型和用户、池状态(启用连接池时为 Idle 或 Active),以及已启用功能(如 DKIM、OAuth2、速率限制和连接池)的标记。

此页面上唯一可由用户编辑的字段是 Test email delivery(测试邮件发送) 下的 Recipient email(收件人邮箱) 字段。一个 Send test email(发送测试邮件) 按钮会向该地址发送一封测试消息。

仅当当前角色启用了“Access the Email Settings page(访问邮件设置页面)”权限时,此页面才可见(更多信息请参阅 RBAC 功能 文档):

邮件配置

基于代码的配置

邮件功能需要在 config/plugins.js|ts 文件中配置一个提供方及提供方配置。详细的安装和配置说明请参阅 提供方。

Sendmail 是 Strapi 邮件功能中默认的邮件提供方。它在内部使用 Nodemailer 进行邮件发送。它为本地开发环境提供了功能,但在默认配置下尚未达到生产就绪状态。对于生产阶段的应用程序,你需要进一步配置 Sendmail 或更改提供方。

TIP

对于大多数使用专用 SMTP 中继的生产环境,考虑切换到 @strapi/provider-email-nodemailer(在你的邮件插件配置中将 provider 设为 "nodemailer")。详情请参阅 专门的 Nodemailer 配置文档。

在非生产环境中,当 sendmail 提供方处于活动状态时,Strapi 会记录一次性的警告,建议进行此切换。

邮件配置选项

插件配置在 config/plugins.js 文件或 config/plugins.ts 文件中定义。详细的、特定于提供方的安装和配置说明请参阅 提供方。

选项(Option)类型(Type)说明默认值(Default Value)备注(Notes)
providerstring要使用的邮件提供方。sendmailRequired
providerOptionsobject邮件提供方选项。{}Optional
providerOptions.apiKeystring邮件提供方的 API 密钥。''Optional
settingsobject邮件设置。{}Optional
settings.defaultFromstring用作发件人的默认邮箱地址。''Optional
settings.defaultReplyTostring用作回复地址的默认邮箱地址。''Optional
ratelimitobject邮件速率限制设置。{}Optional
ratelimit.enabledboolean是否启用速率限制。trueOptional
ratelimit.intervalstring速率限制的时间间隔(分钟)。5Optional
ratelimit.maxnumber在间隔内允许的最大请求数。5Optional
ratelimit.delayAfternumber在应用速率限制之前允许的请求数。1Optional
ratelimit.timeWaitnumber响应请求前的等待时间(毫秒)。1Optional
ratelimit.prefixKeystring速率限制键的前缀。${userEmail}Optional
ratelimit.whitelistarray(string)免于速率限制的 IP 地址数组。[]Optional
ratelimit.storeobject速率限制的存储位置,更多信息请参阅 koa2-ratelimit 文档。MemoryStoreOptional

提供方(Providers)

邮件功能可以通过安装和配置额外的提供方来扩展。

提供方向插件的核心能力添加扩展,例如使用 Amazon SES 而非 Sendmail 来发送邮件。

既有由 Strapi 维护的官方提供方——可通过 应用市场 找到——也有许多由社区维护、可通过 npm 获取的提供方。

安装提供方

可以使用 npm 或 yarn 以 @strapi/provider-<plugin>-<provider> --save 格式安装新的提供方。

例如,安装 Sendgrid 提供方:

Yarn

yarn add @strapi/provider-email-sendgrid

NPM

npm install @strapi/provider-email-sendgrid --save
配置提供方

新安装的提供方在 the /config/plugins file 中启用和配置。如果该文件不存在,你必须创建它。

特定邮件提供方配置
  • 每个提供方可用的配置设置各不相同。请查看该提供方在 应用市场 或 npm 上的对应条目以了解更多信息。

  • 对于使用 Nodemailer 提供方的生产场景(OAuth2、连接池、DKIM 签名、速率限制),请参阅 专门文档。

以下是 Sendgrid 提供方的配置示例:

JavaScript

module.exports = ({ env }) => ({
  // ...
  email: {
    config: {
      provider: 'sendgrid', // For community providers pass the full package name (e.g. provider: 'strapi-provider-email-mandrill')
      providerOptions: {
        apiKey: env('SENDGRID_API_KEY'),
        // region: 'eu', // Optional: set to 'eu' for EU data residency (default: 'global')
      },
      settings: {
        defaultFrom: 'juliasedefdjian@strapi.io',
        defaultReplyTo: 'juliasedefdjian@strapi.io',
        testAddress: 'juliasedefdjian@strapi.io',
      },
    },
  },
  // ...
});

TypeScript

export default ({ env }) => ({
  // ...
  email: {
    config: {
      provider: 'sendgrid', // For community providers pass the full package name (e.g. provider: 'strapi-provider-email-mandrill')
      providerOptions: {
        apiKey: env('SENDGRID_API_KEY'),
        // region: 'eu', // Optional: set to 'eu' for EU data residency (default: 'global')
      },
      settings: {
        defaultFrom: 'juliasedefdjian@strapi.io',
        defaultReplyTo: 'juliasedefdjian@strapi.io',
        testAddress: 'juliasedefdjian@strapi.io',
      },
    },
  },
  // ...
});
EU 数据驻留

如果你使用的 SendGrid API 密钥是在 EU 门户 (app.eu.sendgrid.com) 上创建的,请在 providerOptions 中设置 region: 'eu'。EU API 密钥仅对 EU 端点(https://api.eu.sendgrid.com)有效;如果没有此选项,邮件发送将以 Unauthorized 错误失败。

注意事项
  • 当每个环境使用不同的提供方时,请在 /config/env/${yourEnvironment}/plugins.js|ts 中指定正确的配置(请参阅 环境)。
  • 一次只能有一个邮件提供方处于活动状态。如果 Strapi 没有获取到邮件提供方设置,请验证 plugins.js|ts 文件是否位于正确的文件夹中。
  • 当使用 strapi 安装期间创建的那两个邮件模板测试新的邮件提供方时,模板上的 shipper email(发件人邮箱) 默认为 no-reply@strapi.io,需要根据你的邮件提供方进行更新,否则测试将失败(请参阅 本地配置模板)。
  • 为了最佳的送达率,请与你的邮件提供方配置 SPF/DKIM,并确保 defaultFrom 域名与你在提供方处验证过的域名一致。
按环境配置

在配置你的提供方时,你可能希望根据 NODE_ENV 环境变量更改配置,或使用特定于环境的凭据。

你可以在 /config/env/{env}/plugins.js|ts 配置文件中设置特定的配置,它将用于覆盖默认配置。

某些提供方暴露类似于 SMTP 的连接细节,而不是(或除了)API 密钥。将这些值添加到 providerOptions 中,以便 Strapi 能够访问提供方主机。例如,社区 Nodemailer 提供方期望 host、port 和身份验证凭据:

JavaScript

module.exports = ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: env.int('SMTP_PORT', 587),
        secure: false, // Use `true` for port 465
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'no-reply@example.com',
        defaultReplyTo: 'support@example.com',
      },
    },
  },
});

TypeScript

export default ({ env }) => ({
  email: {
    config: {
      provider: 'nodemailer',
      providerOptions: {
        host: env('SMTP_HOST'),
        port: 587,
        secure: false, // Use `true` for port 465
        auth: {
          user: env('SMTP_USERNAME'),
          pass: env('SMTP_PASSWORD'),
        },
      },
      settings: {
        defaultFrom: 'no-reply@example.com',
        defaultReplyTo: 'support@example.com',
      },
    },
  },
});

如果你的提供方给你的是一个单独的 URL 而不是 host 和 port 值,请使用该包期望的键,在 providerOptions 中传入该 URL(例如 https://api.eu.mailgun.net)。

构建自定义提供方

要构建你自己的提供方、将其发布到 npm,或在你的项目中本地使用,请参阅专门文档:

使用

邮件功能使用 Strapi 全局 API,这意味着它可以从 Strapi 应用程序内部的任何位置调用,既可以通过 控制器或服务 从后端服务器本身调用,也可以从管理面板调用,例如在响应事件时(使用 生命周期钩子)。

使用控制器或服务发送邮件 {#controller-service}

邮件功能有一个 email 服务,其中包含 2 个用于发送邮件的函数:

  • send() 直接包含邮件内容,
  • sendTemplatedEmail() 使用来自内容管理器的数据填充邮件,简化程序化邮件的发送。

使用 send() 函数

要响应用户操作触发邮件,请将 send() 函数添加到 控制器 或 服务 中。send 函数具有以下属性:

属性(Property)类型(Type)说明
fromstring (email address)发件人地址。如果未指定,使用 plugins.js 中的 defaultFrom。
tostring (email address)收件人地址。必填。
ccstring (email address)抄送收件人。可选。
bccstring (email address)密送收件人。可选。
replyTostring (email address)回复地址。如果未指定,使用 plugins.js 中的 defaultReplyTo。
subjectstring邮件主题。必填。
textstring纯文本正文。需要 text 或 html 之一。
htmlstringHTML 正文。需要 text 或 html 之一。
attachmentsobject[]附件对象数组。
headersobject自定义 SMTP 头,例如 { 'X-Custom-Header': 'value' }。
priority'high' \| 'normal' \| 'low'邮件优先级标志。
inReplyTostring所回复邮件的 Message-ID。用于会话线程。
referencesstring \| string[]此邮件引用的 Message-ID 列表。用于会话线程。
envelopeobject带有 from 和 to 字段的自定义 SMTP 信封。用于退信处理。
listobjectRFC 2369 List-* 头。在 Gmail 和 Outlook 中为新闻邮件启用一键退订。
icalEventobjectiCalendar 格式的日历事件邀请。使用 { method, content } 附加。
dsnobject投递状态通知设置。请求退信或投递确认报告。
使用 Nodemailer 提供方时

Nodemailer 提供方对所有 send() 字段使用显式允许列表。未知属性会被静默丢弃。有关受支持字段的完整列表——包括 dkim、amp、raw、每消息 OAuth2 的 auth 等——请参阅 npm 上的提供方 README。

以下代码示例可用于控制器或服务中:

await strapi.plugins['email'].services.email.send({
  to: 'valid email address',
  from: 'your verified email address', //e.g. single sender verification in SendGrid
  cc: 'valid email address',
  bcc: 'valid email address',
  replyTo: 'valid email address',
  subject: 'The Strapi Email feature worked successfully',
  text: 'Hello world!',
  html: 'Hello world!',
}),

使用 sendTemplatedEmail() 函数

sendTemplatedEmail() 函数用于从模板组合邮件。该函数从可用的属性编译邮件,然后发送邮件。

要使用 sendTemplatedEmail() 函数,请定义 emailTemplate 对象并将该函数添加到控制器或服务中。该函数调用 emailTemplate 对象,并可以可选调用 emailOptions 和 data 对象:

参数(Parameter)说明类型(Type)默认值(Default)
emailOptions
Optional包含邮件寻址属性:to、from、replyTo、cc 和 bccobject{ }
emailTemplate包含邮件内容属性:subject、text 和 html,使用 Lodash string templatesobject{ }
data
Optional包含用于编译模板的数据object{ }

以下代码示例可用于控制器或服务中:

const emailTemplate = {
  subject: 'Welcome <%= user.firstname %>',
  text: `Welcome to mywebsite.fr!
    Your account is now linked with: <%= user.email %>.`,
  html: `<h1>Welcome to mywebsite.fr!</h1>
    <p>Your account is now linked with: <%= user.email %>.<p>`,
};

await strapi.plugins['email'].services.email.sendTemplatedEmail(
  {
    to: user.email,
    // from: is not specified, the defaultFrom is used.
  },
    emailTemplate,
  {
    user: _.pick(user, ['username', 'email', 'firstname', 'lastname']),
  }
);

从生命周期钩子发送邮件 {#lifecycle-hook}

要基于管理面板中的管理员操作触发邮件,请使用 生命周期钩子 和 send() 函数。

以下示例说明了如何在内容管理器中每次新增内容条目时,使用 afterCreate 生命周期钩子发送一封邮件:

JavaScript


module.exports = {
    async afterCreate(event) {    // Connected to "Save" button in admin panel
        const { result } = event;

        try{
            await strapi.plugin('email').service('email').send({ // you could also do: await strapi.service('plugin:email.email').send({
              to: 'valid email address',
              from: 'your verified email address', // e.g. single sender verification in SendGrid
              cc: 'valid email address',
              bcc: 'valid email address',
              replyTo: 'valid email address',
              subject: 'The Strapi Email feature worked successfully',
              text: '${fieldName}', // Replace with a valid field ID
              html: 'Hello world!', 
                
            })
        } catch(err) {
            console.log(err);
        }
    }
}

TypeScript


export default {
  async afterCreate(event) {    // Connected to "Save" button in admin panel
    const { result } = event;

    try{
      await strapi.plugins['email'].services.email.send({
        to: 'valid email address',
        from: 'your verified email address', // e.g. single sender verification in SendGrid
        cc: 'valid email address',
        bcc: 'valid email address',
        replyTo: 'valid email address',
        subject: 'The Strapi Email feature worked successfully',
        text: '${fieldName}', // Replace with a valid field ID
        html: 'Hello world!', 
      })
    } catch(err) {
      console.log(err);
    }
  }
}