gpt4 book ai didi

node.js 基于 STMP 协议和 EWS 协议发送邮件

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 27 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章node.js 基于 STMP 协议和 EWS 协议发送邮件由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

本文主要介绍 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: '' ,
  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));

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: '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' ,
})

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.js 基于 STMP 协议和 EWS 协议发送邮件的文章就讲到这里了,如果你想了解更多关于node.js 基于 STMP 协议和 EWS 协议发送邮件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com