서비스
home

[GAS] 네이버 SENS API로 문자 발송하기

목적

네이버 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
복사

관련 포스팅

업무 효율성 200% 올리기, with autooffice

프로젝트 문의는 구글폼을 이용해주세요!