forked from hamano/flask-mail-sendgrid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flask_mail_sendgrid.py
114 lines (95 loc) · 4.08 KB
/
flask_mail_sendgrid.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# -*- coding: utf-8 -*-
"""
flask_mail_sendgrid
~~~~~~~~~~~~~
Flask extension for sendgrid. It has same interface with Flask-Mail.
:copyright: (c) 2018 by HAMANO Tsukasa.
:license: MIT, see LICENSE for more details.
"""
import base64
import sendgrid
from sendgrid.helpers.mail import Mail
from sendgrid.helpers.mail import Email
from sendgrid.helpers.mail import Content
from sendgrid.helpers.mail import Personalization
from sendgrid.helpers.mail import Attachment
from flask_mail import Message
from python_http_client.exceptions import BadRequestsError
class MailSendGrid():
def __init__(self, app=None):
self.app = app
if app is not None:
self.state = self.init_app(app)
else:
self.state = None
def init_app(self, app):
state = {}
self.api_key = app.config['MAIL_SENDGRID_API_KEY']
self.default_sender = app.config.get('MAIL_DEFAULT_SENDER', 'no-reply@localhost')
self.sg = sendgrid.SendGridAPIClient(api_key=self.api_key)
# register extension with app
app.extensions = getattr(app, 'extensions', {})
app.extensions['mail'] = self
return state
def _make_sendgrid_mail(self, message):
mail = Mail()
if message.sender:
mail.from_email = Email(message.sender)
else:
mail.from_email = Email(self.default_sender)
if message.mail_options and message.mail_options.get('from_name'):
mail.from_email.name = message.mail_options.get('from_name')
template_id = getattr(message, 'template_id', None)
if template_id:
mail.template_id = template_id
if message.subject:
mail.subject = message.subject
if message.recipients:
if type(message.recipients) == list:
personalization = Personalization()
for recipient in message.recipients:
personalization.add_to(Email(recipient))
if message.cc:
if type(message.cc) == list:
for recipient in message.cc:
personalization.add_cc(Email(recipient))
else:
raise Exception("type(cc) must be list")
if message.bcc:
if type(message.bcc) == list:
for recipient in message.bcc:
personalization.add_bcc(Email(recipient))
else:
raise Exception("type(bcc) must be list")
dynamic_template_data = getattr(message, 'dynamic_template_data', None)
if dynamic_template_data:
personalization.dynamic_template_data = dynamic_template_data
mail.add_personalization(personalization)
else:
raise Exception("unsupported type yet")
if message.body:
mail.add_content(Content("text/plain", message.body))
if message.html:
mail.add_content(Content("text/html", message.html))
if message.reply_to:
mail.reply_to = Email(message.reply_to)
if message.attachments:
for attachment in message.attachments:
file_content = base64.b64encode(attachment.data).decode('UTF-8')
mail.add_attachment(Attachment(
file_content=file_content,
file_name=attachment.filename,
file_type=attachment.content_type,
disposition=attachment.disposition,
))
return mail
def send(self, message):
mail = self._make_sendgrid_mail(message)
try:
res = self.sg.client.mail.send.post(request_body=mail.get())
if int(res.status_code / 100) != 2:
raise Exception("error response from sendgrid {}".format(res.status_code))
except BadRequestsError as e:
raise Exception("sendgrid response {}: {}".format(e.status_code, e.body))
def __getattr__(self, name):
return getattr(self.state, name, None)