Calling NodeJS function from JS function - javascript

I am doing a project based on firebase and I need to link a server-side function that sends an email to the client-side script.
This is my server-side index.js file
const functions = require('firebase-functions');
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'xxx#gmail.com',
pass: 'password'
}
});
var mailOptions = {
from: 'xxx#gmail.com',
to: 'xxx#gmail.com',
subject: 'Sending Email using Node.js',
text: 'That was easy!'
};
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
I am wondering how I could have a button in html call a function in the script that will call the transporter.sendMail. I have never touched node js before so please excuse my lack of knowledge.
If this helps firebase setup my folders to be separated by functions and public for the server-side and client-side files

First initialize your HTML page with jQuery and on submitting the form send an Ajax request to the server as follows
$(document).ready(function() {
$("#formoid").submit(function(event) {
event.preventDefault();
$.ajax({
url: 'http://xxxxxxx.com/contact', // url where to submit the request
type : "POST", // type of action POST || GET
dataType : 'json', // data type
data : $("#formoid").serialize(), // post data || get data
success : function(result) {
$('#formoid')[0].reset();
},
error: function(xhr, resp, text) {
console.log(xhr, resp, text);
}
})
});
});
Create a route called contact in your NodeJS server and listen for the contact request with All parameters required for your need. In the following case am using an express server and body parser to parse the data from incoming request
app.post('/contact', (req, res) => {
var transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "xxxxx",
pass: "xxxxx"
}
});
var mailOptions = {
from: req.body.email,
to: 'xxxxx#xx.com',
subject: 'Contact form',
text: 'From: ' + req.body.name + '\n Email: ' + req.body.email + '\nMessage: ' + req.body.msg
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
res.status(500).json({
message: "Error",
error: error
})
} else {
res.status(200).json({
message: "Its working",
response: info.response
})
}
});
});
In the above request am sending the name:as name, email: as email and message: as msg

Related

How to send emails using smtp node mailer

I was trying to send a test email using SMTP on node mailer but it says connection timed out. the snippet I was using is down below.
const nodemailer = require("nodemailer");
async function main() {
const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
pool:true,
host: '213.55.96.132',
port: 25,
auth: {
user: "user#ethionet.et",
pass: "drafgthsjaid321##"
},
pool: true,
logger :true,
debug:true,
secure: false,
})
transporter.verify(function(error, success) {
if (error) {
console.log(error);
} else {
console.log('Server is ready to take our messages');
}
});
let mailOptions = {
from: "user#ethionet.et",
to: ["someemail#gmail.com",],
subject: 'Test email',
text: `Hello world`
};
transporter.sendMail(mailOptions, function(err, data) {
if (err) {
console.log("Error " + err);
} else {
console.log("Email sent successfully");
}
});
}
main().catch(console.error);
I don't mind leaking the credentials and it works when i try and send emails through SMTP from here.
why is this faliing?
You need to read a little more than the first page of documentation :)
Create your message
let message = {
...,
from: 'mailer#nodemailer.com', // listed in rfc822 message header
to: 'daemon#nodemailer.com', // listed in rfc822 message header
envelope: {
from: 'Daemon <deamon#nodemailer.com>', // used as MAIL FROM: address for SMTP
to: 'mailer#nodemailer.com, Mailer <mailer2#nodemailer.com>' // used as RCPT TO: address for SMTP
}
}
Send the message through the transporter
transporter.sendMail(...).then(info=>{
console.log('Preview URL: ' + nodemailer.getTestMessageUrl(info));
});
Turns out the problem was that my ISP blocks port 25.

Using nodemailer to send emails not working

I am creating a project with authentication and after registration this function is supposed to call
exports.sendEmail = async (req, res, next) => {
try {
const mailText = `<body style="text-align: center"><h1>Name Of Company</h1><p>This email was automatically sent to you to confirm your account at<b>Name of Company</b><br />Please press on this link to confirm your account</p></body>`;
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "example#gmail.com",
pass: "password",
},
});
const options = {
from: "example#gmail.com",
to: "user#gmail.com",
subject: "Confirm Your Email",
html: mailText,
};
transporter.sendMail(options, function (err, info) {
if (err) {
console.log(err);
return res.status(500).json({
err: err,
});
}
return res.status(200).json({
success: true,
data: "Sent: " + info.response,
});
});
} catch (error) {
console.log("Error");
}
}
But the email is not sending and neither the try or catch are sending anything back.
I have also turned on the less secure apps in gmail
How do I fix this?

Next.JS and Nodemailer, Sending an email from contact form

I have a problem with my contact form in next.js, I don't have any errors (that are shown), everything worked untill deployment (on Vercel). I fetch my form, and have status 200, but I do not recive my email on Gmail. Also I don't recive any additional information.
I've recived emails, when I tested my app on "dev" and "build".
I've also have "less secure apps" option in Gmail account.
Here's my code in Next.JS:
fetch method in contact.js:
fetch("/api/contact", {
method: "POST",
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: mailName,
email: mailAddress,
text: mailText,
}),
}).then((res) => {
console.log("Fetch: ", res);
res.status === 200
?
router.push("/success")
: router.push("/error");
in api/contact.js
require("dotenv").config();
const nodemailer = require("nodemailer");
export default (req, res) => {
const { name, email, text } = req.body;
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL,
pass: process.env.PASSWORD,
},
});
const mailOption = {
from: `${email}`,
to: `${process.env.EMAIL}`,
subject: `New mail from ${email}`,
text: `
${name} wrote:
${text}
`,
};
transporter.sendMail(mailOption, (err, data) => {
if (err) {
console.log(err);
} else {
console.log("mail send");
}
});
console.log(name, email, text);
res.send("success");
};
Please help
Since your code runs fine in local and not in the deployment environment I have two suggestions.
First, make sure you have all the environment variables set.
Secondly, the way you have written your code it will always return success because transporter.sendMail is asynchronous and res.send is outside of it.
Change like,
transporter.sendMail(mailOption, (err, data) => {
if (err) {
console.log(err);
res.send("error" + JSON.stringify(err));
} else {
console.log("mail send");
res.send("success");
}
});

How to add an event listener to trigger a server side email function?

So, I have an express application serving a static index.html page, and a function in my app.js file that sends an email when the server starts up.
What I'd like to do is send the email only when a user hits a 'submit' button on a form (and the form is successfully sent, so on success-confirmation, preferably).
How do I get my program to "listen" for an onClick / form-successfully-sent event and then run the server side code I have that sends an email?
const http = require('http');
const nodemailer = require('nodemailer');
const express = require('express');
const app = express();
const port = 8080;
app.listen(port, () => console.log(`App listening on port ${port}!`));
app.use(express.static('public'));
app.get('/', (req, res) => res.send('index.html'))
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'USERNAME#GMAIL.COM',
pass: 'PASSWORD'
}
});
const mailOptions = {
from: 'USERNAME#GMAIL.COM',
to: 'USERNAME2#GMAIL.COM',
subject: 'Sending Email using Node.js',
text: 'That was easy!'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
})
I would like to trigger the transporter.sendMail method/function when a user successfully submits a form.
Thanks!
Add a route on your server that will handle form submissions. There are multiple ways to do this, however, as a simple example, look at the code below:
app.post("/send", function(req, res, next) {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "test-email#gmail.com",
pass: "test123"
}
});
const mailOptions = {
from: `${req.body.email}`,
to: "test-email#gmail.com",
subject: `${req.body.name}`,
text: `${req.body.message}`,
replyTo: `${req.body.email}`
};
transporter.sendMail(mailOptions, function(err, res) {
if (err) {
console.error("there was an error: ", err);
} else {
console.log("here is the res: ", res);
}
});
});
Then, in your client application, call the function below (or something similar) to send the client-side data to the newly-created endpoint:
function sendEmail(name, email, message) {
const options = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
name: name,
email: email,
message: message
})
};
return fetch("/send", options)
.then(res => res.json())
.then(res => {
console.log("here is the response: ", res);
})
.catch(err => {
console.error("here is the error: ", err);
});
}
You'll have to set up an API endpoint
app.post('/send-mail', function (req, res) {
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
})
})
And then call that from your form code.
onSubmit() {
fetch('/send-mail', {
method: 'POST'
})
}
Edit: typo.
Put this part inside a function and call it when you handle your form request, create parameters in function as needed for f.ex. mailOptions information
function sendEmail(){
const mailOptions = {
from: 'USERNAME#GMAIL.COM',
to: 'USERNAME2#GMAIL.COM',
subject: 'Sending Email using Node.js',
text: 'That was easy!'
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
})
}
const bodyparser = require("body-parser");
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: `${req.body.username}`,
pass: `${req.body.password}`
}
});
const mailOptions = {
from: `${req.body.email}`,
to: 'USERNAME2#GMAIL.COM',
subject: ``${req.body.subject},
text: `${req.body.message}`
};
app.post("/login", (req, res)=>{
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
})
})
remember to do npm install --save body-parser and also app.use(bodyparser.json())

Nodemailer: Greeting never received

When trying to send email within Node using Nodemailer (https://github.com/nodemailer/nodemailer), the call to the sendMail of the Nodemailer transporter is raising the error Greeting never received when using in conjunction with an Ethereal test email account.
I have tried using both a "callback approach" and also an "async/await" approach, but the same error is thrown in both scenarios. Both examples are pretty much straight from the working examples in the Nodemailer documentation. Maybe I'm missing something simple? :)
Here is the "callback approach" code that is producing the error:
it('can send email with a dynamic test account', done => {
nodemailer.createTestAccount((err, account) => {
const transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
auth: {
user: account.user, // generated ethereal user
pass: account.pass // generated ethereal password
}
});
const mailOptions = {
from: '"Fred Foo 👻" <foo#example.com>', // sender address
to: 'bar#example.com, baz#example.com', // list of receivers
subject: 'Hello ✔', // Subject line
text: 'Hello world?', // plain text body
html: '<b>Hello world?</b>' // html body
};
// send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321#example.com>
// Preview URL: https://ethereal.email/message/WaQKMgKddxQDoou...
done();
});
});
}).timeout(10000);
And here is the stacktrace of the error:
{ Error: Greeting never received
at SMTPConnection._formatError (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:606:19)
at SMTPConnection._onError (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:579:20)
at Timeout._greetingTimeout.setTimeout (/Users/<username>/projects/personal/learning-tests/javascript/nodemailer/node_modules/nodemailer/lib/smtp-connection/index.js:520:22)
at ontimeout (timers.js:498:11)
at tryOnTimeout (timers.js:323:5)
at Timer.listOnTimeout (timers.js:290:5) code: 'ETIMEDOUT', command: 'CONN' }
And some additional info:
node version: 8.11.2
nodemailer version: 4.6.4
operating system: OSX version 10.12.6
In my case I needed to set the secure key to true on the transporter object and then it worked.
let transporter = nodemailer.createTransport({
host: "mail.hostname.com",
port: 465,
secure: true, // true for 465, false for other ports
auth: {
user: 'user#hostname.com', // generated ethereal user
pass: 'password', // generated ethereal password
}
});
In my case, when I have changed port 586 to 587, then it worked.
Check your internet connection probably its down .
below is an example with Etheral Email with typescript
import * as nodemailer from "nodemailer";
export const sendEmail = async (recipient: string, url: string, linkText: string) => {
nodemailer.createTestAccount((err, account) => {
if (err) {
console.log(err);
}
const transporter = nodemailer.createTransport({
host: account.smtp.host,
port: account.smtp.port,
secure: account.smtp.secure,
auth: {
user: account.user,
pass: account.pass
}
});
const message = {
from: "Sender Name <sender#example.com>",
to: `Recipient <${recipient}>`,
subject: "Nodemailer is unicode friendly ✔",
text: "Hello to myself!",
html: `
<html>
<body>
<p>Testing sparkpost API</p>
${linkText}
</body>
</html>`
};
transporter.sendMail(message, (err, info) => {
if (err) {
console.log("Error occurred. " + err.message);
}
console.log("Message sent: %s", info.messageId);
// Preview only available when sending through an Ethereal account
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
});
});
};
In my case the smtpd_recipient_restrictions in /etc/postfix/main.cf was causing this issue.
Changed it to:
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
and now it works!
const transporter = nodemailer.createTransport({
service: 'config.mail.service',
port: 8000,
auth: {
user: 'config.mail.username',
pass: 'config.mail.password'
}
});
module.exports = {
activationsMail: function (req) {
// setup email data with unicode symbols
const mailOptions = {
from: '"Ecommerce" <noreply#ecommerce.com>', // sender address
to: req.body.email, // list of receivers
subject: 'Ecommerce Account Activate', // Subject line
html: '<div>Please click here to active your account.</div>' // html body
};
console.log('PORT', req.headers.host);
// send mail with defined transport object
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log('Email Error', error);
} else {
console.log('Email sent: ' + info.response);
}
})
}
};
const transporter = nodemailer.createTransport({
service: config.mail.service,
port: 8000,
auth: {
user: config.mail.username,
pass: config.mail.password
}
});
module.exports = {
activationsMail: function (req, data) {
// setup email data with unicode symbols
const link = 'http://' + req.headers.host + '/user/activate/' + data.verifyCode;
console.log('CODE :', data.verifyCode);
const mailOptions = {
from: '"Ecommerce" <noreply#ecommerce.com>', // sender address
to: req.body.email, // list of receivers
subject: 'Please confirm your Email account', // Subject line
html: '\n\n' + 'Please Click here to verify <a href=' + link + '> Click here</a>'
};
//console.log('PORT', req.headers.host);
// send mail with defined transport object
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log('Email Error', error);
} else {
// callback(true);
console.log('Email sent: ' + info.response);
}
})
};

Categories

Resources