JavaRush /בלוג Java /Random-HE /יצירת בוט טלגרם בג'אווה: מהרעיון ועד לפריסה
John Watson
רָמָה

יצירת בוט טלגרם בג'אווה: מהרעיון ועד לפריסה

פורסם בקבוצה
מה זה בוטים בכלל? תוכלו לקרוא על כך בהרחבה כאן . ראשית, עליך לקרוא את התיעוד הרשמי של הספרייה לפיתוח בוטים בטלגרם (להלן API). היא שוכבת כאן . יצירת בוט של טלגרם ב-Java: מהרעיון לפריסה - 1הכל שם מאוד נגיש ומובן. זה היה נראה כי לכתוב ולשמוח! אבל זה לא כל כך פשוט. לאחר שביליתי זמן רב במנועי חיפוש, מצאתי קטעי ידע על פיתוח בוטים, למשל, כיצד ליצור מקלדת, לעבד CallbackQuery וכדומה. מעולם לא מצאתי מדריך שלם ומקיף לפיתוח בוטים בג'אווה. זה גרם לי לכתוב מאמר זה. ישנם אתרים רבים באינטרנט שבהם אתה יכול ליצור בוט משלך עם פריסה מוכנה. אבל הנקודה היא. שלרוב נוצרים בוטים שיכולים לספק מידע רקע וכן הלאה. הבוט שלנו הוא אפליקציית אינטרנט מלאה אליה ניתן לאגד מסד נתונים, להגיש בקשות לממשקי API שונים, לנתח אתרים, לבצע חישובים מורכבים וכו'. העניין מוגבל רק על ידי הדמיון שלך. אני מקווה שבשורות אלו הסברתי לכם מעט על מה אני הולך לכתוב. רישום בוט בטלגרם הוא פשוט מאוד; תהליך זה מתואר בפירוט בתיעוד בקישור למעלה. עבור היישום שלנו אתה רק צריך לדעת את שם הבוט ואת האסימון שתקבל בהרשמה. בעיקרו של דבר, בוט הוא רק יישום אינטרנט מסוף. ללא חזית, עיבוד פקודות טהור. אם אתה רוצה להשתלט היטב על 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()אנו משיקים את הבוט. לעת עתה, הוא רק מפנה אלינו את כל ההודעות שאנו שולחים אליו, מעין "מראה". הכל עובד באופן הבא: כאשר אתה מפעיל את היישום, הוא מתחיל לשלוח בקשת GET לשרת הטלגרם אחת ל-n מספר שניות בכתובת ה-URL הבאה: https://api.telegram.org/BotToken/getMe, כאשר BotToken נמצא האסימון של הבוט שלך, מקבל בתגובת JSON המכילה את כל ההודעות. כל הודעה כזו מעובדת על ידי הספרייה ומגיעה לשיטה OnUpdateReceived(Update update)כאובייקט Update. עם זה אנחנו עובדים. זה היופי של בוטים של טלגרם, הם יכולים לעבוד על כל מחשב, לבדיקה אתה רק צריך להפעיל את האפליקציה, אתה לא צריך לפרוס אותה לאירוח לאחר כל שינוי. זה מאוד נוח. כמובן שניתן להגדיר את הבוט כך שיעבוד באמצעות webhook; ניתן למצוא את המדריך באינטרנט; לשם הפשטות, נעבוד באמצעות LongPolling. אופן עיבוד ההודעות ומה לשלוח בתגובה מוגבל רק על ידי כלי השפה והספרייה, כל השאר נתון לשיקולך. אתה יכול לעשות בוט שיחפש עבורך סרטונים ביוטיוב, אתה יכול לעשות בוט שכל יום ישלח לך את מה שאתה שולח לעצמך, למשל בעוד שנה, סוג של קפסולת זמן. או שאתה יכול ללמוד איך להשתלב במערכות 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(), אנו קוראים לשיטה זו על ידי העברת הודעה אליה, ובכך מגדירים את המקלדת עבור אותה הודעה. כאשר אנו שולחים הודעה זו למשתמש, הוא יראה את טקסט ההודעה שקבענו, וכן 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, עליהם אכתוב מעט מאוחר יותר. כאן אנו מגדירים את הטקסט עבור הכפתור שלנו שהמשתמש יראה ואז מגדירים את הנתונים שיישלחו לבוט. בדוגמה שלנו, המשתמש רואה "שלום", וכאשר לוחצים עליו, הבוט יישלח את המספר 17, זה שלנו CallbackQuery. כמה מילים על CallbackQuery. כדי להשיג נתונים כאלה מאובייקט, Updateאתה צריך לבצע update.getCallbackQuery(), שיטה זו מחזירה CallbackQuery, שממנו אתה כבר יכול להעביר את הנתונים לבוט. אין צורך לנסות להשיג את הנתונים האלה דרך השיטה update.getMessage().getText(), קבל 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יכול לשלוח תשובה. לכל אובייקט בטלגרם יש מזהה משלו. כדי לשלוח תגובה לאחת ספציפית, CallbackQueryעלינו לדעת רק את המזהה שלו, אותו נקבל מהאובייקט המתאים. כדי לשלוח תגובה, קרא לשיטה זו:
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();
        }
    }
חָשׁוּב:הטקסט בתשובה CallbackQueryלא צריך להיות יותר מ-200 תווים! בעת שליחת תגובה כזו הלקוח יקבל חלון מוקפץ בו תיכתב ההודעה. חלון כזה עשוי להיעלם מספר שניות לאחר הופעתו, או שהוא עשוי להיתקע עד שהמשתמש ילחץ על אישור. כדי להחליף מצבים אלה, אנו קוראים ל- answer.setShowAlert(true). כאשר trueהחלון נתקע עד שתלחץ על OK, כאשר falseהוא נעלם לאחר 5 שניות. באופן עקרוני, אלו כל התכונות הבסיסיות של ספריית הבוטים של טלגרם. אם תרצו, תוכלו ללמוד מהתיעוד דברים כמו שליחת מולטימדיה, מיקום גיאוגרפי וכו'. בואו נעבור לפריסת הבוט שלנו על אירוח. לפרויקט שלי בחרתי ב-Heroku, כי לדעתי מדובר באחסון די נוח שיש לו CLI משלו. זה בחינם, אבל בקצב הזה הבוט שלך יכנס למצב שינה לאחר 30 דקות אם אין בקשות. כששולחים אליו בקשה הוא מתעורר. זה קורה די מהר, אפילו לא תשים לב (אלא אם כן, כמובן, החיבור למסד הנתונים נוצר מחדש). המגבלה על התוכנית החינמית היא 5MB מסד נתונים, 100MB שטח דיסק, תעבורה של 2TB בחודש, 1 דינו. Dino הוא האפליקציה הפועלת שלך. אני אגיד מיד ששלב הפריסה הוא שגרם לי לקשיים, שכן מעולם לא פרסתי את האפליקציות שלי לפני כן. בעת הפריסה, Heroku דורש קובץ בשם Procfile (ללא סיומת). אנו יוצרים אותו בשורש הפרויקט, כותבים שם worker: sh target/bin/workerBot workerBot - השם שאנו מציינים pom.xml בסקריפט sh שנוצר באמצעות תוסף Maven appassembler-maven-plugin יושק. הסקריפט מתאר את הפעלת הצנצנת הקומפילית. שם המחלקה שתושק מצוין בין <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, זה נעשה בהגדרות. ואז אנחנו כותבים
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