sending an email by using webmail through nodemailer - node.js

iam using nodemailer to sent an email but it only working for email not for gmail
// this is config connections
"nodemailer" : {
"host": "xxx.xxxxx.com",
"port": 587,
"secure":true,
"auth": {
"user": "myuser.com",
"pass": "password"
} ,
"tls": {
"rejectUnauthorized": false,
"minVersion": "TLSv1"
},
"debug":true,
"logger":true
},
"receivingEmail": {
"feedbackemail" : "abcd#gmailcom",
"contactemail" : "abcdef#gmail.com"
}
//nodemailer configurations
const transporter = nodemailer.createTransport((config["nodemailer"]));
var mailOptions = {
from: `${config["nodemailer"]["user"]}`,
to: tomail,
subject: subject ,
text: data
};
transporter.verify(function(error, success) {
if (error) {
console.log(error,"17");
} else {
console.log("Server is ready to take our messages");
}
});
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
here iam sending an email but couldn't able to send gmail accounts
Nodemailer 6.1.1 not working with NodeJs >=12
i tried this.. could you suggest me where is the mistake?

You need to make these changes to the gmail account to send an email. Go here and change it ON because Some apps and devices use less secure sign-in technology, which makes your account more vulnerable. You can turn off access for these apps, which we recommend, or turn on access if you want to use them despite the risks.
This thread have some options which you can try and might help if the above solution doesn't work.

Related

Trouble sending emails using Nodemailer with a Google App Password

I am creating a route on an API which features sending an email when a user signs up. I am using nodemailer and google app password to achieve this. It was working perfectly until February 3rd 2023 that was the last use of the password. However, I did not change any code the connection simply just stopped working.
This is how my code is formatted:
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.GOOGLE_EMAIL,
pass: process.env.GOOGLE_APP_PASSWORD
},
});
const mailOptions = {
from: process.env.GOOGLE_EMAIL,
to: "user#gmail.com",
subject: 'Test Email',
html: "<h1>Email is sent<h1>"
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
I have also tried this format but it doesn't work either:
const transporter = nodemailer.createTransport({
host: "smtp.gmail.com",
port: 587, // or 465
secure: true,
auth: {
user: process.env.GOOGLE_EMAIL,
pass: process.env.GOOGLE_APP_PASSWORD
}
});
const mailOptions = {
from: process.env.GOOGLE_EMAIL,
to: "user#gmail.com",
subject: 'Test Email',
html: "<h1>Email is sent<h1>"
};
transporter.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
} else {
console.log('Email sent: ' + info.response);
}
});
In either case the error I receive after trying to send an email with either format is the following:
Error: Connection timeout
at SMTPConnection._formatError (/workspace/elana-backend/node_modules/nodemailer/lib/smtp-connection/index.js:787:19)
at SMTPConnection._onError (/workspace/elana-backend/node_modules/nodemailer/lib/smtp-connection/index.js:773:20)
at Timeout.<anonymous> (/workspace/elana-backend/node_modules/nodemailer/lib/smtp-connection/index.js:232:22)
at listOnTimeout (node:internal/timers:559:17)
at processTimers (node:internal/timers:502:7) {
code: 'ETIMEDOUT',
command: 'CONN'
}
The first block of code was working perfectly fine up until recently. I thought a possible password change may have revoked the app password because I noticed that in google app password documentation. Therefore, I also created a new app password but it still appeared with the same issue.
Edit -
Are you using an App Password to make these requests? This password is used to connect applications to your Google account and WILL NOT allow you to login/authenticate with your Google account
Have you tried using a service account with domain-wide delegation to send the email?
I use a similar piece of code to send emails (as users in our Google Workspace) when a Slack message is posted in a channel, however I struggled to have success authenticating using basic authentication like you are above. Instead I took a suggestion from #Linda Lawton - DalmTo in this question. Below I am using OAuth2.0 to impersonate a service account that is authorized through domain-wide delegation to send emails as users in the workspace. Sample code:
const transport = nodemailer.createTransport({
service: 'Gmail',
auth: {
type: 'OAuth2',
user: process.env.GOOGLE_EMAIL,
//Derived from Service Account
serviceClient: privatekey.client_id,
privateKey: privatekey.private_key
}
})
const mail_options = {
from: process.env.GOOGLE_EMAIL,
to: 'test#gmail.com',
subject: 'Test Mail',
html: '<h1> Test Email </h1>',
}
transport.sendMail(mail_options, function(error, result){
if(error){
console.log('Error: ' + error);
}else{
console.log('Result: ' + result);
}
transport.close();
})
Google has some confusing, but well written documentation on using domain-wide delegation in your workspace here. If you are not familiar with Google Cloud services there might be some other resources to catch up on with as well
You might also need to add the transport.close() method in the body of the callback in your .sendMail() method
References
OAuth2.0 with Service Accounts
Domain-Wide Delegation with Service Account
Domain-Wide Delegation
Service Accounts

Nodemailer "connect ETIMEDOUT" with custom domain

I'm making a forgot password backend route in Node.js and I'm attempting to use nodemailer to send the email from a custom domain I purchased from namecheap.com, along with the email domain. I'm not sure if it's a problem with the host, the port/security, or the auth. However, when I change the host it gives a a ECONREFUSED error instead so I believe that part is working. My firewall is (as far as I can tell) disabled and I restarted, however it is harder to tell because Norton Antivirus controls it.
This is my code, taken from a router.get route in my back-end.
The full error is "connect ETIMEDOUT" then an ip address with :587 at the end.
const transporter = createTransport({
host: 'axotl.com',
port: 587,
secure: false,
auth: {
user: config.get('emailUser'),
pass: config.get('emailPass')
}
});
let resetLink = '';
let authToken = '';
await jwt.sign({ email: req.params.email }, config.get('JWTSecret'), { expiresIn: 10800000 }, (err, token) => {
if (err) throw err;
authToken += token;
})
resetLink = await `${config.get('productionLink')}/recipients/resetpassword/${authToken}`
console.log(`resetlink : ${resetLink}`)
const mailOptions = {
from: '"Axotl Support" <support#axotl.com>',
to: req.params.email,
subject: "Forgot Password",
text: `Hello ${req.name},\n\nHere is the password reset link you requested (expires in 3 hours): ${resetLink}\nIf you did not request this, please notify us at http://axotl.com/support\n\nThanks!\n-Axotl Support`
}
try {
console.log('trycatch entered')
// const verified = await transporter.verify()
// console.log(`verified : ${verified}`)
const res = await transporter.sendMail(mailOptions)
console.log('email completed')
console.log(res)
res.json({ msg: "email sent" })
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error")
}
Turns out I was using the wrong host domain-- the service doesn't directly host the email domain on the website. I don't know enough about this specific section. I changed it to the email host and it worked.

How to update insert records into database with every replied-to email?

I'm testing sending emails to myself with Nodemailer, and I have the basic setup,
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "foo#gmail.com",
pass: "foobar"
}
});
const mailOptionsUser = {
from: "John Doe <foo#bar.com>",
to: 'bar#foo.com',
subject: "Test | New email",
html: `<h3>test</h3>`
};
transporter.sendMail(mailOptionsUser, function(error, info) {
if (error) {
console.log(error);
} else {
console.log("Email sent: " + info.response);
}
});
I want to be able to track conversations on my web app, so that users can send emails to themselves, and they'll be able to see those messages when they log into the app.
I was thinking of using the replyTo feature, but that won't do what I need -- is there any way to update the database with every sent email (that isn't sent through Nodemailer)?

Sending emails using Mailgun with NodeMailer package

A couple of days ago I realized that Google has changed the security of gmail accounts, particularly for the possibility of sending emails from applications. After Googling around for a while I couldn't find a fix for it.
So, I resorted to using Mailgun. I created an account and had it enabled with Business verification. However, I still can't send emails. I keep getting an error about the requested URL not being found.
I am suspecting that since I haven't set up a domain yet, it is not picking the mailgun domain it provided by default. Could someone show me how to test sending emails using Mailgun from NodeMailer indicating the sandbox name provided by mailgun.
thanks in advance
José
var nodemailer = require('nodemailer');
// send mail with password confirmation
var transporter = nodemailer.createTransport( {
service: 'Mailgun',
auth: {
user: 'postmaster#sandboxXXXXXXXXXXXXXXXX.mailgun.org',
pass: 'XXXXXXXXXXXXXXXX'
}
});
var mailOpts = {
from: 'office#yourdomain.com',
to: 'user#gmail.com',
subject: 'test subject',
text : 'test message form mailgun',
html : '<b>test message form mailgun</b>'
};
transporter.sendMail(mailOpts, function (err, response) {
if (err) {
//ret.message = "Mail error.";
} else {
//ret.message = "Mail send.";
}
});
I created the Nodemailer transport for mailgun.
Here it how it works.
You install the package with npm install as you would do with any package, then in an empty file:
var nodemailer = require('nodemailer');
var mg = require('nodemailer-mailgun-transport');
// This is your API key that you retrieve from www.mailgun.com/cp (free up to 10K monthly emails)
var auth = {
auth: {
api_key: 'key-1234123412341234',
domain: 'sandbox3249234.mailgun.org'
}
}
var nodemailerMailgun = nodemailer.createTransport(mg(auth));
nodemailerMailgun.sendMail({
from: 'myemail#example.com',
to: 'recipient#domain.com', // An array if you have multiple recipients.
subject: 'Hey you, awesome!',
text: 'Mailgun rocks, pow pow!',
}, function (err, info) {
if (err) {
console.log('Error: ' + err);
}
else {
console.log('Response: ' + info);
}
});
Replace your API key with yours and change the details and you're ready to go!
It worked me, when I added the domain also to the auth object (not only the api_key). Like this:
var auth = {
auth: {
api_key: 'key-12319312391',
domain: 'sandbox3249234.mailgun.org'
}
};

Nodemailer and GMail with access tokens

I try to use Nodemailer to send an email with my GMail account but it doesn't work, it works in local but on my remote server I recieve an email from Google "Someone is using your account...."
How can I do ?
exports.contact = function(req, res){
var name = req.body.name;
var from = req.body.from;
var message = req.body.message;
var to = '******#gmail.com';
var transport = nodemailer.createTransport("SMTP", {
service: 'Gmail',
auth: {
XOAuth2: {
user: "******#gmail.com",
clientId: "*****",
clientSecret: "******",
refreshToken: "******",
}
}
});
var options = {
from: from,
to: to,
subject: name,
text: message
}
transport.sendMail(options, function(error, response) {
if (error) {
console.log(error);
} else {
console.log(response);
}
transport.close();
});
}
Check out the solution from Unable to send email via google smtp on centos VPS:
In my case, my script is on a VPS so I don't have a way to load any url with a browser. What I did: Changed my gmail pw. Gmail > Settings > Accounts. Then in Google Accounts they listed suspicious logins that were blocked by google (these were my script's attempted logins). Then I clicked the option "Yes, that was me". After that, my script worked (using the new pw).

Resources