
This guide covers:
Setting up necessary AWS resources (IAM User)
Finding your AWS Credentials
Configuring your Django project
Writing the code to send SMS
Creating a simple Django API endpoint for testing with Postman
Prerequisites:
- An AWS Account
- A Django project already set up
- Python and pip installed
- Postman (or similar API client) for testing
Step 1: Create an IAM User in AWS for SNS Access
- Log in to your AWS Management Console.
- Go to IAM (search for it).
- Click Users โ Add users.
- User Details:
- Username:
django-sns-sms-user
- Access type:
Check Programmatic access
- Username:
- Permissions:
- Choose Attach policies directly
- Search for and select
AmazonSNSFullAccess
- Click Next, review, and click Create user
IMPORTANT: For production, consider creating a custom policy allowing only
sns:Publish
.
Step 2: Find and Secure Your AWS Credentials
After creating the IAM user:
Copy the Access key ID and Secret access key
Click Download .csv
Do NOT expose these in your code
Instead, use environment variables or .env
files (more below).
Step 3: Configure Your Django Project
Install boto3 and Django REST Framework:
pip install boto3 djangorestframework
Add to INSTALLED_APPS
in settings.py
:
INSTALLED_APPS = [
...
'rest_framework',
]
Set Environment Variables (locally or via .env
)
export AWS_ACCESS_KEY_ID='YOUR_ACCESS_KEY'
export AWS_SECRET_ACCESS_KEY='YOUR_SECRET_KEY'
export AWS_REGION_NAME='us-east-1'
Use a region that supports SNS SMS (e.g.,
us-east-1
)
Update settings.py
:
import os
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
AWS_REGION_NAME = os.environ.get('AWS_REGION_NAME')
if not all([AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION_NAME]):
print("WARNING: AWS credentials or region not fully configured via environment variables.")
Step 4: Implement the SMS Sending Function
yourapp/utils.py
:
import boto3
from django.conf import settings
import logging
from botocore.exceptions import ClientError
logger = logging.getLogger(__name__)
def send_sms(phone_number: str, message: str) -> bool:
if not all([settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY, settings.AWS_REGION_NAME]):
logger.error("AWS SNS credentials or region not configured in settings.")
return False
if not phone_number.startswith('+'):
logger.error(f"Invalid phone number format: {phone_number}. Must be E.164 (e.g., +1XXXXXXXXXX)")
return False
try:
client = boto3.client(
"sns",
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
region_name=settings.AWS_REGION_NAME
)
response = client.publish(
PhoneNumber=phone_number,
Message=message,
MessageAttributes={
'AWS.SNS.SMS.SMSType': {
'DataType': 'String',
'StringValue': 'Transactional'
}
}
)
logger.info(f"SMS sent successfully to {phone_number}. Message ID: {response.get('MessageId')}")
return True
except ClientError as e:
logger.error(f"AWS ClientError sending SMS: {e.response.get('Error', {}).get('Message')}")
return False
except Exception as e:
logger.error(f"Unexpected error sending SMS: {e}", exc_info=True)
return False
Step 5: Create a Django API View and URL for Testing
yourapp/views.py
:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .utils import send_sms
class SendSMSAPIView(APIView):
def post(self, request, *args, **kwargs):
phone_number = request.data.get('phone_number')
message = request.data.get('message')
if not phone_number or not message:
return Response({"error": "Both 'phone_number' and 'message' are required."},
status=status.HTTP_400_BAD_REQUEST)
if not phone_number.startswith('+') or not phone_number[1:].isdigit():
return Response({"error": "Invalid phone number format (E.164 required)."},
status=status.HTTP_400_BAD_REQUEST)
if len(message) > 1600:
return Response({"error": "Message exceeds maximum length."},
status=status.HTTP_400_BAD_REQUEST)
success = send_sms(phone_number, message)
if success:
return Response({"message": f"SMS sent to {phone_number}."})
return Response({"error": "Failed to send SMS."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
yourapp/urls.py
:
from django.urls import path
from .views import SendSMSAPIView
urlpatterns = [
path('send-sms/', SendSMSAPIView.as_view(), name='send_sms_api'),
]
project/urls.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('yourapp.urls')),
]
Step 6: Postman Testing
Run Django
python manage.py runserver
Postman Setup
- Method:
POST
- URL:
http://127.0.0.1:8000/api/send-sms/
- Headers:
Content-Type: application/json
- Body (raw โ JSON):
{
"phone_number": "+1XXXXXXXXXX",
"message": "Hello from Django and AWS SNS!"
}
If you're in SNS Sandbox, only verified phone numbers will receive the SMS
To send to any number, request production access via AWS Support
Youโve successfully:
- Created AWS IAM access
- Secured your credentials
- Set up SNS SMS in Django
- Built an API endpoint
- Tested it via Postman