[Spring Boot] SMS 전송

네이버 API 프로젝트 생성

먼저 네이버 클라우드에 로그인합니다. (구독 관련 내용이 많으니 참고해주세요.)

https://www.ncloud.com/

네이버 클라우드 플랫폼

엔터프라이즈 클라우드 컴퓨팅 서비스, IaaS, PaaS, SaaS, 글로벌 지역 및 보안 기술 인증 포함

www.ncloud.com


로그인 후 이 경로로 이동합니다.


프로젝트 만들기를 클릭하고 생성에 필요한 프로젝트 이름을 입력한 다음 서비스 유형으로 SMS를 클릭합니다.


생성 후 아래와 같이 프로젝트 정보를 확인할 수 있습니다.

이제 전화번호 등록만 하면 됩니다.

API 통합 정보 검토



Calling Number에서 발신번호를 등록할 수 있습니다.

해당 발신번호가 코드로 필요하니 참고하세요!!


계정 인증키 관리에서 만들어진 액세스 키그리고 비밀 키확인할 수 있습니다
별도로 저장합시다.


프로젝트 의뢰 화면에서 서비스 ID값을 확인하려면 클릭하세요.

별도로 저장합시다.

헤더 구성


https://api.ncloud-docs.com/docs/common-ncpapi

엔클라우드 API

api.ncloud-docs.com

위의 링크는 서명 v2 부분을 생성하는 답변을 제공합니다.
그러나 붙여넣기 하면 잘 됩니다. 암호화 알고리즘에 겁먹지 마십시오. 우정


속성에 관련 정보를 추가합니다. senderPhone은 발신 번호입니다.

서비스

public String makeSignature(Long time) throws Exception {

    String space = " ";
    String newLine = "\n";
    String method = "POST";
    String url = "/sms/v2/services/"+ this.serviceId+"/messages";
    // 1) timestamp
    String timestamp = time.toString();
    // 2) access key
    String accessKey = this.accessKey;

    // 3) secretKey 암호화
    String secretKey = this.secretKey;
    //  알고리즘은 HmacSHA256 사용 -  바이트 배열의 데이터키를 비밀키로 변환
    SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
    //  HMAC 암호화 - 공유된 키를 가지고 메시지 해쉬값(MAC)을 만들어 냅니다. 변조와 위장을 막음
    Mac mac = Mac.getInstance("HmacSHA256");
    mac.init(signingKey);

    String message = new StringBuilder()
            .append(method)
            .append(space)
            .append(url)
            .append(newLine)
            .append(timestamp)
            .append(newLine)
            .append(accessKey)
            .toString();

    //doFinal()은 HMAC 결과로 byte array를 리턴
    byte() rawHmac = mac.doFinal(message.getBytes("UTF-8"));
    String encodeBase64String = Base64.encodeBase64String(rawHmac);

    return encodeBase64String;
}
@Value("${naver-cloud-sms.accessKey}")
private String accessKey;

@Value("${naver-cloud-sms.secretKey}")
private String secretKey;

@Value("${naver-cloud-sms.serviceId}")
private String serviceId;

@Value("${naver-cloud-sms.senderPhone}")
private String senderPhone;



public SmsResponseDto sendSms(MessageDto messageDto) throws Exception{

    Long time = System.currentTimeMillis();

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("x-ncp-apigw-timestamp",time.toString());
    headers.set("x-ncp-iam-access-key", accessKey);
    headers.set("x-ncp-apigw-signature-v2", makeSignature(time));

    List<MessageDto> messages = new ArrayList<>();
    messages.add(messageDto);

    SmsRequestDto request = SmsRequestDto.builder()
            .type("MMS")
            .contentType("COMM")
            .countryCode("82")
            .from(senderPhone)
            .content(messageDto.getContent())
            .messages(messages)
            .build();

    System.out.println("request = " + request);

    ObjectMapper objectMapper = new ObjectMapper();
    String body = objectMapper.writeValueAsString(request);
    HttpEntity<String> httpBody = new HttpEntity<>(body, headers);

    RestTemplate restTemplate = new RestTemplate();

    //post 요청 -> 객체 반환
    SmsResponseDto response = restTemplate.postForObject(new URI("https://sens.apigw.ntruss.com/sms/v2/services/"+ serviceId +"/messages"), httpBody, SmsResponseDto.class);

    System.out.println("response = " + response);

    return response;
}

제어 장치

private final SmsService smsService;

@PostMapping("/send")
public ResponseEntity sendSms(@RequestBody MessageDto messageDto) {
    try {
        SmsResponseDto smsResponseDto = smsService.sendSms(messageDto);
        return ResponseEntity.ok(smsResponseDto);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

우편 배달부 테스트


메시지가 성공적으로 전송되었음을 확인할 수 있습니다.
NAVER API에 대한 설명이 잘 되어 있어서 큰 구현 문제는 없는 것 같습니다.