From my express application, I am trying to send the contact form from godaddy relay server. locally it works fine. but after I hosted with godaddy server it's not working. my local code: ( working using gmail properties )
app.post("/send_mail", function (req, res) {
let { text } = req.body;
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 25,
secure: true,
auth: {
user: "xxxxxx#gmail.com",
pass: "xxxxxxxx"
}
});
let message = {
from: "from#email.com",
to: "xxxx#gmail.com",
subject: "Enquiry from Deane Project Management",
html: `
<hr />
<h1>Request for: ${text.option || "No title"}</h1>
<span>Name: ${text.username}</span><br/>
<span>Email: ${text.email}</span><br/>
<span>Phone: ${text.phone || "No phone"}</span><br/>
<span>Message:</span><br/>
<p>${text.message || "No message"}</p>
<hr />
`
}
transporter.sendMail(message, function (err, info) {
if (err) {
console.log(err);
} else {
console.log('sent', info);
}
});
res.send(200);
});
I am taken this reference,(https://in.godaddy.com/help/send-form-mail-using-an-smtp-relay-server-953#cpanel) relay server so updated my server app.js like this: But not works. I am not getting any error as well. from from end it's shows success message. But no email received yet.
app.post("/send_mail", function(req, res) {
let {text} = req.body;
const transporter = nodemailer.createTransport({
host: 'localhost',
port: 25,
secure: false
});
let message = {
from: "from#email.com",
to: "xxxxx#gmail.com",
subject: "Enquiry from Deane Project Management",
html: `
<hr />
<h1>Request for: ${text.option||"No title"}</h1>
<span>Name: ${text.username}</span><br/>
<span>Email: ${text.email}</span><br/>
<span>Phone: ${text.phone||"No phone"}</span><br/>
<span>Message:</span><br/>
<p>${text.message||"No message"}</p>
<hr />
`
}
transporter.sendMail(message, function(err, info) {
if (err) {
console.log(err);
} else {
console.log('sent',info);
}
});
res.send(200);
})
Related
I have this code in a cloud function where I want to use nodemailer to send some notification emails.
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
user: 'mygmailaddress#gmail.com',
pass: 'apppassword'
}
})
/* Send email for custom programs to unsigned patients */
exports.sendEmailToNewPatient = functions.https.onRequest( (req, res) => {
cors( req, res, () => {
const mailOptions = {
to: req.body.userEmail,
from: 'mygmailaddress#gmail.com',
subject: `${req.body.doctorName} test!`,
text: 'Test message',
html: '<h1>Test message/h1>'
}
transporter.sendMail(mailOptions, (error, info) => {
if( error ) {
res.send(error.message)
}
const sendMailResponse = {
accepted: info.accepted,
rejected: info.rejected,
pending: info.pending,
envelope: info.envelope,
messageId: info.messageId,
response: info.response,
}
res.send(sendMailResponse)
})
})
})
I'm calling the function using a POST request made with axios, when the request is send I will get a status code of 200 and in the data object of axios response I will have this informations
data:
code: "EENVELOPE"
command: "API"
When I check my test email address to verify if the email is sent, I will not have any message as expected.
Any suggestion about?
I can see a small mistake in your code that the heading tag is not closed in the html message.
For more reference on how to send the mail using node mailer you can follow the below code.
As mentioned in the link:
const functions = require("firebase-functions");
const nodemailer = require('nodemailer');
const smtpTransport = require('nodemailer-smtp-transport');
const cors = require("cors")({
origin: true
});
exports.emailMessage = functions.https.onRequest((req, res) => {
const { name, email, phone, message } = req.body;
return cors(req, res, () => {
var text = `<div>
<h4>Information</h4>
<ul>
<li>
Name - ${name || ""}
</li>
<li>
Email - ${email || ""}
</li>
<li>
Phone - ${phone || ""}
</li>
</ul>
<h4>Message</h4>
<p>${message || ""}</p>
</div>`;
var sesAccessKey = 'YOURGMAIL#gmail.com';
var sesSecretKey = 'password';
var transporter = nodemailer.createTransport(smtpTransport({
service: 'gmail',
auth: {
user: sesAccessKey,
pass: sesSecretKey
}
}));
const mailOptions = {
to: "myemail#myemail.com",
from: "no-reply#myemail.com",
subject: `${name} sent you a new message`,
text: text,
html: text
};
transporter.sendMail(mailOptions, function(error, info){
if(error){
console.log(error.message);
}
res.status(200).send({
message: "success"
})
});
}).catch(() => {
res.status(500).send("error");
});
})
;
For more information you can check the blog , thread and documentation where brief explanations including code is provided.
If all above has been followed well then you can check this thread for further details:
First of all, you have to enable the settings to allow less secure apps for the gmail account that you are using. Here is the link.
Secondly, Allow access for "Display Unlock captcha option" (Allow access to your Google account). Here is the link.
As mentioned by Frank van Puffelen ,here you can process POST data in Node.js using console.log(req.body.userEmail) for reference you can check link.
i try to send an email with nodemailer and outlook but after multi try and multiple forum i visited, i found nothing.
I try all the solution i've seen but nothing work. can you help me please
this is my code :
{
const path = require('path');
var message=fs.readFileSync(path.join(__dirname+'../../../asset/templateMail/mail.html')).toString();
message=message.replace('${user}', user.confirmation_code.toString());
var nodemailer = require("nodemailer");
const transporter = nodemailer.createTransport(
{
//service :"Outlook365",
//pool:true,
host: 'SMTP.office365.com',
port: '587',
secure:false,
auth: { user: "it-factory-flex#outlook.fr", pass: process.env.NODEMAILLERPASS },
//secureConnection: false,
//requireTLS:true,
//tls: { ciphers: 'SSLv3' }
}
);
var mailOptions = {
name:"FlexOffice",
from: "it-factory-flex#outlook.com",
to: user.email,
subject: "FlexOffice: Code d'inscription",
html: message
}
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
}
all the commented part are my test
and i always got this:
Error: Connection timeout
at SMTPConnection._formatError (/home/romain/bred/flex-server/node_modules/nodemailer/lib/smtp-connection/index.js:784:19)
at SMTPConnection._onError (/home/romain/bred/flex-server/node_modules/nodemailer/lib/smtp-connection/index.js:770:20)
at Timeout.<anonymous> (/home/romain/bred/flex-server/node_modules/nodemailer/lib/smtp-connection/index.js:235:22)
solved, due to my network who block the flux.
I have this email feature which works fine on my localhost:/3000 but not on the production server. What is stranger, it works fine even on the production server to email as long as it's the simple email and not the email with attachment version. I can't tell what's different in production that's causing it to fail. I'm getting the error message:
502 Bad Gateway nginx/1.14.0 (Ubuntu)
The feature is to filter a database and email the query output to the user. Where do I even begin to troubleshoot?
the file which works contact.handlebars
<form action="/emailfromcustomer" method="post">
<input type="name" class="form-control" name="customerfirst" placeholder="First Name">
<input type="submit" class="btn btn-dark" value="Send Inquiry"></input>
</form>
file which doesnt work email.handlebars
<form action="/email" method="post">
<input id="date1" name="date1">
<input type="submit" class="btn btn-success" value="Send the email"></input>
</form>
routes:
router.get('/contact', (req, res, next) => {
res.render('contact');
});
router.get('/email', function(req, res) {
res.render('email')
});
router.post('/emailfromcustomer', function(req, res) {
var customerfirst = req.body.customerfirst || 'NoFirstNmae'
const nodemailer = require("nodemailer");
main().catch(console.error);
// async..await is not allowed in global scope, must use a wrapper
async function main() {
// Generate test SMTP service account from ethereal.email
// Only needed if you don't have a real mail account for testing
let testAccount = await nodemailer.createTestAccount();
let transporter = nodemailer.createTransport({
host: "myhost.com",
port: 465,
/*587 25*/
secure: true, // true for 465, false for other ports
auth: {
user: 'theuser',
pass: 'somepass'
}
});
let info = await transporter.sendMail({
from: 'someemail#gmail.com',
to: 'myemailgmail.com', // list of receivers
subject: "You got mail", // Subject line
text: "Customer " + customerfirst
});
res.send('Your message has been sent!')
}
});
router.post('/email', function(req, res) {
sendEmail();
function sendEmail() {
var thequery1 = `select top 4 product,units_sold,manufacturing_price
FROM table
where 1 = 1 `
if (req.body.date1) {
thequery1 = thequery1 + ' and Date >= #date1 '
}
var date1 = req.body.date1 || '2000-01-01'
let promise = queries.queryTablewithPararams(thequery1, date1);
promise.then(
data => {
var csv = [];
const fields = ['product', 'units_sold', 'manufacturing_price'];
const json2csvParser = new Json2csvParser({
fields
});
csv = json2csvParser.parse(data);
var path = './public/serverfiledownload/file' + Date.now() + '.csv';
fs.writeFile(path, csv, function(err, data) {
if (err) {
throw err;
} else {
main(csv, path).catch(console.error);
res.send('it sent email')
}
});
}
);
}
const nodemailer = require("nodemailer");
// async..await is not allowed in global scope, must use a wrapper
async function main(csv, path) {
// Generate test SMTP service account from ethereal.email
// Only needed if you don't have a real mail account for testing
let testAccount = await nodemailer.createTestAccount();
let transporter = nodemailer.createTransport({
host: "myhost.com",
port: 465,
/*587 25*/
secure: true, // true for 465, false for other ports
auth: {
user: 'theuser',
pass: 'somepass' // ''generated ethereal password
}
});
let info = await transporter.sendMail({
from: 'someemail#gmail.com', // sender address
to: req.body.inputemail, // list of receivers
subject: "dynamic attachment", // Subject line
text: "Hello world?", // plain text body
attachments: [{ // utf-8 string as an attachment
filename: path,
content: csv
}],
html: `<b>Please find your report attached!</b>` // html body
});
console.log("Message sent: %s", info.messageId);
// Preview only available when sending through an Ethereal account
console.log("Preview URL: %s", nodemailer.getTestMessageUrl(info));
}
});
/etc/nginx/conf.d/server.conf
#
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
}
}
#
Hi if you are using nginx server then in your config file you have to set proxy for your node api. In /etc/nginx/sites-available/default.conf
server {
//...some_stuff
location /node_api {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
and use route as :
router.get('/node_api/email', function(req, res) {
//send_mail
});
I'm aware that Firebase doesn't allow you to send emails using 3rd party email services. So the only way is to send through Gmail.
So I searched the internet for ways, so here's a snippet that works and allows me to send email without cost.
export const shareSpeechWithEmail = functions.firestore
.document("/sharedSpeeches/{userId}")
.onCreate(async (snapshot, context) => {
// const userId = context.params.userId;
// const data = snapshot.data();
const mailTransport = nodemailer.createTransport(
`smtps://${process.env.USER_EMAIL}:${process.env.USER_PASSWORD}#smtp.gmail.com`
);
const mailOptions = {
to: "test#gmail.com",
subject: `Message test`,
html: `<p><b>test</b></p>`
};
try {
return mailTransport.sendMail(mailOptions);
} catch (err) {
console.log(err);
return Promise.reject(err);
}
});
I want to create a template, so I used this package called email-templates for nodemailer.
But the function doesn't get executed in Firebase Console and it doesn't show an error and shows a warning related to "billing".
export const shareSpeechWithEmail = functions.firestore
.document("/sharedSpeeches/{userId}")
.onCreate(async (snapshot, context) => {
const email = new Email({
send: true,
preview: false,
views: {
root: path.resolve(__dirname, "../../src/emails")
// root: path.resolve(__dirname, "emails")
},
message: {
// from: "<noreply#domain.com>"
from: process.env.USER_EMAIL
},
transport: {
secure: false,
host: "smtp.gmail.com",
port: 465,
auth: {
user: process.env.USER_EMAIL,
pass: process.env.USER_PASSWORD
}
}
});
try {
return email.send({
template: "sharedSpeech",
message: {
to: "test#gmail.com",
subject: "message test"
},
locals: {
toUser: "testuser1",
fromUser: "testuser2",
title: "Speech 1",
body: "<p>test using email <b>templates</b></p>"
}
});
} catch (err) {
console.log(err);
return Promise.reject(err);
}
});
You can definitely send emails using third party services and Cloud Functions, as long as your project is on the Blaze plan. The official provided samples even suggest that "if switching to Sendgrid, Mailjet or Mailgun make sure you enable billing on your Firebase project as this is required to send requests to non-Google services."
https://github.com/firebase/functions-samples/tree/master/quickstarts/email-users
The key here, no matter which email system you're using, is that you really need to upgrade to the Blaze plan in order to make outgoing connections.
you can send emails by using nodemailer:
npm install nodemailer cors
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const nodemailer = require('nodemailer');
const cors = require('cors')({origin: true});
admin.initializeApp();
/**
* Here we're using Gmail to send
*/
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'yourgmailaccount#gmail.com',
pass: 'yourgmailaccpassword'
}
});
exports.sendMail = functions.https.onRequest((req, res) => {
cors(req, res, () => {
// getting dest email by query string
const dest = req.query.dest;
const mailOptions = {
from: 'Your Account Name <yourgmailaccount#gmail.com>', // Something like: Jane Doe <janedoe#gmail.com>
to: dest,
subject: 'test', // email subject
html: `<p style="font-size: 16px;">test it!!</p>
<br />
` // email content in HTML
};
// returning result
return transporter.sendMail(mailOptions, (erro, info) => {
if(erro){
return res.send(erro.toString());
}
return res.send('Sended');
});
});
});
See also here
Set Security-Level to avoid error-messages:
Go to : https://www.google.com/settings/security/lesssecureapps
set the Access for less secure apps setting to Enable
Refer to
Call a sendMail() cloud function directly via functions.https.onCall(..) :
As #Micha mentions don't forget to enable Less Secure Apps for the outgoing email: https://www.google.com/settings/security/lesssecureapps
const functions = require('firebase-functions');
const nodemailer = require('nodemailer');
let mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'supportabc#gmail.com',
pass: '11112222'
}
});
exports.sendMail = functions.https.onCall((data, context) => {
console.log('enter exports.sendMail, data: ' + JSON.stringify(data));
const recipientEmail = data['recipientEmail'];
console.log('recipientEmail: ' + recipientEmail);
const mailOptions = {
from: 'Abc Support <Abc_Support#gmail.com>',
to: recipientEmail,
html:
`<p style="font-size: 16px;">Thanks for signing up</p>
<p style="font-size: 12px;">Stay tuned for more updates soon</p>
<p style="font-size: 12px;">Best Regards,</p>
<p style="font-size: 12px;">-Support Team</p>
` // email content in HTML
};
mailOptions.subject = 'Welcome to Abc';
return mailTransport.sendMail(mailOptions).then(() => {
console.log('email sent to:', recipientEmail);
return new Promise(((resolve, reject) => {
return resolve({
result: 'email sent to: ' + recipientEmail
});
}));
});
});
Thanks also to: Micha's post
You can send for free with Firebase extensions and Sendgrid:
https://medium.com/firebase-developers/firebase-extension-trigger-email-5802800bb9ea
DEPRECATED: https://www.google.com/settings/security/lesssecureapps
Use "Sign in with App Passwords": https://support.google.com/accounts/answer/185833?hl=en to create an app password.
follow the steps in the link then use the given password with your user in mailTransport:
const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'user#gmail.com',
pass: 'bunchofletterspassword'
}
});
I've developed my web app using ReactJS and I'm using as a server ExpressJS. Everithing was working fine until I implemented a /contactme endpoint which just must work as restful POST to send an email. I mean, my aim is just publishing an endpoint to send mails.
I'm using express-mailer for the job, but when I try to send an email using send method I'm getting this error:
message:"No default engine was specified and no extension was provided."
stack:"Error: No default engine was specified and no extension was provided.\n at new View (c:\React\web.facundolarocca.com\node_modules\express\lib\view.js:62:11)\n at EventEmitter.render (c:\React\web.facundolarocca.com\node_modules\express\lib\application.js:569:12)\n at sendMail (c:\React\web.facundolarocca.com\node_modules\express-mailer\lib\express-mailer.js:55:5)\n at Object.exports.extend.createSend [as send] (c:\React\web.facundolarocca.com\node_modules\express-mailer\lib\express-mailer.js:98:7)\n at c:\React\web.facundolarocca.com\server.js:28:16\n at Layer.handle [as handle_request] (c:\React\web.facundolarocca.com\node_modules\express\lib\router\layer.js:95:5)\n at next (c:\React\web.facundolarocca.com\node_modules\express\lib\router\route.js:131:13)\n at Route.dispatch (c:\React\web.facundolarocca.com\node_modules\express\lib\router\route.js:112:3)\n at Layer.handle [as handle_request] (c:\React\web.facundolarocca.com\node_modules\express\lib\router\layer.js:95:5)\n at c:\React\web....
I understand that ExpressJS needs some view engine to return html files, but in my case I'm going to respond a simpli JSON.
Below is my code:
var path = require('path');
var express = require('express');
var app = express();
var mailer = require('express-mailer');
var PORT = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, '/build')));
mailer.extend(app, {
from: 'no-reply#gmail.com',
host: 'smtp.gmail.com',
secureConnection: true,
port: 465,
transportMethod: 'SMTP',
auth: {
user: '*********#gmail.com',
pass: '**********'
}
});
app.get('/', function (req, res) {
//this is working fine
res.sendFile(__dirname + '/build/index.html')
});
app.get('/contactme', function (req, res) {
try {
app.mailer.send('test', {
to: 'myemaila#myemail.com.ar',
subject: 'some subject'
}, function (err) {
if (err) {
console.log(err);
res.status(400).json('There was an error sending the email');
} else {
res.status(200).json('Email Sent');
}
});
} catch (error) {
//Error is raised here
res.status(500).json(error);
}
});
app.listen(PORT, function (error) {
if (error) {
console.error(error);
} else {
console.info("==> 🌎 Listening on port %s. Visit http://localhost:%s/ in your browser.", PORT, PORT);
}
});
So I have two problems, on one hand is how to avoid this error , but in the other hand is why do I need an egine view .
I just expect, from the client side, to read the status code to show some message. I thought I could be able to implement in the same way as I was using restify.
My solution was to move to nodemailer. Here is the whole code:
package.json
{
"dependencies": {
"express": "^4.14.0",
"nodemailer": "^2.7.0",
"nodemailer-smtp-transport": "^2.7.2"
}
}
Code
server.post('/contactme', (req, res) => {
try{
let mailer = require('nodemailer')
let smtpTransport = require('nodemailer-smtp-transport')
let options = {
service: config.mailService.service,
secure: true,
auth: {
user: config.mailService.user,
pass: config.mailService.password
}
}
let transport = mailer.createTransport(smtpTransport(options))
let mail = {
from: 'from',
to: 'to',
subject: 'subject',
html: 'body'
}
transport.sendMail(mail, (error, response) => {
transport.close()
if (error) {
res.json(400, {error});
} else {
res.json(200, {response: 'Mail sent.'});
}
})
} catch(error) {
res.json(400, {error});
}
})