ec2 node.js server not sending email - any ideas? - node.js

I have a website that I'm getting back up after a year+ of being down. I haven't made any code changes, and I've got the site back up and everything is working as before except for the site/app sending email.
It's an ubuntu node.js server. It's hosted on Amazon and I had to create another instance and repoint the dns, etc. An example code snippet that used to work but now doesn't:
var emailServer = email.server.connect({user:"<my gmail>",password:"<mypw>",host:"smtp.gmail.com",ssl:true});
emailServer.send({
text: "Your username is: " + userName + ".",
to: emailAddress,
subject: "Activate Your a2zCribbage Account",
attachment: [...]
}, function(err, message) { if (err) console.log(err); });
When I first tried to send email the gmail account I use got a message "sign-in attempt prevented" Someone just tried to sign in to your Google Account <account> from an app that doesn't meet modern security standards.
I followed what Google said and changed the security to allow apps, but still nothing gets sent.
What am I missing? What other things can I try? Do ec2 severs not just allow email to be sent by default?

Gmail is not a platform for sending automated email. Just because you can doesn't mean it's designed for doing so.
AWS EC2 instances are also problematic for sending email; the ports may be blocked or throttled, you are certainly getting higher spam scores for doing so.
The canonical solution is to use AWS SES. Here's sample code and here's the documentation. There's also a simple third-party library.

Related

Send emails through gmail using flask-mail

I have a simple CRUD webapp set up in Python/Flask, when one particular function is activated (approving a request) I'd like to send an email notification to the user, but for all I've tried I can't get the email to send through my code.
Here is my config file with all the relevant environment variables set (inside of a Config object):
MAIL_SERVER = 'smtp.gmail.com'
MAIL_PORT=465
MAIL_USE_SSL=True
MAIL_USERNAME = '**#gmail.com'
MAIL_PASSWORD = '**'
I have also tried calling app.config.update(those values) in my app/init.py file. Here is the current code to do so
mail = Mail()
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(app_config[config_name])
app.config.from_pyfile('./config.py')
app.config.update(
MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=465,
MAIL_USE_SSL=True,
MAIL_USE_TLS=False,
MAIL_USERNAME = '**#gmail.com',
MAIL_PASSWORD = '**')
mail.init_app(app)
And finally here is the code where I actually attempt to send the email:
msg = Message(html=html, sender='**#gmail.com', subject='Your Reservation for %s' % reservation.item.name, recipients=['**'])
mail.send(msg)
Additionally, it currently fails silently and I don't know how to even view what error is happening. Any help is much appreciated!
My suggestion in the comments was indeed the answer to the question.
Enabling "Less Secure Apps" in the Google Account settings was the necessary step to fix the hangup the OP was experiencing. This link from Google's support page walks you through how to enable this option.
I think, you should switch your sending protocol to TLS
this is sample from my project
MAIL_SERVER='smtp.gmail.com',
MAIL_PORT=587,
MAIL_USE_TLS=True,
MAIL_USERNAME = '**#gmail.com',
MAIL_PASSWORD = '**'
for me this works very well.
Now that Google is removing the less-secure app access feature due to security reasons, the best way to get around this is to use Sendgrid. They provide 100 free emails per day forever. You can register your same Gmail address as a single sender in SendGrid. Generate an API key and use it in your flask app to send emails.
For reference: Sending Emails from Python Flask Applications With Twilio SendGrid

Is there a way to send the verification email with the Firebase Admin SDK from my Node.js server?

Is there a way to send the email verification email from my server ?
This is how it's done on the client:
authData.sendEmailVerification().then(function() {
Is there a way to do it on the server ?
firebaser here
To my surprise there currently is no option to send verification email from within the Admin SDK. I'd recommend you file a feature request.
What you can do from the Admin SDK is update a user profile to mark their email as verified. This allows you to take control of the entire verification flow if you want to, finishing with a call to admin.auth().updateUser(...) (on Node.js, see the link for other supported languages).
I just came across the same problem as you. There is a function to generate the verification link using user's email address.
I used this function on an array of email addresses, then load the result to my mail automation API to send mails out. This function is weirdly not documented:
admin.auth().generateEmailVerificationLink([EMAIL_ADDRESS])
You can use :
axios.post('https://identitytoolkit.googleapis.com/v1/accounts:sendOobCode?key=[API_KEY]',
{ requestType: 'VERIFY_EMAIL', idToken: response.data.idToken }
)
https://firebase.google.com/docs/reference/rest/auth#section-send-email-verification

Amazon SES emails no longer sending

Im having a problem with sending emails using Amazon SES. I have an Amazon EC2 instance.
It worked for the first couple of days but I just noticed last week all emails now fail. I have tried sending using Node and the Amazon SES sdk and from within AWS where you can send a test email. I have the following code in Node:
var aws = require('aws-sdk');
// load aws config
aws.config.loadFromPath('email_config.json');
// load AWS SES
var ses = new aws.SES({
apiVersion: '2010-12-01'
});
ses.sendEmail({
Source: from,
Destination: {
ToAddresses: to
},
Message: {
Subject: {
Data: 'Somebody registered'
},
Body: {
Html: {
Data: body,
}
}
}
}, function(err, data) {
console.log('email err is ', err, ' and data is ', data);
});
The result of the log is:
email err is null and data is { ResponseMetadata: { RequestId: 'ad28f526-0b15-11e6-ad87-1108d652684a' },
MessageId: '010101544ebc41b3-f7bd43dd-0505-4eb2-a056-219ce6180fc5-000000' }
But the email doesnt deliever and I then receive an email from Amazon saying:
An error occurred while trying to deliver the mail to the following recipients: < my email address >
This contains an attachment with the following text:
From: < my email address >
To: < my email address >
Subject: Somebody registered
MIME-Version: 1.0
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 7bit
Message-ID: <010101544ebc41b3-f7bd43dd-0505-4eb2-a056-219ce6180fc5-000000#us-west-2.amazonses.com>
Date: Mon, 25 Apr 2016 18:44:01 +0000
X-SES-Outgoing: 2016.04.25-54.240.27.56
Feedback-ID: 1.us-west-2.GkIUmTTEDEIC5VBoooumwcKSnMDcLT8S4Zd3/deS/BU=:AmazonSES
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple;
s=gdwg2y3kokkkj5a55z2ilkup5wp5hhxx; d=amazonses.com; t=1461609841;
h=From:To:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-ID:Date:Feedback-ID;
bh=fHqQiK/2DJ+B7zddmElFttCiWFnADDSNj5umLJQCPJs=;
b=ZI/358zmcRHVBKTdA6qbQky5nj5z/YWw215KvkZ+oD73N0booHbl+jx+O05FdcKR
irDjmyEDppGkp7rToZSTt/NHDeRrbERixT/ZCjGo/KOxvShovD7Z5mnDViRmkS5sTz5
qo0oO0NuRz1lGVPkT5ONHNhKhWs7ncC9id0ycm34=
When I actually log into AWS and send a test email through the console, I get the same failure.
I have verified the senders email address and I have an approved sending limit for the region.
Any ideas what this could be?
EDIT
I just noticed in my AWS control panel > SES Home > Domains it says my domain is 'pending verification'. Could this be it? It says I need to add a TXT DNS record with a name of xxx and value of yyy. I already did this on Register365. Maybe I did it wrong? Register365 doesnt provide name and value fields for a TXT record, only a 'result' field. So I added a TXT record with the 'result' field of: xxx=yyy. Is this the correct approach? This was weeks ago though and its still pending verification....
EDIT
I've since added a TXT record to my Register 365 control panel, and still my domain cannot be verified. The record looks like:
Amazon provided me with the following TXT record to verify my domain:
TXT Name*: _amazonses.mydomain.com
TXT Value: u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k=
So in the Register 365 control panel "result" field I've added the record in the form name=value i.e "_amazonses.mydomain.com=u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k="
I then ran nslookup to find the record but got the message:
server can't find _amazonses.mydomain.com: NXDOMAIN
What am I doing wrong?
EDIT
I have now changed the TXT record to:
But after 3 days I have gotten another email from Amazon saying they have failed to verify the domain. Im utterly baffled now, I've been trying to verify it for 6 weeks!
My SES account is not in sandbox mode - i've already been approved to send email via SES. I've also verified my sender email address.
Are there any other options open to me? The Amazon SES service seems absolutely dire.
Also when I run:
nslookup -type=TXT _amazonses.redmatterapp.com ns-478.awsdns-59.com
I'm still seeing:
server can't find _amazonses.redmatterapp.com: NXDOMAIN
When I run:
nslookup -type=TXT redmatterapp.com ns-478.awsdns-59.com
I get:
Can't find redmatterapp.com: No answer
Why is this happening? My DNS is with Register 365
EDIT
Seems like the nameservers I was using with nslookup were wrong. When I run nslookup, i know get:
_amazonses.redmatterapp.com text = "u1qN5cbTEDb/2EV9Bhd67YHT5jjqVXKJ8KeXj50k="
Which looks right. Yet still verification for my domain fails...
As Michael, the SQL Bot pointed out, you need a hostname (_amazonses) on the left, and the value on the right. That will help to validate the domain.
However, there are a number of other possible reasons for failure. Is SES still in sandbox mode? If that's the case, you'll need to verify the TO and the FROM email addresses.
It might be easier to verify individual email addresses if you can't get the domain verification working. So create them in SES, and go through the validation process. Once you create those (or, if you manage to get the domain verified) create an SNS topic that sends you email, and then configure the Bounce, Complaint, and Delivery notifications to that SNS topic - you should end up with an email for every delivery attempt, regardless of whether it succeeds or not.
The last thing to consider is the possibility that your email address has been added to the supression list. If you generate a lot of errors, SES will add you to a "do not email" list. There is an ability to request removal from this list in the SES console.
The hostname part is _amazonses (left column, next to the number 2)
The value is "u1qHY..."
I think you're on the right track in that last image, only I believe the host name is _amazonses, and u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k= is the result, instead of putting everything in the result field in the form "_amazonses.yourdomain.com=u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k=". Iiuc, the idea is that AWS will curl _amazonses.yourdomain.com, expecting your key to be served as a TXT file, but currently you're serving a TXT file with the contents _amazonses.yourdomain.com=u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k= (I can't quite read, as its cut off; pardon my guess) on yourdomain.com instead.
The reason I believe this is that you're getting the error NXDOMAIN, which means the domain _amazonses.yourdomain.com doesn't exist, which makes sense if you hadn't set up a TXT record for _amazonses.yourdomain.com, but instead set up a txt record for http://yourdomain.com instead with the value _amazonses.yourdomain.com=u1qHYT6/2KV9Kl1VLKsApXjwcPqVXKJ8KeXj50k=. Its also what the other two answers seem to suggest, which makes me feel more confident.
I recently verified a domain for the company I work for successfully, it is set as follows in my domain DNS (as a TXT record):
It may be worth you reading Amazon's troubleshooting page if you're still having issues.
Adding to my answer:
I've just checked in my AWS console, if you open up SES > Domains and click on your domain name. Scroll down then click DKIM, I had to verify some more there:
And add them as CNAME records as follows:
One thing people forget with this process is the fact that, Amazon requires you to leave the TXT record in place even after the verification. Otherwise they will revoke the domain.
Hope this helps!
Yet another edit (sorry)
When I run nslookup -type=TXT _amazonses.redmatterapp.com ns-1471.awsdns-55.org to try and find your TXT record, it comes back:
Server: ns-1471.awsdns-55.org
Address: 205.251.197.191#53
** server can't find _amazonses.redmatterapp.com: NXDOMAIN
This shows that the TXT record is not setup correctly.

Sending email using nodemailer doesn't works on internet service but on local server

I am trying to send email from my node.js app using nodemailer. I am successful in sending email from my local server after enabling less secure apps on google account.
But when I deployed my code to heroku, it is unable to send email because google is blocking my login attempts. So I logged in to my account and clicked on the option that the login attempt was from me indeed. However it still is not working. I then set up a project on runnable.com and got the same sign in prevented. I did the same for this and accepted it as my sign in attempt. However I am still not able to send emails.
The error that is coming is this :
Server listening on port 80
Failed in sending mail
{ success: false, existing: false, sendError: true }
{ [Error: Invalid login]
code: 'EAUTH',
response: '534-5.7.14 <https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbsNg\n534-5.7.14 LiCfP8u0IX20V3Y1nFt7iYuwJCPg4LVgRxVvEPO5y4-XOjzSsm_xa0XIBE3NP2bM5euv4A\n534-5.7.14 m6LSg0_DQ
Qj9kOm_JuwykQxVyYSKaLGyeibhi_cHtx3Pu4I4UISJCPt3TvHdxCUebMzTbu\n534-5.7.14 2F9wLa-IFpKHf9HPap4Aeu11Nup9ZAlpOCGAmcnbERFeAufeIgAsExtGkrmV2X7mktJ5nq\n534-5.7.14 epNHDpwg2EwMVwzOrpt8rGZahYvs> Please log i
n via your web browser and\n534-5.7.14 then try again.\n534-5.7.14 Learn more at\n534 5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754 a76sm5828252oig.11 - gsmtp',
responseCode: 534 }
Please Help. I am in desperate need of getting it running.
I have the same issue, grap the link on your respone message "https://accounts.google.com/ContinueSignIn?sarp=1&scc=1&plt=AKgnsbsNg\n534-5.7.14" and paste to browser, you will see an announcement that showing google just blocked your sign-in request by cause it perform from strange device, then you can follow google instruction to accept that device.
It's work in my case. But I don't know what happen if heroku dynos sleep then waked up again, maybe it change the machine and you would got this problem again.
In this case, considering using a vps for hosting your mailing app.

What am I missing? My app can send e-mail via gmail on my dev box, but not on my server

My config files are identical, except for connection strings.
I'm using IIS on both machines
I elevated the IIS user on the server to ensure it's not a permissions issue
No exceptions are thrown on my server where the e-mails are not being sent
I know the gmail configs are correct because I can send e-mails from my dev box.
Windows firewall is off and the network firewall is not blocking outbound ports.
What else should I look for?
IIS 7 on Win2k8, using ASP.NET w/ C#
SmtpClient smtpClient = new SmtpClient();
smtpClient.EnableSsl = true;
smtpClient.Send(fromAddress, toAddress, subject, body);
Gmail requires authentication from the SMTP client, so you need to fill in the Credentials property on your SmtpClient instance as shown here.
That doesn't explain why it works from your development box (unless the POP3 method still works) but it would explain why the code you have shown doesn't work.
wrap smtpClient.Send(fromAddress, toAddress, subject, body); inside a try catch statment and see what the exception is

Resources