Closing a connection in nodemailer - node.js

I am using nodemailer to send e-mails in nodejs. I am able to send the mails, but the script doesn't terminate. I don't know how to close the connection.
This is the code:
var nodemailer = require('nodemailer');
nodemailer.SMTP = {
host: 'localhost'
}
nodemailer.send_mail(
{
sender: 'me#example.com',
to:'my_gmail_nickname#gmail.com',
subject:'Hello!',
html: 'test',
body:'test'
},
function(error, success){
console.log(error);
console.log(success);
console.log('Message ' + success ? 'sent' : 'failed');
});

I got it working like this:
var nodemailer = require('nodemailer');
var transport = nodemailer.createTransport("SMTP", {
host: 'localhost',
});
var send_email = function (email_content) {
var mailOptions = {
from: 'me#example.com',
to: 'my_gmail_nickname#gmail.com',
subject: 'Hello!',
html: email_content.content
};
transport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Message sent: ' + info.message);
transport.close();
}
})
};

Related

Laravel chat app : Unable to deliver messages to a specific user

I have been trying to develop a chat app on Laravel with socket.io. Now, I am facing problem that is when a user is sending a message to a specific user, the message is being delivered to all the available users. May I know the section of code you need to help me out? Or there's some other area where I can specifically look into.
const express = require("express");
const app = express();
const server = require('http').createServer(app);
const io = require("socket.io")(server, {
cors: { origin: "*" }
});
server.listen(3000, () => {
console.log('Server is running');
io.on("connection", function(socket) {
console.log("User" + socket.id);
socket.on("messageSent", function(message, senderId) {
socket.broadcast.emit("messageSent", message, this.socket.id)
console.log(this.socket.id);
});
//msg
socket.on("msgSent", function(message) {
socket.broadcast.emit("msgSent", message)
});
socket.on("clientMmsgSent", function(message) {
socket.broadcast.emit("clientMmsgSent", message)
});
});
});
Other code:
<sc ript>
var socket = io("{{config('app.server_url')}}");
function sendMessage(event) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//console.log('test');
event.preventDefault();
if (event.keyCode === 13) {
var msg = document.getElementById('msg').value;
var client_id = document.getElementById('client_id').value;
var operator_id = document.getElementById('operator_id').value;
//console.log(smg);
$.ajax({
type: "POST",
url: "{{route('send.msg')}}",
data: {
msg: msg,
client_id: client_id,
operator_id: operator_id,
},
beforeSend: function() {
},
success: function(data) {
var msg = `
<div class="operator-msg">
${data.operator_msg}
</div>
`;
console.log(data);
socket.emit("msgSent", {
'data': data,
});
$('#opt_msg').append(msg);
},
error: function(error) {
console.log(error);
}
});
$('#msg').val(" ");
return true;
} else {
return false;
}
}
</sc ript>

Check Mailbox in a Loop, Read Email and Create PDF

I have a code that reads unseen emails and creates pdf.
The problem is;
I cannot pull email if any new unseen email exist without executing code again.
var Imap = require('imap');
const MailParser = require('mailparser').MailParser;
var pdf = require('html-pdf');
var fs = require('fs');
var Promise = require("bluebird");
Promise.longStackTraces();
var imapConfig = {
user: '*****',
password: '*****',
host: 'imap.gmail.com',
port: 993,
tls: true
};
var imap = new Imap(imapConfig);
Promise.promisifyAll(imap);
imap.once("ready", execute);
imap.once("error", function(err) {
log.error("Connection error: " + err.stack);
});
imap.connect();
function execute() {
imap.openBox("INBOX", false, function(err, mailBox) {
if (err) {
console.error(err);
return;
}
imap.search(["UNSEEN"], function(err, results) {
if(!results || !results.length){console.log("No unread mails");imap.end();return;}
var f = imap.fetch(results, { bodies: "" });
f.on("message", processMessage);
f.once("error", function(err) {
return Promise.reject(err);
});
f.once("end", function() {
console.log("Done fetching all unseen messages.");
imap.end();
});
});
});
}
const options = { format: 'A2', width:"19in", height:"17in", orientation: "portrait" };
function processMessage(msg, seqno) {
console.log("Processing msg #" + seqno);
// console.log(msg);
var parser = new MailParser();
parser.on("headers", function(headers) {
console.log("Header: " + JSON.stringify(headers));
});
parser.on('data', data => {
if (data.type === 'text') {
console.log(seqno);
console.log(data.html); /* data.html*/
var test = data.html
pdf.create(test, options).toStream(function(err, stream){
stream.pipe(fs.createWriteStream('./foo.pdf'));
});
}
});
msg.on("body", function(stream) {
stream.on("data", function(chunk) {
parser.write(chunk.toString("utf8"));
});
});
msg.once("end", function() {
// console.log("Finished msg #" + seqno);
parser.end();
});
}
Also I have tried to use setInterval to check new unseen emails but I get
'Error: Not authenticated'
How can I pull new unseen emails in a loop and create pdf from that email?
Your observation is correct. You must poll your IMAP (or POP3) server on a regular schedule to keep up with incoming messages. Depending on your requirements, a schedule of once every few minutes is good.
continous polling, or polling every second or so, is very rude. The operator of the IMAP server may block your application if you try to do that: it looks to them like an attempt to overload the server.

How to send an email using AWS in Node project

My Angular app sends some data to a node server (app.js) via a POST request, the request body is then returned in the response.
I am now trying to send an email that contains this data sent in the request body.
Currently, I can read a HTML file to populate the email body, & then send the email but I need to replace that HTML file with the data sent in my req.body.
Here is what I have so far in app.js:
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.post('/postData', bodyParser.json(), (req, res) => {
res.json(req.body)
readFile();
sendEmail();
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
var AWS = require('aws-sdk');
const fs = require('fs');
var params;
var htmlFileName = '/Users/myName/Desktop/test.html'
AWS.config.loadFromPath('config-aig.json');
const fromEmail = 'myName';
const toEmail = 'myName'
const subject = 'Test Email' + Date()
function sendEmail() {
// Create the promise and SES service object
var sendPromise = new AWS.SES({ apiVersion: '2010-12-01'}).sendEmail(params).promise();
sendPromise.then(
function (data) {
console.log('send email success');
}).catch(
function (err) {
console.error('error --> ', err, err.stack);
});
}
function readFile(callback) {
return new Promise(
function (resolve, reject) {
fs.readFile(htmlFileName, 'utf8',
function read(err, data) {
if (err) {
return reject(err)
}
else {
console.log('file read success');
return resolve(data);
}
})
}
)
}
readFile()
.then((res) => {
// Create sendEmail params
params = {
Destination: { /* required */
ToAddresses: [
toEmail,
]
},
Message: { /* required */
Body: { /* required */
Html: {
Charset: "UTF-8",
Data: res
}
},
Subject: {
Charset: 'UTF-8',
Data: subject
}
},
Source: fromEmail, /* required */
}
sendEmail();
})
.catch((err) => {
console.log('File Read Error : ', err)
}
)
Can someone please show me how I can replace my htmlFileName with the req.body?
I use ejs to template my email here is a code i frenquently use to send email !
If you have questions i would be glade to answer
const ejs = require('ejs');
const AWS = require('aws-sdk');
const mailcomposer = require('mailcomposer');
const config_aws = {
accessKeyId: '',
secretAccessKey: '',
region: 'eu-west-1',
expeditor: '',
limitExpeditor: 50
};
AWS.config.update(config_aws);
const ses = new AWS.SES();
async function sendAnEmail(
expeditor,
subject,
destinator,
body,
destinator_name = null,
bcc = null,
callback
) {
ejs.renderFile(
`${__dirname}/templates/template.ejs`,
{
destinator,
destinator_name,
subject,
body
},
(err, html) => {
if (err) return console.error(err);
const sesEmailProps = {
Source: config_aws.expeditor,
Destination: {
ToAddresses: [`${destinator}`]
},
Message: {
Body: {
Html: {
Charset: 'UTF-8',
Data: html
},
Text: {
Charset: 'UTF-8',
Data: html ? html.replace(/<(?:.|\n)*?>/gm, '') : ''
}
},
Subject: {
Charset: 'UTF-8',
Data: subject
}
}
};
if (bcc) {
sesEmailProps.Destination = {
ToAddresses: [`${destinator}`],
BccAddresses: bcc // ARRAY LIMIT OF 49
};
}
ses.sendEmail(sesEmailProps, (error, data) => {
if (error) console.error(error);
callback(error, data);
});
}
);
}

Sending a mail via NODE.JS in an IBM Cloud function

I have similar problem as here: PHP mail function doesn't complete sending of e-mail
But after several tries I don't think it's my solution...
Objective:
Create an action which can send email.
Code:
function main(params) {
const params = {
"payload": {
"id": "sender.address#gmail.com",
"password": "CodeForTheSenderAccount",
"receiver": "another.mail.address#gmail.com",
"subject": "Test Wikit",
"body": "<html>HELLO WORLD</html>"
}
}
const nodemailer = require('nodemailer');
//Creation of a SMTP transporter
var transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: params.payload.id,
pass: params.payload.password
}
});
//Creation of data to send
const mail = {
from: '"Wikitest" <' + params.payload.id + '>',
to: params.payload.receiver,
subject: params.payload.subject,
text: 'Hello World',
html: params.payload.body
}
//Sending the mail
return(transporter.sendMail(mail, function (err, info) {
if (err) {
const ret = {status: 'OK'};
} else {
const ret = {status: 'KO'};
}
transporter.close();
return (ret);
}));
}
This code works locally and I receive the email. But not when running the function in the IBM Cloud console.
I think it's due to SMTP servers but I'm not sure...
Some of you will see the "payload" param. It's because this action is in a sequence and the action before send the params.
When working with asynchronous JavaScript in serverless functions, you need to return and resolve a Promise. Here is relevant documentation for your example https://github.com/apache/incubator-openwhisk/blob/master/docs/actions-node.md#creating-asynchronous-actions.
return(new Promise(function(resolve, reject) {
transporter.sendMail(mail, function (err, info) {
if (err) {
const ret = {status: 'OK'};
} else {
const ret = {status: 'KO'};
}
transporter.close();
resolve(ret);
}}));

Using Jade mail template in Nodemailer

I have a contactform created with Nodemailer. Now I want a Jade tempate mail being send whenever the customer submits the contactform.
I already got it working and the mail template is already being send, but somehow the content of the Jade file is being presented in the 'subject' header of the mail. And everyting is presented with all the HTML tags. So, somewhere it goes wrong.
This is my Nodemailer code:
router.post('/contact/send', function(req, res) {
var transporter = nodeMailer.createTransport({
service : 'Gmail',
auth : {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_PASS
}
});
var mailOptions = {
from: req.body.name + ' <' + req.body.email + '>',
to: 'xxxxx#gmail.com',
subject:'Website verzoek',
text:'Er is een website verzoek binnengekomen van '+ req.body.name+' Email: '+req.body.email+'Soort website: '+req.body.website+'Message: '+req.body.message,
html:'<p>Websiteverzoek van: </p><ul><li>Naam: '+req.body.name+' </li><li>Email: '+req.body.email+' </li><li>Soort website: '+req.body.website+' </li><li>Message: '+req.body.message+' </li></ul>'
};
transporter.sendMail(mailOptions, function (err, info) {
if(err) {
console.log(err);
res.redirect('/#contact');
} else {
console.log('Message send');
res.redirect('/#contact');
}
});
var toAddress = req.body.email;
var sendMail = function(toAddress, subject, content, next) {
var mailTemplate = {
from: 'xxxxxx#gmail.com',
to: toAddress,
subject: subject,
html: content
};
transporter.sendMail(mailTemplate, next);
};
var template = process.cwd() + '/views/mails/mail.jade';
fs.readFile(template, 'utf8', function(err, file) {
if (err) {
console.log('Error');
} else {
var compiledTmpl = jade.compile(file, {filename: template});
var context = {title: 'Express'};
var html = compiledTmpl(context);
sendMail(toAddress, html, function(err, response) {
if(err) {
console.log('ERROR!');
} else {
console.log('Template send');
}
});
}
});
});
The problem is a typo mistake. Your sendMail function takes subject as second paramter.
var sendMail = function(toAddress, subject, content, next) {
var mailTemplate = {
from: 'xxxxxx#gmail.com',
to: toAddress,
subject: subject,
html: content
};
transporter.sendMail(mailTemplate, next);
};
Your are passing the compiled html as a second parameter to the function. So it takes the html as header.
sendMail(toAddress, html, function(err, response) {
if(err) {
console.log('ERROR!');
} else {
console.log('Template send');
}
});
Cheers.

Resources