Spring 으로 구축된 서비스에 네이버 클라우드 플랫폼의 SMS API 를 이용해서 SMS 를 보내는 방법입니다.
정식 서비스 명칭은 Simple & Easy Notification Service 이고 줄여서 SENS 라고 부릅니다.
네이버 클라우드 플랫폼 메인 페이지 > 서비스 > Application Service > Simple & Easy Notification Service 에서 확인 가능합니다.
개인적으로 테스트 하고 싶으시면 네이버 클라우드 플랫폼에 가입하신 후
네이버 클라우드 플랫폼 메인 페이지 > 서비스 > Application Service > Simple & Eash Notification Service
에서 이용 신청 하신 후 프로젝트 생성 하셔야 이용 가능합니다.
개인 계정으로 가입해서 테스트 시에는 발송 전화번호를 기입해야 하고, 아래 코드의 sendSMS() 에서 발신번호 항목에 이용 신청한 전화번호를 넣어야 오류 없이 SMS 가 전송됩니다.
법인 계정으로 가입 및 SMS 발송 서비스 이용시에는 별도의 법인 인증 절차 등이 필요합니다.
제 소스코드에서 사용한 import 내용들입니다. 참고하시기 바랍니다.
signature 를 만들 때 Access Key, Secret Key, Service ID 가 필요한데, 아래 SMS API설명서에는 어디에 있는 내용들이라는 설명 따위는 없는 것 같습니다. 몇 번 찾아 봤는데 그런 설명 못 찾겟네요. ㅋ;;;
Access Key, Secret Key, Service ID 는 아래 경로에서 확인 가능합니다.
// Access Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Access Key ID
// Secret Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Secret Key
// Service ID : https://console.ncloud.com/sens/project > Simple & Easy Notification Service > Project > 서비스 ID
아래 코드에 있는 값들은 실제 제가 사용하는 값들에서 몇 몇 문자들을 다른 문자로 임의로 변경한 것입니다. 해당 Key 값의 길이나 형태 등 참고하시라고 비슷한 형태로 놔뒀습니다.
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
// https://api.ncloud-docs.com/docs/common-ncpapi
private String makeSignature(String url, String timestamp, String method, String accessKey, String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
String space = " "; // one space
String newLine = "\n"; // new line
String message = new StringBuilder()
.append(method)
.append(space)
.append(url)
.append(newLine)
.append(timestamp)
.append(newLine)
.append(accessKey)
.toString();
SecretKeySpec signingKey;
String encodeBase64String;
try {
signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
encodeBase64String = e.toString();
}
return encodeBase64String;
}
/*
* https://api.ncloud-docs.com/docs/ko/ai-application-service-sens-smsv2
{
"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"
}
*/
private void sendSMS() {
String hostNameUrl = "https://sens.apigw.ntruss.com"; // 호스트 URL
String requestUrl= "/sms/v2/services/"; // 요청 URL
String requestUrlType = "/messages"; // 요청 URL
String accessKey = "QWALu3XgiCxABC2aynAf"; // 네이버 클라우드 플랫폼 회원에게 발급되는 개인 인증키 // Access Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Access Key ID
String secretKey = "bXGAcyQw1FG9Zjq6f1U8SD5CHMFVsvumivXoP194"; // 2차 인증을 위해 서비스마다 할당되는 service secret key // Service Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Access Key ID
String serviceId = "ncp:sms:kr:178053617394:projectname"; // 프로젝트에 할당된 SMS 서비스 ID // service ID : https://console.ncloud.com/sens/project > Simple & ... > Project > 서비스 ID
String method = "POST"; // 요청 method
String timestamp = Long.toString(System.currentTimeMillis()); // current timestamp (epoch)
requestUrl += serviceId + requestUrlType;
String apiUrl = hostNameUrl + requestUrl;
// JSON 을 활용한 body data 생성
JSONObject bodyJson = new JSONObject();
JSONObject toJson = new JSONObject();
JSONArray toArr = new JSONArray();
//toJson.put("subject",""); // Optional, messages.subject 개별 메시지 제목, LMS, MMS에서만 사용 가능
//toJson.put("content","sms test in spring 111"); // Optional, messages.content 개별 메시지 내용, SMS: 최대 80byte, LMS, MMS: 최대 2000byte
toJson.put("to","01012345678"); // Mandatory(필수), messages.to 수신번호, -를 제외한 숫자만 입력 가능
toArr.put(toJson);
bodyJson.put("type","SMS"); // Madantory, 메시지 Type (SMS | LMS | MMS), (소문자 가능)
//bodyJson.put("contentType",""); // Optional, 메시지 내용 Type (AD | COMM) * AD: 광고용, COMM: 일반용 (default: COMM) * 광고용 메시지 발송 시 불법 스팸 방지를 위한 정보통신망법 (제 50조)가 적용됩니다.
//bodyJson.put("countryCode","82"); // Optional, 국가 전화번호, (default: 82)
bodyJson.put("from","01012345678"); // Mandatory, 발신번호, 사전 등록된 발신번호만 사용 가능
//bodyJson.put("subject",""); // Optional, 기본 메시지 제목, LMS, MMS에서만 사용 가능
bodyJson.put("content","sms test in spring 222"); // Mandatory(필수), 기본 메시지 내용, SMS: 최대 80byte, LMS, MMS: 최대 2000byte
bodyJson.put("messages", toArr); // Mandatory(필수), 아래 항목들 참조 (messages.XXX), 최대 1,000개
//String body = bodyJson.toJSONString();
String body = bodyJson.toString();
System.out.println(body);
try {
URL url = new URL(apiUrl);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("content-type", "application/json");
con.setRequestProperty("x-ncp-apigw-timestamp", timestamp);
con.setRequestProperty("x-ncp-iam-access-key", accessKey);
con.setRequestProperty("x-ncp-apigw-signature-v2", makeSignature(requestUrl, timestamp, method, accessKey, secretKey));
con.setRequestMethod(method);
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.write(body.getBytes());
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
System.out.println("responseCode" +" " + responseCode);
if(responseCode == 202) { // 정상 호출
br = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else { // 에러 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
}
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
} catch (Exception e) {
System.out.println(e);
}
}
* Reference
-. 서비스 안내 : https://www.ncloud.com/product/applicationService/sens
-. 사용 가이드 : https://guide.ncloud-docs.com/docs/ko/sens-sens-1-1
-. SMS API 사용 설명서 : https://api.ncloud-docs.com/docs/ko/ai-application-service-sens
-. 인증키 생성 예제 : https://api.ncloud-docs.com/docs/common-ncpapi
-. SMS 요청 내용(Json) : https://api.ncloud-docs.com/docs/ko/ai-application-service-sens-smsv2