Technique

카카오톡 플러스친구를 이용한 email 간편 전송 서비스 만들기(feat, DJANGO, groomide) 6

JAY-GO 2018. 9. 16. 22:53
반응형

 이번 포스팅에서는 Django 서비스의 동작 로직을 구현하기 위한 view를 작성 하도록 하겠습니다.

 

 전체 코드는 아래와 같고, 이어서 중요 구문에 대하여 설명 하도로 하겠습니다.

<sendemail/views.py>

import json
from django.http import JsonResponse
from django.contrib.auth import get_user_model
from django.views.decorators.csrf import csrf_exempt
from .models import mail_list, message_list
from django.core.mail import EmailMessage

# Create your views here.

User = get_user_model()


def keyboard(request):
return JsonResponse(
{
"type": "text"
}
)


@csrf_exempt
def message(request):
if request.method == 'POST':
load_json = json.loads(request.body.decode('utf8'))
else:
load_json = {}
user_key = load_json.get('user_key')
if user_key:
try:
django_user = User.objects.get(username=user_key)
except User.DoesNotExist:
django_user = User.objects.create_user(username=user_key)

message_type = load_json['type']
content = load_json['content']
email_content = ""

if message_type == 'text' and content == '전송':
stacked_msg = message_list.objects.filter(user=django_user,
emailed=False)
if stacked_msg:
for msg in stacked_msg:
if msg.content_text:
email_content += msg.content_text + "\n"
else:
email_content += "<이미지 링크 : " + msg.content_img + ">\n"
email_title = django_user.username + "님이 전송한 메시지 입니다"
email_list = mail_list.objects.values_list('email', flat=True)
email_sender = EmailMessage(email_title, email_content,
to=email_list)
email_sender.send()
for msg in stacked_msg:
msg.emailed = True
msg.save()
response_msg = {
"message": {
"text": django_user.username +
"님의 메시지가 email로 전송되었습니다.\n\n" +
email_content
}
}
elif message_type == 'text':
form_msg = message_list(user=django_user, content_text=content,
emailed=False)
form_msg.save()
response_msg = {
"message": {
"text": django_user.username + "님의 메시지 입니다.\n" + content
}
}
elif message_type == 'photo':
form_msg = message_list(user=django_user, content_img=content,
emailed=False)
form_msg.save()
response_msg = {
"message": {
"text": django_user.username + "님의 사진 입니다.\n",
"photo": {
"url": content,
"width": 720,
"height": 630
}
}
}
else:
response_msg = {}

return JsonResponse(response_msg)


 ㅇ 사용자 모델 클래스 참조

User = get_user_model()

  - 플러스 친구에서 제공하는 user_key를 저장하고 사용할 User 모델의 클래스를 참조합니다. 향후 사용자모델에 저장된 사용자를 참조 하거나, 새로운 사용자를 생성할때 활용합니다.


 ㅇ 플러스친구 메시지 API의 요청 대응

if request.method == 'POST':
load_json = json.loads(request.body.decode('utf8'))
else:
load_json = {}

  - 플러스친구 API 문서를 보면 메시지 수신 API는 json, utf-8 형식으로 post의 content를 구성합니다. 이를 디코드 하여 json 콘텐츠만 dict 형식으로 load_json 변수에 담습니다.


 ㅇ 사용자 정보 확인

if user_key:
try:
django_user = User.objects.get(username=user_key)
except User.DoesNotExist:
django_user = User.objects.create_user(username=user_key)

  - DB에 기존 사용자와 일치하는지 확인 합니다. 기존 사용자중에 없으면 새로 사용자를 생성 합니다.


  ㅇ email 전송 명령 수신 확인

if message_type == 'text' and content == '전송':
stacked_msg = message_list.objects.filter(user=django_user,
emailed=False)
if stacked_msg:
for msg in stacked_msg:
if msg.content_text:
email_content += msg.content_text + "\n"
else:
email_content += "<이미지 링크 : " + msg.content_img + ">\n"

  - 플러스 친구에서 '전송' 명령이 입력되었는지 확인 합니다. '전송' 명령이 호출되면 해당 user_key로 db에 저장된 컨텐츠들 중 email 전송을 시행하지 않은 컨텐츠들의 쿼릿셋을 가져옵니다. 

  - 가져온 쿼리셋에 값이 존재하면(즉, 발송하지 않은 컨텐츠가 있으면) 이를 나열하여  email 발소을 위한 txt를 만듭니다.

  - 이 과정에서 저장된 컨텐츠의 형식에 따라 다른 형태로 txt를 만들었습니다.(tag 등을 통하여 email에 그림이 바로 나오도록 할 수 도 있을 것입니다.)


  ㅇ email 발송

            email_title = django_user.username + "님이 전송한 메시지 입니다"
email_list = mail_list.objects.values_list('email', flat=True)
email_sender = EmailMessage(email_title, email_content,
to=email_list)
email_sender.send()

  - 앞에서 셋팅한 SMTP 서버 사용을 위한 EmailMessage 함수를 이용하여 email을 전송 합니다.


  ㅇ email 발송결과 저장 및 알림메시지 준비

            for msg in stacked_msg:
msg.emailed = True
msg.save()
response_msg = {
"message": {
"text": django_user.username +
"님의 메시지가 email로 전송되었습니다.\n\n" +
email_content
}
}

  - email 발송이 완료된 후에 그 결과를 db에 저장 합니다.

  - 플러스친구 '전송' 명령의 response로 email 전송이 완료되었음을 알리는 메시지를 준비 합니다.


  ㅇ 플러스친구로 입력된 컨텐츠 확인

    elif message_type == 'text':
form_msg = message_list(user=django_user, content_text=content,
emailed=False)
form_msg.save()
response_msg = {
"message": {
"text": django_user.username + "님의 메시지 입니다.\n" + content
}
}
elif message_type == 'photo':
form_msg = message_list(user=django_user, content_img=content,
emailed=False)
form_msg.save()
response_msg = {
"message": {
"text": django_user.username + "님의 사진 입니다.\n",
"photo": {
"url": content,
"width": 720,
"height": 630
}
}
}

  - 플러스친구로 '전송' 이외의 입력에 대응하는 부분 입니다.

  - 컨텐츠의 형태(text,photo)에 맞게 db에 입력하고, 이후 해당 컨텐츠를 그대로 플러스친구로 response 하도록 하여 입력을 확인하도록 구성되어 있습니다. 


  ㅇ 입력된 컨텐츠에 대한 응답

    return JsonResponse(response_msg)

  - View 로직이 완료되면 항시 response를 합니다. 위에서 각 상황에 따라 달리 작성된 response_msg를 json 형식으로 response 하면 플러스친구가 이를 수신하여 반응 합니다.


여기까지 view에 대한 성명을 마쳤습니다. 여기에 작성된 view는 이해를 돕기 위 하여 예외처리, 모듈화, decorator 등을 사용하지 않고 작성되어 있습니다. 간단하게 구성된 서비스 이기 때문에 위처럼 동작하도록 해도 무방하나, 다양한 상황에 대응해야 하고 서비스 규모가 커져 코드 재사용이 빈번한 경우에는 예외처리, 모듈화 및 decorator 구성을 통하여 체계적으로 코드들을 관리해야 합니다.


다음 포스팅에서는 지금까지 작성된 django 서비스의 동작을 확인해 보도록 하겠습니다.

반응형