Pull email sending concerns out into a standalone service
This commit is contained in:
parent
7d535a2c31
commit
c1a61730d5
4 changed files with 46 additions and 57 deletions
|
|
@ -8,11 +8,11 @@ EmailAddress = str
|
|||
|
||||
@dataclass
|
||||
class Email:
|
||||
api_key: str
|
||||
bird_api_key: str
|
||||
sender: EmailAddress
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, config: dict[str, Any]) -> 'Email':
|
||||
assert_key_of_type(config, 'api_key', str)
|
||||
assert_key_of_type(config, 'bird_api_key', str)
|
||||
assert_key_of_type(config, 'sender', str)
|
||||
return Email(api_key=config['api_key'], sender=config['sender'])
|
||||
return Email(bird_api_key=config['bird_api_key'], sender=config['sender'])
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
from typing import Any
|
||||
from email.utils import formatdate, make_msgid
|
||||
import abc
|
||||
from email.message import EmailMessage
|
||||
|
||||
from ..config.email import Email as EmailConfig
|
||||
from .service import NotificationService
|
||||
from .data import Notification
|
||||
|
||||
|
||||
class EmailService(NotificationService):
|
||||
def __init__(self, config: EmailConfig):
|
||||
self._config = config
|
||||
|
||||
def notify(self, user: Any, notification: Notification):
|
||||
email = self._prepare_email(user.email, notification)
|
||||
self.send_email(email)
|
||||
|
||||
@abc.abstractmethod
|
||||
def send_email(self, email: EmailMessage):
|
||||
pass
|
||||
|
||||
def _render_template_text(self, notification: Notification) -> str:
|
||||
# TODO
|
||||
return ''
|
||||
|
||||
def _render_template_html(self, notification: Notification) -> str:
|
||||
# TODO
|
||||
return ''
|
||||
|
||||
def _prepare_email(self, receiver: str, notification: Notification) -> EmailMessage:
|
||||
msg = EmailMessage()
|
||||
msg['From'] = self._config.sender
|
||||
msg['To'] = receiver
|
||||
msg['Subject'] = notification.title
|
||||
|
||||
msg['Date'] = formatdate(localtime=True)
|
||||
msg['Message-ID'] = make_msgid()
|
||||
|
||||
msg.set_content(self._render_template_text(notification))
|
||||
msg.add_alternative(self._render_template_html(notification), subtype='html')
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
class BirdEmailServiceImpl(EmailService):
|
||||
def send_email(self, email: EmailMessage):
|
||||
# TODO: Implement Bird Specific Email sending and Error handling
|
||||
pass
|
||||
|
||||
|
||||
def get_service(config: EmailConfig) -> EmailService:
|
||||
return BirdEmailServiceImpl(config)
|
||||
42
src/services/email.py
Normal file
42
src/services/email.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
from dataclasses import dataclass, field
|
||||
from email.utils import formatdate, make_msgid
|
||||
import abc
|
||||
|
||||
from ..config.email import Email as EmailConfig, EmailAddress
|
||||
|
||||
|
||||
@dataclass
|
||||
class EmailDTO:
|
||||
# Who the email is from
|
||||
sender: EmailAddress
|
||||
# Who the email is to
|
||||
to: EmailAddress
|
||||
# The subject of the email
|
||||
subject: str
|
||||
# The textual content of the email
|
||||
text: str
|
||||
# HTML alternate content. (Optional: Textual content is required)
|
||||
html: str | None = None
|
||||
# A unique ID for identifying this Email
|
||||
message_id: str = field(default_factory=make_msgid)
|
||||
# The date that the email was sent
|
||||
date: str = field(default_factory=lambda: formatdate(localtime=True))
|
||||
|
||||
|
||||
class EmailService:
|
||||
@abc.abstractmethod
|
||||
def send_email(self, email: EmailDTO):
|
||||
pass
|
||||
|
||||
|
||||
class BirdEmailServiceImpl(EmailService):
|
||||
def __init__(self, config: EmailConfig):
|
||||
self._config = config
|
||||
|
||||
def send_email(self, email: EmailDTO):
|
||||
# TODO: Implement Bird Specific Email sending and Error handling
|
||||
pass
|
||||
|
||||
|
||||
def get_service(config: EmailConfig) -> EmailService:
|
||||
return BirdEmailServiceImpl(config)
|
||||
Loading…
Add table
Add a link
Reference in a new issue