使用 Node.js 发送电子邮件

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

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

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

创建一个新项目文件夹:

mkdir emailtest
cd emailtest

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

{"name": "emailtest","type": "module","main": "index.js","dependencies": {"nodemailer": "^6.0.0"}
}

安装模块(NodeMailer):

npm install

创建以下index.js代码:

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 的结果:

$ 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 和密码:

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

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

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 提供了许多其他消息选项,但最常见的是附件。对象数组定义文件名和内容。例如:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/861644.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot与JMS消息中间件的集成

Spring Boot与JMS消息中间件的集成 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨一下如何在Spring Boot中集成JMS&#xff08;Java Message Se…

jieba--《红楼梦》章节分卷并计算TF-IDF值(超详细)

目录 大致步骤&#xff1a; 任务1&#xff1a; 将红楼梦 根据卷名 分隔成 卷文件 红楼梦txt&#xff1a; 红楼梦卷头&#xff1a; 红楼梦章节分卷&#xff1a; 任务2&#xff1a;对每个卷进行分词&#xff0c;并删除包含停用词的内容 1.遍历所有卷的内容&#xff0c;并添…

Python26 Lambda表达式

1.什么是lambda表达式 lambda 是 Python 中的一个关键字&#xff0c;用于定义简单的匿名函数。与 def 关键字定义的标准函数不同&#xff0c;lambda 函数主要用于需要一个函数对象作为参数的简短操作。lambda 函数的设计哲学是简洁&#xff0c;因此它只能包含一条表达式&#…

7km远距离WiFi实时图传模块,无人机海上无线传输方案,飞睿智能WiFi MESH自组网技术

在浩瀚无垠的海洋上&#xff0c;无人机正在开启一场前所未有的技术创新。它们不再只是天空的舞者&#xff0c;更是海洋的守望者&#xff0c;为我们带来前所未有的视野和数据。而这一切的背后&#xff0c;都离不开一项创新性的技术——飞睿智能远距离WiFi实时图传模块与无线Mesh…

使用Spring Boot和WebSocket实现实时通信

使用Spring Boot和WebSocket实现实时通信 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Spring Boot应用中使用WebSocket实现实时通信&am…

【杂记-浅谈CHAP认证(质询握手身份验证协议)】

CHAP认证&#xff08;质询握手身份验证协议&#xff09; 一、CHAP认证概述二、CHAP认证流程三、CHAP认证优势 一、CHAP认证概述 1、CHAP&#xff0c;Challenge Handshake Authentication Protocol&#xff0c;即质询握手身份验证协议&#xff0c;是一种用于网络连接的验证协议…

JavaScript数组forEach方法退出循环

常规for循环退出循环方法 在for循环中退出循环有3种方式&#xff1a;return&#xff08;终止&#xff09;、break&#xff08;退出整个循环&#xff09;、continue&#xff08;退出当次循环&#xff09;。 let arr [0,1,2,3,4,5,6] for(let i0;i<array.length;i){if(array[…

并发业务使用redis分布式锁

伴随着业务体量的上升&#xff0c;我们的qps与并发问题越来越明显&#xff0c;这时候就需要用到让代码一定情况下进行串行执行的工具&#xff1a;锁 1.业务场景代码 OverrideTransactional(rollbackFor Exception.class)public Object testBatch(User user) {LambdaQueryWrapp…

java必知必会-java IO

系列文章目录 java必知必会-java环境搭建 java必知必会-java开发工具安装与使用 java必知必会-java关键字、变量和常量 java必知必会-java数据类型和变量定义 java必知必会-java类和对象 java必知必会-java面向对象的三大特性 java必知必会-java继承与重写、重载 java必知必会…

昇思25天学习打卡营第1天|快速入门-Mnist手写数字识别

学习目标&#xff1a;熟练掌握MindSpore使用方法 学习心得体会&#xff0c;记录时间 了解MindSpore总体架构 学会使用MindSpore 简单应用时间-手写数字识别 一、MindSpore总体架构 华为MindSpore为全场景深度学习框架&#xff0c;开发高效&#xff0c;全场景统一部署特点。 …

Verilog进行结构描述(三):Verilog模块实例化

目录 1.模块实例化(module instantiation)2.实例数组(Array of Instances) 微信公众号获取更多FPGA相关源码&#xff1a; 1.模块实例化(module instantiation) 模块实例化时实例必须有一个名字。使用位置映射时&#xff0c;端口次序与模块的说明相同。使用名称映射时&#x…

搭建大型分布式服务(四十)SpringBoot 整合多个kafka数据源-支持生产者

系列文章目录 文章目录 系列文章目录前言一、本文要点二、开发环境三、原项目四、修改项目五、测试一下五、小结 前言 本插件稳定运行上百个kafka项目&#xff0c;每天处理上亿级的数据的精简小插件&#xff0c;快速上手。 <dependency><groupId>io.github.vipjo…

【LeetCode】每日一题:无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串的长度。 解题思路 滑动窗口&#xff0c;水题&#xff0c;但是学到了python的内置函数find&#xff0c;可以查找字符串中字符出现的位置&#xff0c;没有的话返回-1&#xff0c;数组中可以使用index&…

ZYNQ学习教程?ZYNQ-FPGA实战教程!

学习 ZYNQ 比FPGA、MCU、ARM 等传统工具开发要求更高&#xff0c;想学好 ZYNQ 也不是一蹴而就的事情。 学习 ZYNQ 要具备的技能&#xff1a; 1、 软件开发人员  计算机组成原理、 C、C语言、 计算机操作系统、tcl 脚本、良好的英语基础 2、 逻辑开发人员 计算机组成原理…

实际开发中Java线程池怎么配

前言 在实际开发中&#xff0c;业务场景是多种多样的&#xff0c;分为IO密集型与CPU密集型俩种。针对不同的场景。如何配置一个合理的线程池是十分重要的&#xff5e;。 接下来我从Java线程池的生命周期以及实际开发场景讲解如何配置Java线程池 Java线程池 线程池七大参数 核…

关于服务器的一些知识

1. 云服务器 和 轻量应用服务器 腾讯云中的"云服务器"&#xff08;Cloud Virtual Machine, CVM&#xff09;和"轻量应用服务器"&#xff08;Lite Cloud Server&#xff09;都是提供云端计算资源的服务&#xff0c;但它们在定位、特性和使用场景上存在一些差…

【昇思大模型平台体验篇】day1快速入门

早闻毕晟、昇思等平台&#xff0c;今日有机会能参加入门课程&#xff0c;非视频课程算是我第一次看&#xff0c;也算是对我自己的一个锻炼&#xff0c;之前也没有系统学习模型之类&#xff0c;每天抽出一点点时间来学习一下也是不错的 MindSpore 看来是和torch类似的结构 处理…

GPT5将引领第四次工业革命:人工智能、物联网、大数据、生物技术、量子计算等的综合体GPT大模型将改变很多现在的工作方式和生活方式,人人必读,人人必用

2024年6月22日&#xff0c;美国达特茅斯工程学院的一场采访引起了全球科技界的广泛关注。OpenAI首席技术官米拉穆拉蒂在采访中确认&#xff0c;备受期待的GPT-5将在一年半后发布。 这一消息不仅激起了科技界的热烈讨论&#xff0c;也让人们对人工智能&#xff08;AI&#xff09…

LongRAG:利用长上下文大语言模型提升检索生成效果

一、前言 前面我们已经介绍了多种检索增强生成 (RAG) 技术&#xff0c;基本上在保证数据质量的前提下&#xff0c;检索增强生成&#xff08;RAG&#xff09;技术能够有效提高检索效率和质量&#xff0c;相对于大模型微调技术&#xff0c;其最大的短板还是在于有限的上下文窗口…

幽默证明题!高考成绩公布后,妈妈连夜写了一封信:孩子,这就是我不让你玩手机的原因——早读(逆天打工人爬取热门微信文章解读)

毛毛雨&#xff0c;五分钟结束&#xff0c;怎么证明今天早上有下雨呢&#xff1f; 引言Python 代码第一篇 洞见 高考成绩公布后&#xff0c;妈妈连夜写了一封信&#xff1a;孩子&#xff0c;这就是我不让你玩手机的原因第二篇 视频新闻结尾 引言 今天睡眠质量不错 发现一个问题…