一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - node.js - node.js 基于 STMP 協議和 EWS 協議發送郵件

node.js 基于 STMP 協議和 EWS 協議發送郵件

2022-01-20 16:52志文工作室 node.js

這篇文章主要介紹了node.js 基于 STMP 協議和 EWS 協議發送郵件的示例,幫助大家更好的理解和使用node.js,感興趣的朋友可以了解下

本文主要介紹 node.js 發送基于 STMP 協議和 MS Exchange Web Service(EWS) 協議的郵件的方法。文中所有參考代碼均以 TypeScript 編碼示例。

1 基于 STMP 協議的 node.js 發送郵件方法

提到使用 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: '',
 // 附件列表
 // attachments: [],
};
const smtpConfig = {
 host: 'smtp.qq.com', //QQ: smtp.qq.com; 網易: smtp.163.com
 port: 465, //端口號。QQ郵箱 465,網易郵箱 25
 secure: true,
 auth: {
 user: '[email protected]', //郵箱賬號
 pass: '', //郵箱的授權碼
 },
};
sendMail(opts, smtpConfig).then(result => console.log(result));

2 基于 MS Exchange 郵件服務器的 node.js 發送郵件方法

對于使用微軟的 Microsoft Exchange Server 搭建的郵件服務,Nodemailer 就無能為力了。Exchange Web Service(EWS)提供了訪問 Exchange 資源的接口,在微軟官方文檔中對其有詳細的接口定義文檔。針對 Exchange 郵件服務的流行第三方庫主要有 node-ews 和 ews-javascript-api。

2.1 使用 node-ews 發送 MS Exchange 郵件

下面以 node-ews 模塊為例,介紹使用 Exchange 郵件服務發送郵件的方法。

2.1.1 封裝一個基于 node-ews 發送郵件的方法

封裝一個 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: '[email protected]',
 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: '',
})

2.1.2 基于 NTLMAuth 的認證配置方式

直接配置 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();

2.2 使用 ews-javascript-api 發送 MS Exchange 郵件

基于 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;
}

3 擴展參考

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.jsk8s node節點重新加入master集群的實現

    k8s node節點重新加入master集群的實現

    這篇文章主要介紹了k8s node節點重新加入master集群的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    Scarborought13922022-01-22
  • node.js在瀏覽器中,把 Vite 跑起來了!

    在瀏覽器中,把 Vite 跑起來了!

    大家好,我是 ssh,前幾天在推上沖浪的時候,看到 Francois Valdy 宣布他制作了 browser-vite[1],成功把 Vite 成功在瀏覽器中運行起來了。這引起了我的興趣,如...

    前端從進階到入院9282022-01-11
  • node.js詳解node.js創建一個web服務器(Server)的詳細步驟

    詳解node.js創建一個web服務器(Server)的詳細步驟

    這篇文章主要介紹了詳解node.js創建一個web服務器(Server)的詳細步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,...

    王佳斌8952021-12-31
  • node.jsnodejs中使用worker_threads來創建新的線程的方法

    nodejs中使用worker_threads來創建新的線程的方法

    這篇文章主要介紹了nodejs中使用worker_threads來創建新的線程的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友...

    flydean程序那些事8982022-01-06
  • node.jsNode.js ObjectWrap 的弱引用問題

    Node.js ObjectWrap 的弱引用問題

    最近在寫 Node.js Addon 的過程中,遇到了一個問題,然后發現是 ObjectWrap 弱引用導致的,本文介紹一下具體的問題和排查過程,以及 ObjectWrap 的使用問題。...

    編程雜技9852022-01-04
  • node.jslinux服務器快速卸載安裝node環境(簡單上手)

    linux服務器快速卸載安裝node環境(簡單上手)

    這篇文章主要介紹了linux服務器快速卸載安裝node環境(簡單上手),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需...

    mose-x8462022-01-22
  • node.jsNode.js 中如何收集和解析命令行參數

    Node.js 中如何收集和解析命令行參數

    這篇文章主要介紹了Node.js 中如何收集和解析命令行參數,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    descire8802021-12-28
  • node.jsrequire加載器實現原理的深入理解

    require加載器實現原理的深入理解

    這篇文章主要給大家介紹了關于require加載器實現原理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需...

    隱冬8462022-03-03
主站蜘蛛池模板: 99国产精品热久久久久久夜夜嗨 | 欧美jjvideo | 国产私拍精品88福利视频 | 2021最新国产成人精品免费 | 性吧有你| 国产精品最新资源网 | 欧美区视频 | 国产成人一区二区三区视频免费蜜 | gay台湾无套男同志可播放 | 亚洲国产精品ⅴa在线观看 亚洲国产高清一区二区三区 | 四虎影视免费观看免费观看 | 女老板用丝袜脚夹我好爽 | 国内精品 大秀视频 日韩精品 | xvideoscom极品肌肉警察 | 午夜爽喷水无码成人18禁三级 | 午夜久久久久久亚洲国产精品 | 国产精品乱码高清在线观看 | 嫩草影院永久在线一二三四 | 亚洲欧美专区 | 清纯漂亮女友初尝性过程 | 91免费在线播放 | 亚洲国产一区二区a毛片 | 4tube高清性欧美 | 日本高清中文字幕一区二区三区 | caoporm碰最新免费公开视频 | 成年人视频免费在线播放 | 女人张开腿让男人桶视频免费大全 | 日本伊人色综合网 | 亚洲国产精品久久久久 | 美女扒开腿让男生捅 | 日韩欧美一区二区三区免费看 | 国产精品二区高清在线 | 男人晚上看的 | 国产精品久久久久久岛国 | 热久久最新地址 | 国产精品欧美韩国日本久久 | 免费网站国产 | 亚洲国内精品久久 | 亚洲haose在线观看 | 精品国产美女福利在线 | 国产精品第一区揄拍 |