Node.js Nodemailer And SES - Error: No transport method defined - node.js

I am using nodemailer to send emails with SES. I am setting it up like this:
require("nodemailer").createTransport("SES", {
AWSAccessKeyID: "AKIAJZFUSYQJNEX3VS2A",
AWSSecretKey: "XXX", //real information removed
SeviceUrl:"https://email.us-west-1.amazonaws.com"
}),
When I Send The Email I Get:
Error: No transport method defined
Any ideas as to why this is happening?
*EDIT:*Tried Both solutions, and they did not work

You have to use your transport on sending mail. Just try as follows,
var nodemailer = require("nodemailer");
var transport = nodemailer.createTransport("SES", {
AWSAccessKeyID: "AKIAJZFUSYQJNEX3VS2A",
AWSSecretKey: "XXX",
SeviceUrl:"https://email.us-west-1.amazonaws.com"
}),
//On sending mail
nodemailer.sendMail({
transport : transport, //pass your transport
sender : 'senderid#email.com' ,
to : 'receiverid#email.com',
subject : "SUBJECT",
html: '<p> Hello World </p>'
})
Note: Here I assume, your transport is valid one and your key is enough permission(Network permission as well.)

Your ServiceUrl is configured incorrectly. Amazon SES is only available in us-east-1 at this time. Please set ServiceUrl to https://email.us-east-1.amazonaws.com.
Also, for future reference, please do not share your AWS Secret Key. I strongly recommend that you rotate your AWS keys since they were posted earlier in your question.

Related

Unable to use SendInBlue with Gmail and Nodemailer Properly

Before I go into this, I know two very common issues with Gmail with Nodemailer is that Allow Less Secure Apps is disabled by default, and I know two factor authentication can provide similar issues. Neither of these is the case.
I am attempting to make a system wherein many user accounts can be created en masse. When they are created, each account will receive an email with a greeting and their password. The issue was that gmail does not like spam, so the emails wouldn't send. I tried adding a 1 second wait period between each mutation thus between each email, but that didn't work either.
I now have a SendInBlue Account, using that same gmail. My code looks like this now...
////////////////////////////////
/// ///
/// EMAIL STUFF ///
/// ///
////////////////////////////////
// Creates the Transporter
const transporter = nodemailer.createTransport({
service: "SendinBlue",
auth: {
user: `${process.env.EMAIL_ADDRESS}`,
pass: `${process.env.EMAIL_PASSWORD}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.EMAIL_ADDRESS}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
throw new Error('Something went wrong, please try again \n' + error)
}
})
Wherein the only thing in the code above that is different than when it was sending (or at least it was trying to send before it got hit with the spam block) is the line service: "SendinBlue", was changed from service: "Gmail",
Is this an issue with SendInBlue, or does this look more like a Gmail / Nodemailer issue? Could anyone assist

Can I use any email under my domain name to send emails using AWS SES?

Pardon me if I am asking a pretty dumb question. I am new to SES and I could not find a straight answer in the AWS docs about this.
Some background info: I am using node server on EC2. I own a domain, let's say "mydomain.com". I only need AWS SES to send out emails to my customers and I plan to use AWS-SDK in my EC2 server to talk to SES. I do not need to receive any emails from customers.
According to AWS SES docs, I only need to verify either my domain OR my email address - just one of them.
Let's say I choose to verify my domain, mydomain.com, and I did not verify email. So, when I use AWS-SDK sendEmail(), what email should/can I use given that I did not verify any email?
Can I use any email as long as it is using my domain name? E.g. support#mydomain.com?
Thank you for your answer!
The verification is there to make sure you are the owner of the domain or at least an email address you want to use.
So when you verify the domain you are verified as the admin of the domain and thus have access to any of the email address on that specific domain.
To elaborate, if you can prove that you can change the DNS records of the domain (as you did for the verification) you can change any email related DNS records such as the MX records (more on the wiki) and thus any additional verification is not necessary.
I encourage you to learn more about the MX records.
As long as you are able to verify your domain, yes you can use any email with your domain name. AWS wants to know you are the owner of the domain.
Tip regarding:
"I plan to use AWS-SDK in my EC2 server to talk to SES."
I would recommend to use AWS Lambda function using NodeJS and trigger them from the API gateway. This way you will save money spent on monthly EC2 instances with highly available API to send out emails.
Additionally you can then use this API anywhere in your business process flows.
Here is a sample code to send out emails using AWS SES service via Lambda function.
var AWS = require('aws-sdk');
var ses = new AWS.SES();
var RECEIVER = 'to#yourdomain.com';
var SENDER = 'from#yourdomain.com';
var response = {
"isBase64Encoded": false,
"statusCode": 200,
"headers": {
"X-Requested-With": '*',
"Access-Control-Allow-Headers": 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,x-requested-with',
"Access-Control-Allow-Origin": '*',
"Access-Control-Allow-Methods": 'POST,GET,OPTIONS'
},
"body": "{\"result\": \"Success.\"}"
};
exports.handler = function (event, context) {
var formdata = JSON.parse(event.body);
sendEmail(formdata, function (err, data) {
context.done(err, response);
});
};
function sendEmail (formdata, done) {
var params = {
Destination: {
ToAddresses: [
RECEIVER
]
},
Message: {
Body: {
Text: {
Data: 'name: ' + formdata.name + '\nemail: ' + formdata.email + '\ndesc: ' + formdata.desc,
Charset: 'UTF-8'
}
},
Subject: {
Data: 'Website Referral Form: ' + formdata.name,
Charset: 'UTF-8'
}
},
Source: SENDER
};
ses.sendEmail(params, done);
}

Nodemailer with ZOHO mail

I'm trying to setup ZOHO mail with Nodemailer. The mail is configured correctly and I'm using following code to send the mail:
var transporter = nodemailer.createTransport({
host: 'smtp.zoho.eu',
port: 465,
secure: true, //ssl
auth: {
user:'info#myaddress.be',
pass:'supersecretpassword'
}
});
sendMail = function(req,res) {
var data = req.body;
transporter.sendMail({
from: data.contactEmail,
to: 'info#myaddress.be',
subject: data.contactSubject,
text: data.contactMsg
});
res.json(data);
};
I contacted official support but no response so far. Maybe someone here has experience with it. The problem is that when using these settings I get a message that relaying is disallowed for the address in variable 'data.contactEmail'. When I change the from e-mail also to info#myaddress.be I do receive the e-mail but of course I do not know who sent it and can't reply to it.
Anyone who knows how to make the 'from' address work with unknown addresses? Like john#gmail.com ?
Solution :
You should make an email account for your server : bot#myaddress.be
When you are going to relay the mail craft a custom MAILBODY containing the subject and message
var MAILBODY ='\n[suject]:\n'+data.contactSubject+'\n\n[msg]:\n'+data.contactMsg;
So you will be sending the original contactEmail as the subject of the mail and using the mail's text (body) to se the message subject and the message content.
transporter.sendMail({
from: 'bot#myaddress.be',
to: 'info#myaddress.be',
subject: data.contactEmail,
text: MAILBODY
});
Reason of Solution :
Example bot account will be able of sending the email to yourself with all the details you really need. (because you control that email account / your domain)
The credentials you are providing are for your OWN account and you are trying to send an email FROM an unknown account. This might only be possible if you had the credentials for the unknown account (given that they have allowed open access to other clients/apps).
You simply can not send an email on behalf of an account you do not have credentials for.

AWS SES from NodeJS not DKIM signed?

I am using nodemailer to send emails using SES
const nodemailer = require('nodemailer')
const sesTransport = require('nodemailer-ses-transport')
const transporter = nodemailer.createTransport(sesTransport({
accessKeyId: '...',
secretAccessKey: '...',
region: 'us-east-1'
}))
When I try to send test emails from AWS SES Dashboard, it works. But when I send via code, it goes into spam. I've already followed the steps to "enable easy DKIM" http://docs.aws.amazon.com/ses/latest/DeveloperGuide/easy-dkim.html. When I check the verification status of DKIM on AWS Dashboard, its verified. Do I need to explicitly sign emails when sending via code? In the example from https://nodemailer.com/dkim/, I need a private key. Which private key isit? Where do I get it? Also what values do I put into domainName and keySelector?
let transporter = nodemailer.createTransport({
service: 'Gmail',
dkim: {
domainName: 'example.com',
keySelector: '2017',
privateKey: '-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...'
}
});
Ok so I can close this. It appears nodemailer didnt correctly sign emails using DKIM. Using AWS SDK directly and calling setIdentityDkimEnabled to enable DKIM fixes things.

how to configure sendgrid 's from email in nodemail?

I am using node.js 's email module nodemail and sendgrid API to send the email to the users.
Here is my code for sending a email
SOURCE_EMAIL = ?????;
var options = {
auth: {
api_user: sendgrid.api,
api_key: sendgrid.key
}
};
transport = nodemailer.createTransport(sgTransport(options));
transport.sendMail({from: SOURCE_EMAIL, to: email, subject: subject, html: html}, function(err,data){
});
my question is when I use the sendgrid API to send email, what SOURCE_MAIL i should configure to ?
You may set SOURCE_EMAIL to anything you want.
It's best to set it to an email you own, control, and can receive email from.
However, it's entirely up to you.

Resources