JavaRush /Java Blog /Random-IT /Il bot di Telegram come primo progetto e il suo significa...
Pavel Mironov (Miroha)
Livello 16
Москва

Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale

Pubblicato nel gruppo Random-IT
Grazie a tutti! Parlaci di te. Ho 24 anni, mi sono laureato in un'università tecnica l'anno scorso e non ho ancora esperienza lavorativa. Guardando al futuro, ci tengo a dire che inizialmente, nel piano previsto (redatto nell'autunno del 2019), prevedevo di andare a lavorare nel periodo marzo-aprile 2020, ma purtroppo è intervenuta la quarantena, quindi ho rimandato tutto a metà -estate e in futuro spero di scrivere la mia storia di successo. Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 1Non sono mai stato attratto dalla programmazione. All'università insegnavano abbastanza programmazione, ma allora questo mestiere non poteva interessarmi. C'erano anche linguaggi procedurali (C), un corso annuale di OOP (Java), database, perfino assembler e C++. Ma a dire il vero, in genere ero indifferente allo studio, poiché la maggior parte delle discipline insegnate mi sembravano inutili, adatte solo a fini di rendicontazione (in linea di principio è così). Dopo la laurea ho dovuto prendere una decisione: non avevo acquisito alcune competenze, ma avevo bisogno di lavorare. Ho dovuto pensare all'autoeducazione (oh, ho già perso almeno 2 anni interi stando seduto a guardare) e la scelta naturalmente è caduta su Java, dato che in un corso OOP all'università uno dei ragazzi mi ha consigliato il corso javarush , e lui, come sai, si dedica specificatamente al linguaggio Java. Ero interessato alla presentazione del corso. Sì, allora non mi piaceva programmare, perché quando incontravo qualche difficoltà rinunciavo subito, e di difficoltà nella programmazione ce ne sono più che sufficienti. Ma allo stesso tempo sentivo di voler scrivere codice, quindi alla fine ho deciso di dedicarmi alla programmazione. Ti racconto brevemente la mia esperienza con Javarush. Ho iniziato ad agosto 2019, ho subito acquistato un abbonamento per un mese, ma al livello 7 mi sono reso conto che i compiti erano difficili. Ho messo da parte il corso e ho preso Shildt. Quindi parallelamente ho completato il corso per 3 mesi. Ho raggiunto il livello 20 (questo è il mio secondo account), ho letto Shildt quasi completamente, poi mi sono stancato dei compiti qui, in cui ho smesso di vedere benefici pratici per me stesso. Sono andato a codewars, leetcode e ho iniziato a guardare corsi video. A proposito, in 3 mesi sono passato da "Oh no, cos'è un array? Come lavorarci e perché è così spaventoso"? ad uno studio dettagliato del codice sorgente delle classi collection (ArrayList, HashMap, ecc.). Sulla base dell'esperienza personale, dirò ai principianti: la cosa principale qui è superare la sensazione che sorge se non capisci nulla e non riesci a risolvere nulla. Quando si presenta, vuoi semplicemente rinunciare a tutto e sembra che tu sia troppo stupido per questa faccenda. Se superi questi momenti dentro di te e riposi mentalmente, il successo arriverà. Penso che molte persone non riescano a farcela, quindi rinunciano rapidamente a tali sforzi. Di conseguenza, a dicembre 2019 ho iniziato a pensare al mio progetto. Ho deciso di scegliere un bot di Telegram, ma non ne avevo idea. Allo stesso tempo, un amico aveva bisogno di funzionalità per il suo gruppo in un telegramma, che avrebbe voluto automatizzare. Lui si è accorto che stavo studiando approfonditamente la programmazione e mi ha offerto un progetto. Per me per l'esperienza e per un futuro curriculum, per lui per la crescita del gruppo. Mi permetto anche di citare la sua idea: "Недавно софтину хотел у программиста заказать, которая загружала бы в выбранное Облако файлы по прямым linkм. Это интересно, так How аналогов нет. И просто очень удобно. Суть: копируешь ссылку, вставляешь в окно и выбираешь нужное Облако (GDrive, Mail, Яндекс Диск и т.п), в своё время софт всё делает на стороне serverа и юзеру ничего не нужно загружать на свою машину (особенно круто, когда у тебя сборка на SSD-накопителях). Думали сделать в web-интерфейсе, чтобы можно было запускать How с телефонов, так и с десктопа... Можно в принципе через приложение реализовать, а не через web-интерфейс. Тебе такое по силам?"Ho iniziato a lavorare, ma alla fine, dopo un paio di giorni, mi sono reso conto che per noi non avrebbe funzionato nulla, in gran parte a causa della mancanza di conoscenza. Un amico aveva bisogno degli stessi collegamenti a Cloud.Mail, ma ancora non li Non ho un'API. C'è stato un tentativo di mettere insieme qualcosa tramite GDrive, ma l'implementazione era debole, inoltre questo servizio cloud non era adatto al "cliente". Sebbene inizialmente avesse offerto diversi cloud tra cui scegliere, alla fine ha rifiutato tutto tranne la posta .ru, per il quale non è stata trovata alcuna soluzione. In qualche modo tutto si è rivelato costoso, era necessario collegare il database, utilizzare un server per l'archiviazione, ecc. A proposito, ha ancora bisogno di questa applicazione web. Poiché le cose non sono andate Poiché per noi andava bene, ho deciso di creare un bot informativo che avrebbe dovuto ricevere collegamenti al gioco dal Google Play Store, analizzare il collegamento e salvare le informazioni ricevute nella libreria, quindi scriverle in un file json. Pertanto, ad ogni richiesta, la libreria può espandersi grazie agli sforzi degli utenti. In futuro, non sarà possibile ottenere informazioni sul gioco in un formato conveniente accedendo a Google Play. Scrivi semplicemente il comando /libraryHere_game_name e ottieni tutto ciò di cui hai bisogno. Ma ci sono diverse difficoltà di cui vi parlerò più avanti. All'inizio ho fatto progressi lentamente, poiché ho iniziato a seguire due corsi SQL contemporaneamente. Semplicemente non riuscivo a capire come funzionasse il bot e come elaborare le richieste. Ho incontrato un amico anche lui interessato a lavorare al progetto. La prima versione del bot era pronta in circa un mese, ma sono sorti disaccordi con un amico (da parte mia). Ho assunto la parte del bot responsabile dell'analisi e lui ha lavorato direttamente sulle richieste al bot e sulla loro elaborazione. Per qualche ragione, ha iniziato a complicare il bot, a introdurre qualche tipo di autorizzazione, a inventare amministratori, ad aggiungere funzionalità non necessarie e inoltre non mi piaceva molto il suo stile di codifica. Secondo me questo non era necessario in un bot informativo. Quindi ho deciso che avrei scritto io stesso un bot da zero con le funzionalità di cui avevo bisogno. Ora ti dirò cosa fa effettivamente il bot (usando un esempio tratto dal codice del progetto). Allegherò il codice completo del progetto alla fine dell'articolo e, purtroppo, non potrò commentarlo integralmente. Qualsiasi messaggio utente inviato al bot è un oggetto della classe Update. Contiene molte informazioni (ID messaggio, ID chat, ID utente univoco, ecc.). Esistono diversi tipi di aggiornamento: può essere un messaggio di testo, può essere una risposta dalla tastiera di telegram (callback), una foto, un audio, ecc. Per evitare che l'utente si distragga troppo, elaboro solo richieste di testo e richiamate dalla tastiera. Se l'utente invia una foto, il bot gli avviserà che non intende farne nulla. Nella classe principale del bot, nel metodo onUpdateReceived, il bot riceve un aggiornamento.
@Override
    public void onUpdateReceived(Update update) {
        UpdatesReceiver.handleUpdates(update);
    }
che passo al gestore (proprio classe 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 è un gestore centrale che, a seconda del tipo di aggiornamento, trasferisce il controllo a un altro gestore specializzato: TextMessageHandler o CallbackQueryHandler, ai cui costruttori passo l'aggiornamento più a valle della catena. L'aggiornamento è la cosa più importante quando si lavora con un bot e non può essere perso, perché con l'aiuto delle informazioni memorizzate nell'aggiornamento scopriamo a quale utente e a quale chat deve essere inviata la risposta. Per generare risposte all'utente, ho scritto una classe separata. Può inviare normali messaggi di testo, messaggi con tastiera in linea, messaggi con immagine e messaggi con tastiera di risposta. Una tastiera in linea si presenta così: Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 1definisce i pulsanti sui quali, cliccando su di essi, l'utente invia una richiamata al server, che può essere elaborata quasi allo stesso modo dei normali messaggi. Per “mantenerlo” è necessario il proprio gestore. Impostiamo un'azione per ciascun pulsante, che viene poi scritta nell'oggetto Update. Quelli. per il pulsante "Costo" impostiamo la descrizione "/prezzo" per la richiamata, che potremo successivamente ottenere dall'aggiornamento. Successivamente, in una classe separata, posso già elaborare questo 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;
...
La tastiera di risposta si presenta così: Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 2E in sostanza sostituisce la digitazione dell'utente. Facendo clic sul pulsante "Libreria" verrà inviato rapidamente un messaggio "Libreria" al bot. Per ogni tipo di tastiera ho scritto la mia classe, implementando il pattern Builder: inline e repliche . Di conseguenza, puoi essenzialmente "disegnare" la tastiera desiderata a seconda delle tue esigenze. Questo è terribilmente conveniente, poiché le tastiere possono essere diverse, ma il principio rimane lo stesso. Ecco un metodo intuitivo per inviare un messaggio con una tastiera in linea:
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());
        }
    }
Per dare al bot una funzionalità rigorosa, sono stati inventati comandi speciali che utilizzano il carattere barra: /library, /help, /game, ecc. Altrimenti dovremmo elaborare tutta la spazzatura che l'utente potrebbe scrivere. In realtà, questo è lo scopo per cui è stato scritto 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());
}
 ...
Pertanto, a seconda del comando inviato al bot, nel lavoro verrà incluso un gestore speciale. Andiamo oltre e guardiamo il lavoro del parser e della libreria. Se invii al bot un collegamento a un gioco nel Google Play Store, funzionerà automaticamente un gestore speciale . In risposta, l'utente riceverà informazioni sul gioco nel seguente formato: Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 3Allo stesso tempo, verrà chiamato un metodo che proverà ad aggiungere il gioco alla libreria del bot (prima sulla mappa locale, poi nel -> file json ). Se il gioco è già nella libreria, verrà effettuato un controllo (come in una normale hashmap) e se i dati del campo (ad esempio, il numero di versione è cambiato), il gioco nella libreria verrà sovrascritto. Se non vengono rilevate modifiche, non verrà effettuata alcuna voce. Se non c'era alcun gioco nella libreria, viene prima scritto sulla mappa locale (un oggetto come tyk ), e poi scritto in un file json, poiché se l'applicazione sul server viene chiusa inaspettatamente, i dati verranno perso, ma può sempre essere letto utilizzando il file. In realtà, all'avvio del programma, la libreria viene sempre caricata per la prima volta da un file proveniente da un blocco statico:
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());
        }
    }
Qui devi inoltre leggere i dati dal file in una mappa temporanea, che viene poi “copiata” in una mappa completa per mantenere l'insensibilità alle maiuscole e minuscole durante la ricerca di un gioco nel file (scrivendo tITan QuEST, il bot troverà comunque il gioco Titan Quest nella libreria). Non è stato possibile trovare un'altra soluzione, queste sono le caratteristiche della deserializzazione tramite Jackson. Quindi, ad ogni richiesta di collegamento, il gioco viene aggiunto alla libreria, se possibile, e la libreria si espande così. Ulteriori informazioni su un gioco specifico possono essere ottenute utilizzando il comando /libraryGame_Name. Puoi scoprire sia un parametro specifico (ad esempio, la versione corrente) sia tutti i parametri contemporaneamente. Ciò viene implementato utilizzando la tastiera in linea, di cui abbiamo parlato in precedenza. Durante il lavoro ho anche applicato le competenze qui acquisite risolvendo i problemi. Ad esempio, un elenco di nomi di giochi casuali presenti nella libreria (l'opzione è disponibile utilizzando il comando /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);
    }
In che modo il bot elabora i collegamenti? Li controlla per vedere se appartengono a Google Play (host, protocollo, porta):
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;
            }
        }
Se tutto è in ordine, il bot si connette tramite un collegamento utilizzando la libreria Jsoup, che consente di ottenere il codice HTML della pagina, che è soggetto a ulteriori analisi e parsing. Non potrai ingannare il bot con un collegamento errato o dannoso.
if (GooglePlayCorrectURL.isLinkValid(link)){
     if (!link.getPath().contains("apps")){
         throw new InvalidGooglePlayLinkException("К сожалению, бот работает исключительно с играми. Введите другую ссылку.");
     }
     URL = forceToRusLocalization(URL);
     document = Jsoup.connect(URL).get();
 }
     else {
         throw new NotGooglePlayLinkException();
      }
...
Qui abbiamo dovuto risolvere un problema con le impostazioni regionali. Il bot si collega al Google Play Store da un server situato in Europa, quindi la pagina nel Google Play Store si apre nella lingua appropriata. Ho dovuto scrivere una stampella che “reindirizza” forzatamente alla versione russa della pagina (il progetto, dopotutto, era rivolto al nostro pubblico). Per fare ciò, alla fine del collegamento è necessario aggiungere con attenzione il parametro hl: &hl=ru nella richiesta GET al server di 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;
    }
Dopo una connessione riuscita, riceviamo un documento HTML pronto per l'analisi e il parsing, ma questo va oltre lo scopo di questo articolo. Il codice del parser è qui . Il parser stesso recupera le informazioni necessarie e crea un oggetto con il gioco, che viene successivamente aggiunto alla libreria, se necessario. <h2>Riassumendo</h2>Il bot supporta diversi comandi che contengono determinate funzionalità. Riceve messaggi dall'utente e li abbina ai suoi comandi. Se si tratta di un collegamento o del comando /game + link, controlla quel collegamento per vedere se appartiene a Google Play. Se il collegamento è corretto, si connette tramite Jsoup e riceve il documento HTML. Questo documento viene analizzato in base al parser scritto. Le informazioni necessarie sul gioco vengono estratte dal documento e quindi l'oggetto con il gioco viene riempito con questi dati. Successivamente, l'oggetto con il gioco viene inserito nella memoria locale (se il gioco non è ancora presente) e immediatamente scritto in un file per evitare la perdita di dati. Un gioco registrato nella libreria (il nome del gioco è la chiave per la mappa, l'oggetto con il gioco è il valore per la mappa) può essere ottenuto utilizzando il comando /library Game_name. Se il gioco specificato viene trovato nella libreria del bot, all'utente verrà restituita una tastiera in linea, con la quale potrà ottenere informazioni sul gioco. Se il gioco non viene trovato, devi assicurarti che il nome sia scritto correttamente (deve corrispondere completamente al nome del gioco nel Google Play Store, salvo caso), oppure aggiungere il gioco alla libreria inviando il bot un collegamento al gioco. Ho distribuito il bot su heroku e per coloro che in futuro intendono scrivere il proprio bot e ospitarlo gratuitamente su heroku, darò un paio di consigli per risolvere le difficoltà che potresti incontrare (poiché le ho incontrate io stesso). Sfortunatamente, a causa della natura di Heroku, la libreria dei bot viene costantemente “reimpostata” una volta ogni 24 ore. Il mio piano non supporta l'archiviazione di file sui server Heroku, quindi estrae semplicemente il mio file di gioco da Github. C'erano diverse soluzioni: utilizzare un database o cercare un altro server che archiviasse questo file con il gioco. Ho deciso di non fare nulla per ora, dato che sostanzialmente il bot non è poi così utile. Ne avevo bisogno piuttosto per fare un'esperienza completa, che in fondo è ciò che ho ottenuto. Quindi, consigli per Heroku:
  1. Molto probabilmente dovrai registrarti su heroku utilizzando una VPN se vivi in ​​Russia.

  2. Alla radice del progetto bisogna mettere un file senza estensione chiamato Procfile. Il suo contenuto dovrebbe essere così: https://github.com/miroha/Telegram-Bot/blob/master/Procfile

  3. In pom.xml, aggiungi le seguenti righe secondo l'esempio , dove nel tag mainClass indica il percorso della classe che contiene il metodo principale: bot.BotApplication (se la classe BotApplication si trova nella cartella bot).

  4. Non creare alcun progetto utilizzando i comandi del pacchetto mvn, ecc., Heroku assemblerà tutto per te.

  5. È consigliabile aggiungere un gitignore al progetto, ad esempio questo:

    # Log file
    *.log
    
    # Compiled resources
    target
    
    # Tests
    test
    
    # IDEA files
    .idea
    *.iml
  6. Carica effettivamente il progetto su github e poi collega il repository a Heroku (o usa altri metodi, ce ne sono 3, se non sbaglio).

  7. Se il download è andato a buon fine ("Build riuscita"), assicurati di andare su Configura Dynos:

    Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 4

    e cambia il cursore, quindi assicurati che sia in posizione ON (a causa del fatto che non l'ho fatto, il mio bot non ha funzionato e mi sono scervellato per un paio di giorni e ho fatto molti movimenti non necessari ).

  8. Nascondi il token del bot su Github. Per fare ciò, devi ottenere il token dalla variabile d'ambiente:

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

    Quindi, dopo aver distribuito il bot, imposta questa variabile nella dashboard di Heroku nella scheda Impostazioni (a destra di TOKEN ci sarà un campo VALUE, copia lì il token del tuo bot):

    Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 5
In totale, in 2 mesi di lavoro sul mio progetto ho:
  • ricevuto un progetto completamente funzionante scritto in Java;
  • imparato a lavorare con API di terze parti (API Bot di Telegram);
  • in pratica ho approfondito la serializzazione, ho lavorato molto con JSON e la libreria Jackson (inizialmente usavo GSON, ma c'erano dei problemi);
  • ho rafforzato le mie capacità quando lavoro con i file, ho conosciuto Java NIO;
  • ho imparato a lavorare con i file di configurazione .xml e mi sono abituato al logging;
  • miglioramento della competenza nell'ambiente di sviluppo (IDEA);
  • ho imparato a lavorare con git e ho imparato il valore di gitignore;
  • acquisita competenze nel parsing di pagine web (libreria Jsoup);
  • appreso e utilizzato diversi modelli di progettazione;
  • sviluppato il senso e il desiderio di migliorare il codice (refactoring);
  • Ho imparato a trovare soluzioni online e a non essere timido nel fare domande alle quali non riuscivo a trovare una risposta.
Il bot di Telegram come primo progetto e il suo significato per la crescita professionale basata sull'esperienza personale - 7Non so quanto utile o inutile si sia rivelato il bot, o quanto carino/brutto fosse il codice, ma l'esperienza che ho avuto ne è valsa sicuramente la pena. Sentivo un senso di responsabilità per il mio progetto. Ogni tanto voglio migliorarlo, aggiungere qualcosa di nuovo. Quando ho potuto eseguirlo e vedere che tutto funzionava come volevo, è stata una vera emozione. Non è questa la cosa principale? Goditi ciò che fai e goditi ogni riga di codice funzionante come l'ultima barretta di cioccolato. Pertanto, se stai padroneggiando la programmazione, allora il mio consiglio è: non restare qui fino al livello 40, ma avvia il tuo progetto il prima possibile. Se qualcuno è interessato, il codice sorgente del progetto è qui (riscritto per la primavera): https://github.com/miroha/GooglePlayGames-TelegramBot Negli ultimi due mesi non ho quasi studiato nuovo materiale, poiché mi sembra che sono arrivato a un vicolo cieco. Senza lavoro non vedo più dove sviluppare, se non forse insegnare lo Spring Framework, che è quello che ho intenzione di fare il prossimo mese. E poi proverò a “riscrivere” il bot utilizzando questo framework. Pronto a rispondere a qualsiasi domanda. :) Buona fortuna a tutti! AGGIORNAMENTO del 07/07/2020 Il repository con il bot in puro Java è andato perso (l'ho cancellato, ne è rimasta una copia su un'altra macchina locale), ma ho scaricato il bot riscritto per Spring Boot: https://github.com/miroha /GooglePlayGames-TelegramBot
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION