Skip to content

Commit

Permalink
smtp fallback
Browse files Browse the repository at this point in the history
Modified arguments placement

Corrected quota info

Sent email and handled error

Cease email service if SMTP not configured

fix travis

divided into two tasks

changed logger message and smtp fallback
  • Loading branch information
mrsaicharan1 committed Jun 20, 2019
1 parent 47363b9 commit 91af8cb
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 65 deletions.
84 changes: 52 additions & 32 deletions app/api/helpers/mail.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import logging
from datetime import datetime

from flask import current_app
Expand All @@ -16,10 +17,28 @@
from app.models.user import User


def check_smtp_config(smtp_encryption):
"""
Checks config of SMTP
"""
config = {
'host': get_settings()['smtp_host'],
'username': get_settings()['smtp_username'],
'password': get_settings()['smtp_password'],
'encryption': smtp_encryption,
'port': get_settings()['smtp_port'],
}
for field in config:
if field is None:
return False
return True


def send_email(to, action, subject, html, attachments=None):
"""
Sends email and records it in DB
"""
from .tasks import send_email_task_sendgrid, send_email_task_smtp
if not string_empty(to):
email_service = get_settings()['email_service']
email_from_name = get_settings()['email_from_name']
Expand All @@ -36,40 +55,41 @@ def send_email(to, action, subject, html, attachments=None):
}

if not current_app.config['TESTING']:
if email_service == 'smtp':
smtp_encryption = get_settings()['smtp_encryption']
if smtp_encryption == 'tls':
smtp_encryption = 'required'
elif smtp_encryption == 'ssl':
smtp_encryption = 'ssl'
elif smtp_encryption == 'tls_optional':
smtp_encryption = 'optional'
else:
smtp_encryption = 'none'

config = {
'host': get_settings()['smtp_host'],
'username': get_settings()['smtp_username'],
'password': get_settings()['smtp_password'],
'encryption': smtp_encryption,
'port': get_settings()['smtp_port'],
}

from .tasks import send_mail_via_smtp_task
send_mail_via_smtp_task.delay(config, payload)
smtp_encryption = get_settings()['smtp_encryption']
if smtp_encryption == 'tls':
smtp_encryption = 'required'
elif smtp_encryption == 'ssl':
smtp_encryption = 'ssl'
elif smtp_encryption == 'tls_optional':
smtp_encryption = 'optional'
else:
payload['fromname'] = email_from_name
key = get_settings()['sendgrid_key']
if not key:
print('Sendgrid key not defined')
return
headers = {
"Authorization": ("Bearer " + key),
"Content-Type": "application/json"
}
from .tasks import send_email_task
send_email_task.delay(payload, headers)
smtp_encryption = 'none'

smtp_config = {
'host': get_settings()['smtp_host'],
'username': get_settings()['smtp_username'],
'password': get_settings()['smtp_password'],
'encryption': smtp_encryption,
'port': get_settings()['smtp_port'],
}
smtp_status = check_smtp_config(smtp_encryption)
if smtp_status:
if email_service == 'smtp':
send_email_task_smtp.delay(payload=payload, headers=None, smtp_config=smtp_config)
else:
key = get_settings().get('sendgrid_key')
if key:
headers = {
"Authorization": ("Bearer " + key),
"Content-Type": "application/json"
}
payload['fromname'] = email_from_name
send_email_task_sendgrid.delay(payload=payload, headers=headers, smtp_config=smtp_config)
else:
logging.exception('SMTP & sendgrid have not been configured properly')

else:
logging.exception('SMTP is not configured properly. Cannot send email.')
# record_mail(to, action, subject, html)
mail = Mail(
recipient=to, action=action, subject=subject,
Expand Down
72 changes: 39 additions & 33 deletions app/api/helpers/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from flask import current_app, render_template
from flask_celeryext import RequestContextTask
from marrow.mailer import Mailer, Message
from marrow.mailer.exc import MessageFailedException, DeliveryFailedException
from app import get_settings
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
Expand Down Expand Up @@ -51,58 +52,63 @@
celery = make_celery()


@celery.task(name='send.email.post')
def send_email_task(payload, headers):
message = Mail(from_email=payload['from'],
to_emails=payload['to'],
subject=payload['subject'],
html_content=payload["html"])
if payload['attachments'] is not None:
for attachment in payload['attachments']:
with open(attachment, 'rb') as f:
file_data = f.read()
f.close()
encoded = base64.b64encode(file_data).decode()
attachment = Attachment()
attachment.file_content = FileContent(encoded)
attachment.file_type = FileType('application/pdf')
attachment.file_name = FileName(payload['to'])
attachment.disposition = Disposition('attachment')
message.add_attachment(attachment)
sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key'])
logging.info('Sending an email regarding {} on behalf of {}'.format(payload["subject"], payload["from"]))
@celery.task(name='send.email.post.sendgrid')
def send_email_task_sendgrid(payload, headers, smtp_config):
try:
message = Mail(from_email=payload['from'],
to_emails=payload['to'],
subject=payload['subject'],
html_content=payload["html"])
if payload['attachments'] is not None:
for attachment in payload['attachments']:
with open(attachment, 'rb') as f:
file_data = f.read()
f.close()
encoded = base64.b64encode(file_data).decode()
attachment = Attachment()
attachment.file_content = FileContent(encoded)
attachment.file_type = FileType('application/pdf')
attachment.file_name = FileName(payload['to'])
attachment.disposition = Disposition('attachment')
message.add_attachment(attachment)
sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key'])
logging.info('Sending an email regarding {} on behalf of {}'.format(payload["subject"], payload["from"]))
sendgrid_client.send(message)
logging.info('Email sent successfully')
except Exception:
logging.exception('Error occured while sending the email')
except urllib.error.HTTPError as e:
if e.code == 429:
logging.warning("Sendgrid quota has exceeded")
send_email_task_smtp.delay(payload=payload, headers=None, smtp_config=smtp_config)
else:
logging.exception("The following error has occurred with sendgrid-{}".format(str(e)))


@celery.task(name='send.email.post.smtp')
def send_mail_via_smtp_task(config, payload):
def send_email_task_smtp(payload, smtp_config, headers=None):
mailer_config = {
'transport': {
'use': 'smtp',
'host': config['host'],
'username': config['username'],
'password': config['password'],
'tls': config['encryption'],
'port': config['port']
'transport': {
'use': 'smtp',
'host': smtp_config['host'],
'username': smtp_config['username'],
'password': smtp_config['password'],
'tls': smtp_config['encryption'],
'port': smtp_config['port']
}
}
}

mailer = Mailer(mailer_config)
mailer.start()
message = Message(author=payload['from'], to=payload['to'])
message.subject = payload['subject']
message.plain = strip_tags(payload['html'])
message.rich = payload['html']
message.attach(name=payload['attachments'])
if payload['attachments'] is not None:
for attachment in payload['attachments']:
message.attach(name=attachment)
mailer.send(message)
logging.info('Message sent via SMTP')
mailer.stop()


@celery.task(base=RequestContextTask, name='resize.event.images', bind=True)
def resize_event_images_task(self, event_id, original_image_url):
event = safe_query(db, Event, 'id', event_id, 'event_id')
Expand Down

0 comments on commit 91af8cb

Please sign in to comment.