Node.js sends emails based on STMP protocol and EWS protocol

Node.js sends emails based on STMP protocol and EWS protocol

This article mainly introduces the method of using node.js to send emails based on STMP protocol and MS Exchange Web Service(EWS) protocol. All reference codes in this article are coded in TypeScript.

1 Node.js method of sending emails based on STMP protocol

When talking about using node.js to send emails, the famous Nodemailer module will basically be mentioned. It is currently the first choice for sending emails using STMP.
There are many articles on the Internet about sending STMP protocol emails based on NodeMailer , and the official documentation is also quite detailed. Here we only list the sample code for comparison and reference:
Encapsulate a sendMail email sending method:

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

 // Create a mail object const mailOpts = Object.assign(
 {
 // Sender from: `Notify <${smtpCfg.auth.user}>`,
 // Subject subject: 'Notify',
 // text: opts.content,
 //html: opts.content,
 // Attachment 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 = 'The email recipient is not configured';
 resultInfo.code = -1010;
 return resultInfo;
 }

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

 // to list to send 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;
}

Use the sendMail method to send mail:

const opts = {
 subject: 'subject for test',
 /** HTML format email content*/
 html: `email content for test: <a href="https://lzw.me" rel="external nofollow" rel="external nofollow" >https://lzw.me</a>`,
 /** TEXT text format email content*/
 text: '',
 to: '[email protected]',
 //Attachments 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: '[email protected]', //Email account pass: '', //Email authorization code},
};
sendMail(opts, smtpConfig).then(result => console.log(result));

2 Node.js method for sending emails based on MS Exchange mail server

Nodemailer is powerless for email services built using Microsoft's Microsoft Exchange Server. Exchange Web Service (EWS) provides an interface for accessing Exchange resources, and there is a detailed interface definition document in Microsoft's official documentation. Popular third-party libraries for Exchange mail services include node-ews and ews-javascript-api.

2.1 Sending MS Exchange emails using node-ews

The following uses the node-ews module as an example to introduce how to send emails using the Exchange mail service.

2.1.1 Encapsulate a method for sending emails based on node-ews

Encapsulate a sendMailByNodeEws method:

import EWS from 'node-ews';

export interface IEwsSendOptions {
 auth:
 user: string;
 pass?: string;
 /** The encrypted password key (NTLMAuth.nt_password). When it is a string, it should be the hex encoding result*/
 nt_password?: string | Buffer;
 /** Password encrypted key (NTLMAuth.lm_password). When it is a string, it should be the hex encoding result*/
 lm_password?: string | Buffer;
 };
 /** Exchange address*/
 host?: string;
 /** Email subject */
 subject?: string;
 /** HTML format email content*/
 html?: string;
 /** TEXT text format email body content (lower priority than html parameter) */
 text?: string;
 to?: string;
}

/**
 * Send email using 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;
}

Use the sendMailByNodeEws method to send email:

sendMailByNodeEws({
 auth:
 user: '[email protected]',
 pass: '123456',
 /** The encrypted password key (NTLMAuth.nt_password). When it is a string, it should be the hex encoding result*/
 nt_password: '',
 /** Password encrypted key (NTLMAuth.lm_password). When it is a string, it should be the hex encoding result*/
 lm_password: '',
 },
 /** Exchange address*/
 host: 'https://ews.xxx.com',
 /** Email subject */
 subject: 'subject for test',
 /** HTML format email content*/
 html: `email content for test: <a href="https://lzw.me" rel="external nofollow" rel="external nofollow" >https://lzw.me</a>`,
 /** TEXT text format email body content (lower priority than html parameter) */
 text: '',
 to: '[email protected]',
})

2.1.2 Authentication configuration based on NTLMAuth

Directly configuring the pass password may lead to the disclosure of the plain text password. We can leave the pass field blank, configure the nt_password and lm_password fields, and use the NTLMAuth authentication mode. These two fields are generated based on the pass plain text. The nodejs generation method can be completed with the help of the httpntlm module. The specific reference is as follows:

import { ntlm as NTLMAuth } from 'httpntlm';

/** Convert the input email account password into NTLMAuth 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 Sending MS Exchange emails using ews-javascript-api

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

/**
 * Use `ews-javascript-api` to send (MS Exchange) emails */
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 attachment // 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 the details of node.js sending emails based on STMP protocol and EWS protocol. For more information about node.js sending emails, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • In-depth analysis of Node.js single-threaded model
  • Understanding what Node.js is is so easy
  • Specific use of node.js global variables
  • The whole process of node.js using express to automatically build the project
  • Detailed explanation of node.js installation and HbuilderX configuration
  • Node.js file copying, folder creation and other related operations
  • Detailed explanation of asynchronous generators and asynchronous iterations in Node.js
  • Detailed explanation of the steps to create a web server with node.js
  • How to collect and parse command line arguments in Node.js
  • Detailed explanation of Alibaba Node.js technical documentation process module learning guide
  • Complete steps to develop cli using node.js
  • How to connect MySQL to Node.js through Sequelize
  • How to install the latest version of Node.js on CentOS 8.2 server
  • How to remove the BOM header of Node.js text file
  • Appium+python automated configuration (adk, jdk, node.js)
  • How to convert a callback in Node.js to a Promise
  • Node.js path module, get the file suffix operation
  • First experience with node.js crawler framework node-crawler
  • Nodejs Exploration: In-depth understanding of the principle of single-threaded high concurrency

<<:  MySql login password forgotten and password forgotten solution

>>:  Compile CPP files using G++ in Ubuntu

Recommend

How to set the width and height of html table cells

When making web pages, you often encounter the pr...

VMware + Ubuntu18.04 Graphic Tutorial on Building Hadoop Cluster Environment

Table of contents Preface VMware clone virtual ma...

Docker connection mongodb implementation process and code examples

After the container is started Log in to admin fi...

Vue3 compilation process-source code analysis

Preface: Vue3 has been released for a long time. ...

Detailed explanation of MySQL/Java server support for emoji and problem solving

This article describes the support and problem so...

Should nullable fields in MySQL be set to NULL or NOT NULL?

People who often use MySQL may encounter the foll...

Detailed explanation of Cgroup, the core principle of Docker

The powerful tool cgroup in the kernel can not on...

SQL statements in Mysql do not use indexes

MySQL query not using index aggregation As we all...

Drawing fireworks effect of 2021 based on JS with source code download

This work uses the knowledge of front-end develop...

Detailed explanation of DOM DIFF algorithm in react application

Table of contents Preface What is VirtualDOM? Rea...

Commonly used HTML format tags_Powernode Java Academy

1. Title HTML defines six <h> tags: <h1&...

How to install and configure MySQL and change the root password

1. Installation apt-get install mysql-server requ...

CentOS 6 Compile and install ZLMediaKit analysis

Install ZLMediaKit on centos6 The author of ZLMed...

Solution to the CSS height collapse problem

1. High degree of collapse In the document flow, ...