I am encountering a problem with nodemailer, specifically, transport.sendMail() function.
When running locally using npm start
, I can send emails just fine when I access the endpoint 'api/email' with a http.post request. When I push my nodejs app (it serves up an angular project bundles into a dist folder), I can access api/email with gets and posts, but the program freezes at transport.sendMail() with Heroku error code=H12, desc="Request timout"
Here is the nodemailer transporter being created in my nodemailer.service.js file:
const express = require('express');
const router = express.Router();
const nodemailer = require('nodemailer');
/* GET users listing. */
router.get('/', function (req, res, next) {
res.json({data: 'send something'});
});
let route = router.route('/').options((req, res) => {
});
route.post((req, res, next) => {
try {
console.log(req.body);
let name = req.body.name;
let senderEmail = req.body.senderEmail;
let subject = req.body.subject;
let text = req.body.textBody;
let transporter;
try {
//TODO: TRUE, SO ENTERS HERE
if (process.env.PRODUCTION) {
console.log('is production!')
transporter = nodemailer.createTransport({
service: process.env.PROD_EMAIL_HOST,
auth: {
user: process.env.PROD_EMAIL_UN,
pass: process.env.PROD_EMAIL_PW
},
from: req.body.senderEmail,
tls: {
ciphers: 'SSLv3'
},
port: process.env.PROD_EMAIL_PORT,
requireTLS: true,
secure: false
});
console.log('created transport');
} else {
console.log('is dev!')
transporter = nodemailer.createTransport({
host: process.env.TEST_EMAIL_HOST,
port: process.env.TEST_EMAIL_PORT,
auth: {
user: process.env.TEST_EMAIL_UN,
pass: process.env.TEST_EMAIL_PW
},
from: req.body.senderEmail,
});
}
} catch (e) {
console.log('OOPS: ' + e.message);
}
Here is where the message body is created
message = {
from: name + ' <' + senderEmail + '>', // Sender address
to: 'team@berwick-house.com', // List of recipients
subject: subject, // Subject line
text: text, // Plain text body
html: text // HTML text body
};
console.log('got message: ' + message);
And here is transporter.sendMail()
where the application just times out when run on Heroku.
console.log('about to send!!!!')
transporter.sendMail(message, (error, info) => {
//TODO: HALTS
console.log('Sending...');
if (error) {
res.status(400).json({data: 'ERROR: ' + error.message, status: error.status});
console.log('error sending: ' + error.message);
} else {
res.status(200).json({data: message, status: 'OK'});
console.log('success!');
}
}).then(r => {
//TODO: r IS UNDEFINED
console.log(r);
});
} catch (error) {
console.log('ERROR: ' + error.message);
}
Any advice would be hugely appreciated! For reference, here is my server.js code
const express = require('express');
const path = require('path');
const cors = require('cors');
const emailRouter = require('./nodesrc/services/nodemailer.service.js');
const versionRouter = require('./nodesrc/services/version.service.js');
const app = express();
const dotenv = require('dotenv');
dotenv.config();
// view engine setup
app.set('view engine', 'jade');
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api/email', emailRouter);
app.use('/api/version', versionRouter);
app.use(cors({
"origin": ["https://berwick-house.herokuapp.com", "http://localhost:8080"],
"methods": "GET, POST, PUT, DELETE, OPTIONS",
"optionsSuccessStatus": 200,
"credentials": true
}));
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
// Serve only the static files form the dist directory.
app.use(express.static(__dirname + '/dist/berwick'));
//Set base index file as into.
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname + '/dist/berwick/index.html'));
});
let port = process.env.PORT || 8080;
app.listen(port);
I've read through the Heroku docs, including this https://help.heroku.com/AXOSFIXN/why-am-i-getting-h12-request-timeout-errors-in-nodejs.
Heroku also seems to block some traffic with firewalls if it deems it a threat - maybe that's the case with nodemailer?
Here are the error logs from heroku logs --tail
2022-01-17T01:23:12.598026+00:00 app[web.1]: name: 'will',
2022-01-17T01:23:12.598027+00:00 app[web.1]: senderEmail: 'angelljamesw@gmail.com',
2022-01-17T01:23:12.598027+00:00 app[web.1]: subject: ' Some subject',
2022-01-17T01:23:12.598028+00:00 app[web.1]: textBody: 'ddhdhkdkdsf some text'
2022-01-17T01:23:12.598028+00:00 app[web.1]: }
2022-01-17T01:23:12.598096+00:00 app[web.1]: is production!
2022-01-17T01:23:12.600149+00:00 app[web.1]: created transport
2022-01-17T01:23:12.600205+00:00 app[web.1]: about to start message
2022-01-17T01:23:12.600275+00:00 app[web.1]: got message: [object Object]
2022-01-17T01:23:12.600320+00:00 app[web.1]: about to send!!!!
2022-01-17T01:23:42.577424+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/api/email" host=berwick-house.herokuapp.com request_id=7f5a0d6b-89a4-43f8-b27b-d11bc830d2c8 fwd="84.67.165.143" dyno=web.1 connect=0ms service=30000ms status=503 bytes=0 protocol=https