I have a Flask server.
In route.py I have this:
from flask_mail import Mail
app = flask.Flask(__name__, static_folder='static')
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'source#gmail.com'
app.config['MAIL_PASSWORD'] = 'password.'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail= Mail(app)
I want to send mail in a function situated in another script using flask_mail.Message() and mail.send, how can I do it?
have a look at this example:
email.py
from flask_mail import Message
from app import mail
def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender=sender, recipients=recipients)
msg.body = text_body
msg.html = html_body
mail.send(msg)
source: https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-x-email-support
(Great tutorial on flask in general)
Related
I want to send emails from Yandex using Flask but I get "authentication failed: This user does not have access rights to this service".
I did this:
from flask import Flask, render_template, redirect, request
from flask_mail import Mail, Message
app=Flask(__name__)
mail = Mail(app)
app.config['MAIL_SERVER'] = 'smtp.yandex.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USERNAME'] = 'my-username#yandex.com'
app.config['MAIL_PASSWORD'] = 'my-password'
mail = Mail(app)
#app.route('/send-email')
def send_mail():
msg = Message('This email was sent by me from Flask', sender='my-username#yandex.com',recipients=['rec#gmail.com'])
msg.body = "This is the email body, I just wanted to test the flask email option, and see how doest it work."
mail.send(msg)
return 'Email sent!'
I was expecting the message to be sent, but I got the authentification error.
PS: My email and password are correct.
I'm trying to send a email via smtp using Django. When I try to send the email, I do not get any error, but my application does not respond and it keeps waiting on to send the email, but obviously it does not send nothing.
I have tried with smtp gmail and smtp hotmail, but it is not working. I have already checked my Windows firewall, and again it is not working. I have tried to send the email using Python shell but it does not send nothing.
I think that I have tried almost everything that I saw on the other posts here in Stack Overflow.
settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.office365.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'myemail#hotmail.com'
EMAIL_HOST_PASSWORD = 'mypassword'
SERVER_EMAIL = EMAIL_HOST_USER
mails.py:
from django.conf import settings
from django.template.loader import get_template
from django.core.mail import EmailMultiAlternatives
class Mail:
#staticmethod
def send_complete_order(orden, user):
subject = 'order sent'
template = get_template('orders/mails/complete.html')
content = template.render({
'user': user
})
message = EmailMultiAlternatives(subject, 'Testing',
settings.EMAIL_HOST_USER, [user.email])
message.attach_alternative(content, 'text/html')
message.send()
views.py:
#login_required(login_url='login')
def complete(request):
cart = get_or_create_cart(request)
order = get_or_create_order(cart, request)
if request.user.id != order.user_id:
return redirect('carts:cart')
order.complete()
Mail.send_complete_order(order, request.user)
destroy_cart(request)
destroy_order(request)
messages.success(request, "order complete")
return redirect('index')
Create a secure SSL context
context = ssl.create_default_context()
try:
with smtplib.SMTP_SSL(smtp_mail, port, context=context) as server2:
server2.login(your_mail, passwort)
server2.sendmail(mail_from, mail_to, message.as_string())
print("Successfully sent email")
I am trying to understand this tutorial code.
from flask import Flask
from flask_mail import Mail, Message
app =Flask(__name__)
mail=Mail(app) # <-- This
app.config['MAIL_SERVER']='smtp.gmail.com'
app.config['MAIL_PORT'] = 465
app.config['MAIL_USERNAME'] = 'yourId#gmail.com'
app.config['MAIL_PASSWORD'] = '*****'
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USE_SSL'] = True
mail = Mail(app) # <-- This
#app.route("/")
def index():
msg = Message('Hello', sender = 'yourId#gmail.com', recipients = ['id1#gmail.com'])
msg.body = "Hello Flask message sent from Flask-Mail"
mail.send(msg)
return "Sent"
if __name__ == '__main__':
app.run(debug = True)
At the line 5 and 13, Mail object are instantiated and assigned to mail.
Even if I comment out the first instantiation in line 5, I can still send emails, so can I say it is just a typo, or it is necessary?
The first mail=Mail(app) is not needed. The primary fuctionality in the Mail() constructor is to read the app configuration. So since the appropriate app config variables are not set before line 5, the first Mail() object would likely not even work.
I've just started working with Celery on my latest project with work; I'm having a bit of trouble with executing tasks asynchronously.
All the code is taken from Miguel Grinbergs 'Using Celery with Flask'
When sending the mail without executing a task, it sends perfectly fine. Though when I attempt to send the mail delayed, it fails out giving me an error as follows.
smtplib.SMTPSenderRefused: (530, b'5.5.1 Authentication Required. Learn more at\n5.5.1 https://support.google.com/mail/answer/14257 h19sm960819igq.6 - gsmtp', 'email-removed#gmail.com')
Here's the code I'm using, in my Flask app.
import os
import time
from flask import Flask, request, render_template, session, flash, redirect, url_for, jsonify
from flask.ext.mail import Mail, Message
from celery import Celery
app = Flask(__name__)
app.config['SECRET_KEY'] = 'super-duper-secret'
# Celery Configuration
app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
# Configuration for Flask-Mail
app.config['MAIL_SERVER'] = "smtp.gmail.com"
app.config['MAIL_PORT'] = 465
app.config['MAIL_USE_SSL'] = True
app.config['MAIL_USE_TLS'] = False
app.config['MAIL_USERNAME'] = 'email-removed#gmail.com'
app.config['MAIL_PASSWORD'] = 'password-removed'
app.config['MAIL_DEFAULT_SENDER'] = 'email-removed#gmail.com'
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
mail = Mail(app)
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'GET':
return render_template('index.html', email=session.get('email', ''))
email = request.form['email']
session['email'] = email
msg = Message("Hello from Flask", recipients=[email])
msg.body = "This is a test message from the flask application!"
if request.form['submit'] == "Send":
send_async_email(msg)
flash('Sending email to {0}'.format(email))
else:
send_async_email.apply_async(args=[msg], countdown=20)
flash('An email to {0} will be sent in a minute.'.format(email))
return redirect(url_for('index'))
#celery.task()
def send_async_email(msg):
with app.app_context():
mail.send(msg)
if __name__ == "__main__":
app.run(debug=True)
I'd appreciate some insight, and perhaps an explanation on how to make this work, and why it isn't working.
I've also looked upon other threads here, and turned on insecure-application access for my google accounts, along with nulling the captcha as suggested in the errors returned URL.
I am trying to make EMAIL_HOST settings configurable within admin and I will create a model with required fields like:
EMAIL_HOST
EMAIL_HOST_USER
EMAIL_HOST_PASSWORD
EMAIL_PORT
But how can I use those fields in views using send_mail?
If you want to use send_mail, you'll have to create your own email backend which uses your custom settings and then pass it to send_mail in the connection attribute.
This works for me
from django.core.mail import EmailMessage
from django.core.mail.backends.smtp import EmailBackend
config = Configuration.objects.get(**lookup_kwargs)
try:
backend = EmailBackend(
host=config.host,
port=config.port,
password=config.password,
username=config.username,
use_tls=config.use_tls,
fail_silently=config.fail_silently
)
mail = EmailMessage(
subject="subject",
body="body",
from_email=config.username,
to=["email#gmail.com"],
connection=backend,
)
mail.send()
except Exception as err:
print(err)
Sending mail with a custom configured SMTP setting in the admin page which is independent of the Django setting:
from django.core import mail
from django.core.mail.backends.smtp import EmailBackend
from <'Your SMTP setting in admin'> import <'Your model'>
def send_mail(subject, contact_list, body):
try:
con = mail.get_connection()
con.open()
print('Django connected to the SMTP server')
mail_setting = <'Your model'>.objects.last()
host = mail_setting.host
host_user = mail_setting.host_user
host_pass = mail_setting.host_pass
host_port = mail_setting.host_port
mail_obj = EmailBackend(
host=host,
port=host_port,
password=host_pass,
username=host_user,
use_tls=True,
timeout=10)
msg = mail.EmailMessage(
subject=subject,
body=body,
from_email=host_user,
to=[contact_list],
connection=con)
mail_obj.send_messages([msg])
print('Message has been sent.')
mail_obj.close()
return True
except Exception as _error:
print('Error in sending mail >> {}'.format(_error))
return False