How to make Nodemailer trigger a seperate .js script - javascript

So i have the main nodejs server file (myserver.js)
const express = require("express");
const app = express();
const nodemailer = require("nodemailer");
const port = 80;
const vectorExpress = require("./node_modules/#smidyo/vectorexpress-nodejs/index");
const fs = require("fs");
var cors = require("cors");
app.use(cors());
app.use(express.json())
var randomnum = require('./randomnum.js');
var number = randomnum.number;
app.post('/mail', (req, res)=>{
console.log(req.body)
let transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '',
pass: ''
}
});
const mailOptions = {
from: req.body.email,
to: 'naizeylines.info#gmail.com',
subject: `Order from ${req.body.name}`,
text:
`${req.body.name}
${req.body.street}
${req.body.postcode} ${req.body.town}
${req.body.country}
Quantity: ${req.body.quantity}
Additional information:
${req.body.message}
Shipping address:
${req.body.name2}
${req.body.street2}
${req.body.postcode2} ${req.body.town2}
${req.body.country2}
${req.body.phone2}
Email: ${req.body.email}
Phone number: ${req.body.phone}
File number: ${number}
`,
attachments: [{ // utf-8 string as an attachment
path: `${number}.svg`,
},
{
path: `${number}.dxf`,
},
]
}
transporter.sendMail(mailOptions, (error, info)=>{
if(error){
console.log(error);
res.send('error');
}else{
console.log('Email sent:' + info.response);
res.send('success');
}
})
})
var bodyParser = require("body-parser");
and a seperate script file (randomnum.js)
function randomnumber() {
return Math.floor(100000 + Math.random() * 900000);
}
var number = randomnumber();
exports.number = number;
console.log(number);
i would like to have it so that everytime nodemailer sends an email the main script would run the randomnum.js so that i would get a new random number generated. been trying for a few days now but i think im in over my head with my limited knowledge.

Based on code you provided, I see one obvious issue. You are defining randomnum out of the POST request. Also If i were you I'd generate random number inside of the myserver.js file.
Try this bit of code:
app.post('/mail', (req, res)=>{
var number = Math.floor(100000 + Math.random() * 900000)
let transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: '',
pass: ''
}
}); REST OF YOUR POST REQUEST LOGIC.....

Put Nodemailer code in separate file and export in main.js file and use with pass your data from main.js file
Hope this code will help to you
const nodemailer = require("nodemailer");
import * as dotenv from "dotenv";
dotenv.config({});
export class SendEmail {
public static send(data) {
const transport = nodemailer.createTransport({
name: process.env.SMTP_HOST,
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT,
auth: {
user: process.env.SMTP_USER_NAME,
pass: process.env.SMTP_PASSWORD,
},
pool: true, // use pooled connection
rateLimit: true, // enable to make sure we are limiting
maxConnections: 1, // set limit to 1 connection only
maxMessages: 3, // send 3 emails per second
});
var mailOptions = {
from: process.env.FROM,
html: data.html,
replyTo: process.env.REPLY_TO,
to: data.to,
subject: data.subject,
text: data.text,
};
transport.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log("Message sent: %s", info.messageId);
return;
});
}
}

Related

ExpressJs - NODEMAILER not sending email on production mode using vercel

im really stuck here. i already try a couple hours to solve this. on development, nodemailer works for sending email, like verification or reset password. but when i deploy or on production mode using vercel, nodemailer not work. can somebody help me? please? i really stuck here. thank you. here's the code
const nodemailer = require("nodemailer");
const fs = require("fs");
const mustache = require("mustache");
const path = require("path");
const gmail = require("../config/gmail");
module.exports = {
sendMail: (data) => {
// eslint-disable-next-line no-new
new Promise((resolve, reject) => {
const transporter = nodemailer.createTransport({
service: "gmail",
host: "smtp.gmail.com",
port: 465,
auth: {
type: "OAuth2",
user: process.env.MAIL_USERNAME,
pass: process.env.APP_PASSWORD,
clientId: gmail.clientId,
clientSecret: gmail.clientSecret,
refreshToken: gmail.refreshToken,
accessToken: gmail.accessToken,
},
secure: "true",
});
const filePath = path.join(
__dirname,
`../../src/templates/email/${data.template}`
);
const fileTemplate = fs.readFileSync(filePath, "utf8");
const mailOptions = {
from: '"Event Organizing" <arkawebdev1#gmail.com>',
to: data.to,
subject: data.subject,
html: mustache.render(fileTemplate, { ...data }),
};
transporter.sendMail(mailOptions, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
},
};

Problems sending mail to gmail with nodemailer

I'm trying to add a contact form in my website using nodemailer.
With plain-text, the email was sent (with the cmd node server.js), but since I have added a form in my html and tried to send the "req.bodies" using a route, it doesn't work anymore and I have the following error : Error: Missing credentials for "PLAIN".
Here are my codes :
Index.js
var express = require("express");
var router = express.Router();
const nodemailer = require("nodemailer");
/* GET home page. */
router.get("/", function (req, res, next) {
res.render("index", { title: "Express" });
});
router.post("/send-email", async function (req, res, next) {
"use strict";
var email = req.body.email;
var name = req.body.name;
var message = req.body.message;
var transporter = nodemailer.createTransport({
// host: "smtp.gmail.com",
service: "gmail",
// secure : false,
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD,
},
});
console.log("message :", req.body.message, "email :", req.body.email);
// send mail with defined transport object
var mailOptions = {
from: email,
to: process.env.EMAIL,
subject: "Nouveau mail contact de " + name, // Subject line
text: name + "0102030405" + message,
};
transporter.sendMail(mailOptions, function (error, response) {
if (error) {
console.log(error);
} else {
res.redirect("/");
}
});
});
module.exports = router;
Server.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const port = 3000;
require("dotenv").config();
app.use(bodyParser.json());
const nodemailer = require("nodemailer");
app.listen(port, () => {
console.log(`Server running on ${port}`);
});
app.use("/index", require("./routes/index"));
// let transport = nodemailer.createTransport({
// service: "gmail",
// auth: {
// user: process.env.EMAIL,
// pass: process.env.PASSWORD,
// },
// });
// let mailOptions = {
// from: '"Fred Foo đź‘»" <process.env.EMAIL>', // sender address
// to: "process.env.EMAIL", // list of receivers
// subject: "Hello âś”", // Subject line
// text: "Hello world?", // plain text body
// html: "<b>Hello world?</b>", // html body
// };
// transport.sendMail(mailOptions, function (err, data) {
// if (err) {
// console.log("Error Occurs");
// } else {
// console.log("Email sent !!");
// }
// });
html
<form action="/send-email" method="POST">
Your Name:
<input type="text" name="name">
Email Address:
<input type="email" name="email" placeholder="Email">
Message:
<textarea name="message"></textarea>
<input type="submit" value="Submit">
</form>
Body-Parser doesn't seem to work because it is strikeout.
“less secure” apps is enabled on my gmail account
Thank you very much for your help !
EDIT : I think it's because it doesn't recognize my process.env because when I directly write them, it works.
I put my file .env in the same directory but it still does not recognize them.

react add data from MongoDB to email

pretty new to react only been doing it for a couple of weeks and I'm working on a project for personal use to send an email to my email using nodemailer which I have managed to do. the next part I want to do is add data to the email that will come from my MongoDB database like the order number, customer name and status of the job I've searched high and low on youtube and google and not really finding anything on the issue
also, it only runs when I type node server.js and then it automatically sends the email which I don't want I want it to run when submit is clicked when a status is updated in the database.
Here is the code for what I have on server.js
require('dotenv').config();
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
});
let mailOptions = {
from: 'group2021#gmail.com',
to: 'edge#gmail.com',
subject: 'Project Update',
text: 'Hello {{name}} please find this email as an update to you project.'
};
transporter.sendMail(mailOptions, function(err, data) {
if(err) {
console.log('Error Occured!', err);
} else {
console.log('Email Sent!')
}
});
I'm not sure how your application looks like, I assume it's SPA react application.
I suggest you to create simple http server using Expressjs and creating endpoint which you will call from the client (react app) e.g. (the code is not tested is just an example)
const express = require('express');
const app = express();
const port = 3000;
const nodemailer = require('nodemailer');
app.get('/mail/:someID', async (req, res) => {
// someID is identifier to find data in db
// it will come from localhost:PORT/mail/>>someID<<
const { someID } = req.params;
let data;
try {
data = await mongoCol.FindOne({
/* query */
}); // reads data from mongo
} catch (err) {
return res.status(500).json(err);
}
// prepare content
var text =
'Hello {{name}} please find this email as an update to you project.\n' + data;
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD
}
});
let mailOptions = {
from: 'group2021#gmail.com',
to: 'edge#gmail.com',
subject: 'Project Update',
text: text
};
transporter.sendMail(mailOptions, function (err, data) {
if (err) {
console.log('Error Occured!', err);
return res.status(500).json(err);
} else {
console.log('Email Sent!');
return res.sendStatus(200);
}
});
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
You should add some kind of authorization to not allow other people to send email by your server.
also, it only runs when I type node server.js and then it automatically sends the email which I don't want
This happens because your code is not in function and any time you import or start file (module) it will execute.

Using nodemailer with handlebars for dynamic emails

I'm having an issue and I can't seem to narrow down what exactly I'm doing wrong. When I run my code, this is the error I get:
[Error: ENOENT: no such file or directory, open 'C:\Users\Alex\Desktop\emailtest\main.handlebars'] { errno: -4058, code: 'ENOENT', syscall: 'open', path: 'C:\\Users\\Alex\\Desktop\\emailtest\\main.handlebars' }
Here is my code:
const nodemailer = require("nodemailer");
const hbs = require("nodemailer-express-handlebars");
const express = require("express");
const app = express();
const port = 3000;
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "useremail",
pass: "userpassword",
},
// tls: {
// rejectUnauthorized: false,
// },
});
transporter.use(
"compile",
hbs({
viewEngine: "express-handlebars",
viewPath: "views",
})
);
const mailOptions = {
from: "myemailhere",
to: "receiverpassword",
subject: "Automated Email",
template: "index",
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log("Email sent: " + info.response);
}
});
app.listen(port, () => {
console.log(
`Listening at http://localhost:${port}`
);
});
Folder structure:
server.js
views
-index.handlebars
Without using Handlebars, I can send emails just fine, but being that I need a way to fill in HTML dynamically, I think Handlebars would be the best option if I can just get it working. Any insight would be great, thanks in advance!
const path = require('path');
const handlebarOptions = {
viewEngine: {
extName: ".handlebars",
partialsDir: path.resolve(__dirname, "views"),
defaultLayout: false,
},
viewPath: path.resolve(__dirname, "views"),
extName: ".handlebars",
};
trasnporter.use('compile', hbs(handlebarOptions));

How to send message with nodemailer and email-templates?

I try to send email with nodemailer and email-templates. Now I have example from here example email templates. But when I check this code, I have error a promise was rejected with a non-error: [object Undefined]
Help me please. This is my code
var nodemailer = require('nodemailer');
var EmailTemplate = require('email-templates').EmailTemplate;
exports.sendOne = function () {
var templatesDir = config.templatesDir;
var template = new EmailTemplate(path.join(templatesDir, 'hello.jade'))
var transport = nodemailer.createTransport({
service: config.service,
auth: config.auth
});
// An example users object with formatted email function
var locals = {
email: 'example#mail.com',
name: {
first: 'Mamma',
last: 'Mia'
}
}
// Send a single email
template.render(locals, function (err, results) {
if (err) {
return console.error(err)
}
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball#spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: results.html,
text: results.text
}, function (err, responseStatus) {
if (err) {
return console.error(err)
}
console.log(responseStatus.message)
})
})
}
My error :
Warning: a promise was rejected with a non-error: [object Undefined]
at /home/project/node_modules/email-templates/lib/util.js:31:39
at FSReqWrap.oncomplete (fs.js:82:15)
From previous event: ...
Tell me please how to fix this error? thanks!
UPDATE code
exports.sendOne = function () {
var nodemailer = require("nodemailer");
var transport = nodemailer.createTransport({
service: "gmail",
auth: {
user: "test#gmail.com",
pass: "123456",
},
});
var EmailTemplate = require("email-templates").EmailTemplate;
var path = require("path");
var templateDir = path.join(__dirname, "templates", "hello");
var myTemplate = new EmailTemplate(templateDir);
var locals = {
email: "example#mail.com",
name: {
first: "Mamma",
last: "Mia",
},
};
myTemplate.render(locals, function (err, result) {
// result.html
// result.text
if (err) {
return console.error(err);
}
transport.sendMail(
{
from: "Spicy Meatball <spicy.meatball#spaghetti.com>",
to: locals.email,
subject: "Mangia gli spaghetti con polpette!",
html: results.html,
text: results.text,
},
function (err, responseStatus) {
if (err) {
return console.error(err);
}
console.log(responseStatus.message);
return responseStatus; // return from status or as you need;
}
);
});
};
I updated my code but now i have error { [Error: ENOENT: no such file or directory, stat '/path-to-my-project/templates/hello''] errno: -2, code: 'ENOENT', syscall: 'stat', path: '/path-to-my-project/templates/hello' }
I guess template rendering issue and you should return something from function (err, responseStatus){} for success
Here I assume hello.jade in templates folder and templates folder in root directory and ensure jade is using as template engine
can try it
var EmailTemplate = require('email-templates').EmailTemplate;
var path = require('path');
var templateDir = path.join(__dirname, 'templates', 'hello');
var myTemplate = new EmailTemplate(templateDir);
var locals = {
email: 'example#mail.com',
name: {
first: 'Mamma',
last: 'Mia'
}
}
myTemplate .render(locals , function (err, result) {
// result.html
// result.text
if (err) {
return console.error(err)
}
// check here what is showing in your result
transport.sendMail({
from: 'Spicy Meatball <spicy.meatball#spaghetti.com>',
to: locals.email,
subject: 'Mangia gli spaghetti con polpette!',
html: results.html,
text: results.text
}, function (err, responseStatus) {
if (err) {
return console.error(err)
}
console.log(responseStatus.message)
return responseStatus;// return from status or as you need;
})
})
Updated: As far I guess it's not nodemailer related issue it's may be template rendering issue. can check by directory or by html page.
Thanks to the previous contributions I have been able to adapt Nodemailer with the current version of email-emplates
const nodemailer = require('nodemailer');
const Email = require('email-templates');
const path = require('path');
//Nodemailer Transporter
const transport = nodemailer.createTransport({
host: "mail.mydomain.com",
port: 465,
secure: true,
auth: {
user: "noreply#mydomain.com",
pass: "841%POHYRYK%",
},
tls: {
rejectUnauthorized: false
}
});
//Generate template (Example: templates/emails/demo/index.pug)
var template = path.join(__dirname, 'templates/emails', 'demo');
var email = new Email({views: { root: template }});
var locals = {email:'myemail#gmail.com', username:'CompaCode'};
async function(){
var html = await email.render(template, locals);
//Send Email
await transport.sendMail({from: 'Apolobit <noreply#apolobit.com>', to: locals.email, subject:'Demo Subject', html});
}

Categories

Resources