본문 바로가기
웹 개발 이야기/django

[django] Twilio를 이용한 랜덤숫자 6자리 SMS 발송

by Gommin 2023. 5. 9.

// Twilio 사이트에서 회원가입 후, 전화번호 및 api key 생성 필요 (사이트에서 안내하는대로 진행하면 된다.)
// Twilio 무료 사용 , 인증한 자신의 휴대폰에만 SMS 보낼 있음

// Twilio 설치 필요
// 1. pip3 install twilio
// 2. Settings.py INSTALLED_APPS ‘twilio’ 추가

laboratory/url.py

app_name = 'laboratory'

urlpatterns = [
    path('sendcertificode/', views.sendcertificode, name='sendcertificode'),
    path('chkcertificode/', views.chkcertificode, name='chkcertificode'),
]

 

views.py

import random
from twilio.rest import Client

# 6자리 숫자 생성
def generate_random_number():
    # Generate a random 6-digit integer
    return random.randrange(100000, 1000000)

# 인증코드 SMS 발송
def sendcertificode(request):
    random_number = generate_random_number()
    request.session['certificode'] = random_number
    hp_number = request.POST.get('hp_number')

    if hp_number:
        # 휴대폰 번호 값이 정상적으로 회신되었을 때
        # twilio SMS Service 이용
        account_sid = 'AC08da4aa7e61d1280b3cc25fe90752e03'  # replace with your Twilio account SID
        auth_token = '6717f35eb1c7399e7fb36793a489fb1a'  # replace with your Twilio auth token
        client = Client(account_sid, auth_token)
        message = client.messages.create(
            body=random_number,
            from_='+12543828682',  # replace with your Twilio phone number
            to=f'+82{hp_number[1:]}',  # replace with the recipient's phone number
        )
        print(message.sid)  # prints the Twilio message SID to the console

        result = HttpResponse(random_number)
        result['code'] = random_number
    else:
        result = HttpResponse('N')
        result['err-reason'] = 'hp_number 없음'

    return result

# 페이지 뷰
def inquire_certify(request):
    mn_depth1 = MainMenu.objects.filter(depth='1').order_by('id')
    mn_depth2_1 = SpaceParent.objects.all().order_by('id')
    mn_depth2_1_first = SpaceParent.objects.first()
    mn_depth2_2 = MainMenu.objects.filter(depth='2', path__contains='0002').order_by('id')

    context = {
        'mn_depth1': mn_depth1,
        'mn_depth2_1': mn_depth2_1,
        'mn_depth2_2': mn_depth2_2,
        'mn_depth2_1_first': mn_depth2_1_first,
    }
    return render(request, 'laboratory/inquire_certify.html', context)

 

laboratory/templates/laboratory/inquire_certify.html

{% extends 'laboratory/base.html' %}
{% load static %}
{% block title %}
TITLE
{% endblock %}

{% block container %}

<style>
    .sub_pg{
        min-height: 300px;
    }
</style>

<div class="container-fluid px-0 w-100">
	<div class="idx_pg sub_pg ">
		<div class="container">
            <div class="breadcrumbs">
                <ul class="d-flex pt_60">
                    <li class="mr_14"><a href="{% url 'laboratory:mainpage' %}" class="fs_14 fw_400 text-light2"><img src="{% static '/img/ico_bread_home.svg' %}" alt="홈" class="mr-2"> 홈</a></li>
                    <li class="mr_14"><img src="{% static '/img/ico_bread_arrow.svg' %}" alt=""></li>
                    <li class="mr_14"><a href="{{ mn_depth2_1_first.get_absolute_url1 }}" class="fs_14 fw_400 text-light2">공간</a></li>
                    <li class="mr_14"><img src="{% static '/img/ico_bread_arrow.svg' %}" alt=""></li>
                    <li class="mr_14"><a class="fs_14 fw_400 text-light2">대관신청조회</a></li>
                </ul>
            </div>
            <form id="form1" method="post" action="{% url 'laboratory:inquire_list' %}">
                {% csrf_token %}
                <div class="inquire_wrap center_wrap">
                    <p class="tit_h3 text-primary">대관신청 조회</p>
                    <p class="fs_16 fw_300 text-secondary line_h1_4 mt-3">대관신청 조회를 위해 휴대폰 인증을 진행해주세요 :)</p>
                    <div class="form-row mt_67">
                        <div class="col-lg-9 col-8">
                            <input type="text" name="srt_tel" id="srt_tel" value="" maxlength="20" class="form-control" placeholder="“-”없이 전화번호를 입력해주세요.">
                            <input type="hidden" name="srt_tel_chk" id="srt_tel_chk" value="">
                        </div>
                        <div class="col-lg-3 col-4 mt-lg-0 ">
                            <button type="button" id="hp_chk_btn" class="btn btn-primary btn-block fs_15 fw_500 dlswmd_btn" onclick="f_hp_chk_custom();">인증요청</button>
                        </div>
                    </div>
                    <div id="certi_hp" class="d-none-temp">
                        <div class="form-row mt-3">
                            <div class="col-lg-9 col-8 ip_valid">
                                <input type="text" name="hp_confirm" id="hp_confirm" numberonly="" value="" class="form-control" maxlength="6" placeholder="인증번호 입력 (숫자만 입력바랍니다.)">

                                <div class="form-row mt-3 ml-2">
                                    <span class="fc_FF88 bg-white fs_16 fw_300 time_chk" id="hp_confirm_timer"></span>
                                </div>
                            </div>
                            <div class="col-lg-3 col-4 mt-lg-0 ">
                                <button type="button" class="btn btn-outline-secondary btn-block fs_15 fw_500 dlswmd_btn" onclick="f_hp_confirm_custom();">인증하기</button>
                            </div>
                        </div>
                    </div>

                    <button type="button" class="btn btn-secondary btn-block fs_18 fw_600 mt_40" onclick="f_inquire_certify();">대관신청 조회</button>

                    <script>
                        $("#srt_tel").on("input", function(){
                            let srt_tel = $(this).val();
                            srt_tel = srt_tel.replaceAll('-','');
                            $("#srt_tel").val(srt_tel);
                            $('#srt_tel_chk').val('N');
                        });

                        function f_hp_chk_custom(){
                            const srt_tel = $("#srt_tel").val();
                            const csrfToken = document.getElementsByName('csrfmiddlewaretoken')[0].value;

                            if(srt_tel==''){
                                jalert("휴대폰 번호를 입력해주세요.", "", "");
                                $("#srt_tel").focus();
                                return false;
                            }

                            $.ajax({
                                type: "POST",
                                url: "{% url 'laboratory:sendcertificode' %}",
                                  headers: { 'X-CSRFToken': csrfToken },
                                data: {hp_number:srt_tel},
                                cache: false,
                                     datatype: "JSON",
                                success: function(data, textStatus, xhr){
                                    const headers = xhr.getAllResponseHeaders();
                                    console.log(data);
                                    //console.log(headers);
                                    if(data == 'N'){
                                        jalert("인증 번호 발송 중 문제가 생겨 정상적으로 진행되지 않았습니다. 새로고침 후 재시도 부탁드리며 동일한 증상 발견 시, 고객센터에 문의바랍니다.", "", "");
                                    }else{
                                        set_timer_custom();
                                    }
                                }
                            });
                        }

                        function set_timer_custom() {
                            var time = 119;
                            var min = "";
                            var sec = "";
                            $("#hp_chk_btn").prop("disabled", true);
                            $("#hp_chk_btn").css("background-color", "#e9ecef");
                            $("#hp_chk_btn").css("border-color", "#e9ecef");
                            $("#hp_chk_btn").css("color", "#222222");
                            $("#srt_tel").prop("readonly", true);
                            $("#srt_tel").css("background-color", "#e9ecef");
                            timer = setInterval(function () {
                                min = parseInt(time / 60);
                                sec = time % 60;
                                $("#certi_hp").show();
                                document.getElementById("hp_confirm_timer").innerHTML = "인증번호를 발송했습니다. (유효시간 : " + min + ":" + sec + ")";
                                time--;
                                if (time < -1) {
                                    jalert("인증번호 유효시간이 만료 되었습니다.", "", "");
                                    clearInterval(timer);
                                    $("#certi_hp").hide();
                                    $("#hp_chk_btn").prop("disabled", false);
                                    $("#hp_chk_btn").css("background-color", "#F04E5A");
                                    $("#hp_chk_btn").css("border-color", "#F04E5A");
                                    $("#hp_chk_btn").css("color", "#ffffff");
                                    $("#srt_tel").prop("readonly", false);
                                }
                            }, 1000);
                        }

                        function f_hp_confirm_custom(){
                            const hp_confirm = $('#hp_confirm').val();
                            const csrfToken = document.getElementsByName('csrfmiddlewaretoken')[0].value;

                            $.ajax({
                                type: "POST",
                                url: "{% url 'laboratory:chkcertificode' %}",
                                  headers: { 'X-CSRFToken': csrfToken },
                                data: {post_number:hp_confirm},
                                cache: false,
                                 datatype: "JSON",
                                success: function(data, textStatus, xhr){
                                    const headers = xhr.getAllResponseHeaders();
                                    console.log(data);

                                    if(data == "Y"){
                                        jalert("인증이 확인되었습니다.", "", "");
                                        clearInterval(timer);
                                        $("#srt_tel_chk").val("Y");
                                        $("#certi_hp").hide();
                                        $("#hp_confirm").prop("readonly", true);
                                        $("#srt_tel").prop("readonly", true);
                                    }else if(data == "N"){
                                        jalert("인증 번호를 다시 확인해주세요.", "", "");
                                    }else if(data == "err"){
                                        jalert("인증 도중 인증 코드와 관련된 문제가 발생했습니다. 고객센터에 문의바랍니다..", "", "");
                                    }else{
                                        jalert("인증 처리 중 문제가 발생하여 정상적으로 처리하지 못했습니다. 고객센터에 문의바랍니다..", "", "");
                                    }

                                }
                            });
                        }

                        function f_inquire_certify() {
                            if($('#srt_tel_chk').val()!='Y') {
                                jalert("인증을 완료해주세요.", '' , $('#srt_tel').focus());
                                return false;
                            }

                            $("#form1").submit();

                            return false;
                        }
                    </script>
                </div>
            </form>
        </div>
	</div>
</div>

{% endblock %}

 

댓글