JavaRush /وبلاگ جاوا /Random-FA /ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه...
Pavel Mironov (Miroha)
مرحله
Москва

ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه ای بر اساس تجربه شخصی

در گروه منتشر شد
درود به همه! از خودتان بگویید. من 24 سالمه پارسال از دانشگاه فنی فارغ التحصیل شدم و هنوز سابقه کار ندارم. با نگاهی به آینده، می خواهم بگویم که در ابتدا، در برنامه تعیین شده (طراحی شده در پاییز 2019)، قصد داشتم در مارس-آوریل 2020 سر کار بروم، اما، متأسفانه، قرنطینه دخالت کرد، بنابراین همه چیز را به اواسط موکول کردم. -تابستان و در آینده امیدوارم داستان موفقیت خودم را بنویسم. ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه ای بر اساس تجربه شخصی - 1هیچ وقت به سمت برنامه نویسی جذب نشدم. در دانشگاه به اندازه کافی برنامه نویسی تدریس می کردند، اما این هنر در آن زمان نمی توانست به من علاقه مند باشد. همچنین زبان‌های رویه‌ای (C)، یک دوره یک ساله در OOP (جاوا)، پایگاه‌های داده، حتی اسمبلر و C++ وجود داشت. اما صادقانه بگویم، من به طور کلی نسبت به مطالعه بی تفاوت بودم، زیرا بیشتر رشته های تدریس شده برای من بی فایده به نظر می رسید و فقط برای مقاصد گزارش مناسب هستند (در اصل، اینطور است). پس از فارغ التحصیلی از دانشگاه، باید تصمیم می گرفتم: برخی از مهارت ها را به دست نیاوردم، اما باید کار می کردم. من باید به خودآموزی فکر می کردم (اوه، من قبلاً حداقل 2 سال کامل را با بیکار نشستن از دست داده ام) و انتخاب به طور طبیعی روی جاوا افتاد، زیرا در یک دوره OOP در دانشگاه یکی از بچه ها دوره javarush را توصیه کرد. و او، همانطور که می دانید، به طور خاص به زبان جاوا اختصاص داده شده است. من علاقه مند به ارائه دوره بودم. بله، من آن زمان برنامه نویسی را دوست نداشتم، زیرا زمانی که با هر مشکلی مواجه می شدم بلافاصله دست از کار می کشیدم و در برنامه نویسی مشکلات بیش از حد کافی وجود دارد. اما در همان زمان احساس می کردم که می خواهم کد بنویسم، بنابراین در نهایت تصمیم گرفتم وارد برنامه نویسی شوم. من به طور خلاصه در مورد تجربه خود با جاواروش به شما می گویم. من در آگوست 2019 شروع کردم، بلافاصله یک اشتراک برای یک ماه خریدم، اما در سطح 7 متوجه شدم که وظایف دشوار است. من دوره را کنار گذاشتم و Shildt را برداشتم. بنابراین به موازات آن دوره را به مدت 3 ماه تمام کردم. من به سطح 20 رسیدم (این دومین حساب من است)، تقریباً Schildt را خواندم، سپس از وظایف اینجا خسته شدم، که در آن دیگر مزایای عملی برای خودم ندیدم. من به Codewars، leetcode رفتم و شروع به تماشای دوره های ویدیویی کردم. در ضمن من در عرض 3 ماه از "اوه نه آرایه چیست؟ چگونه با آن کار کنیم و چرا اینقدر ترسناک است" رفتم؟ به مطالعه دقیق کد منبع کلاس های مجموعه (ArrayList، HashMap، و غیره). بر اساس تجربه شخصی، به مبتدیان خواهم گفت: نکته اصلی در اینجا غلبه بر احساسی است که اگر چیزی را درک نکنید و نتوانید چیزی را حل کنید، ایجاد می شود. وقتی به وجود می آید، فقط می خواهید همه چیز را رها کنید و به نظر می رسد که برای این موضوع خیلی احمق هستید. اگر بر چنین لحظاتی در درون خود غلبه کنید و از نظر ذهنی استراحت کنید، آنگاه موفقیت خواهد آمد. من فکر می کنم بسیاری از مردم نمی توانند با این کار کنار بیایند، بنابراین به سرعت از چنین تلاش هایی دست می کشند. در نتیجه، در دسامبر 2019 شروع به فکر کردن در مورد پروژه خود کردم. تصمیم گرفتم یک ربات تلگرام انتخاب کنم، اما هیچ ایده ای نداشتم. در همان زمان، یکی از دوستان به قابلیت هایی برای گروه خود در تلگرام نیاز داشت که می خواست آن را خودکار کند. او فقط می دانست که من برنامه نویسی را عمیق می خوانم و پروژه ای را به من پیشنهاد داد. برای من، برای تجربه و رزومه آینده، برای او، برای توسعه گروه. حتی به خودم اجازه می‌دهم نظر او را نقل کنم:Недавно софтину хотел у программиста заказать, которая загружала бы в выбранное Облако файлы по прямым linkм. Это интересно, так How аналогов нет. И просто очень удобно. Суть: копируешь ссылку, вставляешь в окно и выбираешь нужное Облако (GDrive, Mail, Яндекс Диск и т.п), в своё время софт всё делает на стороне serverа и юзеру ничего не нужно загружать на свою машину (особенно круто, когда у тебя сборка на SSD-накопителях). Думали сделать в web-интерфейсе, чтобы можно было запускать How с телефонов, так и с десктопа... Можно в принципе через приложение реализовать, а не через web-интерфейс. Тебе такое по силам?"من شروع به کار کردم، اما در نهایت، پس از چند روز، متوجه شدم که هیچ چیز برای ما درست نمی شود، عمدتاً به دلیل عدم آگاهی. یکی از دوستان به همین پیوندها به Cloud.Mail نیاز داشت، اما آنها هنوز هم ندارند." یک API ندارید. تلاشی برای جمع‌آوری چیزی از طریق GDrive وجود داشت، اما پیاده‌سازی آن ضعیف بود، به علاوه این سرویس ابری برای «مشتری» مناسب نبود. اگرچه در ابتدا او چندین ابر را برای انتخاب پیشنهاد کرد، اما در نهایت همه چیز را رد کرد به جز ایمیل. .ru، که هیچ راه حلی برای آن پیدا نشد. به نوعی همه چیز گران تمام شد، لازم بود به پایگاه داده متصل شود، از یک سرور برای ذخیره سازی استفاده شود، و غیره. اتفاقا، هنوز به این برنامه وب نیاز دارد. برای ما کار نکرد، تصمیم گرفتم یک ربات اطلاعاتی بسازم، باید لینک های بازی را از فروشگاه Google Play دریافت کنم، پیوند را تجزیه کرده و اطلاعات دریافتی را در کتابخانه ذخیره کرده و سپس آن را در یک فایل json بنویسم. بنابراین، با هر درخواست، کتابخانه می تواند به لطف تلاش کاربران گسترش یابد.در آینده نمی توانید با مراجعه به Google Play اطلاعات بازی را به شکل مناسبی دریافت کنید. شما فقط دستور /libraryHere_game_name را بنویسید و هر آنچه را که نیاز دارید دریافت کنید. اما چندین مشکل وجود دارد که بعداً به شما خواهم گفت. در ابتدا به آرامی پیشرفت کردم، زیرا شروع به گذراندن دو دوره SQL به طور همزمان کردم. من به سادگی نمی توانستم بفهمم ربات اصلا چگونه کار می کند و چگونه درخواست ها را پردازش کنم. با دوستی آشنا شدم که او نیز علاقه مند به کار روی پروژه بود. اولین نسخه ربات در حدود یک ماه آماده شد، اما با یکی از دوستان (از طرف من) اختلاف نظر ایجاد شد. من بخشی از ربات که مسئول تجزیه است را گرفتم و او مستقیماً روی درخواست‌های ربات و پردازش آنها کار کرد. به دلایلی، او شروع به پیچیده کردن ربات، معرفی نوعی مجوز، اختراع مدیران، اضافه کردن قابلیت های غیر ضروری کرد، به علاوه من واقعاً سبک برنامه نویسی او را دوست نداشتم. به نظر من این در یک ربات اطلاعاتی ضروری نبود. بنابراین تصمیم گرفتم که خودم یک ربات از ابتدا با عملکردی که نیاز داشتم بنویسم. اکنون به شما می گویم که ربات واقعاً چه کاری انجام می دهد (با استفاده از مثالی از کد پروژه). کد کامل پروژه را در انتهای مقاله پیوست می کنم و متاسفانه نمی توانم به طور کامل در مورد آن نظر بدهم. هر پیام کاربری که به ربات ارسال می شود، یک شی از کلاس Update است. این شامل اطلاعات زیادی است (شناسه پیام، شناسه چت، شناسه کاربری منحصر به فرد و غیره). چندین نوع به روز رسانی وجود دارد: می تواند یک پیام متنی باشد، می تواند پاسخی از صفحه کلید تلگرام (کال بک)، عکس، صدا و غیره باشد. برای جلوگیری از مزاحمت بیش از حد کاربر، من فقط درخواست های متنی و تماس های تلفنی را از صفحه کلید پردازش می کنم. اگر کاربر عکسی را ارسال کند، ربات به او اطلاع می دهد که قصد ندارد با آن کاری انجام دهد. در کلاس ربات اصلی، در متد 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 نوشته می شود. آن ها برای دکمه "هزینه"، توضیح "/price" را برای پاسخ به تماس تعیین می کنیم، که بعداً می توانیم از به روز رسانی دریافت کنیم. بعد، در یک کلاس جداگانه، من قبلاً می توانم این callback را پردازش کنم:
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;
...
صفحه کلید Reply به این شکل است: ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه ای بر اساس تجربه شخصی - 2و در اصل جایگزین تایپ کاربر می شود. با کلیک بر روی دکمه "کتابخانه" به سرعت یک پیام "کتابخانه" برای ربات ارسال می شود. برای هر نوع کیبورد، کلاس خودم را نوشتم و الگوی 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());
}
 ...
بنابراین بسته به اینکه چه دستوری برای ربات ارسال می کنید، یک هندلر ویژه در کار گنجانده می شود. بیایید جلوتر برویم و به کار تجزیه کننده و کتابخانه نگاه کنیم. اگر پیوندی به یک بازی در فروشگاه Google Play برای ربات ارسال کنید، یک کنترل کننده ویژه به طور خودکار کار می کند . در پاسخ، کاربر اطلاعات بازی را به شکل زیر دریافت می کند: ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه ای بر اساس تجربه شخصی - 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 در کتابخانه). نمی شد راه حل دیگری پیدا کرد، اینها ویژگی های سریال زدایی با استفاده از جکسون است. بنابراین، با هر درخواست پیوند، بازی در صورت امکان به کتابخانه اضافه می شود و کتابخانه از این طریق گسترش می یابد. اطلاعات بیشتر در مورد یک بازی خاص را می توان با استفاده از دستور /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. اگر در روسیه زندگی می کنید به احتمال زیاد مجبور خواهید بود با استفاده از VPN در heroku ثبت نام کنید.

  2. در ریشه پروژه باید یک فایل بدون پسوند به نام Procfile قرار دهید. محتوای آن باید اینگونه باشد: https://github.com/miroha/Telegram-Bot/blob/master/Procfile

  3. در pom.xml، خطوط زیر را مطابق با مثال اضافه کنید، جایی که در تگ mainClass، مسیر کلاس حاوی متد اصلی را نشان می دهد: bot.BotApplication (اگر کلاس BotApplication در پوشه ربات باشد).

  4. با استفاده از دستورات بسته mvn و غیره هیچ پروژه ای نسازید، هروکو همه چیز را برای شما جمع می کند.

  5. توصیه می شود یک gitignore به پروژه اضافه کنید، به عنوان مثال:

    # Log file
    *.log
    
    # Compiled resources
    target
    
    # Tests
    test
    
    # IDEA files
    .idea
    *.iml
  6. در واقع پروژه را در github آپلود کنید و سپس مخزن را به Heroku متصل کنید (یا از روش های دیگر استفاده کنید، اگر اشتباه نکنم 3 تا از آنها وجود دارد).

  7. اگر دانلود با موفقیت انجام شد ("Build موفق شد")، حتما به Configure 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
در مجموع، در 2 ماه کار روی پروژه خودم:
  • یک پروژه به طور کامل کار نوشته شده در جاوا دریافت کرد.
  • یاد گرفت که با API شخص ثالث (Telegram Bot API) کار کند.
  • در عمل، من به سریال سازی عمیق تر پرداختم، با JSON و کتابخانه جکسون بسیار کار کردم (در ابتدا از GSON استفاده می کردم، اما مشکلاتی با آن وجود داشت).
  • مهارت های خود را در هنگام کار با فایل ها تقویت کردم، با Java NIO آشنا شدم.
  • کار با پیکربندی فایل های xml را یاد گرفتم و به لاگ کردن عادت کردم.
  • مهارت بهبود یافته در محیط توسعه (IDEA)؛
  • کار با git را یاد گرفت و ارزش gitignore را آموخت.
  • کسب مهارت در تجزیه صفحات وب (کتابخانه Jsoup)؛
  • چندین الگوی طراحی را یاد گرفت و استفاده کرد.
  • ایجاد حس و تمایل به بهبود کد (بازسازی)؛
  • من یاد گرفتم که راه حل های آنلاین پیدا کنم و از پرسیدن سوالاتی که نتوانستم پاسخی برای آنها پیدا کنم خجالتی نباشم.
ربات تلگرام به عنوان اولین پروژه و اهمیت آن برای رشد حرفه ای بر اساس تجربه شخصی - 7نمی‌دانم ربات چقدر مفید یا بی‌فایده بود، یا کد زیبا/زشت بود، اما تجربه‌ای که به دست آوردم قطعاً ارزشش را داشت. نسبت به پروژه ام احساس مسئولیت می کردم. هر از گاهی می خواهم آن را بهبود بخشم، چیز جدیدی اضافه کنم. وقتی توانستم آن را اجرا کنم و ببینم همه چیز همانطور که می‌خواستم کار می‌کند، واقعاً هیجان‌انگیز بود. این موضوع اصلی نیست؟ از کاری که انجام می‌دهید لذت ببرید و از هر خط کدی مانند آخرین نوار شکلات لذت ببرید. بنابراین، اگر به برنامه نویسی مسلط هستید، پس توصیه من به شما: تا سطح 40 اینجا نمانید، بلکه پروژه خود را هر چه زودتر شروع کنید. اگر کسی علاقه مند است، کد منبع پروژه اینجاست (بازنویسی شده برای بهار): https://github.com/miroha/GooglePlayGames-TelegramBot در دو ماه گذشته به سختی در حال مطالعه مطالب جدید هستم، زیرا به نظرم می رسد که به بن بست رسیده ام بدون کار، من دیگر نمی بینم که کجا توسعه پیدا کنم، به جز شاید برای آموزش بهار فریم ورک، کاری که قصد دارم در ماه آینده انجام دهم. و سپس سعی خواهم کرد ربات را با استفاده از این چارچوب "بازنویسی" کنم. آماده پاسخگویی به هرگونه سوال :) همگی موفق باشید! به روز رسانی از 07/07/2020 مخزن با ربات در جاوا خالص گم شد (من آن را حذف کردم، یک کپی در یک ماشین محلی دیگر باقی ماند)، اما ربات بازنویسی شده را برای Spring Boot دانلود کردم: https://github.com/miroha /GooglePlayGames-TelegramBot
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION