-
Notifications
You must be signed in to change notification settings - Fork 9
/
mail.py
67 lines (57 loc) · 2.58 KB
/
mail.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
"""
Email backend that uses the GMail API via OAuth2 authentication.
"""
import base64
import logging
from django.conf import settings
from django.core.mail.backends.base import BaseEmailBackend
import google.oauth2.credentials
import googleapiclient.discovery
logger = logging.getLogger(__name__)
class GmailBackend(BaseEmailBackend):
def __init__(self, client_id=None, client_secret=None, refresh_token=None,
user_id=None, fail_silently=False, **kwargs):
super().__init__(fail_silently=fail_silently, **kwargs)
self.client_id = client_id or settings.GMAIL_API_CLIENT_ID
self.client_secret = client_secret or settings.GMAIL_API_CLIENT_SECRET
self.refresh_token = refresh_token or settings.GMAIL_API_REFRESH_TOKEN
if hasattr(settings, 'GMAIL_API_USER_ID'):
self.user_id = user_id or settings.GMAIL_API_USER_ID
else:
self.user_id = user_id or 'me'
credentials = google.oauth2.credentials.Credentials(
'token',
refresh_token=self.refresh_token,
token_uri='https://accounts.google.com/o/oauth2/token',
client_id=self.client_id,
client_secret=self.client_secret
)
self.service = googleapiclient.discovery.build('gmail', 'v1', credentials=credentials, cache_discovery=False)
def send_message(self, email_message):
if not email_message.recipients():
return False
message = email_message.message()
if email_message.bcc:
email_message._set_list_header_if_not_empty(message, 'Bcc', email_message.bcc)
raw_message = {'raw': base64.urlsafe_b64encode(message.as_bytes()).decode()}
return self.service.users().messages().send(userId=self.user_id, body=raw_message)
def send_messages(self, email_messages):
"""Send all messages using BatchHttpRequest"""
if not email_messages:
return 0
msg_count = 0
last_exception = None
def send_callback(r_id, response, exception):
nonlocal msg_count, last_exception
if exception is not None:
logger.exception('An error occurred sending the message via GMail API: %s', exception)
last_exception = exception
else:
msg_count += 1
batch = self.service.new_batch_http_request(send_callback)
for message in email_messages:
batch.add(self.send_message(message))
batch.execute()
if not self.fail_silently and last_exception:
raise last_exception
return msg_count