0과 1을 공부하다.

[Cloud] 문자(sms) 매크로 만들기 - Simple & Easy Notification Service (Naver Cloud) 본문

Study/ETC

[Cloud] 문자(sms) 매크로 만들기 - Simple & Easy Notification Service (Naver Cloud)

Developer_Jay 2023. 1. 8. 22:31
728x90



  필자는 이전 소개글에서 보았던 것과 같이 ROTC 출신 장교이다. 벌써 임관한지 5년이 되었다. 5년이 지났음에도 아직 나의 출신 학군단에서는 동기회가 이어지고 있다. 2023년부터는 필자가 2023년 동기회 부회장을 맡게 되었다.

 

  동기회 부회장을 맡으며 가장 먼저 수행하고 싶었던 일은 동기회 관련 문자를 전송 할 때 자동화 시키는 업무를 제일 먼저 수행하고 싶었다. 동기회에서 발송하는 문자는 입단 및 임관 기념일, 신년인사, 동기들의 생일 축하문자 및 경조사 소식, 정기 모임 문자, 회비 납부 문자가 있다. 일년마다 매번 일정을 체크하여 발송하는 일은 매우 번거롭게 느껴지고 본업을 하며 업무상 바쁜날에는 놓치게 될 것이 뻔해보였다. 개인적으로 컴퓨터공학을 전공하고 개발자로 본업을 하며 매우 중요하게 생각하는 부분은 업무를 자동화 시켜 다른 부분에 집중하여 효율성을 높이는 일이 중요하다고 생각했다.

 

  그래서 동기회에서 발생하는 문자를 자동화 시켜 일정 시간에 발송하게끔 하도록 코드를 작성하기로 결정하였다. SMS를 일정 기간에 발송하는 여러 서비스들이 존재하지만 필자는 클라우드 서비스 및 코딩 경험겸 직접 코딩하여 발송하기로 결정했다. 그래서 현재 회사에서 사용하고 있는 네이버 클라우드의  Simple & Easy Notification Service를 이용하기로 결정하였다.

 

  두서가 너무 길었다. Simple & Easy Notification Service를 이용하는 방법에 대해 알아본다. 

 

 

 

서비스 소개

 

  네이버 클라우드의 Simple & Easy Notification Service는 SMS, PUSH, 알림 등 메시지 알림 기능을 구현한 서비스이다. 

기능으로는 SMS, MMS, PUSH, 카카오 비즈 메시지 등을 제공한다. 해당 포스팅에서는 SMS(단문)와 MMS(장문) 기능만 사용할 예정이므로 다른 기능들의 설명은 생략한다.  

 

요금을 알아보면 SMS(단문)은 50건 이하는 무료이고 초과되는 문자는 건당 9원이다. LMS(장문)는 10건 이하는 무료이고 초과되는 문자는 건당 30원이다. 

 

동기회 인원이 17명이니까 월 최대 50건 보낸다고 가정하여도 1,200원 정도의 금액이 나올 것으로 예상된다. 

 

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

 

 

 

API

 

  NAVER Cloud Platform API는 RESTful API 방식으로 제공되며, XML와 JSON 형식으로 응답한다.  SMS 서비스를 이용하기 위한 요청 URL과 헤더, 바디에 대해 알아본다. 

 

가. 기본 URL

  SMS 서비스의 기본 URL이다.

https://sens.apigw.ntruss.com/sms/v2

 

나. 요청 URL

SMS 서비스의 요청 URL이다. {serviceId}는 아래 프로젝트를 생성할 때 확인한다.

POST https://sens.apigw.ntruss.com/sms/v2/services/{serviceId}/messages

 

다. API 헤더

항목 Mandatory 항목설명
Content-Type Mandatory 요청 Body Content Type을 application/json으로 지정 (POST)
x-ncp-apigw-timestamp Mandatory - 1970년 1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(Millisecond)로 나타냄
- API Gateway 서버와 시간 차가 5분 이상 나는 경우 유효하지 않은 요청으로 간주
x-ncp-iam-access-key Mandatory 포털 또는 Sub Account에서 발급받은 Access Key ID
x-ncp-apigw-signature-v2 Mandatory - 위 예제의 Body를 Access Key Id와 맵핑되는 SecretKey로 암호화한 서명
- HMAC 암호화 알고리즘은 HmacSHA256 사용

 SMS 서비스를 이용하기 위해 API 헤더 항목에 대해 알아본다. 다른 부분을 생략하고 'x-ncp-apigw-signature-v2'에 대해 알아보면  Method, URL, Access Key, Secret Key, TimeStamp(1970년1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(Millisecond)로 나타낸 것)를 이용하여 HmacSHA256 알고리즘으로 암호화한 후 Base64로 인코딩한 서명 결과를 넣는 값이다. 

 

HMAC에 대한 자세한 정보는 아래 링크를 참고한다.

 

REST API 제작시 꼭 알고 있어야 할 HMAC 기반 인증

 여기를 클릭하여 펼치기... 출처: https://en.wikipedia.org/wiki/HMAC#Implementation function hmac is input: key: Bytes // Array of bytes message: Bytes // Array of bytes to be hashed hash: Function // The hash function to use (e.g. SHA-1) block

www.lesstif.com

 

HMAC에 요청에 맞게 Method URL \n TimeStamp \n Access Key 형태로 StringToSign을 생성한다.

 

예시는 아래와 같다.

POST /sms/v2/services/{ServiceId}/messages
{TimeStamp}
{Access Key}

 

StringToSignSecret Key를 HmacSHA256 알고리즘을 이용하여 암호화하고 Base64로 인코딩하여 전달 'x-ncp-apigw-signature-v2'에 파라미터로 전달한다.

 

라. 요청 Body (JSON)

  요청 Body이다. 자세한 내용은 아래 참고사이트의 API 문서를 확인하도록 한다.

{
    "type":"(SMS | LMS | MMS)",
    "contentType":"(COMM | AD)",
    "countryCode":"string",
    "from":"string",
    "subject":"string",
    "content":"string",
    "messages":[
        {
            "to":"string",
            "subject":"string",
            "content":"string"
        }
    ],
    "files":[
        {
            "name":"string",
            "body":"string"
        }
    ],
    "reserveTime": "yyyy-MM-dd HH:mm",
    "reserveTimeZone": "string",
    "scheduleCode": "string"
}

 

더욱 자세한 내용은 아래 참고 사이트의 'API 호출 및 인증'과 'SMS API'를 참고한다.

 

 

 

프로젝트 생성 / 발신자 번호 등록 / 인증키 확인

 

  Simple & Easy Notification Service의 API를 이용하기 위해서는 SMS 프로젝트를 생성하고 발신자 번호를 등록하고 API 헤더의 삽입할 인증키를 확인해야 한다. 

 

가. 프로젝트 생성

 Simple & Easy Notification Service에서 아래 사진과 같은 방법으로 프로젝트를 생성한다.

 

나. 발신 번호 등록

SMS 서비스는 사용자가 입력한 임의의 번호를 이용하여 발송할 수 없다. SMS - Calling Number에서 발송할 휴대전화 인증을 수행한다. 

 

다. Service ID

 생성한 프로젝트에서 '서비스 ID'를 클릭하여 ID를 복사한다. 가급적이면 유출하지 않는 것이 좋다. 

 

라. Secret Key / Access Key

  마이페이지 > 계정 관리 > 인증키 관리에서 확인한다. Secret Key Access Key는 한 쌍으로 구성되어 있으며, 향후 헤더의 'x-ncp-iam-access-key', 'x-ncp-apigw-signature-v2' 파라미터로 이용된다. 최대 2개 까지 발급 가능하다. 절대로  타인에게 유출되지 않도록 유의한다.

 

 

Python 코드 작성

 앞서 프로젝트를 생성하고 발신자 번호 등록 후 요청 URL,  Service ID, Secret Key, Access Key를 확인하였다.  이제는 앞서 확인 내용을 바탕으로 코드를 작성한다.

 

 아래 코드는 실행 인자 1번째에 수신자 번호, 2번째에 발송 내용을 입력하면 문자메세지가 발송되는 코드이다. 도용 방지를 위해 모든 개인 키는 삭제하였다. 블로그뿐만 아니라 개인 깃허브에 코드를 업로드 할 때에도 키값이 노출되지 않도록 유의한다.

import json
import requests
import time
import base64
import hashlib
import hmac
import sys

# 1970년1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(Millisecond)로 나타낸 것
timestamp = str(int(time.time() * 1000))

phone_number = sys.argv[1] # 실행 인자로 받은 핸드폰 번호
content = sys.argv[2] # 실행 인자로 받은 발송 내용

user_access_key = "사용자 access-key" # 사용자 access-key
user_secret_key = "사용자 secret_key" # 사용자 비밀키
user_secret_key = bytes(user_secret_key,'UTF-8')
sms_service_id = "" # sms 서비스ID

url = "/sms/v2/services/"+sms_service_id+"/messages" # 사용자 서명을 위한 URL
api_url = 'https://sens.apigw.ntruss.com/sms/v2/services/'+sms_service_id+'/messages' #requests를 위한 full URL

# HMAC 암호화 알고리즘은 HmacSHA256 사용
def make_signature(url,access_key):
    method = "POST"
    message = method + " " + url + "\n" + timestamp + "\n" + access_key
    message = bytes(message,'UTF-8')
    signingkey = base64.b64encode(hmac.new(user_secret_key,message, digestmod=hashlib.sha256).digest())
    return signingkey

# 헤더 값
headers = {
    'Content-Type': 'application/json; charset=utf-8',
    'x-ncp-apigw-timestamp': timestamp,
    'x-ncp-iam-access-key': user_access_key,
    'x-ncp-apigw-signature-v2': make_signature(url,user_access_key)
}

# body(data) 값
body = {
    "type" : "SMS", # SMS(단문), MMS(장문) 택 1
    "contentType" : "COMM", # COMM(일반 메세지), AD(광고) 택 1
    "countryCode" : "82", # 국가코드 대한민국(82)
    "from" : "01000000000", # 발신자번호
    "content" : content, # 발송내용
    "messages" : [
        {
            "to":phone_number, # 수신자번호
        }
    ]

}

body_result = json.dumps(body)

response = requests.post(api_url,headers=headers,data=body_result)
response.request
response.status_code
response.raise_for_status()
response_result = response.json()

send_result = response_result['statusCode']

# 발송 결과 출력
if send_result == "202":
    print("[SMS] : "+phone_number+" Sending Success")
else:
    print("[SMS] : "+phone_number+" Sending Fail")

 

 

Python 코드 실행 및 결과

 

  작성한 해당 파이썬 코드를 실행한다. 실행인자로 수신자 핸드폰 번호와 문자 내용을 전달한다.

실행 로그와 함께 발송 완료를 확인한다.

 

문자를 수신을 확인한다.

 

 

응용

 

  앞선 내용을 바탕으로 Simple & Easy Notification Service API를 이용하여 원하는 수신자에게 문자를 발송했다. 하지만 본래의 목표는 ⓵ 원하는 날짜⓶ 해당 대상자에게 ⓷ 자신의 이름이 담긴 문자를 발송하는 것이 목표였기 때문에 위 코드로는 아직 부족하다.

 

⓵ 원하는 날짜 는 24시간 돌아가는 서버에서 Cron에 의해 실행되도록 하거나 Serverless Computing 을 통해 정해진 날짜에 코드를 실행하도록 할 수 있도록 한다. Serverless Computing을 이용하는 방법은 향후 포스팅을 통해 네이버 클라우드 Serverless 서비스인 Cloud Functions(FaaS)을 이용하는 방법에 대해 알아본다.

 

⓶ 해당 대상자 에게 발송하는 방법은 DB 혹은 파일에 대상자의 정보를 담아 현재 날짜와 이름을 판별하여 발송하도록 구현한다.

 

⓷ 자신의 이름이 담긴 문자 는 앞선⓶ 해당 대상자 과 동일한 방법으로 처리한다.

 

이 세가지를 반영한 코드는 향후 깃허브 링크를 통해 공유할 예정이다.

 

 

참고사이트

 

 

 

 

 

※ 본 게시글의 정보가 잘못 되었거나 부족한 부분에 대한 피드백을 환영합니다.

 

 

* CopyRight 2023. Jay Park All rights reserved.

728x90
Comments