概要
Django REST FrameworkとAWS SNSを利用してSMSテキストを送信する実装を説明します!
使用技術
pyproject.toml
python = "^3.11.2"
Django = "^4.2.7"
djangorestframework = "^3.14.0"
boto3 = "^1.28.84"
injector = "^0.21.0"
pydantic = "^1.10.7"
gunicorn = "^21.2.0"
説明する前の前提
コードの細部の説明はあまりしません
また、インポートもとのコードが不要な場合は明記していません
ご了承ください🙇
AWS SNSとは
以下、公式サイトに説明は任せる
まずはコードの確認
sms_view.py
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from common.environment_variable import settings
from common.sms import SnsWrapper
from app.injectors import injector
from app.serializers import SmsSerializer
class SmsViewSet(ViewSet):
"""SMSを送信するAPI"""
serializer_class = SmsSerializer
@action(methods=["post"], detail=False)
def sms(self, request):
"""SMS送信API
Parameters:
phone_number(str): 電話番号
Returns:
detail (str): メッセージ
"""
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
sms = injector.get(SnsWrapper)
sms.publish_text_message(
settings.INTERNATIONAL_TEL_IDENTIFICATION_NUMBER
+ serializer.validated_data.get("phone_number"),
)
return Response(
{"detail": "SMS送信に成功しました"},
status=status.HTTP_200_OK,
)
SMS送信のAPIのビュー部分です
injector.py
import boto3
from injector import Binder, Injector, Module
from common.environment_variable import aws_settings
from common.sms import SnsResource, SnsWrapper
class SnsWrapperModule(Module):
def configure(self, binder):
binder.bind(SnsWrapper)
class LocalModule(Module):
"""Local環境用のモジュール"""
def configure(self, binder: Binder) -> None:
sns_resource = SnsResource(
boto3.resource(
"sns",
region_name=aws_settings.REGION_NAME,
# localstackに接続(http://localhost:4566)
endpoint_url=aws_settings.ENDPOINT_URL,
)
)
binder.bind(SnsResource, to=sns_resource)
class DevModule(Module):
"""Dev環境用のモジュール"""
def configure(self, binder: Binder) -> None:
sns_resource = SnsResource(
boto3.resource("sns", region_name=aws_settings.REGION_NAME)
)
binder.bind(SnsResource, to=sns_resource)
injector = Injector([SnsWrapperModule()])
ローカル環境とDEV環境で含めるラッパーモジュールを切り替えられるようにしています
ローカルではlocalstackを使用して、SNSの擬似的なレスポンスを返してくれるようにしています
sms.py
from injector import inject
from common.environment_variable import settings
class SnsResource:
"""SNSのResource用のクラス"""
def __init__(self, sns_resource):
self.sns_resource = sns_resource
class SnsWrapper:
"""Amazon SNSのトピックとサブスクリプションの機能をカプセル化する"""
@inject
def __init__(self, sns_resource: SnsResource):
"""
:param sns_resource: Boto3 Amazon SNSリソース
"""
self.sns_resource = sns_resource.sns_resource
def publish_text_message(self, phone_number):
"""
サブスクリプションを必要とせずに、直接電話番号にテキストメッセージを送信するメソッド
:Parameters:
phone_number(str): 電話番号
"""
message = "SMSテキストメッセージだぽん"
self.sns_resource.meta.client.publish(
PhoneNumber=phone_number,
Message=message,
MessageAttributes={
"AWS.SNS.SMS.SenderID": {
"DataType": "String",
# 差出人名を指定できます
"StringValue": settings.SMS_SENDER_NAME,
}
},
)
以下記事を参考に送信メソッドを実装します
環境変数の管理方法について
環境変数の管理方法については以下を参照ください
boto3について
最後に
流れさえ、抑えればスムーズに開発が進められると思います🐰