Profile picture

[Python] 텔레그램(Telegram) API로 간단한 Chat bot 만들기 - 텔레그램 웹훅(webhook)

JaehyoJJAng2023년 08월 22일

▶ telegram api 활용하기

텔레그램 api를 활용하면 특정 채팅방에서 발생하는 여러 이벤트들을 지정한 서버로 전달하거나, 서버에서 특정 채팅방으로 챗봇 이벤트를 수행하도록 설정하는 것도 가능하다.

대화병 챗봇을 제작하기 위해서는 아래 과정이 수행되어야 한다.

🔎 참고

API 서버에 SSL 인증서가 필수적으로 적용되어 있어야 한다.
텔레그램 api의 webhook은 https 프로토콜을 사용하는 사이트에만 전달할 수 있음.

  • BotFather를 이용하여 새로운 봇 생성 및 토큰 발행받기
  • 챗봇 동작 지시용 리눅스 서버
  • 서버에 SSL 인증서 적용
  • 봇에 웹훅 URL 설정
  • 원하는 봇 구현

▶ 새로운 봇 생성 및 토큰 발행

봇이 생성되어 있지 않다면 아래 블로그 글을 참고하여 봇을 생성하도록 하자.
https://blog.naver.com/monkeychoi/223185247922


▶ 서버 준비 + SSL 적용

간단하게 구현하기 위해 파이썬 웹 프레임워크 중 하나인 fastapi를 사용하여 웹 서버를 구축해볼 것이다.

여기서 구축하는 서버는 챗봇이 참여한 채팅방에서 발생하는 여러 이벤트들을 웹훅을 통해 수신하게 될 서버이다.

텔레그램 API는 웹훅 수신용 서버로 SSL이 적용된 서버만 허용해주기 때문에

여기서 만들 서버는 SSL 인증서가 필수적으로 적용되어 있어야 한다.

또한, 웹훅용 URL로는 다른 임의의 트래픽이 접근하지 않을만한 특별한 path를 지정해 주는 것이 좋다.

  • 본 예제에서 사용될 웹훅 URL ▸ https://teleapi.waytothem.shop/chat
  • 수신 메서드의 경우 반드시 POST 방식을 사용
  • 웹훅 서버의 경우는 80, 88, 443, 8443만을 지원함.

본인의 경우 Proxmox를 통하여 Dev라는 이름으로 봇 개발 서버를 별도 구축하고

Nginx Proxy Manager 서버도 별도 구축하여 웹 서버 리버스 프록시 + SSL 인증서를 적용해줄거다.

구축 방법에 대해서는 자세하게 다루지는 않겠다.
image


마지막으로 서브 도메인별로 API를 나누어 리버스 프록시를 설정할 것이므로,

아래와 같이 구입한 도메인 사이트에 들어가서 서브 도메인을 설정해주자.
image


▶ 봇에 웹훅 URL 설정

생성한 봇과 서버가 연결되기 위해서는 봇의 이벤트를 수신할 웹훅 서버를 별도로 지정해 주어야 한다.

여기서는 웹훅 서버를 위의 Dev 서버로 지정할 것이다.

텔레그램에서 제공하는 챗봇용 api중 하나인 setWebhook을 사용해보자. 설정은 다음과 같이 api를 하나 호출해주면 된다.

https://api.telegram.org/bot[Bot_token]/setWebhook?url=[웹훅서버도메인]/path
# 예시
https://api.telegram.org/botabcd1234/setWebhook?url=https://teleapi.waytothem.shop/chat

GET 방식으로 쿼리 파라미터만 전달해주면 되기 때문에 일반 웹 브라우저에 위 형식으로 URL을 입력해주거나

맥북 또는 리눅스 서버 환경인 경우 아래 명령어를 사용하여 웹훅 설정을 완료할 수 있다.

$ curl -X GET "https://api.telegram.org/bot[Bot_token]/setWebhook?url=[웹훅서버도메인]"
{"ok":true,"result":true,"description":"Webhook was set"}

🔦 API 호출 결과가 위와 같이 true로 출력되면 정상적으로 설정된 것이다!


▶ 테스트

아래는 fastapi 서버를 활용하여 간단한 웹훅 서버를 구축한 예시이다.

아래의 코드를 작성하여 서버를 기동시키고, SSL 적용, 웹훅 설정까지 완료한다면 사용자가 입력한 채팅이 출력으로 서버 시스템에 출력될 것이다.

만약 도커로 구동했다면 컨테이너 로그에 채팅 기록이 남을 것이다.

example.py

from fastapi import Request, FastAPI

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "TelegramChatbot"}

@app.post("/chat")
async def chat(request: Request):
    telegramrequest = await request.json()
    print(telegramrequest)
    return 0

requirements.txt

fastapi

▶ 마무리

NPM으로 서브 도메인에 대해 리버스 프록시 + SSL 인증서를 적용한 결과
image


애플리케이션 동작 확인
image


본인의 경우 도커로 구동하였기에

아래와 같이 컨테이너 로그에 채팅 기록이 찍히는 것을 볼 수 있다.
image


▶ 번외

프로젝트 구조

.
├── composes
│   ├── app.yaml
│   ├── Dockerfile
│   ├── requirements.txt
│   ├── serverset.py
│   └── start_fastapi.sh
└── docker-compose.yaml

파이썬 Flask 애플리케이션을 컨테이너화하기.

Dockerfile 작성

Dockerfile

FROM python:3.10-slim-buster

WORKDIR /usr/src/app

COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt

COPY . .

EXPOSE 8888

CMD ["bash", "start_fastapi.sh"]

start_fastapi.sh

#!/usr/bin/bash

scriptPath='/usr/src/app'
scriptFile="serverset"

PORT=8888

cd "$scriptPath"
uvicorn "$scriptFile":app --host=0.0.0.0 --port=$PORT --reload

Docker Compose

docker-compose.yaml

version: "3.9"

include:
  - "composes/app.yaml"

networks:
  telegram-ai-net:
    driver: bridge
    external: false

composes/app.yaml

services:
  app:
    build: .
    restart: always
    ports:
      - "5444:5444"
    volumes:
      - "./:/usr/src/app"
    container_name: "telegram_ai"
    networks:
      - "telegram-ai-net"

docker-compose up -d --build

Loading script...