텔레그램 가상화폐 시세 알림봇 만들기 1편을 안보신 분은 아래 게시글을 확인해주세요.

 

 

 

가상화폐 시세 알리미 - 텔레그램 봇 만들기 - 1편

텔레그램 봇 만들기 오늘은 가상화폐 시세를 알려주는 텔레그램 봇을 만들어보려고 합니다. 가상화폐를 보유하고 있으면 스마트폰으로 하루에도 수십 번 시세를 확인할 텐데요. 본격적으로 코

juni-official.tistory.com

 

 

 

텔레그램 봇

 

 

 

텔레그램 가상화폐 시세 알림봇


1편에 이어 2편에서는 서버에 배포하는 코드를 작성해보도록 하겠습니다. 매일2시간씩 하루에 12번 메시지를 보내야 하기 때문에 24시간 돌아가는 서버가 필요합니다. 다행히도 저는 포트폴리오 배포를 위한 AWS ec2 Linux 서버를 돌리고 있어 텔레그램 봇이랑 같이 배포해보도록 하겠습니다.

 

Node Express를 사용하고 있어 코드는 자바스크립트를 사용합니다. 

 

 

요구사항 중 매 2시간 단위로 메시지를 보내야 합니다. 그렇게 하기 위해서는 자바스크립트에서 제공하는 setInterval() 메서드를 사용하면 되지만,  나중에 잠자는 시간에는 메시지를 안 받게 한다거나 1시간 주기로 바꾼다거나 요구사항이 바뀔 수 있기 때문에 유지보수/확장성을 고려해 스케줄 라이브러리를 사용하보겠습니다.

 

 

 

스케줄 업무 자동화: Node-cron vs Node-schedule 비교 👊

🎯 필자는 Plating의 소프트웨어 엔지니어로 근무 중이며 "셰프의 찾아가는 구내식당"을 서비스를 제공하는 회사이다. 현재 특정 고객사들은, 각 직원이 마감 시간전까지 원하는 메뉴를 주문하는

velog.io

 

스케줄 라이브러리 3개를 비교한 글이 있습니다. 위 글에서는 node-schedule을 사용했으나 같은 cron방식의 node-cron을 사용해보겠습니다. 

 

> npm i node-cron

 

 

cron syntax


 # ┌────────────── second (optional)
 # │ ┌──────────── minute
 # │ │ ┌────────── hour
 # │ │ │ ┌──────── day of month
 # │ │ │ │ ┌────── month
 # │ │ │ │ │ ┌──── day of week
 # │ │ │ │ │ │
 # │ │ │ │ │ │
 # *   *   *   *   *   *

 

field value
second 0-59
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names)
day of week 0-7 (or names, 0 or 7 are sunday)

 


 

node-cron의 자세한 설명은 아래 글을 확인해주세요.

 

 

[Node.js] node-cron을 이용한 NodeJS 스케줄러 설정

node-cron을 이용한 NodeJS 스케줄러 설정 node-cron 기본 개념 Cron이란 Cron은 유닉스 계열 컴퓨터 운영 체제의 시간 기반 Job 스케줄러입니다. 소프트웨어 환경을 설정하고 관리하는 사람들은 작업을 고

miiingo.tistory.com

 

 

간단하게 cron 표현식을 만들고 싶다면 아래 홈페이지에서 만들어주세요.

 

 

Crontab.guru - The cron schedule expression editor

loading... Cron job failures can be disastrous! We created Cronitor because cron itself can't alert you if your jobs fail or never start. Cronitor is easy to integrate and provides you with instant alerts when things go wrong. Learn more about cron job mon

crontab.guru

 

 

저는 다른 코드들과 분리하기 위해 cryptoAlarm.js 파일을 만들어 기능 구현을 하고, www.js 파일을 만들어 서버를 실행시키도록 하겠습니다.

 

cryptoAlarm.js


const axios = require("axios");

const token = "<Telegram Bot Token>";
const id = "<Telegram ID>";
const upbit_url = 'https://api.upbit.com/v1/ticker?markets=';
const tel_url = `https://api.telegram.org/bot${token}/sendmessage?chat_id=${id}&text=`;
const crypto = "KRW-BTC,KRW-ETH,KRW-ORBS";


const getPrice = async () => { //업비트 시세 조회

    const getPrice_res = await axios(upbit_url+crypto)
                        .then((res) => {return res; })
                        .catch((err) => { return err; });

    return getPrice_res;
}

const sendTel = async (msg) => { //텔레그램 메시지 전송
    
    const sendTel_res = await axios.get(tel_url+encodeURI(msg))
                .then(res => { return res; })
                .catch(err => { return err; });

    return sendTel_res;
}

const nowDate = () => {
    
    const _date = new Date();
    const date = `Date : ${_date.getFullYear()}/${(_date.getMonth()+1)}/${_date.getDate()}/${_date.getHours()}:${_date.getMinutes()}`;

    return date;

}


const sendAlarm = async () => {

    const getPrice_res = await getPrice(); //업비트 시세 조회

    if(getPrice_res.status === 200){ //시세 조회 성공

        const btc = getPrice_res.data[0].trade_price.toLocaleString(); //비트코인
        const eth = getPrice_res.data[1].trade_price.toLocaleString(); //이더리움
        const orbs = getPrice_res.data[2].trade_price.toLocaleString(); //오브스
        
        const msg = `비트코인(₿) : ${btc}원\n이더리움(⧫) : ${eth}원\n오브스(⎔) : ${orbs}원`;

        const sendTel_res = await sendTel(msg);

        if(sendTel_res.status === 200){ //메시지 전송 성공
            console.log(`${nowDate()}  - 메세지 전송 성공`);
        }else{                   //메시지 전송 실패
            console.log(`${nowDate()}  - 메세지 전송 실패\n${sendTel_res}`);
        }

    }else{
        await sendTel('업비트 시세 조회 실패'); //실패 메시지 전송
    }
    
}

module.exports = sendAlarm

 

www.js


const cron = require('node-cron');
const sendAlarm = require("./router/cryptoAlarm.js");


cron.schedule('*/10 * * * * *', ()=> {
    console.log('10초 마다 실행');
    sendAlarm();
});

 

실행될 서버 코드까지 작성했습니다. 우선 테스트를 위해 10초마다 메시지를 보내도록 설정했고 이제 서버를 실행하기만 하면 됩니다. 실행될 파일 경로까지 터미널로 이동해 서버 실행 명령어를 입력해줍니다.

 

> node www.js

 

 

제 경우 pm2 프로세스 관리자를 사용하므로 아래 명령어를 사용하겠습니다.

> pm2 start www.js --watch

 

pm2의 클러스터 모드를 사용하는 경우 아래의 단일 프로세스에서 작동하도록 설정해주어야 합니다. 제 AWS ec2는 성능이 좋지 않아.. ㅎ

 

 

PM2 : 클러스터 모드의 단일 프로세스에서 cron-job 실행

PM2는 node.js 애플리케이션의 프로세스 관리자입니다.

ichi.pro

 

 

텔레그램 봇 테스트
Test

 

서버를 실행하고 10초마다 정상적으로 메시지가 도착하는 것을 확인할 수 있습니다. 이제 10초 주기를 2시간 주기로 변경해 주면 완성입니다.

 

const cron = require('node-cron');
const sendAlarm = require("./router/cryptoAlarm.js");

cron.schedule('0 */2 * * *', ()=> { //“At minute 0 past every 2nd hour.”
    sendAlarm();
});

 

오브스 가주아~
텔레그램 봇

 

 

PC에서는 바로 도착했는데 핸드폰에서는 약간의 딜레이가 발생하네요.