본문 바로가기
개발

24시간 돌아가는 코인 시세 알림 봇 만들기 #2

by wafla 2024. 1. 3.

이번에는 텔레그램에서 봇을 생성하는 방법을 알아봅시다 !

 

1. 봇 생성

 

텔레그램 검색창에 botfather를 검색하고 인증 마크가 있는 봇을 클릭합니다.

 

/start를 입력하면 명령어들이 나타납니다.

 

봇을 생성하는 방법은 다음과 같습니다.

 

1. /newbot 

2. 봇 이름 입력

3. 유저네임 입력

4. API 키 발급

 

이제 검색창에 봇을 검색하면 나타납니다

 

2. 채팅방 id 확인

 

https://api.telegram.org/bot {api키}/getUpdates 

 

위 주소에 방금 발급 받은 api키를 입력하고 접속합니다.

 

 

위와 같이 현재 대화방 목록이 뜨는데 아직은 아무것도 보이지 않습니다.

아까 생성한 봇에게 아무 문자를 보내봅시다.

 

새고고침을 해보니 뭔가 생겼습니다. 여기서 chat id를 알아야 메시지를 보낼 수 있는데 1921902212가 chat id입니다.

 

3. 코드 작성

chat id를 확인했으니 파이썬 코드를 작성하고 메시지를 보내봅시다.

 

혹시나 텔레그램 모듈을 설치하지 않았다면 pip install python-telegram-bot 으로 설치해줍시다.

 

코드는 다음과 같습니다.

async def send(chat):

    token = "{api키}"
    bot = telegram.Bot(token)

    print(chat)
    await bot.send_message(chat_id="{chat_id}", text=chat)
    
asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
asyncio.run(send('hello'))

 

실행 결과 메시지가 도착한 것을 확인할 수 있습니다.

 

만약 다수의 사람들에게 봇 기능을 제공하려면 사용자 만큼의 chat_id를 알아야 합니다.

 

위의 사이트에서 chat_id를 parsing 하는 방법도 있지만 채널을 생성하고 봇을 넣어놓으면 훨씬 간단해집니다.

 

4. 채널 생성

텔레그램 메인 화면에서 글쓰기 버튼을 누릅니다.

 

채널 만들기를 누릅니다.

 

채널명과 소개를 적습니다.

 

공개 링크 주소를 채웁니다. (비공개 하실 분들은 비공개로)

 

채널이 만들어졌습니다.

 

채널 이름 부분을 클릭하여 설정 창으로 이동하고 관리자를 클릭합니다.

 

관리자 추가를 누르고 아까 생성한 봇을 넣어줍니다.

 

이후에 채팅을 하나 보내고 chat id를 확인하는 과정은 2. 채팅방 id 확인과 동일합니다.

 

채널의 채팅방 id는 -로 시작합니다.

 

메시지 전송 코드에서 chat_id를 바꾼뒤 메시지를 보내면 정상적으로 작동되는 것을 확인할 수 있습니다.

 

5. 비트코인 시세 전송

이제 저번에 작성한 파이썬 코드로 비트코인 시세를 구하고 전송해 봅시다.

 

먼저 보안을 위해 authcreds.json 파일에 token을 추가해 줍시다.

 

파이썬 코드를 다음과 같이 수정합니다.

from pybit.unified_trading import HTTP
import pandas as pd
import pandas_ta as ta
import numpy as np
import datetime as dt
import time 
import json
import pytz

import telegram
import asyncio

with open('authcreds.json') as j:
    creds = json.load(j)

key = creds['KEY_NAME']['key']
secret = creds['KEY_NAME']['secret']
token = creds['KEY_NAME']['token']
  
session = HTTP(api_key=key, api_secret=secret, testnet=False)

def get_market(response):
    data = response.get('list', None)
    if not data:
        return 
    
    data = pd.DataFrame(data,
                        columns =[
                            'timestamp',
                            'open',
                            'high',
                            'low',
                            'close',
                            'volume',
                            'turnover'
                            ],
                        )
    
    f = lambda x: dt.datetime.utcfromtimestamp(int(x)/1000)
    data.index = data.timestamp.apply(f)
    return data[::-1].apply(pd.to_numeric)

async def send(chat):

    bot = telegram.Bot(token)

    print(chat)
    await bot.send_message(chat_id="-1002137634582", text=chat)

response = session.get_kline(category='linear', 
                             symbol='BTCUSDT', 
                             interval='D').get('result')

btc_market = get_market(response)
now = dt.datetime.now()
price = str(btc_market['open'][-1])
chat = f'{now.year}년 {now.month}월 {now.day}일 비트코인 시세는 {price}달러입니다'

asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
asyncio.run(send(chat))

 

실행 결과

 

달러를 원화로 고치고 싶다면 업비트 API를 사용하거나 USDT 코인 가격을 구해서 곱해주면 됩니다.

 

마지막으로 매일 09시마다 메시지를 전송해야 되니 해당 코드를 추가해 봅시다.

 

또 비트코인 시세 정보를 가져오는 와중에 오류가 나서 프로그램이 종료될 수 있으니 예외 처리 코드도 추가하겠습니다.

from pybit.unified_trading import HTTP
import pandas as pd
import pandas_ta as ta
import numpy as np
import datetime as dt
import time 
import json
import pytz
import telegram
import asyncio

with open('authcreds.json') as j:
    creds = json.load(j)

key = creds['KEY_NAME']['key']
secret = creds['KEY_NAME']['secret']
token = creds['KEY_NAME']['token']
  
session = HTTP(api_key=key, api_secret=secret, testnet=False)

def get_market(response):
    data = response.get('list', None)
    if not data:
        return 
    
    data = pd.DataFrame(data,
                        columns =[
                            'timestamp',
                            'open',
                            'high',
                            'low',
                            'close',
                            'volume',
                            'turnover'
                            ],
                        )
    
    f = lambda x: dt.datetime.utcfromtimestamp(int(x)/1000)
    data.index = data.timestamp.apply(f)
    return data[::-1].apply(pd.to_numeric)

def check_coin():
    try:
        response = session.get_kline(category='linear', 
        symbol='BTCUSDT', 
        interval='D').get('result') 
    except: asyncio.run(send('오류 발생'))
    
    btc_market = get_market(response)
    now = dt.datetime.now()
    price = str(btc_market['open'][-1])
    chat = f'{now.year}년 {now.month}월 {now.day}일 비트코인 시세는 {price}달러입니다'

    asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
    asyncio.run(send(chat))

async def send(chat):

    bot = telegram.Bot(token)
    await bot.send_message(chat_id="-1002137634582", text=chat)

while True:
    now = dt.datetime.now()
    if now.hour == 0 and now.minute == 0:
        check_coin()
    time.sleep(60)

 

now.hour와 now.minute에 내가 원하는 시간을 적어놓으면 해당 시간마다 알람을 보냅니다.

 

"09시마다 보낸다면서 왜 0시 0분으로 해놨지?" 하실 수 있을텐데 저희가 사용할 서버는 미국에 있기 때문에 미국 기준으로 작성했습니다.

 

다음은 서버를 설정하러 가봅시다 !

 

목차 -

 

(0) 개요

https://wafla.tistory.com/4

(1) 바이비트 API를 사용해 코드 짜기

https://wafla.tistory.com/5

(3) 오라클 클라우드에서 서버 만들기

https://wafla.tistory.com/7

 

 

참고자료

 

[텔레그램 봇] 1. 텔레그램 봇 제작 환경 구축, 텔레그램 api 활용하기(2023 텔레그램 업데이트 버전 대응) : https://blog.naver.com/lifelectronics/223198582215