使用 Node.js 发送电子邮件

前言:大多数 Web 应用程序都需要发送电子邮件。它可能用于注册、密码重置、状态报告,甚至是完整的营销活动(例如新闻通讯和促销)。本教程介绍如何在 Node.js 中发送电子邮件,但这些概念和挑战适用于您使用的任何系统。

为了演示,我使用免费的 WPOven Test SMTP Server

废话不多说,直接开始操作

创建一个新项目文件夹:

javascript 复制代码
mkdir emailtest
cd emailtest

然后创建一个新的 package.json 文件,其 JSON 内容如下:

javascript 复制代码
{
  "name": "emailtest",
  "type": "module",
  "main": "index.js",
  "dependencies": {
    "nodemailer": "^6.0.0"
  }
}

安装模块(NodeMailer):

javascript 复制代码
npm install

创建以下index.js代码:

javascript 复制代码
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.freesmtpservers.com',
  port: 25
});

try {

  const send = await transporter.sendMail({
    from: '"Test Email" <test@email.com>',  // 发件人地址
    to: 'someone@example.com',              // 接收者名单
    subject: 'Hello!',                      // 主题行
    text: 'Hello world!',                   // 纯文本正文
    html: '<p>Hello world!</p>',            // HTML 主体
  });

  console.dir(send, { depth: null, color: true });

}
catch(e) {

  console.dir(e, { depth: null, color: true });

}

(考虑将收件人:地址更改为唯一地址,以便您可以检查自己的测试电子邮件!)

运行代码。您应该看到一个带有 250 OK 响应和 messageId 的结果:

javascript 复制代码
$ node index.js
{
  accepted: [ 'someone@example.com' ],
  rejected: [],
  ehlo: [ 'SIZE 33554432', '8BITMIME', 'SMTPUTF8', 'HELP' ],
  envelopeTime: 486,
  messageTime: 289,
  messageSize: 595,
  response: '250 OK',
  envelope: {
    from: 'test@email.com',
    to: [ 'someone@example.com' ]
  },
  messageId: '<4673597e-a9e4-e422-85f7-4422edf31774@email.com>'
}

在 to: 的邮箱里面,单击"Hello!"消息来检查内容。

NodeMailer 基础

要发送电子邮件,您必须创建一个 NodeMailer 传输器对象来定义服务类型。SMTP 是最常见的,但其他服务也可用于替代服务。通常需要身份验证用户 ID 和密码:

javascript 复制代码
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.yourserver.com',
  port: 587,
  auth: {
    user: 'myid@yourserver.com',
    pass: 'my-password'
  },
});

您可以使用传输器的 sendMail() 方法向一个或多个收件人发送电子邮件:

javascript 复制代码
const send = await transporter.sendMail({
  from: '"Test Email" <test@email.com>',          // 发件人地址
  to: 'someone@example.com, sometwo@example.com', // 接收者名单
  cc: 'somethree@example.com',
  bcc: 'somefour@example.com',
  subject: 'Hello!',                              // 主题行
  text: 'Plain text version of the message',      // 纯文本正文
  html: '<p>HTML version of the message</p>',     // HTML 主体
});

 

所有电子邮件客户端都支持纯文本消息。当电子邮件客户端支持 HTML 时,您还可以发送相同消息的富格式版本(有关详细信息,请参见下文)。

NodeMailer 提供了许多其他消息选项,但最常见的是附件。对象数组定义文件名和内容。例如:

javascript 复制代码
const send = await transporter.sendMail({
  // ...
  attachments: [
    { // 从磁盘获取文件内容
      filename: 'text1.txt',
      path: '/path/to/file1.txt'
    },
    {  // 从 URL 获取文件内容
      filename: 'text2.txt',
      path: 'https://myserver.com/text2.txt'
    },
    { // 从 UTF-8 字符串创建文件
      filename: 'text3.txt',
      content: 'This is the file content!'
    },
    { //根据数据 URI 创建文件
      filename: 'text4.txt',
      path: 'data:text/plain;base64,SGVsbG8gd29ybGQh'
    }
  ]
});

发送服务

简单的发送已经完成,但是还有可能会遇到一些问题,下面列出你可能遇到的情况

1、您可能没有 SMTP 服务器。并非所有电子邮件服务都提供 SMTP(Google 正在撤销 Gmail 中的基本 SMTP 支持)。

2、大多数服务都会限制外发电子邮件。如果您发送大量电子邮件,可能会达到提供商的限制。届时,通过同一服务发送的所有电子邮件都将失败:您的时事通讯以及个人和商业消息。

3、您可能会成为垃圾邮件发送者。收件人很容易将您的电子邮件标记为"垃圾邮件"------即使它不是。当有足够多的人这样做时,您可能会发现来自您域的所有电子邮件都会在互联网上被阻止。

异步应用程序架构

发送一封电子邮件通常很快,但是:

SMTP 服务器可能已关闭,因此需要重试,或者

该消息可能被卡在批量新闻通讯发布中

通常,最好将数据发送到任务队列,而不是直接在 Node.js 应用程序中发送电子邮件。最终用户无需等待响应,可以继续使用该应用程序。

另一个进程可以监视电子邮件队列,发送下一条消息,并在发生故障时重新排队项目。

编写 HTML 电子邮件

HTML5 和 CSS3 在现代浏览器中始终运行良好。电子邮件客户端则是另一回事,这让我们回想起 20 世纪 90 年代末令人沮丧的表格和内联样式时代。

以下是您将面临的一些问题:

有数十种原生和基于 Web 的电子邮件客户端,包括 Gmail、Yahoo Mail、Apple Mail、iOS Mail、Android Mail、Windows Mail、Outlook、Outlook.com、(新)Outlook、Thunderbird、AOL、Claws、RoundCube 等。

所有客户端都使用自己奇怪而又奇妙的渲染引擎,但存在独特的问题和错误。有点奇怪的是,Outlook 自 2007 年以来一直使用 Microsoft Word 来渲染 HTML(尽管新的预览版是基于浏览器的)。

大多数客户端会阻止或限制字体、图像、跟踪器、媒体查询、iframe、视频、音频、表单和脚本。

即使是在浏览器中运行的基于 Web 的电子邮件客户端也必须删除危险或可能影响 UI 布局的 HTML、CSS 和 JavaScript。例如,电子邮件不应该自动点击自己的链接或将元素绝对定位在删除按钮上方。

电子邮件客户端可以重新格式化您的 HTML,以确保它是单列或符合用户的亮/暗模式偏好。

可以手动编写 HTML 电子邮件,但除非您的布局简单,否则这会很困难、令人沮丧且容易出错。以下部分建议使用一些工具和资源,让您的生活更轻松。

相关推荐
Myli_ing41 分钟前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
dr李四维1 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
I_Am_Me_1 小时前
【JavaEE进阶】 JavaScript
开发语言·javascript·ecmascript
雯0609~1 小时前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ1 小时前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z1 小时前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
前端百草阁2 小时前
【TS简单上手,快速入门教程】————适合零基础
javascript·typescript
彭世瑜2 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4042 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish2 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue