티스토리 뷰


사용 계기

과거에 어떤 학우분께서 과목의 자리가 나면 등록 한 번호로 문자를 자동으로 전송하게끔 하는 프로그램을 제작해주신 적 있다. 그리고 그 분이 사용하신 문자 전송 api가 네이버 클라우드 문자 전송 api인 "Simple & Easy Notification Service" SENS 서비스였다.

 

어떤 프로젝트에 사용해야할지 고민하다, 본인이 관심을 가지고 있는 암호화폐의 특정 가격이 되면 문자를 보내주는 서비스를 구현하는 곳에 사용해보기로 했다.

 

아래 링크의 프로젝트이다!

 

 

근황이자 진행중인 프로젝트 소개

요즘 너무 뜸했죠? 그래도 제 블로그를 찾아주시는 분들 너무 감사드립니다. 현재 아래의 토이 프로젝트를 진행중에 있습니다. 물론! 다른 훌륭하신 분들이 많이 만드셨겠으나, 저는 아래의 기

jae04099.tistory.com

 

문자는 아래와 같이 전송된다.

 

 

물론 최종 프로젝트 결과물은 이렇게 나오진 않을것이고,

실시간 wss를 사용해서 '~원에 도달하였습니다' 형식으로 문자가 전송 될 것이다.

이 게시글에서는 문자 전송 api의 사용법만 간단히 알아보겠다.


Simple & Easy Notification Service 신청하기

 

 

NAVER CLOUD PLATFORM

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

www.ncloud.com

 

 

많은 sns 전송 플랫폼이 있지만, 네이버는 한 달에 50건이 무료이기 때문에  상업용으로 사용하지 않을 나에게 적합해서 선택하였다.

가격표는 아래와 같다.

 

출처: https://www.ncloud.com/product/applicationService/sens

위의 링크 맨 아래를 내리면 서비스 신청 버튼이 있다.

네이버 클라우드 플랫폼의 계정이 따로 있어야 하며, 계정을 생성한 후 서비스를 신청하자.

아래와 같은 콘솔창이 나올 것이다.

 

영어로 돼 있다.

 

본인은 이미 서비스를 이용하고 있기에 저렇게 나오는 것 이고, 왼쪽에 Project를 누르자.

본인의 프로젝트를 생성하고 맨 왼편 서비스 ID를 누른다.

 

 

왼쪽의 ID를 환경변수에 저장해주자. Secret Key는 사용할 일이 없었다.

 

문자를 발신 할 번호를 지정해주자.

콘솔 왼편의 Calling Number에 번호를 저장하는데, 본인은 본인 번호를 지정하였다.

 

 

마지막으로 api 키를 발급받아야 한다.

콘솔에서 나가, 클라우드 웹에서 마이페이지-계정관리-인증키관리 에 들어간다.

API 인증 키를 받은 적 없다면 새로 발급받는다.

 

마찬가지로 Access Key ID와  Secret Key를 환경변수에 저장한다.

 

 

다시한번 정리하자면,

Access Key, Secret Key, Service Id 세 개가 환경변수에 저장 돼 있으면 된다.

 


실제 코드

API 공식 문서는 이곳에 있다.

깊이 알아보고 싶다면 아래를 참고하면 된다.

 

 

Simple & Easy Notification Service 소개 - Simple & Easy Notification Service

 

guide.ncloud-docs.com

 

본인은 우선 sens 폴더를 새로 만들어 모듈로 만들었다.

코드는 이 분의 코드를 참고하였다.

본인은 request 모듈이 deprecated 돼서 2020년 이후로 업데이트가 되지 않는 것 때문에 axios를 사용하였다.

 

코드가 복잡해보일 수 있으니 잘라서 보여주겠다.

 

send_message라는 이름의 모듈을 만들 것 이며, 매개변수는 신청자 전화번호, 신청자 이름, 신청 한 코인 이름을 넣었다.

// sens.js
function send_message(coin_name, nickname, phone) {
	
    // 예약자 번호, 닉네임, 코인이름
    const user_phone_number = phone;
    const user_nickname = nickname;
    const user_coin_name = coin_name;
    
    // 모듈들을 불러오기. 오류 코드는 맨 마지막에 삽입 예정
    const finErrCode = 404;
    const axios = require('axios');
    const CryptoJS = require('crypto-js');
    const date = Date.now().toString();
    
    // 환경변수로 저장했던 중요한 정보들
    const serviceId = process.env.SENS_SERVICE_ID; 
    const secretKey = process.env.SENS_SECRET_KEY;
    const accessKey = process.env.SENS_ACCESS_KEY;
    const my_number = process.env.SENS_MYNUM;
    
    // 그 외 url 관련
    const method = "POST";
    const space = " ";
    const newLine = "\n";
    const url = `https://sens.apigw.ntruss.com/sms/v2/services/${uri}/messages`;
    const url2 = `/sms/v2/services/${uri}/messages`;
		
        
        ...

}

module.exports = send_message;

최대한 하드코딩을 하지 않으려는 모습이 인상적이다.

변수명이 무엇을 의미하는지 애매한 부분은 수정하였다.

 

// sens.js
function send_message(coin_name, nickname, phone) {
    
    	...
    
    // 중요한 key들을 한번 더 crypto-js 모듈을 이용하여 암호화 하는 과정.
    // 이런 모습은 꽤나 믿을 만 한 api이다.

    const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secretKey);
    hmac.update(method);
    hmac.update(space);
    hmac.update(url2);
    hmac.update(newLine);
    hmac.update(date);
    hmac.update(newLine);
    hmac.update(accessKey);
    const hash = hmac.finalize();
    const signature = hash.toString(CryptoJS.enc.Base64);

    	...
}

module.exports = send_message;

 

참고로 axios와 crypto-js는 따로 npm install 해 주어야 한다.

 

// sens.js
function send_message(coin_name, nickname, phone) {
    
    	...

    axios({
        method: method,
        // request는 uri였지만 axios는 url이다
        url: url,
        headers: {
            "Contenc-type": "application/json; charset=utf-8",
            "x-ncp-iam-access-key": accessKey,
            "x-ncp-apigw-timestamp": date,
            "x-ncp-apigw-signature-v2": signature,
        },
        // request는 body였지만 axios는 data다
        data: {
            type: "SMS",
            countryCode: "82",
            from: my_number,
            // 원하는 메세지 내용
            content: `${user_nickname}님 ${user_coin_name} 가격 예약을 신청해주셔서 감사합니다.`,
            messages: [
            // 신청자의 전화번호
                { to: `${user_phone_number}`, },],
        },
    }).then(res => {
        console.log(res.data);
    })
        .catch(err => {
            console.log(err);
        })
    return finErrCode;
}

module.exports = send_message;

 

크게 세 부분으로 나누어 코드를 작성 해 보았는데, 한번에 사용하려면 send_message 함수 안에 순서대로 셋을 붙여넣으면 된다.

 


해당 모듈을 클라이언트에서 예약 폼을 post 시켰을 때 실행시키고 싶기 때문에,

post router 파일에서 모듈을 사용하였다.

 

// 모듈 임포트
const send_message = require('../sens/sens')

router.post('/', async (req, res, next) => {
    const coin_name = req.body.coin_name
    const coin_code = req.body.coin_code
    const alert_price = req.body.alert_price
    const nickname = req.body.nickname
    const phone_number = req.body.phone_number
    const agreement = req.body.agreement
    const user = new UserReg({
        coin_name,
        coin_code,
        alert_price,
        nickname,
        phone_number,
        agreement
    });
    res.setHeader('Content-Type', 'application/json')

    console.log('post is work')
    try {
    	// user 정보를 mongodb에 저장한 후
        await user.save()
    	// send_message 모듈을 실행시킨다. 
        await send_message(coin_name, nickname, phone_number)
        res.send("send message!")
    }catch(err){
        console.log(err)
    }
});

module.exports = router;

이런식으로 본인의 코드를 응용하면 직접 web발신 메시지를 보내볼 수 있을 것이다.

재밌는 경험이었다. 끝까지 프로젝트가 잘 완성 됐으면 좋겠다.

반응형
댓글