45 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			45 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """email factor tasks"""
 | |
| from smtplib import SMTPException
 | |
| from typing import Any, Dict, List
 | |
| 
 | |
| from celery import group
 | |
| from django.core.mail import EmailMessage
 | |
| from structlog import get_logger
 | |
| 
 | |
| from passbook.factors.email.models import EmailFactor
 | |
| from passbook.root.celery import CELERY_APP
 | |
| 
 | |
| LOGGER = get_logger()
 | |
| 
 | |
| 
 | |
| def send_mails(factor: EmailFactor, *messages: List[EmailMessage]):
 | |
|     """Wrapper to convert EmailMessage to dict and send it from worker"""
 | |
|     tasks = []
 | |
|     for message in messages:
 | |
|         tasks.append(_send_mail_task.s(factor.pk, message.__dict__))
 | |
|     lazy_group = group(*tasks)
 | |
|     promise = lazy_group()
 | |
|     return promise
 | |
| 
 | |
| 
 | |
| @CELERY_APP.task(bind=True)
 | |
| def _send_mail_task(self, email_factor_pk: int, message: Dict[Any, Any]):
 | |
|     """Send E-Mail according to EmailFactor parameters from background worker.
 | |
|     Automatically retries if message couldn't be sent."""
 | |
|     factor: EmailFactor = EmailFactor.objects.get(pk=email_factor_pk)
 | |
|     backend = factor.backend
 | |
|     backend.open()
 | |
|     # Since django's EmailMessage objects are not JSON serialisable,
 | |
|     # we need to rebuild them from a dict
 | |
|     message_object = EmailMessage()
 | |
|     for key, value in message.items():
 | |
|         setattr(message_object, key, value)
 | |
|     message_object.from_email = factor.from_address
 | |
|     LOGGER.debug("Sending mail", to=message_object.to)
 | |
|     try:
 | |
|         num_sent = factor.backend.send_messages([message_object])
 | |
|     except SMTPException as exc:
 | |
|         raise self.retry(exc=exc)
 | |
|     if num_sent != 1:
 | |
|         raise self.retry()
 | 
