목적
네이버 SENS SMS API 를 앱스 스크립트에서 사용해서 문자를 발송하는 방법을 이해합니다.
네이버 SENS SMS API 사용하기
네이버 SENS SMS API 를 사용하기 위해서는 우선 네이버 클라우드 플랫폼에 가입해야 합니다.
네이버답게 네이버 계정 로그인을 지원해서 편합니다.
가입을 완료하고, 마이페이지 > 계정 관리에 들어가면 인증키 관리 메뉴가 있습니다. 여기서 신규 API 인증키 생성을 클릭해서 새로운 Access Key ID와 Secret Key를 얻습니다. 잘 기록해두세요.
우측 메뉴에서 Services 을 클릭하면 엄청나게 많은 메뉴가 나오는데, 검색창에 SENS 를 입력하면 메뉴가 검색됩니다.
SENS(Simple & Easy Notification Service) 메뉴에 접속해서 프로젝트 생성하기를 클릭합니다.
프로젝트를 생성하면 이제 Project 메뉴에서 생성한 프로젝트를 볼 수 있고, 서비스 ID를 얻을 수 있습니다. 우측의 자물쇠 모양을 누르면 OPEN API Key 를 확인할 수 있는데, 여기서 SMS의 ID를 복사해서 기록해둡니다. 여기서 Secret Key 는 사용하지 않습니다.
SMS을 발송하기 위해서는 법령에 따라 발신번호 사전등록을 해두어야 합니다. 좌측의 메뉴의 SMS > Calling Number 에서 서류인증 또는 본인인증으로 등록합니다. 서류인증의 경우에는 1일 정도면 승인이 됩니다.
여기까지 진행하는 것으로 콘솔에서 할 일은 끝났습니다. 이제 앱스 스크립트로 가보실까요?
UrlFetchApp을 사용해 SMS 보내기
UrlFetchApp 사용하기
UrlFetchApp을 사용해서 API를 호출하는 방법은 이전 포스팅에서 다루었습니다.
// Make a POST request with a JSON payload.
var data = {
'name': 'Bob Smith',
'age': 35,
'pets': ['fido', 'fluffy']
};
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};
UrlFetchApp.fetch('https://httpbin.org/post', options);
JavaScript
복사
NAVER SENS API HEADER 준비하기
그런데 NAVER SENS SMS API 를 사용하기 위해서는 중요한 점으로 header에 정보를 넣는 것이 있습니다. 단순히 ID, PWD 를 문자열로 넣는 것이 아니라, 암호화된 서명을 넣는 부분이라 조금 까다로울 수 있는데, 어떻게 하는지 함께 살펴보시죠.
header에 어떤 정보가 들어가야 하는지는 네이버 SMS API 가이드에 다음과 같이 소개되어 있습니다.
POST https://sens.apigw.ntruss.com/sms/v2/services/{serviceId}/messages
Content-Type: application/json; charset=utf-8
x-ncp-apigw-timestamp: {Timestamp}
x-ncp-iam-access-key: {Sub Account Access Key}
x-ncp-apigw-signature-v2: {API Gateway Signature}
JavaScript
복사
4가지 항목을 넣어주어야 하는데, 어떻게 넣어주어야 한다는 말일까요?
1.
우선 Content-Type은 지정된 대로 application/json; charset=utf-8 를 넣습니다.
2.
x-ncp-apigw-timestamp는 “1970년 1월 1일 00:00:00 협정 세계시(UTC)부터의 경과 시간을 밀리초(Millisecond)로 나타냄”이라고 설명되어 있는데, 코드는 간단합니다. 마지막에 toString()으로 문자열 변환을 꼭 해주세요.
new Date().getTime().toString()
JavaScript
복사
3.
x-ncp-iam-access-key는 계정관리 > 인증키 관리에서 받은 Access Key ID입니다.
4.
x-ncp-apigw-signature-v2가 조금 까다롭습니다. 인증키 생성가이드를 참고해보면, 지금까지 확보한 여러 정보를 합쳐서 Secret Key로 암호화해야 하는데 어떻게 할 수 있을까요? 단계별로 살펴보겠습니다.
a.
정보 병합
다음과 같이 지금까지 얻은 정보들을 hmac 변수에 할당해줍니다. 백틱으로 문자열을 만들어줄 수 있지만, 이 경우에는 자동 문서 서식 기능을 사용하다보면 공백이 추가로 발생하기 때문에 +를 사용해서 만들어줍니다.
let space = ' ' //한 칸 공백
let newLine = '\n' //개행 문자
let method = 'POST'
let serviceId = '콘솔에서 얻은 서비스ID'
let uri = `/sms/v2/services/${serviceId}/messages`
let timestamp = new Date().getTime().toString()
let accessKey = '인증키 관리에서 받은 Access Key ID'
let secretKey = '인증키 관리에서 Access Key ID와 매칭되는 Secret Key'
let hmac = method + space + uri + newLine + timestamp + newLine + accessKey
JavaScript
복사
b.
암호화
Utilities 클래스의 computeHmacSha256Signature 메서드를 사용해서 hmac를 secretKey로 암호화해 줍니다.
let byteSignature = Utilities.computeHmacSha256Signature(hmac, secretKey)
JavaScript
복사
c.
base64 인코딩
Byte 형식의 결과를 base64Encode 메서드로 인코딩합니다. 마지막에 toString()으로 문자열 변환을 해주세요.
let signature = Utilities.base64Encode(byteSignature).toString()
JavaScript
복사
이제 header에 필요한 signature 를 얻었습니다.
SMS BODY 준비하기
let body = {
"type": "SMS",
"contentType": "COMM",
"countryCode": "82",
"from": "발신번호에 등록한 전화번호",
"content": "내용",
"messages": [
{
"to": "받는사람 전화번호",
"content": "문자 보내기 API 테스트입니다."
}
]
}
JavaScript
복사
위와 같이 작성하는 경우 실제 내용은 messages의 content로 발송됩니다. 관련된 조건은 가이드에 잘 설명되어 있습니다.
문자 발송 관련 조건
•
최대 지원 가능한 사이즈 초과 시 잘림 처리되어 발송 됩니다.
•
메시지(subject, content) 인코딩은 EUC-KR 기준으로 발송되며, 지원하지 않는 이모지 문자 포함 시 발송에 실패합니다.
•
messages 내에 subject, content를 정의하지 않으면 기본 subject, content로 지정된 값으로 발송 됩니다.
•
messages 내에 subject, content가 기본 subject, content 보다 우선순위가 높습니다.
•
type이 MMS인데 첨부하려는 파일이 없는경우 LMS로 발송됩니다.
•
reserveTime, scheduleCode를 모두 요청하는 경우 예약 발송으로 처리됩니다. (예약발송이 우선순위가 높음)
그런데 아까 header 의 Content-Type을 json 으로 지정하였었죠? 때문에 body를 json 으로 변환시켜주어야 합니다.
let jsonBody = JSON.stringify(body)
JavaScript
복사
API로 문자 발송하기
이제 모든 것이 준비되었으니, 문자를 발송해볼까요?
UrlFetchApp의 매개변수(options)의 headers 부분에 준비한 header 를 넣고, payload에 jsonBody를 넣어줍니다. method는 POST로 보내주어야 합니다.
최종 코드는 다음과 같습니다.
function sendSMS() {
let body = {
"type": "SMS",
"contentType": "COMM",
"countryCode": "82",
"from": "발신번호에 등록한 전화번호",
"content": "내용",
"messages": [
{
"to": "받는사람 전화번호",
"content": "문자 보내기 API 테스트입니다."
}
]
}
let jsonBody = JSON.stringify(body)
let space = ' ' //한 칸 공백
let newLine = '\n' //개행 문자
let method = 'POST'
let serviceId = '콘솔에서 얻은 서비스ID'
let uri = `/sms/v2/services/${serviceId}/messages`
let timestamp = new Date().getTime().toString()
let accessKey = '인증키 관리에서 받은 Access Key ID'
let secretKey = '인증키 관리에서 Access Key ID와 매칭되는 Secret Key'
let hmac = method + space + uri + newLine + timestamp + newLine + accessKey
let byteSignature = Utilities.computeHmacSha256Signature(hmac, secretKey)
let signature = Utilities.base64Encode(byteSignature).toString()
let apiUrl = `https://sens.apigw.ntruss.com/sms/v2/services/${serviceId}/messages`
let options = {
'method': method,
'muteHttpExceptions': true,
'headers': {
'Content-Type': 'application/json; charset=utf-8',
'x-ncp-apigw-timestamp': timestamp,
'x-ncp-iam-access-key': accessKey,
'x-ncp-apigw-signature-v2': signature
},
'payload': jsonBody
}
let response = UrlFetchApp.fetch(apiUrl, options)
Logger.log(response)
}
JavaScript
복사
실행했을 때, 다음과 같은 응답을 받으면 성공한 것입니다.
{"statusCode":"202","statusName":"success","requestId":"1ec0356537c14fec95435f3a65d65248","requestTime":"2022-08-31T10:35:00.687"}
JavaScript
복사