파이썬을 사용하여 텔레그램 봇을 만들어 볼 것이다. 카카오톡은 오픈채팅에서 사용할 수 있는 봇을 추가할 수 있지만 텔레그램에서는 그런 기능을 직접 코드로 구현해야되는 것으로 보인다. 그래도 카톡 오픈채팅으로 메시지를 보낼 수 있는 코드를 따라해보려고 하였으나 채팅 입력 및 송신, 마지막 단계에서 실패했다. 그래서 텔레그램으로라도 메시지 송신이 가능한 봇을 만들어보고자 이 글을 쓰게 되었다.
Index
1. 텔레그램 봇 만들기
이 글을 읽는 독자들은 기본적으로 텔레그램 계정을 가지고 있을 것으로 짐작된다. 검색창에 'botfather'를 입력하고, 해당 계정으로 들어가 채팅을 시작한다. '/newbot'을 치면 새로운 봇을 만들 수 있다. 봇의 이름과 식별명을 부여하고, 토큰 번호를 받았으면 이상없이 만들어진 것이다.
2. 텔레그램 메시지 전송
1) chat_id 확인
우선, 위에서 생성한 봇과의 채팅을 시작하여야 한다. 해당 채팅방에 들어가 start를 누르고 메시지를 보낸다. 채팅을 보냈지만 다른 블로그에서 나온 것처럼 아래 코드로 chat_id를 확인할 수는 없었다.
# import telegram
# mytoken = "yourtoken"
# chat = telegram.Bot(token = mytoken)
# updates = chat.getUpdates()
# for u in updates:
# print(u.message['chat']['id'])
import telegram
token = "yourtoken"
bot = telegram.Bot(token)
updates = bot.getUpdates()
print(updates[0].mesage.chat_id)
이 경우, "TypeError: 'coroutine' object is not subscriptable sys:1: RuntimeWarning: coroutine 'Bot.get_updates' was never awaited"라는 메시지가 뜨면서 에러가 발생한다. 업데이트하면서 이전과 다른 체계를 도입한 듯하다. 그래서 chat_id는 https://api.telegram.org/bot[본인토큰]/getUpdates (대괄호 없이 bot 다음에 토큰 입력) 라는 주소로 들어가 id를 확인하여야 한다. 아래 이미지에서 chat : {id} 에 해당하는 부분이다.
2) 메시지 송신
토큰과 chat id를 알았으므로 메시지를 보내는 코드를 짜보도록 하자. 기존에는 아래와 유사하게 코딩하면 메시지가 보내졌던 것으로 보이나 이제는 되지 않는다. VSC에서 돌려보니 "RuntimeWarning: coroutine 'Bot.send_message' was never awaited" 이런 에러가 생긴다.
import telegram
bot = telegram.Bot(token='본인 토큰')
chat_id = 657656424
bot.sendMessage(chat_id=chat_id, text="메시지")
그래서 구글링으로 새로운 해결책을 찾았다. 바로 asyncio를 불러오는 방법이다. 아래 코드를 실행하니 메시지가 보내졌다. 그런데 여기서 궁금증. asyncio는 과연 무엇일까? 다음 챕터에서 그 의문에 간략하게 답을 하고 이어나가도록 하겠다.
import telegram
import asyncio
bot = telegram.Bot(token='>')
chat_id = ?
asyncio.run(bot.send_message(chat_id = chat_id, text = "python test"))
(1) asyncio
asyncio는 비동기 프로그래밍을 위한 모듈로 CPU 작업과 I/O (Input & Output)을 병렬로 처리하는 기능을 제공한다. 병렬이란 단어로 어떤 작업을 동시에 진행한다는 것까지는 감을 잡았는데 완벽히 이해되지는 않았다 (코딩도장).
일반적으로 함수는 동기, 즉 이전 코드를 실행하고 나서 다음의 코드를 실행하는 식의 구조를 취한다. 그러나 어떤 경우에는 동시에 코드를 진행하는 것이 효율적일 수 있다. 비동기 함수는 호출된 함수의 실행이 마무리되지 않았다고 해도, 함수의 결과를 return하고 스스로 백그라운드 환경에서 실행된다. 그리고 해당 작업이 완료되면 호출된 함수에게 작업이 끝났음을 알려주는 것이다. 일반적으로 I/O 작업을 할 때는 CPU가 쉬기 때문에 CPU를 채찍질하여 프로그램의 속도를 높이는 것이 비동기 처리의 목적인 셈이다.
def 앞에 async를 붙인 async def 비동기 함수를 나타낸다. 이런 함수를 코루틴 (coroutine)이라고 한다. 비동기 함수는 'await'와 자주 쓰이는데 이것은 특정 객체가 종료될 때까지 대기한 후 결과를 반환한다. 그리고 비동기 함수를 호출하기 위해서는 이벤트 루프에 등록해야 하고, run함수로 실행시켜야만 한다 (코뮤 블로그).
(2) 텔레그램 그룹에 봇 추가
텔레그램 그룹에 봇을 추가하려면 먼저, BotFather에서 봇의 그룹 추가가 가능한지 살펴봐야 한다. 추가하려는 봇이 ENABLED라고 표시돼야 한다.
그후 생성된 그룹에 BOT을 초대하고, 그룹의 chat_id로 변경한 다음, 메시지를 보내면 된다. 그룹의 chat_id는 일반 채팅과 다르게 음수로 표기된다. 확인 방법은 위에 일러두었으니 생략하겠다. 필자가 만든 buddybuddy 봇이 test라는 메시지를 보낸 것으로 봐서 2023년 2월 기준, 이상없이 실행되는 것을 알 수 있다.
3. 참고
'Python > SNS BOT' 카테고리의 다른 글
[Python] 텔레그램 봇 메시지 발송 (ChatGPT의 코딩 실력은?) (0) | 2023.02.19 |
---|