Notice
Recent Posts
Recent Comments
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

아직도 텔레그램 안쓰니?

확장 기능: 첫 번째 봇 (ChatGPT 번역) 본문

python-telegram-bot

확장 기능: 첫 번째 봇 (ChatGPT 번역)

텔레그램사랑 2024. 1. 6. 20:41

https://github.com/python-telegram-bot/python-telegram-bot/wiki/Extensions---Your-first-Bot

확장 기능: 첫 번째 봇

소개

telegram.ext 서브모듈은 순수한 API 구현 위에 구축되었습니다. 이것은 사용자에게 쉽게 사용할 수 있는 인터페이스를 제공하며 프로그래머의 작업을 일부 덜어주어 반복 작업을 피할 수 있게 도와줍니다.

이 서브모듈에는 여러 클래스가 포함되어 있지만 가장 중요한 것은 telegram.ext.Application입니다.

Application 클래스는 update_queue에서 업데이트를 가져오는 역할을 담당합니다. Updater 클래스가 지속적으로 Telegram에서 새로운 업데이트를 가져와 이 큐에 추가하는 곳입니다. Application 객체를 ApplicationBuilder를 사용하여 생성하면 자동으로 Updater를 생성하고 asyncio.Queue로 연결합니다. 그런 다음 Application에 다른 유형의 핸들러를 등록할 수 있으며, 이 핸들러는 Updater가 가져온 업데이트를 등록한 핸들러에 따라 정렬하고 사용자가 정의한 콜백 함수로 전달합니다.

모든 핸들러는 telegram.ext.BaseHandler 클래스의 하위 클래스의 인스턴스입니다. 라이브러리는 거의 모든 사용 사례에 대한 핸들러 클래스를 제공하지만 매우 구체적인 것이 필요한 경우 Handler를 직접 하위 클래스로 만들 수도 있습니다.

시작하려면 액세스 토큰이 필요합니다. API 소개를 이미 읽고 따랐다면 그때 생성한 토큰을 사용할 수 있습니다. 그렇지 않은 경우: 액세스 토큰을 생성하려면 @BotFather와 몇 가지 간단한 단계를 따라야 합니다(여기에서 설명됨). 그러나 먼저 소개를 정독하는 것이 좋습니다.

첫 번째 봇, 단계별로

이 튜토리얼을 따르려면 새 파일을 만들어주세요. 튜토리얼 도중에 파일에 여러 번 내용을 추가할 것입니다. 간결성을 위해 매번 무엇을 추가할 때마다 모든 내용을 반복하지는 않겠습니다.

그러니 시작해 봅시다! 다음 내용을 파일에 붙여넣어주세요:

import logging
from telegram import Update
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")

if __name__ == '__main__':
    application = ApplicationBuilder().token('TOKEN').build()

    start_handler = CommandHandler('start', start)
    application.add_handler(start_handler)

    application.run_polling()

이것은 많은 내용을 소화해야 하므로 단계별로 진행하겠습니다.

import logging
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)

이 부분은 로깅 모듈을 설정하는 부분으로, 작업이 예상대로 작동하지 않을 때 언제 (그리고 왜) 문제가 발생했는지를 알 수 있게 합니다.

참고: 더 자세한 내용은 예외, 경고 및 로깅에 관한 기사를 읽어보세요.

application = ApplicationBuilder().token('TOKEN').build()

여기서 첫 번째 실제 마법이 일어납니다. Application 객체를 생성해야 합니다. 'TOKEN'을 봇의 API 토큰으로 대체하십시오. 이 작동 방식에 대한 자세한 내용은 이 페이지를 참조하십시오.

관련 문서: telegram.ext.ApplicationBuilder, telegram.ext.Application

application만으로는 아무 일도 수행하지 않습니다. 기능을 추가하려면 두 가지 작업을 수행합니다. 먼저, 특정 유형의 업데이트를 처리해야 하는 함수를 정의합니다.

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(
        chat_id=update.effective_chat.id,
        text="I'm a bot, please talk to me!"
    )

목표는 이 함수가 봇이 /start 명령을 포함한 텔레그램 메시지를 수신할 때마다 호출되도록 하는 것입니다.

이 함수는 두 개의 매개변수를 받는 것을 볼 수 있습니다. 첫 번째는 업데이트이며, 이는 텔레그램 자체에서 가져온 모든 정보와 데이터를 포함하는 객체입니다(메시지, 명령을 내린 사용자 등). 두 번째는 컨텍스트이며, 이는 라이브러리 자체의 상태에 대한 정보와 데이터를 포함하는 다른 객체입니다(봇, 애플리케이션, job_queue 등).

관련 문서: send_message, telegram.ext.CallbackContext (context 인수의 유형), telegram.Update (update 인수의 유형)

봇에게 /start 명령을 수신하도록 알리려면 CommandHandler(제공되는 Handler 하위 클래스 중 하나)를 사용하고 애플리케이션에 등록하면 됩니다.

from telegram.ext import CommandHandler
start_handler = CommandHandler('start', start)
application.add_handler(start_handler)

관련 문서: telegram.ext.CommandHandler, telegram.ext.Application.add_handler

이게 다입니다.

마지막으로, application.run_polling() 라인은 CTRL+C를 누를 때까지 봇을 실행합니다.

관련 문서: telegram.ext.Application.run_polling

한 번 시도해 보세요! 봇과 채팅을 시작하고 /start 명령을 내려보세요. 모든 것이 올바르게 진행되었다면 봇이 응답할 것입니다.

하지만 우리 봇은 이제 /start 명령에만 응답할 수 있습니다. 일반 메시지를 수신하는 다른 핸들러를 추가해 보겠습니다. 모든 텍스트 메시지를 에코하는 데 MessageHandler를 사용하십시오. 먼저 CTRL+C를 눌러 봇을 중지하십시오. 그런 다음 새로운 함수를 정의하고 해당 핸들러를 추가합니다.

from telegram import Update
from telegram.ext import filters, MessageHandler, ApplicationBuilder, CommandHandler, ContextTypes

...

async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text=update.message.text)


if __name__ == '__main__':
    ...
    echo_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), echo)

    application.add_handler(start_handler)
    application.add_handler(echo_handler)

    application.run_polling()

관련 문서: telegram.ext.MessageHandler, telegram.ext.filters

이제부터 봇은 수신하는 모든 비 명령 메시지를 에코해야 합니다.

참고: filters 모듈에는 텍스트, 이미지, 상태 업데이트 등의 수신 메시지를 필터링하는 여러 필터가 포함되어 있습니다. MessageHandler에 전달된 필터 중 하나에 대해 True를 반환하는 모든 메시지가 수락됩니다. 필요한 경우 직접 필터를 작성할 수도 있습니다. 자세한 내용은 고급 필터에서 확인하세요.

이제 봇에 실제 기능을 추가해 보겠습니다. /caps 명령을 구현할 것이며, 이 명령은 텍스트를 인수로 받아 (예: /caps argument) 해당 텍스트를 대문자로 변환하여 응답합니다. 콜백 함수에서 명령에 전달된 인수 (공백으로 분리된 목록으로)를 사용할 수 있도록 구현할 것입니다.

async def caps(update: Update, context: ContextTypes.DEFAULT_TYPE):
    text_caps = ' '.join(context.args).upper()
    await context.bot.send_message(chat_id=update.effective_chat.id, text=text_caps)

if __name__ == '__main__':
    ...
    caps_handler = CommandHandler('caps', caps)

    application.add_handler(start_handler)
    application.add_handler(echo_handler)
    application.add_handler(caps_handler)

    application.run_polling()

참고: context.args 사용법을 살펴보세요. CallbackContext에는 사용된 핸들러에 따라 여러 속성이 있습니다.

텔레그램 봇 API의 또 다른 멋진 기능 중 하나는 인라인 모드입니다. 봇에 인라인 기능을 구현하려면 먼저 @BotFather와 대화를 시작하고 /setinline을 사용하여 인라인 모드를 활성화해야 합니다. 봇이 클라이언트에서 인라인 봇으로 등록되기까지는 때로는 시간이 걸릴 수 있습니다. 텔레그램 앱을 다시 시작하여 프로세스를 가속화할 수 있을 때도 있지만 때로는 그냥 기다려야 할 수도 있습니다.

봇이 분명히 매우 큰 소리로 말하는 봇이기 때문에 인라인 모드로 계속 진행하겠습니다. 지금까지 프로세스를 아마 이미 알고 있을 것입니다. 그러나 여기에는 새로운 유형이 여러 개 사용되므로 주의해서 살펴보세요.

from telegram import InlineQueryResultArticle, InputTextMessageContent
from telegram.ext import InlineQueryHandler

...

async def inline_caps(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = update.inline_query.query
    if not query:
        return
    results = []
    results.append(
        InlineQueryResultArticle(
            id=query.upper(),
            title='Caps',
            input_message_content=InputTextMessageContent(query.upper())
        )
    )
    await context.bot.answer_inline_query(update.inline_query.id, results)

if __name__ == '__main__':
    ...
    inline_caps_handler = InlineQueryHandler(inline_caps)
    application.add_handler(inline_caps_handler)

    application.run_polling()

관련 문서: telegram.ext.InlineQueryHandler, answer_inline_query

멋지네요! 이제 봇은 명령을 통해 소리치거나(하!) 인라인 모드를 통해 메시지를 전달할 수 있습니다.

일부 혼란스러운 사용자는 봇이 이해하지 못하는 명령을 보낼 수 있으므로 이전 핸들러에서 인식되지 않은 모든 명령에 대답하는 COMMAND 필터를 사용한 MessageHandler를 사용할 수 있습니다.

async def unknown(update: Update, context: ContextTypes.DEFAULT_TYPE):
    await context.bot.send_message(chat_id=update.effective_chat.id, text="Sorry, I didn't understand that command.")

if __name__ == '__main__':
    ...

    # 다른 핸들러들
    unknown_handler = MessageHandler(filters.COMMAND, unknown)
    application.add_handler(unknown_handler)

    application.run_polling()

중요: 이 핸들러는 마지막에 추가되어야 합니다. 이 핸들러를 다른 핸들러들 앞에 추가하면 명령 핸들러들이 업데이트를 검토하기 전에 트리거될 것입니다. 한 번 업데이트가 처리되면 모든 후속 핸들러가 무시됩니다. 이를 우회하기 위해 add_handler에 group (int) 키워드 인수를 0 이외의 값으로 전달할 수 있습니다. 자세한 내용은 telegram.ext.Application.add_handler 및 이 위키 페이지를 참조하세요.

놀기를 마치면 CTRL+C를 눌러 봇을 중지하세요.

다음에 무엇을 읽어야 할까요?

  • 실행 가능한 예제를 확인해 보세요.
  • 예외, 경고 및 로깅에 대한 예외와 모범 사례를 알아보세요.
  • 더 많은 기능이 필요하신가요? JobQueue 확장을 확인하세요!

'python-telegram-bot' 카테고리의 다른 글

사용자 정의 필터  (0) 2024.01.09
텔레그램 봇 API 소개 (ChatGPT 번역)  (1) 2024.01.06
python-telegram-bot - 소개 (ChatGPT 번역)  (0) 2024.01.06