I am trying to send two sorts of emails from my website:
- a randomly generated password sent to a user who asks for one (from module PayAsYouLike), and
- a get-in-touch form that sends the email to my personal account so I can read it (from module GetInTouch).
Now, I am using the exact same router file called ’email.js’ to send both kinds of emails. However, 100% of the time, (2) works and the email goes through, but 100% of the time (1) doesn’t and the console logs a “ERR_CONNECTION_REFUSED” error. I can’t be more clearer: the endpoint aka email.js works perfectly well for both 1) and 2) when tested through Thunder client. However, as soon as the front-end makes the call, 1) doesn’t work but 2) always does.
I am adding the ’email.js’ router code here and just remember that on the server side console, it only gets as far as the console.log inside the sendMail function that says ‘Inside sendMail, but before transporter.sendMail call!’. That puts the error somewhere inside the transporter.sendMail(mailOptions) call. REMEMBER: all of this works perfectly well when email.js is used to send the form from GetInTouch.
const express = require("express");
const router = express.Router();
require("dotenv").config();
const nodeMailer = require("nodemailer");
router.route("/").post((req, res) => {
const form = req.body;
let mailOptions = {};
console.log(form);
const transporter = nodeMailer.createTransport({
service: "gmail",
host: "smtp.gmail.com",
port: 587,
secure: false,
auth: {
user: process.env.USER,
pass: process.env.APP_PASSWORD,
},
});
if ("password" in form) {
const passwordDate = new Date(form.date);
const passwordValidity = new Date(passwordDate.getTime() + 172800000);
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hour12: true
};
mailOptions = {
from: process.env.USER,
to: form.email,
subject: "Your PASSWORD is here!",
html: `Dear ${
form.name || form.email
}, <br><br>Your PASSWORD: <h3 style="display:inline;">${
form.password
}</h3><br><i>Expiry:</i> <h4 style="display:inline;">${passwordValidity.toLocaleDateString('en-US', options)}</h4>`,
};
} else {
mailOptions = {
from: process.env.USER,
to: "[email protected]",
subject: "GetInTouch form",
html: `FROM: ${form.name}<br>EMAIL: ${form.email}<br>SUBJECT: ${form.subject}<br>MESSAGE: ${form.message}`,
};
}
console.log("Mail options prepared:", mailOptions);
const sendMail = async (transporter, mailOptions) => {
try {
console.log('Inside sendMail, but before transporter.sendMail call!')
await transporter.sendMail(mailOptions);
console.log("Email has been sent successfully!!");
res.json({
status: "Success",
message: "Email sent successfully",
});
} catch (error) {
console.log(error);
res.json({
status: "Error",
message: "Failed to send email",
error: error.message,
});
}
};
sendMail(transporter, mailOptions);
});
module.exports = router;
I’ve done everything, from making two seperate router files, or using a callback function in App.jsx to update a state variable object that I can use to let PayAsYouLike use the fetch of GetInTouch to send its password through email, but somehow, React/Express knows that this is a object coming in from PayAsYouLike and creates the connection refused error.
Karan Gour is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.