JavaRush /Blog Java /Random-VI /Tạo bot Telegram trong Java: từ ý tưởng đến triển khai
John Watson
Mức độ

Tạo bot Telegram trong Java: từ ý tưởng đến triển khai

Xuất bản trong nhóm
Dù sao thì bot là gì? Bạn có thể đọc chi tiết về điều này ở đây . Trước tiên, bạn cần đọc tài liệu chính thức của thư viện phát triển bot trên Telegram (sau đây gọi là API). Cô ấy nằm đây . Tạo bot Telegram trong Java: từ ý tưởng đến triển khai - 1Mọi thứ ở đó đều rất dễ tiếp cận và dễ hiểu. Có vẻ như viết và vui mừng! Nhưng nó không đơn giản như vậy. Sau khi dành nhiều thời gian cho các công cụ tìm kiếm, tôi đã tìm thấy những đoạn kiến ​​​​thức về phát triển bot, chẳng hạn như cách tạo bàn phím, xử lý CallbackQuery và những thứ tương tự. Tôi chưa bao giờ tìm thấy hướng dẫn đầy đủ và toàn diện để phát triển bot trong Java. Điều này thôi thúc tôi viết bài này. Có rất nhiều trang web trên Internet nơi bạn có thể tạo bot của riêng mình bằng cách triển khai sẵn sàng. Nhưng vấn đề là. rằng phần lớn, các bot được tạo ra có thể cung cấp thông tin cơ bản, v.v. Bot của chúng tôi là một ứng dụng web hoàn chỉnh mà bạn có thể liên kết cơ sở dữ liệu, đưa ra yêu cầu tới nhiều API khác nhau, phân tích trang web, thực hiện các phép tính phức tạp, v.v. Vấn đề chỉ bị giới hạn bởi trí tưởng tượng của bạn. Tôi hy vọng rằng trong những dòng này tôi đã giải thích cho bạn một chút về những gì tôi sắp viết. Đăng ký bot trong Telegram rất đơn giản, quá trình này được mô tả chi tiết trong tài liệu ở liên kết trên. Đối với ứng dụng của chúng tôi, bạn chỉ cần biết tên bot và mã thông báo mà bạn sẽ nhận được khi đăng ký. Về cơ bản, bot chỉ là một ứng dụng web trên bảng điều khiển. Không có giao diện người dùng, xử lý lệnh thuần túy. Nếu bạn muốn thành thạo Hibernate hoặc tìm hiểu cách phân tích cú pháp JSON, thì dự án này là dành cho bạn. Hãy bắt đầu bằng cách đưa phần phụ thuộc vào pom.xml (chúng tôi giả định rằng bạn đang sử dụng Maven). Bạn có thể làm điều đó như thế này:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Sau đó, chúng ta tạo một lớp Bot, kế thừa nó từ lớp đó TelegramLongPollingBot, ghi đè các phương thức của nó:
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;
    }
}
Vâng, nội dung của phương pháp main:
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Bằng cách nhập nó vào các phương thức getBotUsername(), getBotToken()chúng tôi khởi chạy bot. Hiện tại, anh ấy chỉ chuyển hướng đến chúng tôi bất kỳ tin nhắn nào chúng tôi gửi cho anh ấy, một loại “tấm gương”. Tất cả đều hoạt động như sau: khi bạn khởi chạy ứng dụng, nó bắt đầu gửi yêu cầu GET đến máy chủ Telegram cứ n giây một lần tại URL sau: https://api.telegram.org/BotToken/getMe, trong đó BotToken mã thông báo của bot của bạn, nhận được phản hồi JSON chứa tất cả các tin nhắn. Mỗi thông báo như vậy sẽ được thư viện xử lý và đưa vào phương thức này OnUpdateReceived(Update update)dưới dạng một đối tượng Update. Đó là những gì chúng tôi làm việc cùng. Đây là điểm hay của Telegram bot, chúng có thể hoạt động trên mọi máy tính, để kiểm tra bạn chỉ cần khởi chạy ứng dụng, không cần triển khai lên hosting sau mỗi lần thay đổi. Nó rất thoải mái. Tất nhiên, bot có thể được cấu hình để hoạt động bằng webhook; bạn có thể tìm thấy hướng dẫn sử dụng trên Internet; để đơn giản, chúng ta sẽ sử dụng LongPolling. Cách xử lý tin nhắn và nội dung cần gửi để phản hồi chỉ bị giới hạn bởi các công cụ ngôn ngữ và thư viện, mọi thứ khác đều do bạn quyết định. Bạn có thể tạo một bot sẽ tìm kiếm video trên YouTube cho bạn, bạn có thể tạo một bot mỗi ngày sẽ gửi cho bạn những gì bạn gửi cho chính mình, chẳng hạn như trong một năm, một loại viên nang thời gian. Hoặc bạn có thể học cách tích hợp vào hệ thống CRM và tạo bot cho doanh nghiệp nhỏ, mọi thứ đều bị giới hạn bởi trí tưởng tượng của bạn. Hãy tiếp tục. Những người đã sử dụng bot đều biết rằng việc tương tác với chúng rất thuận tiện bằng cách sử dụng các lệnh bắt đầu bằng dấu «/»chẳng hạn /start. Nhưng có một cách thuận tiện hơn - các nút. Có hai loại nút: nút xuất hiện bên dưới trường nhập ReplyKeyboardMarkupvà nút xuất hiện ngay bên dưới thông báo mà chúng được liên kết tới InlineKeyboardMarkup. Trong tài liệu, bạn có thể làm quen ngắn gọn với mô tả của họ. Trả lờiKeyboardMarkup. Về cơ bản đây là một mảng các mảng nút, List<KeyboardRow<KeyboardButton>>. Đây là một mã ví dụ tạo bàn phím
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);
    }
Trong một phương thức sendMsg(), chúng ta gọi phương thức này bằng cách chuyển một tin nhắn đến nó, do đó đặt bàn phím cho tin nhắn đó. Khi chúng ta gửi tin nhắn này cho người dùng, anh ta sẽ nhìn thấy nội dung tin nhắn mà chúng ta đã đặt, cũng như 2 nút Hello và Help nằm cạnh nhau. Bằng cách nhấp vào các nút này, một tin nhắn sẽ được gửi đến bot, nội dung của tin nhắn đó chính là nội dung được viết trên nút. Nghĩa là, nếu khách hàng nhấp vào “Trợ giúp”, bot sẽ nhận được tin nhắn có nội dung “Trợ giúp”. Đối với anh ta, điều đó giống như việc khách hàng tự viết tin nhắn “Trợ giúp” và gửi cho anh ta. Vâng, sau đó bạn xử lý những tin nhắn như vậy. InlineKeyboardMarkup Đây cũng là một mảng các mảng, nó tương tự như Markup trước đó, nhưng logic hoạt động ở đây hơi khác một chút. Bàn phím như vậy được gắn với một tin nhắn cụ thể và chỉ tồn tại cho nó. Đây là phương pháp cài đặt bàn phím nội tuyến
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);
    }
Tạo Listtrong List, thêm nút Nội tuyến vào dòng đầu tiên. Một nút như vậy có thể chứa một URL, một liên kết đến một kênh hoặc CallbackQuery, mà tôi sẽ viết về nó sau. Ở đây, chúng tôi đặt văn bản cho nút mà người dùng sẽ nhìn thấy và sau đó đặt dữ liệu sẽ được gửi đến bot. Trong ví dụ của chúng tôi, người dùng nhìn thấy “Xin chào” và khi nhấp vào, bot sẽ được gửi số 17, đây là tệp CallbackQuery. Một vài lời về CallbackQuery. Để lấy dữ liệu như vậy từ một đối tượng, Updatebạn cần phải thực thi update.getCallbackQuery(), phương thức này trả về CallbackQuery, từ đó bạn có thể lấy dữ liệu được chuyển đến bot. Không cần phải cố gắng lấy dữ liệu này thông qua phương thức 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());
        }
    }
Nếu có tin nhắn, chúng tôi gửi tin nhắn để xử lý đến một luồng mới; nếu có tin nhắn CallbackQuery, chúng tôi gửi tin nhắn đó để xử lý đến luồng thích hợp. Bạn CallbackQuerycó thể gửi trả lời. Mỗi đối tượng trong Telegram đều có id riêng. Để gửi phản hồi đến một đối tượng cụ thể, CallbackQuerychúng ta chỉ cần biết id của nó mà chúng ta sẽ nhận được từ đối tượng tương ứng. Để gửi phản hồi, hãy gọi phương thức này:
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();
        }
    }
QUAN TRỌNG:Văn bản trong câu trả lời CallbackQuerykhông được dài hơn 200 ký tự! Khi gửi phản hồi như vậy, khách hàng sẽ nhận được một cửa sổ bật lên trong đó tin nhắn sẽ được viết. Cửa sổ như vậy có thể biến mất vài giây sau khi xuất hiện hoặc có thể bị treo cho đến khi người dùng nhấn OK. Để chuyển đổi các chế độ này, chúng tôi gọi answer.setShowAlert(true). Khi truecửa sổ bị treo cho đến khi bạn nhấn OK, falsenó sẽ biến mất sau 5 giây. Về nguyên tắc, đây đều là những tính năng cơ bản của thư viện bot Telegram. Nếu muốn, bạn có thể tìm hiểu những thứ như gửi đa phương tiện, định vị địa lý, v.v. từ tài liệu. Hãy chuyển sang triển khai bot của chúng tôi trên dịch vụ lưu trữ. Đối với dự án của mình, tôi đã chọn Heroku, vì theo tôi đây là một dịch vụ lưu trữ khá tiện lợi và có CLI riêng. Nó miễn phí, nhưng với tốc độ này bot của bạn sẽ chuyển sang chế độ ngủ đông sau 30 phút nếu không có yêu cầu. Khi một yêu cầu được gửi đến anh ta, anh ta thức dậy. Điều này xảy ra khá nhanh, thậm chí bạn sẽ không nhận thấy (tất nhiên trừ khi kết nối tới cơ sở dữ liệu được thiết lập lại). Giới hạn của gói miễn phí là cơ sở dữ liệu 5 MB, dung lượng ổ đĩa 100 MB, lưu lượng 2TB mỗi tháng, 1 dino. Dino là ứng dụng đang chạy của bạn. Tôi phải nói ngay rằng chính giai đoạn triển khai đã gây khó khăn cho tôi vì trước đây tôi chưa bao giờ triển khai các ứng dụng của mình. Khi triển khai, Heroku yêu cầu file có tên Procfile (không có phần mở rộng). worker: sh target/bin/workerBot Chúng tôi tạo nó trong thư mục gốc của dự án, viết workerBot vào đó - tên mà chúng tôi chỉ định trong pom.xml Tập lệnh sh được tạo bằng plugin Maven appassembler-maven-plugin sẽ được khởi chạy. Kịch bản mô tả việc chạy jar đã biên dịch. Tên lớp cần khởi chạy được chỉ định giữa <mainClass></mainClass>, tên tập lệnh giữa <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>
Trước khi bắt đầu quá trình này, bạn nên đăng ký trên Heroku, cài đặt Git và Heroku CLI. Nếu ứng dụng của bạn yêu cầu cơ sở dữ liệu thì khi đăng ký ứng dụng mới, đừng quên thêm cơ sở dữ liệu bạn cần. Tiếp theo, bạn cần tìm ra máy chủ, tên người dùng, mật khẩu và cổng của cơ sở dữ liệu, sau đó chỉ định nó trong ứng dụng của bạn. Tiếp theo, trước khi triển khai, hãy xây dựng dự án của bạn bằng Maven.
mvn clean install
Để bắt đầu, chúng ta vào thư mục của dự án, khởi tạo kho lưu trữ bằng lệnhgit init Sau đó, chúng ta thêm dự án của mình vào kho lưu trữ này
git add .
Sau khi chúng tôi cam kết thay đổi
git commit -m “First commit in project”
Tiếp theo bạn cần đăng nhập vào heroku, viết dòng lệnh
heroku login
Nhập dữ liệu của bạn được chỉ định trong quá trình đăng ký. Sau đó, bạn cần tìm ra URL của kho lưu trữ của mình trên Heroku, việc này được thực hiện trong cài đặt. Sau đó chúng tôi viết
git remote add heroku [url]
Kho lưu trữ từ xa heroku sẽ được thêm vào kho lưu trữ của bạn. Tiếp theo chúng tôi viết
git push heroku master
Chúng tôi đang chờ đợi... Nếu việc triển khai ứng dụng thành công, chúng tôi sẽ thực thi lệnh
heroku ps:scale worker=1
Và thế là xong, ứng dụng của bạn đang chạy. Nếu điều này không xảy ra, hãy xem kỹ nhật ký; rất có thể có lỗi trong ứng dụng của bạn khiến ứng dụng bị lỗi. Cảm ơn bạn đã đọc một bài viết dài như vậy, tôi hy vọng ai đó thấy nó hữu ích và tiết kiệm nhiều thời gian ở những nơi tôi vấp ngã trong quá trình phát triển.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION