- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章node.js 基于 STMP 协议和 EWS 协议发送邮件由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文主要介绍 node.js 发送基于 STMP 协议和 MS Exchange Web Service(EWS) 协议的邮件的方法。文中所有参考代码均以 TypeScript 编码示例.
提到使用 node.js 发送邮件,基本都会提到大名鼎鼎的 Nodemailer 模块,它是当前使用 STMP 方式发送邮件的首选。 基于 NodeMailer 发送 STMP 协议邮件的文章网上已非常多,官方文档介绍也比较详细,在此仅列举示例代码以供对比参考: 封装一个 sendMail 邮件发送方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
/**
* 使用 Nodemailer 发送 STMP 邮件
* @param {Object} opts 邮件发送配置
* @param {Object} smtpCfg smtp 服务器配置
*/
async
function
sendMail(opts, smtpCfg) {
const resultInfo = { code: 0, msg:
''
, result:
null
};
if
(!smtpCfg) {
resultInfo.msg =
'未配置邮件发送信息'
;
resultInfo.code = - 1009;
return
resultInfo;
}
// 创建一个邮件对象
const mailOpts = Object.assign(
{
// 发件人
from: `Notify <${smtpCfg.auth.user}>`,
// 主题
subject:
'Notify'
,
// text: opts.content,
// html: opts.content,
// 附件内容
// /*attachments: [{
// filename: 'data1.json',
// path: path.resolve(__dirname, 'data1.json')
// }, {
// filename: 'pic01.jpg',
// path: path.resolve(__dirname, 'pic01.jpg')
// }, {
// filename: 'test.txt',
// path: path.resolve(__dirname, 'test.txt')
// }],*/
},
opts
);
if
(!mailOpts.to) mailOpts.to = [];
if
(!Array.isArray(mailOpts.to)) mailOpts.to = String(mailOpts.to).split(
','
);
mailOpts.to = mailOpts.to.map(m => String(m).trim()).filter(m => m.includes(
'@'
));
if
(!mailOpts.to.length) {
resultInfo.msg =
'未配置邮件接收者'
;
resultInfo.code = - 1010;
return
resultInfo;
}
const mailToList = mailOpts.to;
const transporter = nodemailer.createTransport(smtpCfg);
// to 列表分开发送
for
(const to of mailToList) {
mailOpts.to = to.trim();
try
{
const info = await transporter.sendMail(mailOpts);
console.log(
'mail sent to:'
, mailOpts.to,
' response:'
, info.response);
resultInfo.msg = info.response;
}
catch
(error) {
console.log(error);
resultInfo.code = -1001;
resultInfo.msg = error;
}
}
return
resultInfo;
}
|
使用 sendMail 方法发送邮件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
const opts = {
subject:
'subject for test'
,
/** HTML 格式邮件正文内容 */
html: `email content
for
test: <a href=
"https://lzw.me"
rel=
"external nofollow"
rel=
"external nofollow"
>https://lzw.me</a>`,
/** TEXT 文本格式邮件正文内容 */
text:
''
,
to:
'xxx@lzw.me'
,
// 附件列表
// attachments: [],
};
const smtpConfig = {
host:
'smtp.qq.com'
,
//QQ: smtp.qq.com; 网易: smtp.163.com
port: 465,
//端口号。QQ邮箱 465,网易邮箱 25
secure:
true
,
auth: {
user:
'xxx@qq.com'
,
//邮箱账号
pass:
''
,
//邮箱的授权码
},
};
sendMail(opts, smtpConfig).then(result => console.log(result));
|
对于使用微软的 Microsoft Exchange Server 搭建的邮件服务,Nodemailer 就无能为力了。Exchange Web Service(EWS)提供了访问 Exchange 资源的接口,在微软官方文档中对其有详细的接口定义文档。针对 Exchange 邮件服务的流行第三方库主要有 node-ews 和 ews-javascript-api.
下面以 node-ews 模块为例,介绍使用 Exchange 邮件服务发送邮件的方法.
封装一个 sendMailByNodeEws 方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
import EWS from
'node-ews'
;
export interface IEwsSendOptions {
auth: {
user: string;
pass?: string;
/** 密码加密后的秘钥(NTLMAuth.nt_password)。为字符串时,应为 hex 编码结果 */
nt_password?: string | Buffer;
/** 密码加密后的秘钥(NTLMAuth.lm_password)。为字符串时,应为 hex 编码结果 */
lm_password?: string | Buffer;
};
/** Exchange 地址 */
host?: string;
/** 邮件主题 */
subject?: string;
/** HTML 格式邮件正文内容 */
html?: string;
/** TEXT 文本格式邮件正文内容(优先级低于 html 参数) */
text?: string;
to?: string;
}
/**
* 使用 Exchange(EWS) 发送邮件
*/
export async
function
sendMailByNodeEws(options: IEwsSendOptions) {
const resultInfo = { code: 0, msg:
''
, result:
null
};
if
(!options) {
resultInfo.code = -1001;
resultInfo.msg =
'Options can not be null'
;
}
else
if
(!options.auth) {
resultInfo.code = -1002;
resultInfo.msg =
'Options.auth{user,pass} can not be null'
;
}
else
if
(!options.auth.user || (!options.auth.pass && !options.auth.lm_password)) {
resultInfo.code = -1003;
resultInfo.msg =
'Options.auth.user or Options.auth.password can not be null'
;
}
if
(resultInfo.code)
return
resultInfo;
const ewsConfig = {
username: options.auth.user,
password: options.auth.pass,
nt_password: options.auth.nt_password,
lm_password: options.auth.lm_password,
host: options.host,
// auth: 'basic',
};
if
(ewsConfig.nt_password &&
typeof
ewsConfig.nt_password ===
'string'
) {
ewsConfig.nt_password = Buffer.from(ewsConfig.nt_password,
'hex'
);
}
if
(ewsConfig.lm_password &&
typeof
ewsConfig.lm_password ===
'string'
) {
ewsConfig.lm_password = Buffer.from(ewsConfig.lm_password,
'hex'
);
}
Object.keys(ewsConfig).forEach(key => {
if
(!ewsConfig[key])
delete
ewsConfig[key];
});
// initialize node-ews
const ews =
new
EWS(ewsConfig);
// define ews api function
const ewsFunction =
'CreateItem'
;
// define ews api function args
const ewsArgs = {
attributes: {
MessageDisposition:
'SendAndSaveCopy'
,
},
SavedItemFolderId: {
DistinguishedFolderId: {
attributes: {
Id:
'sentitems'
,
},
},
},
Items: {
Message: {
ItemClass:
'IPM.Note'
,
Subject: options.subject,
Body: {
attributes: {
BodyType: options.html ?
'HTML'
:
'Text'
,
},
$value: options.html || options.text,
},
ToRecipients: {
Mailbox: {
EmailAddress: options.to,
},
},
IsRead:
'false'
,
},
},
};
try
{
const result = await ews.run(ewsFunction, ewsArgs);
// console.log('mail sent to:', options.to, ' response:', result);
resultInfo.result = result;
if
(result.ResponseMessages.MessageText) resultInfo.msg = result.ResponseMessages.MessageText;
}
catch
(err) {
console.log(err.stack);
resultInfo.code = 1001;
resultInfo.msg = err.stack;
}
return
resultInfo;
}
|
使用 sendMailByNodeEws 方法发送邮件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
sendMailByNodeEws({
auth: {
user:
'abc@xxx.com'
,
pass:
'123456'
,
/** 密码加密后的秘钥(NTLMAuth.nt_password)。为字符串时,应为 hex 编码结果 */
nt_password:
''
,
/** 密码加密后的秘钥(NTLMAuth.lm_password)。为字符串时,应为 hex 编码结果 */
lm_password:
''
,
},
/** Exchange 地址 */
host:
'https://ews.xxx.com'
,
/** 邮件主题 */
subject:
'subject for test'
,
/** HTML 格式邮件正文内容 */
html: `email content
for
test: <a href=
"https://lzw.me"
rel=
"external nofollow"
rel=
"external nofollow"
>https://lzw.me</a>`,
/** TEXT 文本格式邮件正文内容(优先级低于 html 参数) */
text:
''
,
to:
'xxx@lzw.me'
,
})
|
直接配置 pass 密码可能会导致明文密码泄露,我们可以将 pass 字段留空,配置 nt_password 和 lm_password 字段,使用 NTLMAuth 认证模式。此二字段基于 pass 明文生成,其 nodejs 生成方式可借助 httpntlm 模块完成,具体参考如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import { ntlm as NTLMAuth } from
'httpntlm'
;
/** 将输入的邮箱账号密码转换为 NTLMAuth 秘钥(hex)格式并输出 */
const getHashedPwd = () => {
const passwordPlainText = process.argv.slice(2)[0];
if
(!passwordPlainText) {
console.log(
'USEAGE: \n\tnode get-hashed-pwd.js [password]'
);
return
;
}
const nt_password = NTLMAuth.create_NT_hashed_password(passwordPlainText.trim());
const lm_password = NTLMAuth.create_LM_hashed_password(passwordPlainText.trim());
// console.log('\n password:', passwordPlainText);
console.log(` nt_password:`, nt_password.toString(
'hex'
));
console.log(` lm_password:`, lm_password.toString(
'hex'
));
return
{
nt_password,
lm_password,
};
};
getHashedPwd();
|
基于 ews-javascript-api 发送邮件的方式,在其官方 wiki 有相关示例,但本人在测试过程中未能成功,具体为无法取得服务器认证,也未能查证具体原因,故以下代码仅作参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
/**
* 使用 `ews-javascript-api` 发送(MS Exchange)邮件
*/
export async
function
sendMailByEwsJApi(options: IEwsSendOptions) {
const resultInfo = { code: 0, msg:
''
, result:
null
};
if
(!options) {
resultInfo.code = -1001;
resultInfo.msg =
'Options can not be null'
;
}
else
if
(!options.auth) {
resultInfo.code = -1002;
resultInfo.msg =
'Options.auth{user,pass} can not be null'
;
}
else
if
(!options.auth.user || (!options.auth.pass && !options.auth.lm_password)) {
resultInfo.code = -1003;
resultInfo.msg =
'Options.auth.user or Options.auth.password can not be null'
;
}
const ews = require(
'ews-javascript-api'
);
const exch =
new
ews.ExchangeService(ews.ExchangeVersion.Exchange2010);
exch.Credentials =
new
ews.WebCredentials(options.auth.user, options.auth.pass);
exch.Url =
new
ews.Uri(options.host);
ews.EwsLogging.DebugLogEnabled =
true
;
// false to turnoff debugging.
const msgattach =
new
ews.EmailMessage(exch);
msgattach.Subject = options.subject;
msgattach.Body =
new
ews.MessageBody(ews.BodyType.HTML, escape(options.html || options.text));
if
(!Array.isArray(options.to)) options.to = [options.to];
options.to.forEach(to => msgattach.ToRecipients.Add(to));
// msgattach.Importance = ews.Importance.High;
// 发送附件
// msgattach.Attachments.AddFileAttachment('filename to attach.txt', 'c29tZSB0ZXh0');
try
{
const result = await msgattach.SendAndSaveCopy();
// .Send();
console.log(
'DONE!'
, result);
resultInfo.result = result;
}
catch
(err) {
console.log(
'ERROR:'
, err);
resultInfo.code = 1001;
resultInfo.msg = err;
}
return
resultInfo;
}
|
nodemailer.com/about/ github.com/CumberlandG… github.com/gautamsi/ew… github.com/lzwme/node-… 。
以上就是node.js 基于 STMP 协议和 EWS 协议发送邮件的详细内容,更多关于node.js 发送邮件的资料请关注我其它相关文章! 。
原文链接:https://lzw.me/a/nodejs-stmp-exchange-email-send.html 。
最后此篇关于node.js 基于 STMP 协议和 EWS 协议发送邮件的文章就讲到这里了,如果你想了解更多关于node.js 基于 STMP 协议和 EWS 协议发送邮件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在学习构建单页应用程序 (SPA) 所需的所有技术。总而言之,我想将我的应用程序实现为单独的层,其中前端仅使用 API Web 服务(json 通过 socket.io)与后端通信。前端基本上是
当我看到存储在我的数据库中的日期时。 这是 正常 。日期和时间就是这样。 但是当我运行 get 请求来获取数据时。 此格式与存储在数据库 中的格式不同。为什么会发生这种情况? 最佳答案 我认为您可以将
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试使用backbone.js 实现一些代码 和 hogan.js (http://twitter.github.com/hogan.js/) Hogan.js was developed ag
我正在使用 Backbone.js、Node.js 和 Express.js 制作一个 Web 应用程序,并且想要添加用户功能(登录、注销、配置文件、显示内容与该用户相关)。我打算使用 Passpor
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我尝试在 NodeJS 中加载数据,然后将其传递给 ExpressJS 以在浏览器中呈现 d3 图表。 我知道我可以通过这种方式加载数据 - https://github.com/mbostock/q
在 node.js 中,我似乎遇到了相同的 3 个文件名来描述应用程序的主要入口点: 使用 express-generator 包时,会创建一个 app.js 文件作为生成应用的主要入口点。 通过 n
最近,我有机会观看了 john papa 关于构建单页应用程序的精彩类(class)。我会喜欢的。它涉及服务器端和客户端应用程序的方方面面。 我更喜欢客户端。在他的实现过程中,papa先生在客户端有类
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一个图形新手,需要帮助了解各种 javascript 2D 库的功能。 . . 我从 Pixi.js 中得到了什么,而我没有从 Konva 等基于 Canvas 的库中得到什么? 我从 Konva
我正在尝试将一些 LESS 代码(通过 ember-cli-less)构建到 CSS 文件中。 1) https://almsaeedstudio.com/ AdminLTE LESS 文件2) Bo
尝试查看 Express Passport 中所有登录用户的所有 session ,并希望能够查看当前登录的用户。最好和最快的方法是什么? 我在想也许我可以在登录时执行此操作并将用户模型数据库“在线”
我有一个 React 应用程序,但我需要在组件加载完成后运行一些客户端 js。一旦渲染函数完成并加载,运行与 DOM 交互的 js 的最佳方式是什么,例如 $('div').mixItUp() 。对
请告诉我如何使用bodyparser.raw()将文件上传到express.js服务器 客户端 // ... onFilePicked(file) { const url = 'upload/a
我正在尝试从 Grunt 迁移到 Gulp。这个项目在 Grunt 下运行得很好,所以我一定是在 Gulp 中做错了什么。 除脚本外,所有其他任务均有效。我现在厌倦了添加和注释部分。 我不断收到与意外
我正在尝试更改我的网站名称。找不到可以设置标题或应用程序名称的位置。 最佳答案 您可以在 config/ 目录中创建任何文件,例如 config/app.js 包含如下内容: module.expor
经过多年的服务器端 PHP/MySQL 开发,我正在尝试探索用于构建现代 Web 应用程序的新技术。 我正在尝试对所有 JavaScript 内容进行排序,如果我理解得很好,一个有效的解决方案可以是服
我是 Nodejs 的新手。我在 route 目录中有一个 app.js 和一个 index.js。我有一个 app.use(multer....)。我还定义了 app.post('filter-re
我正在使用 angular-seed用于构建我的应用程序的模板。最初,我将所有 JavaScript 代码放入一个文件 main.js。该文件包含我的模块声明、 Controller 、指令、过滤器和
我是一名优秀的程序员,十分优秀!