Emails not sending when using Flask-Mail with Heroku and Mailgun - python

I have been writing a simple app to test how to send emails via an SMTP method (needs to be SMTP to be portable to different SMTP services) using Flask-Mail. For this I am trying to use Mailgun through Heroku, but after much trial, error and research I still cannot seem to get emails to send.
My question is on a similar vein to this question, Flask on Heroku with MailGun config issues, however I can see no resolution in this question other than to use Mailgun's API, which isn't feasible for the project I am working on.
Currently I have the flask/flask-mail code set up as follows (stripped down of course):
from flask import Flask
from flask.ext.mail import Mail
from flask.ext.mail import Message
app = Flask(__name__)
mail = Mail(app)
app.config.setdefault('SMTP_SERVER', environ.get('MAILGUN_SMTP_SERVER'))
app.config.setdefault('SMTP_LOGIN', environ.get('MAILGUN_SMTP_LOGIN'))
app.config.setdefault('SMTP_PASSWORD', environ.get('MAILGUN_SMTP_PASSWORD'))
app.config.setdefault('MAIL_SERVER', environ.get('MAILGUN_SMTP_SERVER'))
app.config.setdefault('MAIL_USERNAME', environ.get('MAILGUN_SMTP_LOGIN'))
app.config.setdefault('MAIL_PASSWORD', environ.get('MAILGUN_SMTP_PASSWORD'))
app.config.setdefault('MAIL_USE_TLS', True)
def EmailFunction(UserEmail):
msg = Message("Hello",
sender='testing#test.com',
recipients=[UserEmail])
msg.html = "<b>testing</b>"
mail.send(msg)
return msg.html
#app.route('/EmailTest/')
def EmailTestPage():
EmailFunction('developer#test.com')
return 'Email Sent'
if __name__ == '__main__':
app.run(host='0.0.0.0',debug=True)
Am I missing something? And is there a way to test what is going wrong as the code passes and 'Email Sent' is returned, but no email is sent/received seemingly.
Thanks for any help you can provide!

It looks like you're not reading in the SMTP port. By default Flask mail likely tries to use 25 whereas mailgun uses 587.

Related

How to send mails from gmail account using heroku?

I'm trying to build a simple app in python which sends emails if stock/crypto prices increase or decrease by x percent. I'm using yagmail to send these emails through a Gmail account. I have already tested the code locally and now I want to move it to Heroku. I have created GitHub secrets for the email addresses and for the Google App Password for yagmail's SMTP server and now I can deploy the app by connecting it to my Github repo. As far as I can tell it runs just fine, but the emails are not being sent.
I'm thinking that the problem stems from the Google App Password for yagmail's SMTP server, but I'm not sure. This is my first app so it could be that I'm missing something really basic.
Here is a simple code sample which is working on my desktop but not through Heroku:
SENDER_EMAIL = os.getenv("SENDER_EMAIL")
SENDER_APP_PASSWORD = os.getenv("SENDER_APP_PASSWORD")
RECEIVER_EMAIL = os.getenv("RECEIVER_EMAIL")
test_sub = "Test mail"
test_cont = "Test content"
with yagmail.SMTP(SENDER_EMAIL, SENDER_APP_PASSWORD) as yag:
yag.send(RECEIVER_EMAIL, test_sub, test_cont)
You need to define the configuration parameters (SENDER_EMAIL, SENDER_APP_PASSWORD, RECEIVER_EMAIL) as Config Vars.
They will be injected at runtime in your Heroku Dyno (on GitHubActions your secrets can be use for your GitHubActions pipeline for example) where you can grab them using Python os package.

django-sendgrid-v5 Everything seems to work fine but mails don't get delivered

I'm using the django-sendgrid-v5 package to send mails in django. Everything works fine but the mail never reaches to the inbox, neither spam.
Here are my current configurations:
.env file:
EMAIL_BACKEND='sendgrid_backend.SendgridBackend'
SENDGRID_API_KEY='SG.the_rest_of_the_api_key'
settings.py file:
EMAIL_BACKEND = env('EMAIL_BACKEND')
SENDGRID_API_KEY = env('SENDGRID_API_KEY')
SENDGRID_SANDBOX_MODE_IN_DEBUG=False
and my mail function:
from django.core.mail import send_mail
send_mail( mail_subject, message, 'noreply.cpsb#nyeri.go.ke', [to_email], fail_silently=False )
On sending the email, I get no error, but still the mail doesn't get delivered.
What could I be missing?
I finally worked it through. The problem was Sender Authentication, Which By the way is not very elaborate in the documentation.
After generating an API key you're supposed to add some CNAME records to your DNS service provider for sendgrid to be authenticated to send emails.
With a lot of help from This medium article
So the problem was not on the code.

Reply to Incoming Message Twilio SMS Python Quickstart

I'm currently working on the Twilio SMS Quickstart; specifically I'm stuck on the "Reply to an incoming message using Twilio SMS".
*update, I've realized I haven't used the 'request' module I imported from Flask. Would appreciate any tips on if I need to utilize this module and, if I do, how do I use it in this specific script?
Up to this point I've successfully sent a message using a Twilio script called "send_sms.py". I'm now stuck with being unable use my virtualenv to receive and reply to messages. Here's the code titled 'run.py':
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route('/sms', methods=['POST'])
def sms_ahoy_reply():
"""Respond to incoming messages with a friendly SMS."""
# Start our response
resp = MessagingResponse()
# Add a message
resp.message("Ahoy! Thanks so much for your message.")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
I get an error from my code editor, Spyder, next to 'from flask import Flask, request'; however, when I delete ', request' the error goes away.
As a result of this issue I'm unable to successfully run the script which would allow me to receive and reply to text messages via Twilio.

Flask-Mail on Google App Engine Flexible ENV

I'm trying to get Flask-Mail setup on in Flexible ENV on Google App Engine. Flask-Mail works on my localhost using the credentials for a domain I am trying to use to send the mail. However, when using it on GAE through my API it returns a 502 error, however it shows no error messages in the logs or console. Going through the documentation for GAE Flexible it doesn't mention anything about NOT being able to use it, however it doesn't show how one would setup Flask-Mail either.
I have this..
mail = Mail()
print('1') // We Get here
msg = Message("Hello",
sender="me#mydomain.com",
recipients=["me#mydomain.com"])
print('2') // We get here
msg.body = 'Testing'
print('3') // We get here
mail.send(msg)
print('4') // This never gets call because I timeout on a 502 before this
I can tell I am not getting any fatal errors because the app stays working. However this fails with the 502. I have tried adding my email to the list of authorized senders but it doesn't seem to have helped.
I would appreciate any feedback. If I forced to use a 3rd party service to send mail it may cause me to move the project off of GAE.
As Ivan posted on his comment, to send email from a GAE app you need to use a mail service. Right now there are 3 options for apps on a flexible environment: Mailgun, MailJet and SendGrid. Choose the one you see better for your app.
After setting up an account on the mail service you have chosen, you have to prepare your code by integrating the parts related to the mail service.
These tutorials should help you establish the mail service for your app:
Mailgun
MailJet
SendGrid
I've had the same error but on a virtual machine on the internet ( linode service ) and it turned out that it has some thing to do with rDNS and some domain name config that you have to set up for your Ip address to get things working correctly , check this
https://www.linode.com/community/questions/19082/i-just-created-my-first-linode-and-i-cant-send-emails-why

Using HTML templates to send emails in python

I'm trying to write a separate mail service, which is decoupled with our Flask application. I'm looking for a way to send welcome emails when users first log into our Flask application. I'm using Celery and RabbitMQ to do it asynchronously.
Here is my email function:
sen = 'example#gmail.com'
pwd = 'my_password'
#celery.task
def send_email(nickname, email):
msg = MIMEMultipart('alternative')
msg['Subject'] = 'my_sub'
msg['From'] = sen
msg['To'] = email
html = <b>test_body</b>
part1 = MIMEText(html, 'html')
msg.attach(part1)
server = smtplib.SMTP("smtp.gmail.com", 587)
server.ehlo()
server.starttls()
server.login(sen, pwd)
server.sendmail(sen, [email], msg.as_string())
server.close()
Initially I was using Flask's render_template to get the HTML body and subject. But I don't want to use the Flask extension (I have my reasons). So my questions are:
How can I use email templates so that the subject and body fields can be configured easily?
How can I put the default email sender and password in a config file/email template (might be related to q1)?
It seems to be that I have a lot of code to send a simple email. Can you suggest some optimization techniques (omitting steps)?
I've wrritten a simple module(mail.py) to send emails using templates(HTML/TEXT). Hope that helps!
https://github.com/ludmal/pylib
It may be simpler to use an external service.
A service (e.g. Mailchimp) is simple to integrate. You can design the template in their layer, and trigger emails by sending merge data from your app to the service API. Functionally it's a lot like rendering a template locally and mailing it out via SMTP, but they have sophisticated tools for adapting message format to devices, tracking bounces, improving deliverability, reporting etc.
Services like this often have a free tier for up to 1000's of emails per month.

Categories