개요
텔레그램에서 제공하는 Bot Father
를 활용하여 파이썬으로 텔레그램 메시지 보내기 실습을 진행해보자.
파이썬에서는 텔레그램 Bot API를 쉽게 사용할 수 있는python-telegra-bot
이라는 라이브러리가 존재한다
봇 생성
1. 텔레그램 앱에서 /newbot 이라고 채팅을 입력하면 봇 채팅방을 개설할 수 있는 단계가 시작된다.
2. 봇 채팅방 이름을 지정해주자.
3. 봇의 이름을 지정해주자. 중요한 점은 봇의 이름을 지정할 때는 봇 이름 마지막에 _bot
이라고 끝나야 한다.
4. 이후 봇 채팅방이 개설되고, 다음의 봇 토큰이 생성되었다. 해당 토큰은 이번 실습에서만 사용하고 이후 삭제된다.
5. 마지막으로 생성된 봇 채팅방 검색 후, start
버튼을 클릭하면 된다. (본인이 생성한 봇을 정확히 찾도록 하자.)
이제 생성한 봇을 가지고 파이썬으로 답변을 할 수 있는 코드를 작성하면 된다.
라이브러리 설치
해당 실습의 경우 python-telegram-bot
라이브러리의 버전이 20.1
이상이어야 한다.
20.1
이하인 라이브러리를 사용 중인 경우 정상적인 실습 진행이 불가능할 수 있다.
python-telegram-bot
에 비동기 로직이 추가되면서 20.1 이하 버전에서 해당 실습 코드 사용 시 아래와 같은 에러를 만나게 될 것이다.
coroutine 'Bot.send_message' was never awaited
python-telegra-bot
라이브러리를 설치해보자.
pip install python-telegram-bot
봇을 컨트롤하기 위한 기본 코드
import os
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler
# 텔레그램 API 토큰 가져오기
_TELEGRAM_TOKEN :str = os.getenv('TELEGRAM_TOKEN', '8015190100:AAG8nQb_Guw_2foZM8mDOOV_AndEBV9PVik')
# 텔레그램 메시지 전송을 위한 핸들러 클래스 정의
class TelegramBotHandler():
# /help 핸들러 정의
@classmethod
async def help(cls, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
message = "저는 여러분들을 돕기 위한 봇 입니다!"
await update.message.reply_text(message)
def main() -> None:
bot_handler = TelegramBotHandler()
try:
application = ApplicationBuilder().token(_TELEGRAM_TOKEN).build()
application.add_handler(CommandHandler('help', bot_handler.help))
application.run_polling()
except (KeyboardInterrupt, SystemExit):
print(f"사용자 입력에 따라 프로그램이 종료됨.")
if __name__ == '__main__':
main()
위 코드는 봇 채팅방에서 /help
라고 메시지를 보냈을 때, 봇이 자동으로 '저는 여러분들을 돕기 위한 봇 입니다!' 라는 답변을 하는 코드이다.
CommandHandler
에 의해help
명령이TelegramBotHandler
라는 클래스의help
라는 클래스 메소드와 매핑되도록 콜백 함수를 등록하였다.- 이후
run_polling()
함수를 통해, 사용자로부터/help
라는 채팅이 오는 순간 자동으로 콜백 함수가 실행된다.
위 코드를 실행하고 텔레그램 채팅방에서 /help
라고 쳐보자.
python3 main.py
봇 명령어 등록해보기
위에서 작성했던 /help
라고하는 핸들러를 텔레그램 채팅방에서 명령어로 등록해보자.
1. 봇 채팅창 상단 제목을 클릭하여 봇 관리를 클릭하자.
2. 그리고 명령어 수정을 클릭하면 BotFather 채팅방으로 이동하게 된다.
3. BotFather 채팅방에서 추가할 명령과 명령에 대한 설명을 등록해보자.
4. 이제 이전에 만든 봇 채팅방으로 이동해 /help 명령을 쳐보자.
정상적으로 명령어가 등록 되었다.
여러 유형의 메시지를 보내는 방법
텍스트 전송하기
텍스트를 전송할 때에는 send_message
메소드를 사용하면 된다.
import telegram
import asyncio
TELEGRAM_TOKEN :str = "텔레그램 봇 토큰"
TELEGRAM_CHAT_ID :int = "텔레그램 채팅 ID"
async def main() -> None:
bot = telegram.Bot(token=TELEGRAM_TOKEN)
message :str = "안녕하세요!"
await bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=message)
asyncio.run(main())
$ python3 main.py
이미지 전송하기
이미지를 전송할 때에는 텍스트를 전송했을 때와 비슷하게 send_photo
메소드를 사용하면 된다.
import telegram
import asyncio
TELEGRAM_TOKEN :str = "텔레그램 봇 토큰"
TELEGRAM_CHAT_ID :int = "텔레그램 채팅 ID"
async def main() -> None:
bot = telegram.Bot(token=TELEGRAM_TOKEN)
image_file_name :str = 'test.png'
with open(image_file_name, 'rb') as fp:
await bot.send_photo(chat_id=TELEGRAM_CHAT_ID, photo=fp)
asyncio.run(main())
$ python3 main.py
HTML 파일 전송하기
HTML 파일을 전송할 때에는 sendDocuemnt
메소드를 사용해보자.
import telegram
import asyncio
TELEGRAM_TOKEN :str = "텔레그램 봇 토큰"
TELEGRAM_CHAT_ID :int = "텔레그램 채팅 ID"
async def main() -> None:
bot = telegram.Bot(token=TELEGRAM_TOKEN)
html_file :str = 'test.html'
await bot.sendDocument(chat_id=TELEGRAM_CHAT_ID, document=html_file)
asyncio.run(main())
$ python3 main.py
주기적으로 텍스트 전송하기
특정 메시지를 3초 간격마다 보내려면 아래와 같이 작성한다.
add_job
함수에는 seconds
말고 minutes
, hours
등의 인자로도 변경할 수 있다.
from telegram.ext import ApplicationBuilder
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from telegram import Bot
import asyncio
import pytz
TELEGRAM_TOKEN :str = "텔레그램 봇 토큰"
TELEGRAM_CHAT_ID :int = "텔레그램 채팅 ID"
# 애플리케이션 빌더 생성
application = ApplicationBuilder().token(TELEGRAM_TOKEN).build()
scheduler = AsyncIOScheduler(timezone=pytz.UTC) # 타임존 설정
# 메시지를 보내는 함수
async def send_message(text: str) -> None:
await application.bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=text)
# 봇 초기화 함수
async def initialize() -> None:
await application.initialize()
await application.start()
await application.updater.start_polling()
# 봇 정지 함수
async def stop() -> None:
await application.updater.stop()
# 메인 함수
async def main() -> None:
await initialize()
await send_message(text='안녕하세요!')
# 스케줄러에 작업 추가 (args를 튜플로 수정)
scheduler.add_job(send_message, trigger='interval', seconds=3, args=('안녕하세요!',))
scheduler.start()
try:
await asyncio.Event().wait() # 무한 대기
except (KeyboardInterrupt, SystemExit):
print("프로그램 종료!")
finally:
await application.updater.stop()
# 이벤트 루프 실행
if __name__ == '__main__':
asyncio.run(main())
$ python main.py
실행하면 3초 간격으로 메시지가 전송된다.