텔레그램 봇 만들기
오늘은 가상화폐 시세를 알려주는 텔레그램 봇을 만들어보려고 합니다. 가상화폐를 보유하고 있으면 스마트폰으로 하루에도 수십 번 시세를 확인할 텐데요. 본격적으로 코인판에 불장이 왔을 때는 정말 5분마다 시세를 확인하고 밤을 지새우며 시세를 봤던 때가 생각나네요. 지금은 그 정도는 아니지만 하루에 여러 번 시세를 확인하곤 합니다.
하지만 이렇게 시세를 보고 있으면 다른 급등 코인들에 쓸데없이 시간을 뺏기기도 하고 잘못 된 판단을 할 수 있게하는 불필요한 정보를 피하기 위해 텔레그램 봇으로 필요한 시세만 조회할 수 있도록 만들어보겠습니다.
우선 간단하게 제가 필요로 하는 요구사항을 나열해보겠습니다.
요구사항
1. 2시간 단위로 텔레그램을 통해 가상화폐 시세를 전달받는다. (12시 -> 2시 -> 4시)
2. 24시간 자는 동안에도 메시지를 받는다.
3. 시세에는 우리의 머장님 비트코인, 2대 머장님 이더리움, 편안하게 스테이킹 중인 오브스 총 3개의 현재가를 포함한다.
3가지 요구사항에 만족하려면 24시간 돌아가는 서버에 배포해야 합니다. 마침 제 포트폴리오를 업로드해놓은 AWS ec2 리눅스 서버가 있어 여기에 배포를 하면 되겠습니다. 저는 Node Express를 사용해서 만들었습니다.
시세는 국내 거래량이 가장 많은 업비트에 시세조회 API를 이용해 값을 얻어오도록 합니다.
1. 텔레그램 봇 생성하기
1. /newbot 입력
2. 봇 이름을 입력
3. 봇 사용자 이름 입력(헷갈릴 거 같아 저는 같은 이름으로 했습니다)
ㄴ 이름 중복되거나 이름 끝에 Bot, _bot으로 끝나지 않는 경우 경고 메시지가 옵니다.
4. 완료됐다면 HTTP API 토큰을 담은 메시지 수신
5. 봇 생성 완료
2. 봇 사용법 알아보기
이제 해당 토큰을 복사하여 아래 주소 형식에 토큰을 입력하고 브라우저에 접속합니다.
https://api.telegram.org/bot<토큰키>/getUpdates
위 주소로 접속했을 때, 아래와 같은 JSON 형식의 텍스트가 보인다면 정상적으로 봇이 작동하고 있습니다.
JSON을 모르시는 분들은 위 글을 참고해주세요.
1. 텔레그램으로 이동해서 만들었던 봇 이름으로 검색
2. Start를 눌러 대화 시작
3. 다시 브라우저로 이동해서 새로고침
처음과 달라진 JSON 파일을 볼 수 있는데요. JSON 파일 내에 from 안에 잇는 id 값이 방금 자신이 보낸 텔레그램 아이디 값이므로 이 아이디를 사용해 메시지를 보낼 수 있습니다.
https://api.telegram.org/bot<토큰키>/sendmessage?chat_id=<복사한 아이디>&text=<입력할 메세지>
이와 같은 url 형식으로 아이디와 입력할 메시지를 넣어 브라우저 주소에 입력해봅니다.
이렇게 봇을 통해 입력한 메시지가 전달된 것을 확인할 수 있습니다. 다음으로는 텔레그램 메시지를 브라우저가 아닌 소스코드를 통해 보내보겠습니다.
HTTP 통신은 Axios 라이브러리를 사용합니다.
import axios from "axios";
const token = "<token값>";
const id = "<id값>";
const tel_url = `https://api.telegram.org/bot${token}/sendmessage?chat_id=${id}&text=`;
async function sendTel() {
const msg = "전송하고싶은 메세지";
const res = await axios.get(tel_url + msg)
.then(res => { return res; })
.catch(err => { return err; });
if(res.status === 200){
console.log("전송 성공!");
}else{
console.log("전송 실패!");
}
}
에러발생
TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters new ClientRequest
code: 'ERR_UNESCAPED_CHARACTERS'
영문을 전송할 경우 아무런 문제없이 잘 보내지지만 한글을 입력해서 보내는 경우 위와 같은 에러가 발생합니다. 주소에서 통용하는 알파벳이나 특수문자 - / : ? & . # 등 을 제외한 문자가 들어오는 경우 발생하는 에러인데요.
자바스크립트에서는 encodeURI() 함수를 사용해서 문제를 해결할 수 있습니다.
axios.get(url + encodeURI(msg))
여기까지 간단하게 봇을 통해 메시지를 보낼 수 있는 방법까지 확인했고 다음으로는 업비트 시세조회 API를 통해 원하는 가상화폐 시세를 조회하는 방법을 확인해보도록 하겠습니다.
>
업비트 개발자 센터 공식문서를 참고해서 시세를 조회해 보도록 하겠습니다.
REST API를 이용한 업비트 시세 수신에서 확인한 url을 가지고 Axios를 통해 GET 요청을 보내보도록 하겠습니다.
async function getCryptoPrice() {
const url = 'https://api.upbit.com/v1/ticker?markets=KRW-BTC';
try {
const res = await axios(url)
console.log(res)
} catch (e) {
console.error(e)
}
}
GET 요청을 보낸 후 res.status 값에 200이라는 성공 응답 상태 코드를 받았습니다. 반대로 404 Error가 나왔다면 url 주소나 코드를 다시 확인해 봐야 합니다.
성공적으로 값을 전달받았다면 res.data에 요청했던 데이터가 들어있습니다.
이상한 점은 data는 배열로 되어있는데, 왜냐하면 여러 개의 값을 요청할 수 있기 때문입니다. 위 코드는 KRW-BTC 비트코인의 원화 가격을 조회하는 코드입니다.
지금 제가 필요로 하는 것은 비트코인과 이더리움, 오브스의 원화 가격을 조회하는 것이기 때문에 다시 코드를 수정해봅니다.
async function getCryptoPrice() {
const crypto = "KRW-BTC,KRW-ETH,KRW-ORBS"; //비트코인 이더리움 오브스
const upbit_url = "https://api.upbit.com/v1/ticker?markets=";
const getData = await axios(upbit_url + crypto)
.then(res => { console.log(res); })
.catch(err => { console.log(err); })
}
data 배열에 요청했던 데이터들이 순서대로 들어있습니다. 배열 안에 우리가 필요한 값은 trade_price입니다. 값들을 뽑아 정리해서 출력해보는 코드를 작성해보겠습니다.
async function getCryptoPrice() {
const url = 'https://api.upbit.com/v1/ticker?markets=KRW-BTC,KRW-ETH,KRW-ORBS';
const getData = await axios(url)
.then(res => { return res; })
.catch(err => { return err; });
if(getData.status === 200){ //Success
const btcPrice = getData.data[0].trade_price;
const ethPrice = getData.data[1].trade_price;
const orbsPrice = getData.data[2].trade_price;
console.log(`비트코인 : ${btcPrice}원\n이더리움 : ${ethPrice}원\n오브스 : ${orbsPrice}원`);
}else{ //err
console.log(getData);
}
}
필요한 데이터는 다 얻었습니다. 이제 24시간 돌아가는 서버에서 텔레그램 메세지를 보내야합니다. 서버에서 배포하는 코드는 다음 포스팅에서 작성해보도록 하겠습니다.