개발 & 구현

[Python] Telegram 응답 받기

ssh9308 2023. 5. 3. 17:38
반응형

https://goodbyeanma.tistory.com/157

 

[Python] Telegram 메시지 보내주기

Python과 Telegram을 조합해서 알람 서비스를 만드는 이유 1. 편리한 알림 기능 Python과 Telegram을 함께 사용하면 간단하고 빠르게 알람 서비스를 구축할 수 있다. Telegram의 알림 기능을 활용하여 사용

goodbyeanma.tistory.com

위의 글에서는 Python 외부라이브러리를 사용해서 telegram 봇이 메시지를 보내주는 기능을 구현해 보았다.

 

이번 글에서는 사용자의 메시지에 Telegram 봇이 응답해 주는 기능을 구현해 볼 것이다.

 

 

 

라이브러리 로직 기본 구조

 

이번에는 안정적인 구현을 위해서 python-telegram-bot 13.8 버전을 다운로드하여 줄 것이다.

 

# 기존 라이브러리 제거
pip3 uninstall python-telegram-bot

# python-telegram-bot 13.8 버전 설치
pip3 install python-telegram-bot==13.8

 

봇과 응답을 주고받기 위해서는 아래의 객체구조를 이해해야 한다.

 

 

python-telegram-bot 라이브러리에서는 Updater와 Dispatcher 객체를 사용해서

 

Telegram Bot과 상호작용 할 수 있게 해 준다.

 

Updater는 사용자로부터 새로운 메시지가 왔는지를 주기적으로 확인하는 기능을 수행한다.

 

그리고 만약, 사용자로부터 메시지 혹은 특정 명령어가 왔다면 이를 Queue에 저장을 해준다.

 

Dispatcher는 Updater 가 Queue에 넣어둔 사용자 입력 데이터를 가져가서 처리한다.

 

각 요청에 대한 처리를 담당할 핸들러 객체를 미리 지정해 두고 

 

특정 요청이 들어오게 되면, 지정된 핸들러를 통해서 명령이나 메시지에 대한 

 

처리를 수행한다.

 

 

 

 

 

Telegram Bot 응답하기

 

처음에는 간단하게 사용자가 '/command' 명령어를 적어주면,

 

Telegram Bot 이 반응을 하는 기능을 구현해 보자.

 

from telegram.ext import *
import json

""" 
Read telegram related information.
""" 
def telegram_read_infos(telegram_info_path):
    
    telegram_dict = {}

    with open(telegram_info_path, "r") as f:
        data = json.load(f)

    telegram_dict["token"] = data["token"]

    return telegram_dict


# command handler
def start(update, context):
    user_id = update.effective_chat.id
    context.bot.send_message(chat_id=user_id, text="안녕하세요 Telegram bot 입니다.")
    
    

""" 
main function
""" 
def main():
    
    tele_info_path = './tele_info.json'
    telegram_dict = telegram_read_infos(tele_info_path)

    updater = Updater(token=telegram_dict['token'], use_context=True)
    dispatcher = updater.dispatcher
    
    start_handler = CommandHandler('command', start)
    dispatcher.add_handler(start_handler)

    
    #polling
    updater.start_polling()
    updater.idle()
    

""" 
main function - execute
""" 
if __name__ == '__main__':
    main()

 

json 파일에서 Telegram bot에 관한 토큰 정보를 읽어와서

 

사용자가 '/command'라는 특정 메시지를 보내주면 응답해 주는 구조이다.

 

코드를 실행하면 아래와 같이 정상적으로 기능을 수행하는 것을 볼 수 있다.

 

그럼 이번에는 추가적으로, 사용자가 보내는 메시지를 

 

따라서 응답해주는 코드를 추가해 주자.

 

python-telegram-bot Handler는 크게 두 개로 나뉜다.

 

하나는 '/~'와 같은 명령어를 처리해 주는 'CommandHandler' 

 

또 하나는, 명령어가 아닌 사용자의 메시지를 받아서 처리해주는

 

'MessageHandler'가 존재한다.

 

이번에 추가할 기능은 사용자의 메시지를 받아서 그대로 사용자에게 출력해줘야 하므로

 

'MessageHandler' 객체를 사용하면 된다.

 

from telegram.ext import *
import json

""" 
Read telegram related information.
""" 
def telegram_read_infos(telegram_info_path):
    
    telegram_dict = {}

    with open(telegram_info_path, "r") as f:
        data = json.load(f)

    telegram_dict["token"] = data["token"]

    return telegram_dict


# command handler
def start(update, context):
    user_id = update.effective_chat.id
    context.bot.send_message(chat_id=user_id, text="안녕하세요 Telegram bot 입니다.")
    

# message handler
def echo(update, context):
    user_id = update.effective_chat.id
    user_text = update.message.text
    context.bot.send_message(chat_id=user_id, text=user_text)


""" 
main function
""" 
def main():
    
    tele_info_path = './tele_info.json'
    telegram_dict = telegram_read_infos(tele_info_path)

    updater = Updater(token=telegram_dict['token'], use_context=True)
    dispatcher = updater.dispatcher
    
    start_handler = CommandHandler('command', start)
    dispatcher.add_handler(start_handler)

    echo_handler = MessageHandler(Filters.text & (~Filters.command), echo)
    dispatcher.add_handler(echo_handler)
    
    #polling
    updater.start_polling()
    updater.idle()
    

""" 
main function - execute
""" 
if __name__ == '__main__':
    main()

 

해당 코드를 실행해 주면 아래와 같이 정상적으로 기능하는 것을 확인할 수 있다.

 

 

 

 

 

 

Telegram Bot 응답 응용 - 환율정보 받아오기

 

이번에는 Telegram Bot을 사용해서 환율 정보를 가져오는 코드를 구성해 보자.

 

"미국 환율"이라고 치면 1달러당 원화로 얼마인지 봇이 응답해 주는 방식이다.

 

웹 스크랩핑 전용 라이브러리인 'beautifulsoup4' 라이브러리를 설치해 주자.

 

pip3 install beautifulsoup4

 

그리고 아래와 같이 구현해 주면 된다.

 

from telegram.ext import *
import json
from bs4 import BeautifulSoup
import requests

""" 
Read telegram related information.
""" 
def telegram_read_infos(telegram_info_path):
    
    telegram_dict = {}

    with open(telegram_info_path, "r") as f:
        data = json.load(f)

    telegram_dict["token"] = data["token"]

    return telegram_dict


"""
Function to get exchange rate information
"""
def exchange_rate(query):

    currency_dict = {}

    # 검색 결과 페이지에 접속하여 HTML 코드를 가져옴
    url = f"https://www.google.com/search?q={query}"
    response = requests.get(url)
    html = response.text
    
    # HTML 코드를 분석하여 원하는 데이터 추출
    soup = BeautifulSoup(html, "html.parser")
    
    target_currency = soup.find("span", {"class": "r0bn4c rQMQod"}).get_text()
    korea_won = soup.find("div", {"class": "BNeawe iBp4i AP7Wnd"}).get_text()

    currency_dict['target_currency'] = target_currency
    currency_dict['korea_won'] = korea_won

    return currency_dict


# command handler
def start(update, context):
    user_id = update.effective_chat.id
    context.bot.send_message(chat_id=user_id, text="안녕하세요 Telegram bot 입니다.")
    

# message handler
def echo(update, context):
    user_id = update.effective_chat.id
    user_text = update.message.text
    currency_dict = exchange_rate(user_text)

    result = '{} {}'.format(currency_dict['target_currency'],currency_dict['korea_won'])

    context.bot.send_message(chat_id=user_id, text=result)


""" 
main function
""" 
def main():
    
    tele_info_path = './tele_info.json'
    telegram_dict = telegram_read_infos(tele_info_path)

    updater = Updater(token=telegram_dict['token'], use_context=True)
    dispatcher = updater.dispatcher
    
    start_handler = CommandHandler('command', start)
    dispatcher.add_handler(start_handler)

    echo_handler = MessageHandler(Filters.text & (~Filters.command), echo)
    dispatcher.add_handler(echo_handler)
    
    #polling
    updater.start_polling()
    updater.idle()
    

""" 
main function - execute
""" 
if __name__ == '__main__':
    main()

 

 

웹 스크랩핑은 HTML, XML, JSON 등의 마크업 언어를 파싱하고 분석하는 것으로,

 

환율 정보가 어떤 tag / class 내에 있는지 확인해보아야 한다.

    target_currency = soup.find("span", {"class": "r0bn4c rQMQod"}).get_text()
    korea_won = soup.find("div", {"class": "BNeawe iBp4i AP7Wnd"}).get_text()

 

위의 코드 부분은 파이썬 코드에서 print(soup) 의 결과를 분석하여

 

환율 정보를 찾아내어 tag 종류와 class 명을 기입해 준 것이다.

 

코드를 실행해 주고 환율 정보를 물어봐주면 아래와 같이 정확하게 응답한다.

반응형