Technologies

Sending Transactional OTP Emails in Django

Discover how to efficiently send OTP emails in Django using threading, AWS SES, and Redis, ensuring timely delivery and optimized user expe..

Transactional emails, especially OTPs (One-Time Passwords), are a critical part of many web applications. Ensuring timely delivery while maintaining a responsive user experience can be challenging. In this guide, we'll combine Django, threading, AWS SES, and Redis to create an efficient OTP email system.

What is Threading?

Threading refers to the concurrent execution of more than one sequential set of instructions. In the context of web applications, threading can allow a program to run multiple operations simultaneously in separate threads. This is especially useful in scenarios where certain tasks might take time (like sending emails), and we don’t want to keep the user waiting. By offloading such tasks to a separate thread, the main application remains responsive.

What is AWS SES?

Amazon Simple Email Service (AWS SES) is a cloud-based email sending service designed to help digital marketers and application developers send transactional, marketing, or informational emails. It provides a reliable, scalable, and cost-effective way to send emails without having to maintain your own infrastructure. With SES, you have no upfront fees, and you pay for what you use.

What is Redis?

Redis is an open-source, in-memory data structure store that can be used as a database, cache, and message broker. It supports various data structures like strings, hashes, sets, and lists. Redis excels in scenarios where quick access to data is crucial, such as caching. In our context, we're using Redis to cache the OTPs, ensuring efficient resend mechanisms.

Why This Approach?

Threading: To send the email without blocking the main application.

AWS SES: A scalable and reliable email sending service. Learn more about its benefits in our Deep Dive into AWS Services article.

Redis: To cache OTPs, ensuring users don’t get a new OTP every time they click "resend". Redis is a robust in-memory data structure store. Learn more about Redis here.

Prerequisites:

A Django project set up.

AWS account with SES and necessary credentials.

Redis server running.

Steps:

Setup AWS SES:

Verify your sending domain or email address.

Note down the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

Install Required Packages:


pip install boto3 redis

Django Configuration:

In your settings.py:


AWS_ACCESS_KEY_ID = 'your_access_key'
AWS_SECRET_ACCESS_KEY = 'your_secret_key'
AWS_REGION_NAME = 'your_region'

Setting up Redis:

In settings.py:


REDIS_HOST = 'localhost'
REDIS_PORT = 6379

Sending Email with AWS SES:


import boto3
from threading import Thread

def send_email(subject, message, to_email): 
    client = boto3.client(
        'ses', 
        aws_access_key_id=AWS_ACCESS_KEY_ID, 
        aws_secret_access_key=AWS_SECRET_ACCESS_KEY, 
        region_name=AWS_REGION_NAME 
    ) 
    response = client.send_email(
        Source='[email protected]', 
        Destination={'ToAddresses': [to_email]}, 
        Message={ 
            'Subject': {'Data': subject}, 
            'Body': {'Text': {'Data': message}} } 
        ) 
    return response

def threaded_send_email(subject, message, to_email): 
    thread = Thread(target=send_email, args=(subject, message, to_email)) 
    thread.start()

Generating and Caching OTP:


import random
import redis

r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)

def generate_otp(email):
   otp = ''.join(random.choices('0123456789', k=6))
   r.setex(email, 300, otp)  # Cache OTP for 5 minutes
   return otp

def get_cached_otp(email):
   return r.get(email)

Tying Everything Together:


def send_otp_email(email):
   otp = get_cached_otp(email)
   if not otp:
       otp = generate_otp(email)
   subject = "Your OTP Code"
   message = f"Your OTP code is: {otp}"
   threaded_send_email(subject, message, email)

Handling Resend OTP:

In your view or API:


def resend_otp(request, email):
   send_otp_email(email)
   return HttpResponse("OTP resent successfully!")

Conclusion

With this approach, sending OTPs is efficient and user-friendly. AWS SES ensures reliable delivery, Redis optimizes the resend mechanism, and threading keeps the application snappy. Always monitor your AWS costs and the state of your Redis server to ensure smooth operation!

Need help with optimizing your Django Apps for optimum delivery ? Check out our Product Development & Engineering Service.

Get a consultation