Skip to content

Commit

Permalink
Add SMTP node. Allow expanding properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
TekMonksGitHub committed May 19, 2021
1 parent 940ba81 commit 862a3bb
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"type": "node",
"request": "launch",
"name": "Launch ESB Clustered",
"program": "${workspaceFolder}/esb.js"
"program": "${workspaceFolder}/esb.js",
"env": {"JAVA_HOME":"${workspaceFolder}/../../Programs/jdk-16.0.1"}
}
]
}
3 changes: 2 additions & 1 deletion conf/crypt.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"key":"C77AE67918DAF5A819EE6EF2E9930554W2"
"key":"C77AE67918DAF5A819EE6EF2E9930554W2",
"crypt_algo":"aes-256-ctr"
}
2 changes: 1 addition & 1 deletion flows/pipeline_editojson.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"route1": {
"type":"ediparser",
"dependencies":["route0"],
"java":"c:/Users/Rohit Kapoor/source/jdk8/bin/java.exe"
"java":"{{process.env.JAVA_HOME}}/bin/java.exe"
},
"output": {
"type": "filewriter",
Expand Down
2 changes: 1 addition & 1 deletion flows/pipeline_editojson2.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"route2": {
"type":"ediparser",
"dependencies":["route1.1"],
"java":"c:/Users/Rohit Kapoor/source/jdk8/bin/java.exe"
"java":"{{process.env.JAVA_HOME}}/bin/java.exe"
},
"route3": {
"type":"filewriter",
Expand Down
31 changes: 31 additions & 0 deletions flows/pipeline_emailFileNotification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"flow":{
"name":"Email file notification",
"disabled":false
},
"listener": {
"type":"file",
"isMessageGenerator": true,
"path":"C:/test/in/*",
"donePath":"C:/test/done"
},
"route0":{
"type": "js",
"dependencies":"listener",
"module":"{{ESB_DIR}}/custom/email_custom.js"
},
"output": {
"type": "email",
"dependencies":"route0",
"host":"smtp.mailgun.org",
"port": 465,
"secure": true,
"user": "[email protected]",
"password": "<encrypted password goes here>",
"to": "[email protected]",
"from": "[email protected]",
"title": "New request was submitted",
"text": "New file has been submitted for processing.",
"html": "<p>New file has been submitted for processing.</p>"
}
}
2 changes: 1 addition & 1 deletion lib/crypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ if (require.main === module) {
console.log(eval(args[0])(args[1]));
}

module.exports = { encrypt, decrypt };
module.exports = { encrypt, decrypt };
35 changes: 35 additions & 0 deletions lib/mailer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Email module.
*
* (C) 2020 TekMonks. All rights reserved.
* See enclosed LICENSE file.
*/
const nodemailer = require("nodemailer");

/**
* Sends an email.
* @param {*} to To email address
* @param {*} from From email address
* @param {*} title The subject of the email
* @param {*} email_html The content of the email as HTML
* @param {*} email_text The content of the email as Text
* @param {*} attachments The set of attachments, format [{path: path/to/file},...]
* @param {*} conf The config contains {host, port, secure, user, pass} for SMTP
* @returns {result:true|false, response: Mailer response on true, error: Error on false}
*/
module.exports.email = async function(to, from, title, email_html, email_text, attachments, conf) {
const smtpConfig = { pool: true, host: conf.server, port: conf.port, secure: conf.secure,
auth: {user: conf.user, pass: conf.pass} },
transporter = nodemailer.createTransport(smtpConfig);

const nodeMailerAttachments = []; for (const attachment of attachments) nodeMailerAttachments.push({path:attachment});

try {
const response = await transporter.sendMail({"from": from, "to": to, "subject": title, "text": email_text,
"html": email_html, attachments: nodeMailerAttachments});
return {result: true, response};
} catch (err) {
LOG.error(`Email send failed due to ${err}`);
return {result: false, error: err};
}
}
2 changes: 1 addition & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function launchNewFlowInstance(flow) {
let routeNames = Object.keys(flow);
routeNames.splice(routeNames.indexOf("flow"), 1);
routeNames.splice(routeNames.indexOf("env"), 1);
LOG.info(`[ESB] Starting flow: ${flow.flow.name}`);
LOG.info(`[ESB] Starting the flow: ${flow.flow.name}`);

routeNames.forEach(route => flow[route].flow = flow);
runFlow(flow, routeNames);
Expand Down
8 changes: 7 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* (C) 2015 - 2018 TekMonks. All rights reserved.
*/
const mustache = require("mustache");

function getDateTime() {

Expand Down Expand Up @@ -36,4 +37,9 @@ function getObjectKeyValueCaseInsensitive(obj, key) {
return null;
}

module.exports = { getDateTime, getTimeStamp, getObjectKeyValueCaseInsensitive };
function expandProperty(property, flow, message) {
const data = {esb: global.ESB, flow, message, constants: global.CONSTANTS, ESB_DIR: CONSTANTS.ROOTDIR, process: global.process};
return mustache.render(property, data);
}

module.exports = { getDateTime, getTimeStamp, getObjectKeyValueCaseInsensitive, expandProperty };
7 changes: 7 additions & 0 deletions outputs/email.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* email.js - Sends email, output node
*
* (C) 2020 TekMonks. All rights reserved.
*/

exports.start = require(`${CONSTANTS.ROOTDIR}/routes/email.js`).start;
40 changes: 40 additions & 0 deletions routes/email.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* email.js - Sends an email via SMTP
*
* (C) 2018 TekMonks. All rights reserved.
*/
const crypt = require(`${CONSTANTS.LIBDIR}/crypt.js`);
const mailer = require(`${CONSTANTS.LIBDIR}/mailer.js`);

exports.start = async (routeName, email, _messageContainer, message) => {
if (message.env[routeName]?.isProcessing) return;
if (!message.env[routeName]) message.env[routeName] = {isProcessing: true};
message.setGCEligible(false);

// transfer email and email routing data, if specified, from the message content
email.to = message.content.to || email.to; email.from = message.content.from || email.from;
email.title = message.content.title || email.title; email.html = message.content.html; email.text = message.content.text;
email.attachments = email.attachments || []; if (message.content.attachments) for (const attachment of message.content.attachments) email.attachments.push(attachment);

LOG.info(`[EMAIL] Emailing ${email.to}, from ${email.from} with incoming message with timestamp: ${message.timestamp}`);

if (!email.port) email.port = (email.secure?587:25); // handle ports

const result = await mailer.email(email.to, email.from, email.title,
email.html, email.text, email.attachments, { user: email.user,
pass: crypt.decrypt(email.password), server: email.host, port: email.port, secure: email.secure });

if (result.result) {
message.addRouteDone(routeName);
delete message.env[routeName]; // clean up our mess
message.setGCEligible(true);
message.content = result.response;
LOG.info(`[EMAIL] Email sent for message with timestamp: ${message.timestamp}`);
LOG.debug(`[EMAIL] Response data is: ${result.response}`);
} else {
LOG.error(`[EMAIL] Email failed with error: ${result.error}, for message with timestamp: ${message.timestamp}`);
message.addRouteError(routeName);
delete message.env[routeName]; // clean up our mess
message.setGCEligible(true);
}
}
4 changes: 2 additions & 2 deletions routes/httpclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ exports.start = (routeName, httpclient, _messageContainer, message) => {
httpclient.timeout, (error, result) => {

if (error) {
LOG.error(`[HTTP] Call failed with error: ${error}`);
LOG.error(`[HTTP] Call failed with error: ${error}, for message with timestamp: ${message.timestamp}`);
message.addRouteError(routeName);
delete message.env[routeName]; // clean up our mess
message.setGCEligible(true);
} else {
message.addRouteDone(`${routeName}`);
message.addRouteDone(routeName);
delete message.env[routeName]; // clean up our mess
message.setGCEligible(true);
message.content = result.response;
Expand Down
3 changes: 2 additions & 1 deletion routes/js.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
*
* (C) 2018 TekMonks. All rights reserved.
*/
const utils = require(`${CONSTANTS.LIBDIR}/utils.js`);

exports.start = (routeName, js, messageContainer, message) => {
LOG.info(`[ROUTE_JS] Processing message with timestamp: ${message.timestamp}`);

if (js.module) {require(js.module).start(routeName, js, messageContainer, message);} else {
if (js.module) {require(utils.expandProperty(js.module, js.flow, message)).start(routeName, js, messageContainer, message);} else {
try {
const flow = js.flow; // allows JS code below to call the flow.
eval(js.js);
Expand Down

0 comments on commit 862a3bb

Please sign in to comment.