JavaRush /จาวาบล็อก /Random-TH /Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่า...
Pavel Mironov (Miroha)
ระดับ
Москва

Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพโดยพิจารณาจากประสบการณ์ส่วนตัว

เผยแพร่ในกลุ่ม
สวัสดีทุกคน! บอกเราเกี่ยวกับตัวคุณ. ฉันอายุ 24 ปี สำเร็จการศึกษาจากมหาวิทยาลัยเทคนิคเมื่อปีที่แล้วและยังไม่มีประสบการณ์การทำงาน เมื่อมองไปข้างหน้าฉันอยากจะบอกว่าในตอนแรกในแผนงานที่วางไว้ (ร่างขึ้นในฤดูใบไม้ร่วงปี 2562) ฉันวางแผนที่จะไปทำงานในเดือนมีนาคม-เมษายน 2563 แต่น่าเสียดายที่การกักกันเข้ามาแทรกแซงฉันจึงเลื่อนทุกอย่างออกไปจนถึงกลางเดือน - ฤดูร้อนและในอนาคตฉันหวังว่าจะเขียนเรื่องราวความสำเร็จของตัวเอง Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 1ฉันไม่เคยสนใจการเขียนโปรแกรม ที่มหาวิทยาลัยพวกเขาสอนการเขียนโปรแกรมมากพอ แต่งานฝีมือชิ้นนี้ทำให้ฉันไม่สนใจเลย นอกจากนี้ยังมีภาษาขั้นตอน (C) หลักสูตรระยะยาวหนึ่งปีใน OOP (Java) ฐานข้อมูล แม้แต่แอสเซมเบลอร์และ C++ แต่พูดตามตรงโดยทั่วไปแล้วฉันไม่แยแสกับการเรียนเนื่องจากสาขาวิชาส่วนใหญ่ที่สอนดูเหมือนไร้ประโยชน์สำหรับฉันเหมาะสำหรับการรายงานเท่านั้น (โดยหลักการแล้วเป็นเช่นนั้น) หลังจากเรียนจบมหาวิทยาลัย ฉันต้องตัดสินใจ: ฉันไม่ได้รับทักษะบางอย่าง แต่ฉันต้องทำงาน ฉันต้องคิดถึงการศึกษาด้วยตนเอง (โอ้ ฉันพลาดไปแล้วอย่างน้อย 2 ปีเต็มจากการนั่งเฉยๆ ) และตัวเลือกก็ตกอยู่ที่ Java ตามธรรมชาติ เนื่องจากในหลักสูตร OOP ที่มหาวิทยาลัย หนึ่งในนั้นแนะนำหลักสูตร javarush และอย่างที่คุณทราบ เขาทุ่มเทให้กับภาษา Java โดยเฉพาะ ฉันสนใจการนำเสนอหลักสูตร ใช่ ตอนนั้นฉันไม่ชอบการเขียนโปรแกรม เพราะฉันยอมแพ้ทันทีเมื่อพบกับปัญหาใดๆ และการเขียนโปรแกรมก็มีความยากมากเกินพอ แต่ในขณะเดียวกัน ฉันก็รู้สึกว่าอยากเขียนโค้ด ดังนั้นสุดท้ายฉันก็ตัดสินใจเข้าสู่การเขียนโปรแกรม ฉันจะเล่าสั้น ๆ เกี่ยวกับประสบการณ์ของฉันกับ javarush ฉันเริ่มในเดือนสิงหาคม 2019 โดยซื้อการสมัครสมาชิกทันทีเป็นเวลาหนึ่งเดือน แต่เมื่อถึงระดับ 7 ฉันพบว่างานนั้นยาก ฉันละทิ้งเส้นทางแล้วหยิบ Shildt ขึ้นมา ในขณะเดียวกันฉันก็เรียนจบหลักสูตรเป็นเวลา 3 เดือน ฉันมาถึงระดับ 20 แล้ว (นี่คือบัญชีที่สองของฉัน) อ่าน Schildt เกือบหมดแล้วก็เบื่อกับงานที่นี่ซึ่งฉันไม่เห็นประโยชน์เชิงปฏิบัติสำหรับตัวเองเลย ฉันไปที่ codewars, leetcode และเริ่มดูหลักสูตรวิดีโอ อย่างไรก็ตาม ใน 3 เดือน ฉันก็เปลี่ยนจาก “โอ้ ไม่นะ อาเรย์คืออะไร ทำงานกับมันอย่างไร และทำไมมันถึงน่ากลัวนัก”? เพื่อศึกษารายละเอียดของซอร์สโค้ดของคลาสคอลเลกชัน (ArrayList, HashMap ฯลฯ ) จากประสบการณ์ส่วนตัวฉันจะบอกผู้เริ่มต้น: สิ่งสำคัญที่นี่คือเอาชนะความรู้สึกที่เกิดขึ้นหากคุณไม่เข้าใจสิ่งใดและไม่สามารถแก้ไขสิ่งใดได้ เมื่อมันเกิดขึ้นคุณแค่อยากจะยอมแพ้ทุกอย่างและดูเหมือนว่าคุณโง่เกินไปสำหรับเรื่องนี้ หากคุณเอาชนะช่วงเวลาดังกล่าวภายในตัวเองและพักผ่อนจิตใจได้ ความสำเร็จก็จะมาถึง ฉันคิดว่าหลายๆ คนไม่สามารถรับมือกับเรื่องนี้ได้ ดังนั้นพวกเขาจึงยอมแพ้อย่างรวดเร็ว ด้วยเหตุนี้ในเดือนธันวาคม 2019 ฉันจึงเริ่มคิดถึงโครงการของตัวเอง ฉันตัดสินใจเลือกบอท Telegram แต่ไม่มีความคิดใด ๆ ในเวลาเดียวกัน เพื่อนคนหนึ่งต้องการฟังก์ชันการทำงานสำหรับกลุ่มของเขาทางโทรเลข ซึ่งเขาต้องการให้ทำให้เป็นแบบอัตโนมัติ เขาเพิ่งรู้ว่าฉันกำลังเรียนการเขียนโปรแกรมเชิงลึกและเสนอโปรเจ็กต์ให้ฉัน สำหรับฉัน สำหรับประสบการณ์ และเรซูเม่ในอนาคต สำหรับเขา เพื่อการพัฒนาของกลุ่ม ฉันจะยอมให้ตัวเองพูดความคิดของเขาด้วย: "Недавно софтину хотел у программиста заказать, которая загружала бы в выбранное Облако файлы по прямым linkм. Это интересно, так How аналогов нет. И просто очень удобно. Суть: копируешь ссылку, вставляешь в окно и выбираешь нужное Облако (GDrive, Mail, Яндекс Диск и т.п), в своё время софт всё делает на стороне serverа и юзеру ничего не нужно загружать на свою машину (особенно круто, когда у тебя сборка на SSD-накопителях). Думали сделать в web-интерфейсе, чтобы можно было запускать How с телефонов, так и с десктопа... Можно в принципе через приложение реализовать, а не через web-интерфейс. Тебе такое по силам?"ฉันเริ่มทำงาน แต่ในท้ายที่สุด หลังจากผ่านไปสองสามวัน ฉันก็ตระหนักว่าไม่มีอะไรจะได้ผลสำหรับเรา ส่วนใหญ่เกิดจากการขาดความรู้ เพื่อนคนหนึ่งต้องการลิงก์เดียวกันนี้ไปยัง Cloud.Mail แต่ก็ยังทำไม่ได้' ไม่มี API มีความพยายามที่จะรวบรวมบางสิ่งเข้าด้วยกันผ่าน GDrive แต่การใช้งานนั้นงี่เง่า อีกทั้งบริการคลาวด์นี้ไม่เหมาะกับ "ลูกค้า" แม้ว่าในตอนแรกเขาจะเสนอคลาวด์หลายตัวให้เลือก แต่ในที่สุดเขาก็ปฏิเสธทุกอย่างยกเว้นเมล .ru ซึ่งไม่พบวิธีแก้ไข บางอย่างกลับกลายเป็นว่ามีราคาแพง จำเป็นต้องเชื่อมต่อฐานข้อมูล ใช้เซิร์ฟเวอร์สำหรับจัดเก็บข้อมูล ฯลฯ อย่างไรก็ตาม มันยังต้องการเว็บแอปพลิเคชันนี้ เนื่องจากสิ่งต่าง ๆ ไม่ได้ ได้ผลสำหรับเราฉันตัดสินใจสร้างบอตข้อมูล ควรรับลิงก์ไปยังเกมจาก Google Play Store แยกวิเคราะห์ลิงก์และบันทึกข้อมูลที่ได้รับลงในไลบรารีแล้วเขียนลงในไฟล์ json ดังนั้นในแต่ละคำขอห้องสมุดจึงสามารถขยายได้เนื่องจากความพยายามของผู้ใช้ ในอนาคต คุณไม่สามารถรับข้อมูลเกี่ยวกับเกมในรูปแบบที่สะดวกได้โดยไปที่ Google Play คุณเพียงแค่เขียนคำสั่ง /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 ซึ่งฉันส่งผ่านตัวสร้างการอัปเดตต่อไปในห่วงโซ่ การอัปเดตเป็นสิ่งสำคัญที่สุดเมื่อทำงานกับบอทและไม่ควรสูญหาย เนื่องจากด้วยความช่วยเหลือของข้อมูลที่เก็บไว้ในการอัปเดต เราจะค้นหาว่าผู้ใช้คนไหนและแชทใดที่ควรส่งการตอบกลับ เพื่อสร้างคำตอบให้กับผู้ใช้ ฉันจึงเขียนชั้นเรียนแยกต่างหาก สามารถส่งข้อความปกติ ข้อความด้วยแป้นพิมพ์อินไลน์ ข้อความพร้อมรูปภาพ และข้อความด้วยแป้นพิมพ์ตอบกลับ แป้นพิมพ์อินไลน์มีลักษณะดังนี้: Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 1มันกำหนดปุ่มที่เมื่อคลิกแล้ว ผู้ใช้จะส่งการโทรกลับไปยังเซิร์ฟเวอร์ ซึ่งสามารถประมวลผลได้เกือบจะเหมือนกับข้อความทั่วไป ในการ "รักษา" มัน คุณต้องมีผู้ดูแลของคุณเอง เราตั้งค่าการดำเนินการสำหรับแต่ละปุ่ม ซึ่งจากนั้นจะถูกเขียนไปยังวัตถุอัปเดต เหล่านั้น. สำหรับปุ่ม "ต้นทุน" เรากำหนดคำอธิบาย "/ ราคา" สำหรับการโทรกลับ ซึ่งเราสามารถรับได้ในภายหลังจากการอัปเดต ถัดไป ในคลาสที่แยกต่างหาก ฉันสามารถประมวลผลการโทรกลับนี้ได้แล้ว:
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;
...
แป้นพิมพ์ตอบกลับมีลักษณะดังนี้: Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 2และโดยพื้นฐานแล้ว แป้นพิมพ์นี้จะมาแทนที่การพิมพ์ของผู้ใช้ การคลิกปุ่ม "Library" จะส่งข้อความ "Library" ไปยังบอทอย่างรวดเร็ว สำหรับคีย์บอร์ดแต่ละประเภท ฉันเขียนคลาสของตัวเองโดยใช้รูปแบบ Builder: inlineและReply ด้วยเหตุนี้คุณจึงสามารถ "วาด" แป้นพิมพ์ที่ต้องการได้ตามความต้องการของคุณ สะดวกมากเนื่องจากคีย์บอร์ดอาจแตกต่างกัน แต่หลักการยังคงเหมือนเดิม ต่อไปนี้เป็นวิธีการที่ใช้งานง่ายในการส่งข้อความด้วยแป้นพิมพ์อินไลน์:
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());
}
 ...
ดังนั้นขึ้นอยู่กับคำสั่งที่คุณส่งไปยังบอท ตัวจัดการพิเศษจะรวมอยู่ในงาน มาดูผลงานของ parser และไลบรารีกันดีกว่า หากคุณส่งลิงก์ไปยังเกมใน Google Play สโตร์ให้บอท ตัวจัดการ พิเศษจะทำงานโดย อัตโนมัติ ในการตอบสนอง ผู้ใช้จะได้รับข้อมูลเกี่ยวกับเกมในรูปแบบต่อไปนี้: Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 3ในเวลาเดียวกันจะมีการเรียกใช้เมธอดที่จะพยายามเพิ่มเกมลงในไลบรารีของบอท (อันดับแรกไปที่แผนที่ในเครื่อง จากนั้นไปที่ -> ไฟล์ json ). หากเกมมีอยู่ในไลบรารีแล้ว จะมีการตรวจสอบ (เช่นเดียวกับในแฮชแมปปกติ) และหากข้อมูลในฟิลด์ (เช่น หมายเลขเวอร์ชันมีการเปลี่ยนแปลง) เกมในไลบรารีจะถูกเขียนทับ หากตรวจไม่พบการเปลี่ยนแปลง ก็จะไม่มีรายการใดๆ เกิดขึ้น หากไม่มีเกมในไลบรารีเลย ก่อนอื่นเกมจะถูกเขียนลงในแผนที่ในเครื่อง (วัตถุเช่น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 ในห้องสมุด) ไม่สามารถหาวิธีแก้ปัญหาอื่นได้ นี่คือคุณลักษณะของการดีซีเรียลไลซ์โดยใช้ Jackson ดังนั้นทุกครั้งที่มีการร้องขอลิงก์ เกมจะถูกเพิ่มเข้าไปในห้องสมุด ถ้าเป็นไปได้ และห้องสมุดก็จะขยายออกไปด้วย ข้อมูลเพิ่มเติมเกี่ยวกับเกมเฉพาะสามารถรับได้โดยใช้คำสั่ง/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 Store จากเซิร์ฟเวอร์ที่ตั้งอยู่ในยุโรป ดังนั้นหน้าใน Google Play Store จะเปิดขึ้นในภาษาที่เหมาะสม ฉันต้องเขียนไม้ยันรักแร้ที่จะบังคับให้ "เปลี่ยนเส้นทาง" ไปยังหน้าเวอร์ชันรัสเซีย (ท้ายที่สุดแล้วโครงการนี้มุ่งเป้าไปที่ผู้ชมของเรา) ใน การ ดำเนินการนี้ ในตอนท้ายของลิงก์ คุณจะต้องเพิ่มพารามิเตอร์ 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 Store โดยสมบูรณ์ ยกเว้นในกรณีนี้) หรือเพิ่มเกมลงในไลบรารีโดยการส่งบอท ลิงก์ไปยังเกม ฉันปรับใช้บอทบน 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 แล้วเชื่อมต่อ Repository กับ Heroku (หรือใช้วิธีอื่นก็มี 3 วิธีนะ ถ้าจำไม่ผิด)

  7. หากการดาวน์โหลดสำเร็จ ("สร้างสำเร็จ") อย่าลืมไปที่กำหนดค่า Dynos:

    Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 4

    และเปลี่ยนแถบเลื่อน จากนั้นตรวจสอบให้แน่ใจว่ามันอยู่ในตำแหน่งเปิด (เนื่องจากฉันไม่ได้ทำสิ่งนี้ บอทของฉันก็ไม่ทำงาน และฉันก็ใช้สมองของฉันไปสองสามวันและทำการเคลื่อนไหวที่ไม่จำเป็นมากมาย ).

  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 ให้คัดลอกโทเค็นของบอทของคุณที่นั่น):

    Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 5
โดยรวมแล้วใน 2 เดือนของการทำงานในโปรเจ็กต์ของตัวเอง ฉัน:
  • ได้รับโปรเจ็กต์การทำงานเต็มรูปแบบที่เขียนด้วยภาษา Java
  • เรียนรู้การทำงานกับ API บุคคลที่สาม (Telegram Bot API)
  • ในทางปฏิบัติ ฉันเจาะลึกลงไปในการทำให้เป็นอนุกรม ทำงานกับ JSON และไลบรารี Jackson เป็นอย่างมาก (ตอนแรกฉันใช้ GSON แต่มีปัญหากับมัน)
  • เสริมทักษะของฉันเมื่อทำงานกับไฟล์ ทำความคุ้นเคยกับ Java NIO
  • เรียนรู้การทำงานกับไฟล์การกำหนดค่า .xml และคุ้นเคยกับการบันทึก
  • ปรับปรุงความสามารถในสภาพแวดล้อมการพัฒนา (IDEA)
  • เรียนรู้ที่จะทำงานกับ git และเรียนรู้คุณค่าของ gitignore
  • ได้รับทักษะในการแยกวิเคราะห์หน้าเว็บ (ไลบรารี Jsoup)
  • เรียนรู้และใช้รูปแบบการออกแบบหลายแบบ
  • พัฒนาความรู้สึกและความปรารถนาที่จะปรับปรุงโค้ด (การปรับโครงสร้างใหม่)
  • ฉันเรียนรู้ที่จะค้นหาวิธีแก้ปัญหาทางออนไลน์ และไม่ต้องอายที่จะถามคำถามที่หาคำตอบไม่ได้
Telegram bot เป็นโครงการแรกและมีความสำคัญต่อการเติบโตอย่างมืออาชีพจากประสบการณ์ส่วนตัว - 7ฉันไม่รู้ว่าบอทมีประโยชน์หรือไร้ประโยชน์แค่ไหน หรือโค้ดสวย/น่าเกลียดแค่ไหน แต่ประสบการณ์ที่ฉันได้รับนั้นคุ้มค่าแน่นอน ฉันรู้สึกถึงความรับผิดชอบต่อโครงการของฉัน ฉันต้องการปรับปรุงเพิ่มสิ่งใหม่ๆ เป็นครั้งคราว เมื่อฉันสามารถวิ่งได้และเห็นว่าทุกอย่างเป็นไปตามที่ฉันต้องการ มันเป็นความตื่นเต้นจริงๆ นั่นไม่ใช่สิ่งสำคัญเหรอ? สนุกกับสิ่งที่คุณทำและเพลิดเพลินไปกับโค้ดทุกบรรทัดที่ใช้งานได้เหมือนช็อกโกแลตแท่งสุดท้าย ดังนั้นหากคุณเชี่ยวชาญการเขียนโปรแกรม คำแนะนำของฉันคือ อย่าอยู่ที่นี่จนกว่าจะถึงระดับ 40 แต่ให้เริ่มโปรเจ็กต์ของคุณเองให้เร็วที่สุด หากใครสนใจซอร์สโค้ดของโครงการอยู่ที่นี่ (เขียนใหม่สำหรับ Spring): https://github.com/miroha/GooglePlayGames-TelegramBot ในช่วงสองเดือนที่ผ่านมาฉันแทบจะไม่ได้ศึกษาเนื้อหาใหม่เลยเนื่องจากดูเหมือนว่าสำหรับฉัน ว่าฉันได้มาถึงทางตันแล้ว หากไม่มีงานทำ ฉันไม่เห็นว่าจะพัฒนาตรงไหนอีกต่อไป ยกเว้นบางทีอาจสอน Spring Framework ซึ่งเป็นสิ่งที่ฉันวางแผนจะทำในเดือนหน้า จากนั้นฉันจะพยายาม "เขียนใหม่" บอทโดยใช้เฟรมเวิร์กนี้ พร้อมตอบทุกคำถาม :) โชคดีนะทุกคน! อัปเดตตั้งแต่วันที่ 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