한국어
오픈소스포럼
 이곳은 다양한 오픈소스 프로젝트를 소개하고 리뷰, 활용 방법을 공유합니다.

텔레그램(Telegram) Bot 개발

makersweb 2019.07.21 19:07 조회 수 : 6552

Telegram에서 제공하는 Bot API를 이용하여 Qt 및 C++언어 기반의 봇(Bot)을 개발하는 방법을 간단히 설명한다.

Bot API는 Telegram 용 봇 개발을 위해 만들어진 HTTP 기반 인터페이스이다.

 

Bot은 서버의 단순하고 반복적인 서비스를 제공하고자 할 때 유용하다.

 

봇생성 및 인증

우선 텔레그램 설치후 botfather를 검색해서 챗을 시작한다. 시작버튼을 누르거나 /start 를 입력한다.

/newbot 명령후 안내 메세지에 따라 입력하면 봇 생성과 함께 HTTP API 토큰이 발급된다.

botfather.png

 

텔레그램 봇 API에 대한 모든 쿼리는 HTTPS를 통해 제공되며 https://api.telegram.org/bot<token>/METHOD_NAME 형식으로 호출해야한다.

예를 들면 다음과 같다.

https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/getMe

 

전체 API 목록은 다음 링크 페이지를 참조하자.

https://core.telegram.org/bots/api

 

여러 언어를 위한 예제 샘플들이 제공된다.

https://core.telegram.org/bots/samples

 

그 중 Qt 기반의 C++로 개발할 수 있는 예제를 사용해보았다.

https://github.com/Codenegaar/TarnaBot

 

먼저 TarnaBot 객체 및 sender객체 생성시 발급된 토큰을 이용한다.

TarnaBasicSender *sender = new TarnaBasicSender("<< Token >>");
Telegram::TarnaBot *bot = new Telegram::TarnaBot(sender);

 

TarnaBot클래스는 HTTP API와 1:1로 매칭되는 Method를 제공하고 있다.

다음은 유용하게 사용될 수 있는 클래스 일부 Method들이다.
getUpdates
sendMessage
getMe
forwardMessage
sendPhoto
sendSticker
sendAudio
sendDocument
sendVideo
sendVoice
sendVideoNote
sendMediaGroup

 

한가지 예를 들어 간단한 텍스트 메세지를 보내고자 할때 다음과 같이 사용할 수 있다.

bot->sendMessage(12345678, "Hello");

 

대화시작하기

봇에서 메세지를 보내려면 chat_id 가 반드시 있어야 하는데 chat_id 는 대화가 시작될때 생성된다.

대화는 사용자로부터 시작이 되어야 한다. 텔레그램에서 생성된 봇을 검색하여 대화를 시작한다.

 

업데이트 정보 가져오기

수신 업데이트는 봇이 수신할 때까지 텔레그램서버에 24시간동안 저장되며 봇에서 업데이트된 대화를 가져오는 두가지 방법이 있다. 

하나는 getUpdates 를 호출하는 방법이고 다른 하나는 Webhook이다. getUpdates는 pull 메커니즘이며 setWebhook은 push로 동작된다.

 

getUpdates

업데이트된 정보를 가져오는 가장 간단한 방법이다.

폴링을 사용하여 수신 업데이트를 받으려면 이 방법을 사용하면된다.

봇은 텔레그램 서버에 getUpdates를 호출하여 업데이트된 정보를 얻을 수 있다. (Update 개체 배열이 반환됨)

qint64 g_chatId = -1;

while(true){
    QVector<Telegram::Update> latest = bot->getUpdates();
    g_chatId = latest.first().getMessage().getChat().getId();

    // do something.

    QThread::currentThread()->sleep(1);
}

 

setWebhook

Webhook의 개념은 매우 간단하지만 개별 구성 요소의 설정은 많이 까다로울 수 있다. 왜냐하면 http 서버구축과 외부에서 접속 할 수 있도록 포트포워딩 같은 작업이 필요하기 때문이다.

 

어쨋든 Webhook을 사용하면 텔레그램 서버는 업데이트가 도착하자마자 우리의 봇에 알려주기 때문에 다음과 같은 몇가지 고려사항과 관련해서 getUpdates보다 나은 선택이다.

1. 봇이 자주 텔레그램서버에 업데이트를 요청하는 것을 지양할 것.
2. 어떤 종류든 폴링 메커니즘은 좋은 방법이 아니다.

 

몇 가지 기본 요구 사항은 있다 :

▶현재 Webhooks에서 IPv4를 지원한다.

▶포트 443, 80, 88 또는 8443의 서브넷 149.154.160.0/20 및 91.108.4.0/22에서 들어오는 POST를 수락.

▶TLS1.0 + HTTPS 트래픽을 처리.

 

Webhook을 이용한 방법을 간단히 구현해봤다.

 

ngrok를 이용하면 로컬서버를 외부에 https로 제공할 수 있다.

https://dashboard.ngrok.com/auth

 

http 서버 구현은 다음 링크 페이지를 참고하였다.

http://nikhilism.com/post/2011/qhttpserver-web-apps-in-qt/

 

ngrok를 옵션(포트 및 토큰등)과 함께 실행하면 아래 화면처럼 외부에서 접속 가능한 주소가 발급된다.

ngrok.png

 

그다음은 setWebhook을 호출해서 새로운 https 주소를 텔레그램 서버에 webhook으로 설정하는것이다.

Webhook을 설정한다는 것은 URL 형식으로 위치 정보를 제공하는 것이다. 이 위치에서 봇은 업데이트를 수신 대기할 것이다.

https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/setWebhook?url=https://b24c926f.ngrok.io

 

정상적으로 설정되면 다음과 같은 결과가 돌아온다.

{"ok":true,"result":true,"description":"Webhook was set"}

 

이제 업데이트가 있을때 텔레그램 서버에서 webhook으로 설정된 url로 POST 요청에 json 형식의 업데이트된 정보를 보내온다.

webhook.png

 

봇은 업데이트된 정보로 필요한 행동을 한다.

여기서는 봇이 message를 받으면 바로 "hello"를 보내도록 했다.

hellomakersweb.png