본문 바로가기
Programming/Spring

[Spring] 텔레그램 봇(Telegram Bot) 만들기 #2 - 명령어 처리 & 메세지 발송

by NAIMJAE 2024. 12. 19.

#2 텔레그램 봇 명령어 처리 & 메세지 발송

 

 

[Spring] 텔레그램 봇(Telegram Bot) 만들기 #1

#1 텔레그램 봇 생성 & 스프링부트 프로젝트 연결목차Ⅰ 텔레그램 봇이란?Ⅱ 텔레그램 봇 생성Ⅲ 스프링부트 프로젝트와 텔레그램 봇 연결 Ⅰ 텔레그램 봇이란?텔레그램 봇은 사용자가 텔레그

naimjae.tistory.com

 

지난 포스팅에서 텔레그램 봇을 생성하고 스프링부트 프로젝트와 연동해보았습니다.

이번에는 텔레그램 봇 명령어를 처리하는 방법에 대해 알아보겠습니다.


Ⅰ 텔레그램 봇 명령어 처리

1. 텔레그램 봇 라이브러리 분석

본격적으로 명령어를 처리하기 전에, 텔레그램 봇 라이브러리가 어떻게 메세지를 받아오는지 살펴보겠습니다.

프로젝트와 연동된 텔레그램 봇에서는 사용자의 메세지를 onUpdateReceived 메서드를 통해 메세지를 받아옵니다.

 

Update 객체의 구조

onUpdateReceived 서드에 전달되는 Update 객체는 다음과 같은 JSON 구조를 가지고 있습니다.

{
  "updateId": 310987036,
  "message": {
    "messageId": 6,
    "from": {
      "id": 7789395608,
      "firstName": "p",
      "isBot": false,
      "lastName": "coder",
      "userName": "coderpark",
      "languageCode": "ko",
      "canJoinGroups": null,
      "canReadAllGroupMessages": null,
      "supportInlineQueries": null,
      "isPremium": null,
      "addedToAttachmentMenu": null
    },
    "date": 1734586846,
    "chat": {
      "id": 7789395608,
      "type": "private",
      "title": null,
      "firstName": "p",
      "lastName": "coder",
      "userName": "coderpark",
      "photo": null,
      "description": null,
      ...
    },
    "forwardFrom": null,
    "forwardFromChat": null,
    "forwardDate": null,
    "text": "안녕하세요",
    "entities": null,
    ...
    }
...
}

 

주요 필드 설명

Update 객체에서 우리가 주목해야 할 주요 정보는 다음 3가지입니다.

  • from : 메세지를 보낸 사용자에 대한 정보 (ID, 이름 등)
  • chat : 메세지가 발생한 채팅방에 대한 정보 (ID, 유형 등)
  • text : 메세지 내용

 

메세지 데이터 처리

사용자가 보낸 메세지 내용은 Update 객체의 Message 필드 안 text 값에 담겨있습니다.

onUpdateReceived 메서드에서 이를 활용하면 사용자가 보낸 메세지를 확인할 수 있습니다.

@Override
public void onUpdateReceived(Update update) {
    System.out.println("채팅 내용 : " + update.getMessage().getText());
}

 


2. 텔레그램 봇 메세지 전송

메세지 전송을 위한 SendMessage 객체

텔레그램 봇 라이브러리에서 사용자에게 메세지를 전송하기 위해서는 SendMessage 객체를 사용합니다.

SendMessage 객체에 메세지를 받을 chatId 와 전송할 메세지 내용을 입력하면 됩니다.

@Override
public void onUpdateReceived(Update update) {
    System.out.println("채팅 내용 : " + update.getMessage().getText());
    
    // SendMessage 객체 생성 및 설정
    SendMessage message = new SendMessage();
    message.setChatId(update.getMessage().getChatId());
    message.setText("안녕하세요. 텔레그램 봇 예제입니다.");
    
    try {
        // 메세지 전송
        execute(message);
    } catch (TelegramApiException e) {
        System.out.println("Error" + e.getMessage());
    }
}

 

코드 설명

  • SendMessage 객체 생성 및 설정
    • setChatId() 메서드를 사용하여 메세지를 받을 사용자의 ID를 설정
    • setText() 메서드를 사용하여 전송할 메세지 내용을 설정
  • 메세지 전송
    • execute() 메서드에 SendMessage 객체를 전달하면 성공적으로 메세지가 전송됩니다.
    • 전송 중 오류가 발생하면 TelegramApiException을 통해 처리할 수 있습니다.

 

실행 결과

위 코드를 실행하면 텔레그램 봇이 사용자가 보낸 메세지에 응답하는 구조가 됩니다.

사용자가 어떤 메세지를 보내더라고 같은 응답만 받게 됩니다.

 


3. 텔레그램 봇 명령어 처리

명령어 처리를 위한 BotHandler 클래스 생성

이제 텔레그램 봇이 특정 메세지에만 반응하게 명령어 처리를 구현 해보겠습니다. 

우선 메세지 핸들링을 위한 Handler 디렉토리를 생성한 후 BotHandler 클래스를 만듭니다.

src
 ─ main
         └─ java/com/naexamplebot
                  ─ bot
                      ─ Handler
                           └─ BotHandler.java
                      └─ TelegramBot.java
                  ─ config
                           └─ TelegramBotConfig.java

 

package com.naexamplebot.bot.handler;
import java.time.LocalDate;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.objects.Update;

@Component
public class BotHandler {
    // 메세지 핸들링을 위한 메서드
    public String commandHandle(Update update) {
        String message = update.getMessage().getText();

        if(message.contains("/hello")) {
            return "안녕하세요. 텔레그램 봇 예제입니다.";

        }else if(message.contains("/apple")) {
            return "apple은 사과입니다.";

        }else if(message.contains("/date")) {
            return "오늘은 " + LocalDate.now().toString() + " 입니다.";

        }else {
            return null;
        }
    }
}

 

코드 설명

  • commandHandle 메서드
    • Update 객체를 받아와 메세지 내용만 추출합니다.
    • 메세지 내용이 특정 단어와 일치하는지 확인한 후 해당하는 메세지를 반환합니다.

 

commandHandle 메서드 연결

이제 onUpdateReceived 메서드로 돌아와 commandHandle 메서드를 호출하여 명령어를 처리합니다.

@RequiredArgsConstructor
@Component
public class TelegramBot extends TelegramLongPollingBot {

    private final BotHandler botHandler;

    ... 생략 ...

    @Override
    public void onUpdateReceived(Update update) {
        // commandHandle 메서드를 통한 명령어 처리
        String messageText = botHandler.commandHandle(update);
        
        if (messageText != null) {
            SendMessage message = new SendMessage();
            message.setChatId(update.getMessage().getChatId());
            message.setText(messageText);

            try {
                execute(message);
            } catch (TelegramApiException e) {
                System.out.println("Error" + e.getMessage());
            }
        }
    }
}

 

실행 결과

위 코드를 실행하면 텔레그램 봇이 정의된 명령어에 따라 적절한 응답을 반환합니다.

 

주의 사항

텔레그램 봇 메세지 핸들링 과정에서 equal()contains()는 서로 다르게 동작합니다.

@Component
public class BotHandler {
    public String commandHandle(Update update) {
        String message = update.getMessage().getText();
        
        // "/hello" 를 포함하고 있는 모든 메세지에 반응
        if(message.contains("/hello")) {
            return "안녕하세요. 텔레그램 봇 예제입니다.";
        
        // "/apple" 와 정확히 일치하는 메세지에만 반응
        }else if(message.equals("/apple")) {
            return "apple은 사과입니다.";

        }else {
            return null;
        }
    }
}

 

  • equals() : 명령어와 완전히 일치할 때 메세지에 반응
  • contains() : 명령어를 포함하고 있는 모든 메세지에 반응

 

텔레그램 봇을 만드는 과정에서 equals()contains() 사용에 주의하여야 합니다.

  • 텔레그램 대화방에 봇이 하나인 경우
    • equals()contains()은 큰 차이를 보이지 않습니다.
  • 텔레그램 대화방에 여러 봇이 있는 경우
    • 여러 종류의 봇이 있는 경우 서로 명령어가 겹치는 것을 방지하기 위해 명령어 뒤에 봇의 이름이 붙습니다.
    • ex) /hello@NA_Example_bot
    • 이런 상황에서 equals()는 명령어를 제대로 처리하지 못합니다.

 


Ⅱ 텔레그램 봇 명령어 등록

1. BotFather를 통한 대화방 명령어 등록

성공적으로 명령어가 동작한다면, 이제 BotFather를 통해 대화방 명령어를 등록해 봅시다.

 

BotFather에서 /mybots 명령어 입력후 @봇 선택 ▶ Edit Bot ▶ Edit Commands 로 이동합니다.

 

그럼 다음과 같은 메세지가 출력되는데 명령어와 설명을 양식에 맞춰 입력하면 됩니다.

명령어에는 '/' 는 생략합니다.

명령어 - 명령어 설명

hello - 텔레그램 봇 소개
apple - apple은 사과입니다.
date - 현재 날짜 출력

 

Success! Command list updated. 가 뜨면 성공적으로 명령어가 등록되었습니다.

 

나중에 새로운 명령어를 등록하기 위해서는 똑같이 Edit Commands에서 등록하면 되는데,

이때 새로운 명령어만 입력하는게 아니라 기존의 명령어까지 포함해서 모두 입력해주셔야 합니다.

 

이제 명령어를 등록했기때문에 봇이 있는 채팅방에서 '/' 만 입력해도 명령어 목록을 보여줍니다.

 

 


지금까지 텔레그램 봇의 명령어 처리 및 메세지 발송을 해봤습니다.

 

3편에서는 메세지에 스타일을 지정하고 이미지 전송을 해보겠습니다. 😁