node. js sends mail based on STMP protocol and EWS protocol

  • 2021-10-27 06:18:58
  • OfStack

Directory 1 node. js mail sending method based on STMP protocol
2 node. js mail sending method based on MS Exchange mail server
2.1 Send an MS Exchange message using node-ews
2.1. 1 Encapsulate a method of sending mail based on node-ews
2.1. 2 Authentication configuration based on NTLMAuth
2.2 Send an ES22Exchange message using ews-javascript-api
3 Extended Reference

This article mainly introduces node. js sending based on STMP Agreements and MS Exchange Web Service(EWS) Protocol of the mail method. All reference codes in this paper are encoded in TypeScript.

1 node. js sending mail method based on STMP protocol

When it comes to using node. js to send emails, you will basically mention the famous Nodemailer Module, which is currently the first choice for sending mail using STMP.
Based on NodeMailer There are many articles on the Internet that send STMP protocol mail, and the official documents are introduced in detail. Here, only sample codes are listed for comparative reference:
Package 1 sendMail Mail sending method:


/**
 *  Use  Nodemailer  Send  STMP  Mail 
 * @param {Object} opts  Mail sending configuration 
 * @param {Object} smtpCfg smtp  Server configuration 
 */
async function sendMail(opts, smtpCfg) {
 const resultInfo = { code: 0, msg: '', result: null };
 if (!smtpCfg) {
 resultInfo.msg = ' Mail sending information is not configured ';
 resultInfo.code = - 1009;
 return resultInfo;
 }

 //  Create 1 Mail objects 
 const mailOpts = Object.assign(
 {
 //  Sender 
 from: `Notify <${smtpCfg.auth.user}>`,
 //  Theme 
 subject: 'Notify',
 // text: opts.content,
 // html: opts.content,
 //  Contents of attachments 
 // /*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 = ' Mail recipients are not configured ';
 resultInfo.code = - 1010;
 return resultInfo;
 }

 const mailToList = mailOpts.to;
 const transporter = nodemailer.createTransport(smtpCfg);

 // to  Send lists separately 
 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;
}

Send a message using the sendMail method:


const opts = {
 subject: 'subject for test',
 /** HTML  Format message body content  */
 html: `email content for test: <a href="https://lzw.me" rel="external nofollow" rel="external nofollow" >https://lzw.me</a>`,
 /** TEXT  Text format message body content  */
 text: '',
 to: 'xxx@lzw.me',
 //  Attachment list 
 // attachments: [],
};
const smtpConfig = {
 host: 'smtp.qq.com', //QQ: smtp.qq.com;  NetEase : smtp.163.com
 port: 465, // Port number. QQ Mailbox  465 NetEase Mailbox  25
 secure: true,
 auth: {
 user: 'xxx@qq.com', // Email account number 
 pass: '', // Authorization code of mailbox 
 },
};
sendMail(opts, smtpConfig).then(result => console.log(result));

node. js mail sending method based on MS Exchange mail server

There is nothing Nodemailer can do about the mail service built with Microsoft's Microsoft Exchange Server. Exchange Web Service (EWS) provides an interface to access Exchange resources, which has detailed interface definition documents in Microsoft official documents. Popular third-party libraries for Exchange mail services are node-ews and ews-javascript-api.

2.1 Send an MS Exchange message using node-ews

Using the node-ews module as an example, the following describes how to use the Exchange mail service to send mail.

2.1. 1 Encapsulate a method of sending mail based on node-ews

Encapsulate 1 sendMailByNodeEws method:


import EWS from 'node-ews';

export interface IEwsSendOptions {
 auth: {
 user: string;
 pass?: string;
 /**  Secret key after password encryption (NTLMAuth.nt_password) . Is a string, should be  hex  Encoding result  */
 nt_password?: string | Buffer;
 /**  Secret key after password encryption (NTLMAuth.lm_password) . Is a string, should be  hex  Encoding result  */
 lm_password?: string | Buffer;
 };
 /** Exchange  Address  */
 host?: string;
 /**  Mail Subject  */
 subject?: string;
 /** HTML  Format message body content  */
 html?: string;
 /** TEXT  Text format message body content ( Priority is lower than  html  Parameter ) */
 text?: string;
 to?: string;
}

/**
 *  Use  Exchange(EWS)  Send Mail 
 */
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;
}

Send a message using the sendMailByNodeEws method:


sendMailByNodeEws({
 auth: {
 user: 'abc@xxx.com',
 pass: '123456',
 /**  Secret key after password encryption (NTLMAuth.nt_password) . Is a string, should be  hex  Encoding result  */
 nt_password: '',
 /**  Secret key after password encryption (NTLMAuth.lm_password) . Is a string, should be  hex  Encoding result  */
 lm_password: '',
 },
 /** Exchange  Address  */
 host: 'https://ews.xxx.com',
 /**  Mail Subject  */
 subject: 'subject for test',
 /** HTML  Format message body content  */
 html: `email content for test: <a href="https://lzw.me" rel="external nofollow" rel="external nofollow" >https://lzw.me</a>`,
 /** TEXT  Text format message body content ( Priority is lower than  html  Parameter ) */
 text: '',
 to: 'xxx@lzw.me',
})

2.1. 2 Authentication configuration based on NTLMAuth

Configuring the pass password directly may cause the plaintext password to be leaked. We can leave the pass field blank, configure the nt_password and lm_password fields, and use NTLMAuth authentication mode. These 2 fields are generated based on pass plaintext, and the nodejs generation mode can be completed with the help of httpntlm module. For specific reference, please refer to the following:


import { ntlm as NTLMAuth } from 'httpntlm';

/**  Convert the entered email account password to  NTLMAuth  Secret key (hex) Format and output  */
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 Send an MS Exchange message using ews-javascript-api

Based on the way ews-javascript-api sends mail, there are relevant examples in its official wiki, but I failed in the test process, specifically, I could not obtain server authentication and could not verify the specific reasons, so the following code is for reference only:


/**
 *  Use  `ews-javascript-api`  Send (MS Exchange) Mail 
 */
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;

 //  Send attachments 
 // 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 Extended Reference

nodemailer.com/about/
github. com/CumberlandG …
github. com/gautamsi/ew …
github. com/lzwme/node-…

The above is node. js based on STMP protocol and EWS protocol to send mail details, more information about node. js send mail please pay attention to other related articles on this site!


Related articles: