Email Notification in Django
- General
Email Notification in Django
For sending email notification in django we use django’s send_mail function, with using some smtp sever.
we can get smtp server from free smtp service providers like SendGrid.
In our settings.py file we define some parameters for sending mails like:-
1 2 3 4 5 6 7 8 9 10 11 12 |
if os.getenv('DEV_ENV') == 'PRODUCTION': EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_USE_TLS = True EMAIL_PORT = 587 EMAIL_HOST = "email-smtp.****com" EMAIL_HOST_USER = "AK*******GSPHDZ72SANP" EMAIL_HOST_PASSWORD = "*******" FROM_EMAIL = 'Interface <default server>' else: EMAIL_BACKEND = "sgbackend.SendGridBackend" SENDGRID_API_KEY = os.getenv('SENDGRID_KEY') FROM_EMAIL = '<mail id registered on sendgrid>' |
we define a function in our service file for sending mails like-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def send_email(subject="", html_content="", recipients=[], files=None, from_email=settings.FROM_EMAIL): try: from_email = settings.FROM_EMAIL if from_email is None else from_email if subject == "" or html_content == "" or len(recipients) == 0: return False msg = EmailMessage(subject=subject, body=html_content, from_email=from_email,to=recipients,reply_to=[settings.FROM_EMAIL]) msg.content_subtype = "html" # Main content is now text/html if files is not None: msg.attach_file(files) mail_status = msg.send() if mail_status: log_info.info("email send") return True, {} else: log.error("error in sending email.") return False, {'message': 'error in sending email.'} except Exception as e: log.error("Exception: " + str(e)) return False, {'message': str(e)} |
Now if we want to send mails asynchronously we define a decorator:
1 2 3 4 5 6 7 |
def execute_in_background(function): def start_thread(*args, **kwargs): thread = Thread(target=function, args=args, kwargs=kwargs) thread.start() return start_thread |
and define a async send_mail function which calls previously defined send_mail function,
1 2 3 4 5 6 |
@execute_in_background def send_email_async(subject="", html_content="", recipients=[], files=None, from_email=settings.FROM_EMAIL): try: stat,msg = send_email(subject=subject, html_content=html_content, recipients=recipients, files=files, from_email=from_email) except Exception as e: log.error("Exception in send_email_async: " + str(e)) |
Now for sending template based email notifications we define some types of notifications in a constant file like:
1 2 3 4 5 6 7 |
EMAIL_NOTIFICATION_TYPES = { "VERIFICATION_EMAIL":"verification_email", "SIGNUP_SUCCESSFUL":"signup_successful", "PAYMENT_SUCCESSFUL":"payment_successful", "FAILURE_OF_PAYMENTS":"failure_of_payment", ... } |
and then a general function for sending those mails:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
def send_email_notification(email_type, context_data, recipients=[],files = None): try: #2 if email_type == EMAIL_NOTIFICATION_TYPES.get('SIGNUP_SUCCESSFUL',''): template = get_template("email_notifications/signup_successful.html") context_data['login_page_link'] = LOGIN_LINK html = template.render(context_data) mail_status, response = send_email(subject="Signup Successful", html_content=html, recipients=recipients, files=None, from_email=settings.FROM_EMAIL) #3 if email_type == EMAIL_NOTIFICATION_TYPES.get('PAYMENT_SUCCESSFUL',''): template = get_template("email_notifications/payment_successful.html") context_data['login_page_link'] = LOGIN_LINK html = template.render(context_data) mail_status, response = send_email(subject="Payment Successful", html_content=html, recipients=recipients, files=None, from_email=settings.FROM_EMAIL) #4 elif email_type == EMAIL_NOTIFICATION_TYPES.get('FAILURE_OF_PAYMENTS',''): template = get_template("email_notifications/payment_failure.html") context_data['login_page_link'] = LOGIN_LINK html = template.render(context_data) mail_status, response = send_email(subject="Failure of payment", html_content=html,recipients=recipients, files=None, from_email=settings.FROM_EMAIL) #5 .... |
and we are using edited templates(html templates) for rendering and we pass all related data in context_data which is a dict object.
Next for sending these asynchronously we define a new async function in which we call our send_email_notification function.
1 2 3 4 5 6 7 8 9 10 |
@execute_in_background def send_email_notification_async(email_type, context_data, recipients=[],files = None): try: mail_status, response = send_email_notification(email_type=email_type, context_data=context_data, recipients=recipients,files=files) log_info.info(f"mail sent to {recipients }") except Exception as e: log.error("Exception in send_email_notification_async:" + str(e)) responseData = {'message': str(e), 'status': False, "status_code": status.HTTP_300_MULTIPLE_CHOICES} return False, responseData |
Now we can call it like-
1 |
send_email_notification_async(email_type=EMAIL_NOTIFICATION_TYPES.get("SIGNUP_SUCCESSFUL",None),context_data=context_data,recipients=recipients) |
Related content
Auriga: Leveling Up for Enterprise Growth!
Auriga’s journey began in 2010 crafting products for India’s