DEV Community

Tonny Kirwa
Tonny Kirwa

Posted on

OTP Generation, Redis Storage, SMS Sending, and Verification with African Talking API in Django and DRF

To implement OTP generation, storage in Redis, sending an SMS, and OTP verification using the African Talking API in a Django Rest Framework (DRF) application, follow these steps:

1. Create a Django Project and App:
If you haven't already, create a Django project and a DRF app:

django-admin startproject project_name
cd project_name
python manage.py startapp otp_api
Enter fullscreen mode Exit fullscreen mode

2. Install Required Packages:
Install the necessary packages for Redis, the African Talking API, and Django Rest Framework:

pip install redis africastalking djangorestframework
Enter fullscreen mode Exit fullscreen mode

3. Configure Django Settings:
Add the following configurations to your project's settings:

# project_name/settings.py

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'otp_api',
]

# Redis configuration
REDIS_HOST = 'localhost'  # Replace with your Redis server host
REDIS_PORT = 6379         # Replace with your Redis server port
REDIS_DB = 0              # Replace with your Redis database number

# African Talking API configuration
AFRICASTALKING_API_USERNAME = 'YOUR_API_USERNAME'
AFRICASTALKING_API_KEY = 'YOUR_API_KEY'
Enter fullscreen mode Exit fullscreen mode

4. Create OTP Generation and SMS Sending Logic:
Inside your otp_api app, create views and serializers for OTP generation, SMS sending, and OTP verification.

Here's an example of what these views might look like:

# otp_api/views.py

import random
import redis
from django.conf import settings
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.serializers import Serializer, CharField
from africastalking.Africastalking import initialize
from africastalking.SMS import send

# Initialize Redis client
redis_client = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB)

# Initialize African Talking API
initialize(settings.AFRICASTALKING_API_USERNAME, settings.AFRICASTALKING_API_KEY)

class GenerateOTPSerializer(Serializer):
    phone_number = CharField()

class VerifyOTPSerializer(Serializer):
    phone_number = CharField()
    otp = CharField()

class SendOTP(APIView):
    def post(self, request):
        serializer = GenerateOTPSerializer(data=request.data)
        if serializer.is_valid():
            phone_number = serializer.validated_data['phone_number']
            otp = str(random.randint(1000, 9999))
            redis_client.setex(phone_number, 300, otp)

            # Send OTP via SMS
            message = f'Your OTP is: {otp}'
            recipients = [phone_number]
            try:
                send(message, recipients)
                return Response({'message': 'OTP sent successfully.'}, status=status.HTTP_200_OK)
            except Exception as e:
                return Response({'error': f'Failed to send OTP: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

class VerifyOTP(APIView):
    def post(self, request):
        serializer = VerifyOTPSerializer(data=request.data)
        if serializer.is_valid():
            phone_number = serializer.validated_data['phone_number']
            otp = serializer.validated_data['otp']

            # Check if OTP exists in Redis
            stored_otp = redis_client.get(phone_number)
            if stored_otp and stored_otp.decode('utf-8') == otp:
                # OTP is valid
                return Response({'message': 'OTP verified successfully.'}, status=status.HTTP_200_OK)
            else:
                # OTP is invalid
                return Response({'error': 'Invalid OTP.'}, status=status.HTTP_400_BAD_REQUEST)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Enter fullscreen mode Exit fullscreen mode

5. Configure URLs:
Add URL patterns for the views in your app's urls.py:

# otp_api/urls.py

from django.urls import path
from .views import SendOTP, VerifyOTP

urlpatterns = [
    path('send-otp/', SendOTP.as_view(), name='send-otp'),
    path('verify-otp/', VerifyOTP.as_view(), name='verify-otp'),
]
Enter fullscreen mode Exit fullscreen mode

6. Run Migrations:
Apply migrations to create the necessary database tables for DRF:

python manage.py migrate
Enter fullscreen mode Exit fullscreen mode

7. Run the Development Server:
Start the Django development server:

python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

8. Testing:
You can now send POST requests to /send-otp/ to generate and send an OTP via SMS and /verify-otp/ to verify the OTP. Make sure to replace http://localhost:8000/ with your actual server URL.

Here's an example of how to test the endpoints using curl:

Sending OTP:

curl -X POST http://localhost:8000/send-otp/ -d "phone_number=RECIPIENT_PHONE_NUMBER"
Enter fullscreen mode Exit fullscreen mode

Verifying OTP:

curl -X POST http://localhost:8000/verify-otp/ -d "phone_number=RECIPIENT_PHONE_NUMBER" -d "otp=1234"
Enter fullscreen mode Exit fullscreen mode

Replace RECIPIENT_PHONE_NUMBER with the recipient's phone number and adjust the endpoints according to your project's URL configuration.

Remember to handle exceptions and errors more robustly in a production environment and implement proper authentication and validation for your API endpoints.

Top comments (0)