JavaRush /בלוג Java /Random-HE /בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת ע...
Pavel Mironov (Miroha)
רָמָה
Москва

בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת על ניסיון אישי

פורסם בקבוצה
ברכות לכולם! ספר לנו על עצמך. אני בן 24, בוגר אוניברסיטה טכנית בשנה שעברה ועדיין אין לי ניסיון בעבודה. במבט קדימה, אני רוצה לומר שבתחילה, בתוכנית שנקבעה (שגובשה בסתיו 2019), תכננתי לצאת לעבודה במרץ-אפריל 2020, אבל, לצערי, ההסגר התערב, אז דחיתי הכל לאמצע -קיץ ובעתיד אני מקווה לכתוב את סיפור ההצלחה שלי. בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת על ניסיון אישי - 1מעולם לא נמשכתי לתכנות. באוניברסיטה לימדו מספיק תכנות, אבל המלאכה הזו לא יכלה לעניין אותי אז. היו גם שפות פרוצדורליות (C), קורס של שנה ב-OOP (Java), מסדי נתונים, אפילו assembler ו-C++. אבל למען האמת, בדרך כלל הייתי אדיש ללימודים, שכן רוב המקצועות הנלמדים נראו לי חסרי תועלת, מתאימות רק לצורכי דיווח (באופן עקרוני, זה כך). לאחר שסיימתי את הלימודים באוניברסיטה, הייתי צריך לקבל החלטה: לא רכשתי כמה כישורים, אבל הייתי צריך לעבוד. הייתי צריך לחשוב על חינוך עצמי (אוי, כבר פספסתי לפחות שנתיים תמימות בישיבה בחיבוק ידיים) והבחירה נפלה כמובן על ג'אווה, שכן בקורס OOP באוניברסיטה אחד מהחבר'ה המליץ ​​על קורס javarush , והוא, כידוע, מוקדש במיוחד לשפת ג'אווה. התעניינתי בהצגת הקורס. כן, לא אהבתי אז תכנות, כי מיד ויתרתי כשנתקלתי בקושי כלשהו, ​​ויש די והותר קשיים בתכנות. אבל במקביל, הרגשתי שאני רוצה לכתוב קוד, אז בסופו של דבר החלטתי להיכנס לתכנות. אני אספר לך בקצרה על הניסיון שלי עם javarush. התחלתי באוגוסט 2019, מיד קניתי מנוי לחודש, אבל ברמה 7 הבנתי שהמשימות קשות. שמתי בצד את הקורס והרמתי את שילדט. אז במקביל סיימתי את הקורס למשך 3 חודשים. הגעתי לרמה 20 (זה החשבון השני שלי), קראתי את שילדט כמעט לגמרי, ואז נמאס לי מהמשימות כאן, בהן הפסקתי לראות יתרונות מעשיים לעצמי. הלכתי ל-codewars, leetcode, והתחלתי לצפות בקורסי וידאו. אגב, תוך 3 חודשים עברתי מ"אוי לא, מה זה מערך? איך עובדים איתו ולמה זה כל כך מפחיד"? ללימוד מפורט של קוד המקור של כיתות אוסף (ArrayList, HashMap וכו'). בהתבסס על ניסיון אישי, אני אגיד למתחילים: העיקר כאן הוא להתגבר על התחושה שמתעוררת אם אתה לא מבין כלום ולא יכול לפתור שום דבר. כשזה עולה, אתה פשוט רוצה לוותר על הכל ונראה שאתה טיפש מדי בשביל העניין הזה. אם תתגבר על רגעים כאלה בתוכך ותנוח נפשית, אז ההצלחה תגיע. אני חושב שאנשים רבים לא יכולים להתמודד עם זה, אז הם מוותרים מהר על מאמצים כאלה. כתוצאה מכך, בדצמבר 2019 התחלתי לחשוב על הפרויקט שלי. החלטתי לבחור בבוט של טלגרם, אבל לא היה לי מושג. במקביל, חבר אחד נזקק לפונקציונליות עבור הקבוצה שלו במברק, שאותו היה רוצה להפוך לאוטומטיות. הוא פשוט היה מודע לכך שאני לומד תכנות לעומק והציע לי פרויקט. בשבילי, לניסיון ולרזומה עתידי, בשבילו, לפיתוח הקבוצה. אני אפילו ארשה לעצמי לצטט את הרעיון שלו: "Недавно софтину хотел у программиста заказать, которая загружала бы в выбранное Облако файлы по прямым linkм. Это интересно, так How аналогов нет. И просто очень удобно. Суть: копируешь ссылку, вставляешь в окно и выбираешь нужное Облако (GDrive, Mail, Яндекс Диск и т.п), в своё время софт всё делает на стороне serverа и юзеру ничего не нужно загружать на свою машину (особенно круто, когда у тебя сборка на SSD-накопителях). Думали сделать в web-интерфейсе, чтобы можно было запускать How с телефонов, так и с десктопа... Можно в принципе через приложение реализовать, а не через web-интерфейс. Тебе такое по силам?"התחלתי לעבוד, אבל בסופו של דבר, אחרי כמה ימים, הבנתי ששום דבר לא יסתדר לנו, בעיקר בגלל חוסר ידע. חבר היה צריך את אותם קישורים ל-Cloud.Mail, אבל הם עדיין לא אין לך API. היה ניסיון להרכיב משהו דרך GDrive, אבל היישום היה עלוב, בנוסף שירות הענן הזה לא התאים ל"לקוח". למרות שבתחילה הוא הציע מספר עננים לבחירה, בסופו של דבר הוא דחה הכל מלבד דואר .ru, שעבורו לא נמצא פתרון. איכשהו הכל התברר כיקר, היה צורך לחבר את מסד הנתונים, להשתמש בשרת לאחסון וכו'. אגב, הוא עדיין צריך את אפליקציית האינטרנט הזו. מאז דברים לא לא יסתדר לנו, החלטתי ליצור בוט מידע. זה צריך היה לקבל קישורים למשחק מחנות Google Play, לנתח את הקישור ולשמור את המידע שהתקבל בספריה, ואז לכתוב אותו לקובץ json. כך, עם כל בקשה, הספרייה יכולה להתרחב הודות למאמצי המשתמשים. בעתיד, לא תוכל לקבל מידע על המשחק בצורה נוחה על ידי מעבר לגוגל פליי. אתה פשוט כותב את הפקודה /libraryHere_game_name וקבל את כל מה שאתה צריך. אבל יש כמה קשיים שעליהם אספר בהמשך. בהתחלה התקדמתי לאט, כשהתחלתי לקחת שני קורסי SQL במקביל. פשוט לא הצלחתי להבין איך הבוט עובד בכלל ואיך לעבד בקשות. פגשתי חבר שגם הוא היה מעוניין לעבוד על הפרויקט. הגרסה הראשונה של הבוט הייתה מוכנה תוך כחודש, אך התגלעו חילוקי דעות עם חבר (מצידי). לקחתי את החלק של הבוט שאחראי על הניתוח, והוא עבד ישירות על בקשות לבוט ועיבודן. משום מה, הוא התחיל לסבך את הבוט, להכניס איזושהי הרשאה, להמציא אדמינים, להוסיף פונקציונליות מיותרת, בנוסף לא ממש אהבתי את סגנון הקידוד שלו. לדעתי זה לא היה נחוץ בבוט מידע. אז החלטתי שאני אכתוב בעצמי בוט מאפס עם הפונקציונליות שאני צריך. עכשיו אני אגיד לך מה הבוט עושה בפועל (באמצעות דוגמה מקוד הפרויקט). את הקוד המלא של הפרויקט אצרף בסוף המאמר ולצערי לא אוכל להגיב עליו במלואו. כל הודעת משתמש שנשלחת לבוט היא אובייקט של מחלקת העדכון. הוא מכיל מידע רב (מזהה הודעה, מזהה צ'אט, מזהה משתמש ייחודי וכו'). ישנם מספר סוגי עדכון: זה יכול להיות הודעת טקסט, זה יכול להיות תגובה ממקלדת הטלגרם (התקשרות חזרה), תמונה, אודיו וכו'. כדי למנוע מהמשתמש להתעסק יותר מדי, אני מעבד רק בקשות טקסט והתקשרויות חוזרות מהמקלדת. אם המשתמש ישלח תמונה, הבוט יודיע לו כי אין בכוונתו לעשות איתה דבר. במחלקת הבוט הראשית, בשיטת onUpdateReceived, הבוט מקבל עדכון.
@Override
    public void onUpdateReceived(Update update) {
        UpdatesReceiver.handleUpdates(update);
    }
שאני מעביר למטפל (מחלקה של UpdatesReceiver משלו):
public static void handleUpdates(Update update) {
        ...
        if (update.hasMessage() && update.getMessage().hasText()){
            log.info("[Update (id {}) типа \"Текстовое сообщение\"]", update.getUpdateId());
            new TextMessageHandler(update, replyGenerator).handleTextMessage();
        }
        else if (update.hasCallbackQuery()) {
            //логгирование
            new CallbackQueryHandler(update, replyGenerator).handleCallBackQuery();
        }
        else {
           //логгирование
            replyGenerator.sendTextMessage(update.getMessage().getChatId(), "Я могу принимать только текстовые messages!");
        }
    }
UpdatesReceiver הוא מטפל מרכזי, אשר בהתאם לסוג העדכון, מעביר את השליטה למטפל מיוחד אחר: TextMessageHandler או CallbackQueryHandler, שאליו אני מעביר עדכון בהמשך השרשרת. עדכון הוא הדבר החשוב ביותר בעבודה עם בוט ואי אפשר לאבד אותו, כי בעזרת המידע המאוחסן בעדכון, אנו מגלים לאיזה משתמש ולאיזה צ'אט יש לשלוח את התגובה. כדי ליצור תגובות למשתמש, כתבתי מחלקה נפרדת. זה יכול לשלוח הודעת טקסט רגילה, הודעה עם מקלדת מוטבעת, הודעה עם תמונה והודעה עם מקלדת תשובה. מקלדת מוטבעת נראית כך: בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת על ניסיון אישי - 1היא מגדירה כפתורים שבלחיצה עליהם המשתמש שולח התקשרות חוזרת לשרת, שניתן לעבד אותה כמעט באותו אופן כמו הודעות רגילות. כדי "לשמור" עליו אתה צריך מטפל משלך. אנו מגדירים פעולה עבור כל כפתור, שנכתבת לאחר מכן לאובייקט Update. הָהֵן. עבור כפתור "עלות" אנו מגדירים את התיאור "/מחיר" עבור ההתקשרות חזרה, אותו נוכל לקבל מאוחר יותר מהעדכון. בשלב הבא, בכיתה נפרדת, אני כבר יכול לעבד את ההתקשרות חזרה:
public void handleCallBackQuery() {
  String call_data = update.getCallbackQuery().getData();
  long message_id = update.getCallbackQuery().getMessage().getMessageId();
  long chat_id = update.getCallbackQuery().getMessage().getChatId();
    switch (call_date){
      case "/price" :
        //тут что-то сделать
        break;
...
מקלדת התשובה נראית כך: בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת על ניסיון אישי - 2ובעצם, היא מחליפה את ההקלדה של המשתמש. לחיצה על כפתור "ספרייה" תשלח במהירות הודעת "ספרייה" לבוט. עבור כל סוג של מקלדת, כתבתי מחלקה משלי, תוך יישום דפוס ה-Builder : מוטבע ותשובה . כתוצאה מכך, אתה בעצם יכול "לצייר" את המקלדת הרצויה בהתאם לדרישות שלך. זה נורא נוח, מכיוון שהמקלדות עשויות להיות שונות, אבל העיקרון נשאר זהה. הנה שיטה אינטואיטיבית לשליחת הודעה עם מקלדת מוטבעת:
public synchronized void sendInlineKeyboardMessage(long chat_id, String gameTitle) {
        SendMessage keyboard = InlineKeyboardMarkupBuilder.create(chat_id)
                .setText("Вы может узнать следующую информацию об игре " + gameTitle)
                .row()
                .button("Стоимость " + "\uD83D\uDCB0", "/price " + gameTitle)
                .button("Обновлено " + "\uD83D\uDDD3", "/updated " + gameTitle)
                .button("Версия " + "\uD83D\uDEE0", "/version " + gameTitle)
                .endRow()
                .row()
                .button("Требования " + "\uD83D\uDCF5", "/requirements " + gameTitle)
                .button("Покупки " + "\uD83D\uDED2", "/iap " + gameTitle)
                .button("Размер " + "\uD83D\uDD0E", "/size " + gameTitle)
                .endRow()
                .row()
                .button("Получить всю информацию об игре" + "\uD83D\uDD79", "/all " + gameTitle)
                .endRow()
                .row()
                .button("Скрыть клавиатуру", "close")
                .endRow()
                .build();
        try {
            execute(keyboard);
        } catch (TelegramApiException e) {
            log.error("[Не удалось отправить сообщение с -inline- клавиатурой]: {}", e.getMessage());
        }
    }
כדי להעניק לבוט פונקציונליות קפדנית, הומצאו פקודות מיוחדות המשתמשות בתו האלכסון: /library, /help, /game וכו'. אחרת, נצטרך לעבד כל זבל שהמשתמש עשוי לכתוב. למעשה, בשביל זה נכתב MessageHandler:
if (message.equals(ChatCommands.START.getDescription())) {
     replyGenerator.sendTextMessage(chat_id, new StartMessageHandler().reply());
     replyGenerator.sendReplyKeyboardMessage(chat_id);
}
else if (message.equals(ChatCommands.HELP.getDescription())
             || message.equalsIgnoreCase("Помощь")) {
      replyGenerator.sendTextMessage(chat_id, new HelpMessageHandler().reply());
}
 ...
לפיכך, בהתאם לפקודה שתשלח לבוט, מטפל מיוחד ייכלל בעבודה. בואו נלך רחוק יותר ונסתכל על עבודת המנתח והספרייה. אם תשלח לבוט קישור למשחק בחנות Google Play, מטפל מיוחד יפעל אוטומטית . בתגובה, המשתמש יקבל מידע על המשחק בצורה הבאה: בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית על בסיס ניסיון אישי - 3במקביל תיקרא שיטה שתנסה להוסיף את המשחק לספריית הבוט (תחילה למפה המקומית, לאחר מכן לקובץ -> json ). אם המשחק כבר נמצא בספרייה, אז תתבצע בדיקה (כמו במפת hashmap רגילה), ואם נתוני השדה (לדוגמה, מספר הגרסה השתנו), אז המשחק בספרייה יוחלף. אם לא יתגלו שינויים, לא יבוצעו ערכים. אם בכלל לא היה משחק בספרייה, אז הוא נכתב תחילה למפה המקומית (אובייקט כמו tyk ), ואז נכתב לקובץ json, שכן אם האפליקציה בשרת נסגרת באופן בלתי צפוי, הנתונים יהיו אבד, אבל תמיד ניתן לקרוא אותו באמצעות הקובץ. למעשה, כאשר התוכנית מתחילה, הספרייה תמיד נטענת בפעם הראשונה מקובץ מבלוק סטטי:
static {
        TypeFactory typeFactory = mapper.getTypeFactory();
        MapType mapType = typeFactory.constructMapType(ConcurrentSkipListMap.class, String.class, GooglePlayGame.class);

        try {
            Path path = Paths.get(LIBRARY_PATH);
            if (!Files.exists(path)) {
                Files.createDirectories(path.getParent());
                Files.createFile(path);
                log.info("[Файл библиотеки создан]");
            }
            else {
                ConcurrentMap<string, googleplaygame=""> temporary = mapper.readValue(new File(LIBRARY_PATH), mapType);
                games.putAll(temporary);
                log.info("[Количество игр в загруженной библиотеке] = " + games.size());
            }
        }
        catch (IOException e) {
            log.error("[Ошибка при чтении/записи file] {}", e.getMessage());
        }
    }
כאן אתה בנוסף צריך לקרוא נתונים מהקובץ לתוך מפה זמנית, אשר לאחר מכן "מועתקת" למפה מלאה על מנת לשמור על חוסר רגישות לרישיות בעת חיפוש משחק בקובץ (על ידי כתיבת tITan QuEST, הבוט עדיין ימצא המשחק Titan Quest בספרייה). לא ניתן היה למצוא פתרון אחר, אלו הן התכונות של דה-סריאליזציה באמצעות ג'קסון. לכן, עם כל בקשה לקישור, המשחק מתווסף לספרייה, במידת האפשר, והספרייה מתרחבת בכך. מידע נוסף על משחק ספציפי ניתן לקבל באמצעות הפקודה /libraryGame_Name. אתה יכול לגלות גם פרמטר ספציפי (לדוגמה, הגרסה הנוכחית) וגם את כל הפרמטרים בבת אחת. זה מיושם באמצעות המקלדת המוטבעת, אשר נידונה קודם לכן. במהלך העבודה יישמתי גם את המיומנויות שנרכשו כאן תוך כדי פתרון בעיות. לדוגמה, רשימה של שמות של משחקים אקראיים הנמצאים בספרייה (האפשרות זמינה באמצעות הפקודה /library):
private String getRandomTitles(){
        if (LibraryService.getLibrary().size() < 10){
            return String.join("\n", LibraryService.getLibrary().keySet());
        }
        List<string> keys = new ArrayList<>(LibraryService.getLibrary().keySet());
        Collections.shuffle(keys);
        List<string> randomKeys = keys.subList(0, 10);
        return String.join("\n", randomKeys);
    }
איך תהליך הבוט מקשר? זה בודק אותם כדי לראות אם הם שייכים ל-Google Play (מארח, פרוטוקול, יציאה):
private static class GooglePlayCorrectURL {

        private static final String VALID_HOST = "play.google.com";

        private static final String VALID_PROTOCOL = "https";

        private static final int VALID_PORT = -1;

        private static boolean isLinkValid(URI link) {
            return (isHostExist(link) && isProtocolExist(link) && link.getPort() == VALID_PORT);
        }

        private static boolean isProtocolExist(URI link) {
            if (link.getScheme() != null) {
                return link.getScheme().equals(VALID_PROTOCOL);
            }
            else {
                return false;
            }
        }

        private static boolean isHostExist(URI link) {
            if (link.getHost() != null) {
                return link.getHost().equals(VALID_HOST);
            }
            else {
                return false;
            }
        }
אם הכל תקין, אז הבוט מתחבר באמצעות קישור באמצעות ספריית Jsoup, המאפשרת לקבל את קוד ה-HTML של העמוד, אשר נתון לניתוח וניתוח נוסף. לא תוכל לרמות את הבוט עם קישור שגוי או מזיק.
if (GooglePlayCorrectURL.isLinkValid(link)){
     if (!link.getPath().contains("apps")){
         throw new InvalidGooglePlayLinkException("К сожалению, бот работает исключительно с играми. Введите другую ссылку.");
     }
     URL = forceToRusLocalization(URL);
     document = Jsoup.connect(URL).get();
 }
     else {
         throw new NotGooglePlayLinkException();
      }
...
כאן היינו צריכים לפתור בעיה עם הגדרות אזוריות. הבוט מתחבר לחנות Google Play משרת שנמצא באירופה, כך שהדף בחנות Google Play נפתח בשפה המתאימה. הייתי צריך לכתוב קב ש"מפנה" בכוח לגרסה הרוסית של העמוד (הפרויקט היה, אחרי הכל, מכוון לקהל שלנו). לשם כך, בסוף הקישור עליך להוסיף בזהירות את הפרמטר hl: &hl=ru בבקשת GET לשרת Google Play .
private String forceToRusLocalization(String URL) {
        if (URL.endsWith("&hl=ru")){
            return URL;
        }
        else {
            if (URL.contains("&hl=")){
                URL = URL.replace(
                        URL.substring(URL.length()-"&hl=ru".length()), "&hl=ru");
            }
            else {
                URL += "&hl=ru";
            }
        }
        return URL;
    }
לאחר חיבור מוצלח, אנו מקבלים מסמך HTML מוכן לניתוח וניתוח, אך זה מעבר לתחום המאמר הזה. קוד המנתח נמצא כאן . המנתח עצמו מאחזר את המידע הדרוש ויוצר אובייקט עם המשחק, שמתווסף מאוחר יותר לספרייה במידת הצורך. <h2>לסיכום</h2>הבוט תומך במספר פקודות המכילות פונקציונליות מסוימת. הוא מקבל הודעות מהמשתמש ומתאים אותם לפקודות שלו. אם זה קישור או הפקודה /game + link, הוא בודק את הקישור כדי לראות אם הוא שייך ל-Google Play. אם הקישור נכון, הוא מתחבר דרך Jsoup ומקבל את מסמך ה-HTML. מסמך זה מנותח על סמך המנתח הכתוב. המידע הדרוש על המשחק נשלף מהמסמך, ואז האובייקט עם המשחק מתמלא בנתונים אלה. לאחר מכן, האובייקט עם המשחק ממוקם באחסון מקומי (אם המשחק עדיין לא שם) ומיד נכתב לקובץ כדי למנוע אובדן נתונים. משחק מוקלט בספרייה (שם המשחק הוא המפתח למפה, האובייקט עם המשחק הוא הערך של המפה) ניתן להשיג באמצעות הפקודה /library Game_name. במידה והמשחק שצוין נמצא בספריית הבוט, תוחזר למשתמש מקלדת מוטבעת, איתה יוכל לקבל מידע על המשחק. אם המשחק לא נמצא, עליך לוודא שהשם מאויית נכון (הוא חייב להתאים לחלוטין לשם המשחק בחנות Google Play, למעט המקרה), או להוסיף את המשחק לספרייה על ידי שליחת הבוט קישור למשחק. פרסתי את הבוט ב-heroku ולמי שמתכננים בעתיד לכתוב בוט משלהם ולארח אותו בחינם ב-heroku, אתן כמה המלצות לפתרון הקשיים שעלולים להיתקל בהם (מאחר שנתקלתי בהם בעצמי). לרוע המזל, בשל אופיו של Heroku, ספריית הבוטים "מאפסת" כל הזמן אחת ל-24 שעות. התוכנית שלי לא תומכת באחסון קבצים בשרתי Heroku, אז היא פשוט מושכת את קובץ המשחק שלי מ-Github. היו כמה פתרונות: השתמש במסד נתונים, או חפש שרת אחר שיאחסן את הקובץ הזה עם המשחק. החלטתי לא לעשות כלום בינתיים, מכיוון שבעצם הבוט לא כל כך שימושי. הייתי צריך את זה דווקא כדי לצבור חוויה מלאה, וזה בעצם מה שהשגתי. אז, המלצות על Heroku:
  1. סביר להניח שתצטרך להירשם ב-heroku באמצעות VPN אם אתה גר ברוסיה.

  2. בשורש הפרוייקט צריך לשים קובץ ללא סיומת בשם Procfile. התוכן שלו צריך להיות כזה: https://github.com/miroha/Telegram-Bot/blob/master/Procfile

  3. ב-pom.xml, הוסף את השורות הבאות לפי הדוגמה , כאשר בתגית mainClass ציינו את הנתיב למחלקה המכילה את השיטה הראשית: bot.BotApplication (אם המחלקה BotApplication נמצאת בתיקיית הבוט).

  4. אל תבנו שום פרויקט באמצעות פקודות חבילת mvn וכו', Heroku מרכיב עבורכם הכל.

  5. רצוי להוסיף gitignore לפרויקט, למשל זה:

    # Log file
    *.log
    
    # Compiled resources
    target
    
    # Tests
    test
    
    # IDEA files
    .idea
    *.iml
  6. למעשה העלה את הפרויקט ל-github, ואז חבר את המאגר להרוקו (או השתמש בשיטות אחרות, יש 3 כאלה, אם אני לא טועה).

  7. אם ההורדה הצליחה ("הבנייה הצליחה"), הקפד לעבור אל הגדר את Dynos:

    בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית על בסיס ניסיון אישי - 4

    ותחליף את המחוון, ולאחר מכן תוודא שהוא במצב ON (בגלל העובדה שלא עשיתי זאת, הבוט שלי לא עבד ופגעתי במוח שלי במשך כמה ימים ועשיתי הרבה תנועות מיותרות ).

  8. הסתר את אסימון הבוט ב-Github. כדי לעשות זאת, עליך לקבל את האסימון ממשתנה הסביבה:

    public class Bot extends TelegramLongPollingBot {
    
        private static final String BOT_TOKEN = System.getenv("TOKEN");
    
        @Override
        public String getBotToken() {
            return BOT_TOKEN;
        }
    ...
    }

    ולאחר מכן לאחר פריסת הבוט, הגדר את המשתנה הזה בלוח המחוונים של Heroku בלשונית ההגדרות (מימין ל-TOKEN יהיה שדה VALUE, העתק את האסימון של הבוט שלך לשם):

    בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית המבוססת על ניסיון אישי - 5
בסך הכל, במשך חודשיים של עבודה על הפרויקט שלי, אני:
  • קיבל פרויקט עובד במלואו כתוב ב-Java;
  • למד לעבוד עם API של צד שלישי (Telegram Bot API);
  • בפועל, התעמקתי בהמשכיות, עבדתי הרבה עם JSON ועם ספריית ג'קסון (בהתחלה השתמשתי ב-GSON, אבל היו עם זה בעיות);
  • חיזקתי את כישורי בעבודה עם קבצים, הכרתי את Java NIO;
  • למדתי לעבוד עם קובצי .xml תצורה והרגיל את עצמי לרישום;
  • שיפור מיומנות בסביבת הפיתוח (IDEA);
  • למד לעבוד עם git ולמד את הערך של gitignore;
  • צבר מיומנויות בניתוח דפי אינטרנט (ספריית Jsoup);
  • למד והשתמש במספר דפוסי עיצוב;
  • פיתח חוש ורצון לשפר קוד (refactoring);
  • למדתי למצוא פתרונות באינטרנט ולא להתבייש לשאול שאלות שלא הצלחתי למצוא עליהן תשובה.
בוט טלגרם כפרויקט ראשון ומשמעותו לצמיחה מקצועית על בסיס ניסיון אישי - 7אני לא יודע עד כמה הבוט היה שימושי או חסר תועלת, או עד כמה הקוד היה יפה/מכוער, אבל הניסיון שקיבלתי היה בהחלט שווה את זה. הרגשתי תחושת אחריות על הפרויקט שלי. מדי פעם אני רוצה לשפר אותו, להוסיף משהו חדש. כשהצלחתי להפעיל אותו ולראות שהכל עובד כמו שרציתי, זה היה ריגוש אמיתי. זה לא העיקר? תהנה ממה שאתה עושה ותיהנה מכל שורת קוד עובדת כמו חפיסת השוקולד האחרונה. לכן, אם אתה שולט בתכנות, אז העצה שלי אליך: אל תישאר כאן עד רמה 40, אלא התחל פרויקט משלך מוקדם ככל האפשר. אם מישהו מעוניין, קוד המקור של הפרויקט נמצא כאן (שכתוב לקראת אביב): https://github.com/miroha/GooglePlayGames-TelegramBot בחודשיים האחרונים כמעט ולא למדתי חומר חדש, שכן נראה לי שהגעתי למבוי סתום. בלי עבודה, אני כבר לא רואה לאן להתפתח, חוץ מאשר אולי ללמד את מסגרת האביב, שזה מה שאני מתכנן לעשות בחודש הקרוב. ואז אנסה "לשכתב" את הבוט באמצעות המסגרת הזו. מוכן לענות על כל שאלה. :) בהצלחה לכולם! עדכון מ-07/07/2020 המאגר עם הבוט ב-Java טהור אבד (מחקתי אותו, עותק נשאר במחשב מקומי אחר), אבל הורדתי את הבוט המשוכתב עבור Spring Boot: https://github.com/miroha /GooglePlayGames-TelegramBot
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION