使用 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 电子邮件,但除非您的布局简单,否则这会很困难、令人沮丧且容易出错。以下部分建议使用一些工具和资源,让您的生活更轻松。

相关推荐
sunshine64113 分钟前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻37 分钟前
Vue(四)
前端·javascript·vue.js
蜜獾云39 分钟前
npm淘宝镜像
前端·npm·node.js
dz88i839 分钟前
修改npm镜像源
前端·npm·node.js
Jiaberrr43 分钟前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook
程序员_三木1 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
顾平安2 小时前
Promise/A+ 规范 - 中文版本
前端
聚名网2 小时前
域名和服务器是什么?域名和服务器是什么关系?
服务器·前端
桃园码工2 小时前
4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]
前端·html·gin·模板渲染
不是鱼2 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js