JavaRush /Java Blog /Random-KO /Java로 Telegram 봇 만들기: 아이디어부터 배포까지
John Watson
레벨 27

Java로 Telegram 봇 만들기: 아이디어부터 배포까지

Random-KO 그룹에 게시되었습니다
어쨌든 봇이란 무엇입니까? 자세한 내용은 여기에서 읽어보실 수 있습니다 . 먼저 텔레그램 봇 개발용 라이브러리(이하 API) 공식 문서를 읽어야 합니다. 그녀는 여기 누워있습니다 . Java로 텔레그램 봇 만들기: 아이디어부터 배포까지 - 1모든 것이 매우 접근 가능하고 이해하기 쉽습니다. 쓰고 기뻐하는 것 같습니다! 그러나 그렇게 간단하지는 않습니다. 검색 엔진에서 많은 시간을 보낸 후 키보드를 만드는 방법, CallbackQuery를 처리하는 방법 등과 같은 봇 개발에 대한 지식의 일부를 찾았습니다. 저는 Java로 봇을 개발하기 위한 완전하고 포괄적인 가이드를 찾지 못했습니다. 이것이 제가 이 글을 쓰게 된 계기가 되었습니다. 이미 만들어진 배포를 통해 자신만의 봇을 만들 수 있는 사이트가 인터넷에 많이 있습니다. 그러나 요점은입니다. 대부분의 경우 배경 정보 등을 제공할 수 있는 봇이 생성됩니다. 우리 봇은 데이터베이스 바인딩, 다양한 API에 대한 요청, 사이트 구문 분석, 복잡한 계산 수행 등을 수행할 수 있는 본격적인 웹 애플리케이션입니다. 문제는 당신의 상상력에 의해서만 제한됩니다. 이 글을 통해 제가 쓰려는 내용을 여러분에게 조금 설명하였기를 바랍니다. Telegram에 봇을 등록하는 것은 매우 간단합니다. 이 프로세스는 위 링크의 문서에 자세히 설명되어 있습니다. 우리의 애플리케이션을 위해서는 봇의 이름과 등록 시 받게 될 토큰만 알면 됩니다. 기본적으로 봇은 콘솔 웹 애플리케이션일 뿐입니다. 프런트엔드 없음, 순수 명령 처리. Hibernate를 잘 익히고 싶거나 JSON을 구문 분석하는 방법을 배우고 싶다면 이 프로젝트가 당신을 위한 것입니다. pom.xml에 종속성을 포함하는 것부터 시작하겠습니다(Maven을 사용한다고 가정합니다). 다음과 같이 할 수 있습니다:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
그런 다음 클래스를 만들고 Bot클래스에서 상속하여 TelegramLongPollingBot해당 메서드를 재정의합니다.
public class Bot extends TelegramLongPollingBot {

    /**
     * Method for receiving messages.
     * @param update Contains a message from the user.
     */
    @Override
    public void onUpdateReceived(Update update) {
	String message = update.getMessage().getText();
	sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Method for setting up a message and sending it.
     * @param chatId chat id
     * @param s The string to send as a message.
     */
    public synchronized void sendMsg(String chatId, String s) {
        SendMessage sendMessage = new SendMessage();
        sendMessage.enableMarkdown(true);
        sendMessage.setChatId(chatId);
        sendMessage.setText(s);
        try {
            sendMessage(sendMessage);
        } catch (TelegramApiException e) {
            log.log(Level.SEVERE, "Exception: ", e.toString());
        }
    }

    /**
     * The method returns the name of the bot specified during registration.
     * @return bot name
     */
    @Override
    public String getBotUsername() {
        returnBotName;
    }

    /**
     * The method returns the bot's token to communicate with the Telegram server
     * @return token for the bot
     */
    @Override
    public String getBotToken() {
        returnBotToken;
    }
}
음, 메소드의 내용은 다음과 같습니다 main.
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
이를 메소드에 입력하여 getBotUsername()getBotToken()을 시작합니다. 현재 그는 일종의 "거울"로서 우리가 그에게 보내는 모든 메시지를 우리에게만 리디렉션합니다. 모두 다음과 같이 작동합니다. 애플리케이션을 시작하면 다음 URL에서 n초마다 한 번씩 Telegram 서버에 GET 요청을 보내기 시작합니다: https://api.telegram.org/BotToken/getMe, 여기서 BotToken은 모든 메시지가 포함된 JSON 응답으로 수신되는 봇의 토큰입니다. 이러한 각 메시지는 라이브러리에 의해 처리되어 메소드에 OnUpdateReceived(Update update)객체로 제공됩니다 Update. 그것이 우리가 함께 일하는 것입니다. 이것이 Telegram 봇의 장점입니다. 모든 컴퓨터에서 작동할 수 있습니다. 테스트를 위해 애플리케이션을 실행하기만 하면 되며, 각 변경 후에 호스팅에 배포할 필요가 없습니다. 매우 편안합니다. 물론 웹훅을 사용하여 작동하도록 봇을 구성할 수 있으며, 매뉴얼은 인터넷에서 찾을 수 있습니다. 단순화를 위해 LongPolling을 사용하여 작업하겠습니다. 메시지를 처리하는 방법과 응답으로 보낼 내용은 언어 도구와 라이브러리에 의해서만 제한되며 다른 모든 것은 귀하의 재량에 달려 있습니다. YouTube에서 동영상을 검색하는 봇을 만들 수 있습니다. 예를 들어 일종의 타임캡슐과 같이 1년 안에 자신에게 보내는 내용을 매일 보내는 봇을 만들 수 있습니다. 또는 CRM 시스템에 통합하고 소규모 기업을 위한 봇을 만드는 방법을 배울 수 있습니다. 모든 것은 여러분의 상상력에 달려 있습니다. 계속하세요. 봇을 사용해 본 사람들은 «/»예를 들어 기호로 시작하는 명령을 사용하여 로봇과 상호 작용하는 것이 편리하다는 것을 알고 있습니다 /start. 그러나 더 편리한 방법이 있습니다 - 버튼. 버튼에는 두 가지 유형이 있습니다. 입력 필드 아래에 나타나는 ReplyKeyboardMarkup버튼과 연결된 메시지 바로 아래에 나타나는 버튼입니다 InlineKeyboardMarkup. 문서에서 해당 설명을 간략하게 익힐 수 있습니다. ReplyKeyboardMarkup. 본질적으로 이는 버튼 배열의 배열입니다 List<KeyboardRow<KeyboardButton>>. 다음은 키보드를 생성하는 예제 코드입니다.
public synchronized void setButtons(SendMessage sendMessage) {
        // Create a keyboard
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Create a list of keyboard strings
        List<KeyboardRow> keyboard = new ArrayList<>();

        // First line of the keyboard
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Add buttons to the first line of the keyboard
        keyboardFirstRow.add(new KeyboardButton(“Привет”));

        // Second line of the keyboard
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Add buttons to the second line of the keyboard
        keyboardSecondRow.add(new KeyboardButton(“Помощь”);

        // Add all keyboard strings to the list
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // and set this list to our keyboard
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
메소드에서는 sendMsg()메시지를 전달하여 이 메소드를 호출하고 해당 메시지에 대한 키보드를 설정합니다. 이 메시지를 사용자에게 보내면 사용자는 우리가 설정한 메시지 텍스트와 함께 Hello 및 Help라고 적힌 2개의 버튼이 나란히 표시됩니다. 이 버튼을 클릭하면 버튼에 쓰여진 텍스트와 같은 메시지가 봇으로 전송됩니다. 즉, 클라이언트가 "도움말"을 클릭하면 봇은 "도움말"이라는 텍스트가 포함된 메시지를 받게 됩니다. 그에게는 마치 고객이 직접 "도움말"이라는 텍스트를 작성하여 그에게 보낸 것과 같습니다. 그러면 그러한 메시지를 처리하게 됩니다. InlineKeyboardMarkup 이것도 배열의 배열로 이전 Markup과 유사하지만 여기의 작동 논리는 약간 다릅니다. 이러한 키보드는 특정 메시지와 연결되어 있으며 해당 메시지에만 존재합니다. 인라인 키보드를 설치하는 방법은 다음과 같습니다.
private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText(“Кнопка“).setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
List에서 생성 하고 List첫 번째 줄에 인라인 버튼을 추가합니다. 이러한 버튼에는 URL, 채널 링크 또는 CallbackQuery나중에 작성하게 될 가 포함될 수 있습니다. 여기서는 사용자가 볼 버튼의 텍스트를 설정한 다음 봇으로 전송될 데이터를 설정합니다. 이 예에서 사용자는 "Hello"를 보고 클릭하면 봇에 숫자 17이 전송됩니다. 이것이 우리의 CallbackQuery. 에 대해 몇 마디 CallbackQuery. 개체에서 이러한 데이터를 얻으려면 를 Update실행해야 하며 update.getCallbackQuery(), 이 메서드는 를 반환하며 CallbackQuery, 여기에서 이미 봇으로 전송된 데이터를 얻을 수 있습니다. update.getMessage().getText()get 메소드를 통해 이 데이터를 얻으려고 시도할 필요가 없습니다 NullPointerException.
@Override
    public void onUpdateReceived(Update update) {
        if(update.hasMessage()) {
            ThreadClass thread = new ThreadClass(update.getMessage());
        } else  if(update.hasCallbackQuery()) {
            AnswerCallbackThread answerThread = new AnswerCallbackThread(update.getCallbackQuery());
        }
    }
메시지가 있으면 처리를 위해 새 스레드로 메시지를 보내고, 메시지가 있으면 CallbackQuery처리를 위해 적절한 스레드로 보냅니다. CallbackQuery답장을 보내실 수 있습니다 . 텔레그램의 각 객체에는 고유한 ID가 있습니다. 특정 개체에 응답을 보내려면 CallbackQuery해당 개체에서 받을 ID만 알면 됩니다. 응답을 보내려면 다음 메소드를 호출하십시오.
public synchronized void answerCallbackQuery(String callbackId, String message) {
        AnswerCallbackQuery answer = new AnswerCallbackQuery();
        answer.setCallbackQueryId(callbackId);
        answer.setText(message);
        answer.setShowAlert(true);
        try {
            answerCallbackQuery(answer);
        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }
중요한:답변 내용은 CallbackQuery200자(영문 기준) 이하여야 합니다! 이러한 응답을 보내면 클라이언트는 메시지가 작성될 팝업 창을 받게 됩니다. 이러한 창은 나타난 후 몇 초 후에 사라지거나 사용자가 확인을 누를 때까지 중단될 수 있습니다. 이러한 모드를 전환하려면 answer.setShowAlert(true). true확인을 누를 때까지 창이 멈춰 있을 때 , false5초 후에 사라질 때. 원칙적으로 이는 Telegram 봇 라이브러리의 모든 기본 기능입니다. 원하는 경우 문서에서 멀티미디어 전송, 위치 정보 등과 같은 내용을 배울 수 있습니다. 호스팅에 봇을 배포하는 방법을 살펴보겠습니다. 제 프로젝트에서는 Heroku를 선택했습니다. 제 생각에는 자체 CLI가 있는 상당히 편리한 호스팅이기 때문입니다. 무료이지만 이 속도에서는 요청이 없으면 30분 후에 봇이 최대 절전 모드로 전환됩니다. 그에게 요청이 전송되면 그는 깨어납니다. 이는 매우 빠르게 발생하므로 사용자도 눈치채지 못할 것입니다(물론 데이터베이스에 대한 연결이 다시 설정되지 않는 한). 무료 플랜의 한도는 5MB 데이터베이스, 100MB 디스크 공간, 월별 2TB 트래픽, 1디노입니다. Dino는 실행 중인 애플리케이션입니다. 이전에 애플리케이션을 배포한 적이 없었기 때문에 나에게 어려움을 초래한 것은 배포 단계였다고 바로 말씀드리겠습니다. 배포할 때 Heroku에는 Procfile(확장자 없음)이라는 파일이 필요합니다. 프로젝트 루트에 생성하고 거기에 worker: sh target/bin/workerBot WorkerBot을 작성합니다 . pom.xml Maven 플러그인 appassembler-maven-plugin을 사용하여 생성된 sh 스크립트가 실행됩니다. 스크립트는 컴파일된 jar 실행을 설명합니다. 시작할 클래스의 이름은 <mainClass></mainClass> 사이에 표시되고, <name></name> pom.xml 사이에는 스크립트 이름이 표시됩니다.
...
<build>
    <plugins>
        ...
       <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>1.1.1</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>com.home.server.TelegramBot</mainClass>
                        <name>workerBot</name>
                    </program>
                </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
이 프로세스를 시작하기 전에 Heroku에 등록하고 Git 및 Heroku CLI를 설치해야 합니다. 애플리케이션에 데이터베이스가 필요한 경우 새 애플리케이션을 등록할 때 필요한 데이터베이스를 추가하는 것을 잊지 마세요. 다음으로 데이터베이스의 호스트, 사용자 이름, 비밀번호 및 포트를 찾아 애플리케이션에서 지정해야 합니다. 다음으로 배포하기 전에 Maven을 사용하여 프로젝트를 빌드합니다.
mvn clean install
우선 프로젝트 디렉토리로 이동하여 다음 명령을 사용하여 저장소를 초기화한git init 다음 프로젝트를 이 저장소에 추가합니다.
git add .
변경 사항을 커밋한 후
git commit -m “First commit in project”
다음으로 heroku에 로그인하고 명령줄에 작성해야 합니다.
heroku login
등록 시 지정한 데이터를 입력하세요. 그런 다음 Heroku에서 저장소의 URL을 찾아야 하며 이는 설정에서 수행됩니다. 그럼 우리는 쓴다
git remote add heroku [url]
heroku 원격 저장소가 저장소에 추가됩니다. 다음으로 우리는 쓴다
git push heroku master
기다리고 있습니다... 애플리케이션 배포가 성공하면 다음 명령을 실행합니다.
heroku ps:scale worker=1
이것이 전부입니다. 애플리케이션이 실행 중입니다. 이런 일이 발생하지 않으면 로그를 주의 깊게 살펴보십시오. 애플리케이션에 충돌을 일으킨 오류가 있을 가능성이 높습니다. 이렇게 긴 글을 읽어주셔서 감사합니다. 제가 개발 중에 헤매었던 부분을 누군가가 유용하게 여기고 많은 시간을 절약해 주셨으면 좋겠습니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION