Nel precedente articolo Implementazione di un Bot Telegram abbiamo visto come implementare un bot Telegram in java utilizzando le TelegramBots API. In questo articolo parliamo di comandi telegram e di come implementarli in modo semplice tramite una apposita estensione delle API Telegram.
Un comando Telegram è una funzionalità che consente a un bot Telegram di eseguire azioni specifiche quando riceve un messaggio dall’utente che inizia con il prefisso “/”. I comandi sono un modo semplice e intuitivo per interagire con un bot Telegram, poiché gli utenti possono, attraverso il semplice invio di un messaggio di testo, ottenere informazioni o eseguire azioni. Ad esempio, un bot potrebbe avere un comando “/weather” che fornisce le previsioni del tempo per una determinata città, oppure un comando “/translate” che traduce una frase in una lingua specifica.
Soluzione Banale
Esiste chiaramente una soluzione banale per la gestione di comandi Telegram che consiste semplicemente nell’implementare una serie di if-then-else
che verificano se il messaggio inizia con una stringa specifica. Ad esempio, riprendendo l’esempio del precedente articolo, potremmo implementare il comando /hello
nel seguente modo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class JavaBossBot extends TelegramLongPollingBot { /* * Non utilizzare questo metodo per conservare username e token */ private final static String USERNAME = "..."; private final static String TOKEN = "..."; public String getBotUsername() { return USERNAME; } public String getBotToken() { return TOKEN; } public void onUpdateReceived(Update update) { if (update.hasMessage() && update.getMessage().hasText()) { SendMessage message = null; String text = update.getMessage().getText(); if ( text.startsWith("/hello") ) { message = helloCommand( update ); } else { message = new SendMessage(); message.setChatId( update.getMessage().getChatId() ); message.setText("Benvenuto! Come posso aiutarti?"); } try { execute(message); } catch (TelegramApiException e) { e.printStackTrace(); } } } private SendMessage helloCommand(Update update) { SendMessage message = new SendMessage(); message.setChatId( update.getMessage().getChatId() ); message.setText("Hello world!"); return message; } } |
La figura seguente mostra la semplice interazione con il bot appena descritto in cui si evince il comportamento dello stesso quando riceve il comando /hello
.
L’implementazione fornita, sebbene funzionante, presenta diverse limitazioni. Innanzitutto il comando /hello
è assolutamente indistinguibile da una qualsiasi altro comando che inizia con lo stesso prefisso, ad esempio /hellobaby
. Ma questo è chiaramente un bug dovuto alla “cattiva” implementazione fornita. Ben più importante è il fatto che non tiene assolutamente conto del fatto che il comando potrebbe richiedere dei parametri in ingresso. Ad esempio se vogliamo fornire il servizio di meteo per una città specifica, il relativo comando potrebbe essere /meteo Roma
. Questo chiaramente richiederebbe quindi un parsing più complesso del messaggio in ingresso. Fortunatamente ci vengono in aiuto le telegram Extension API.
Telegram Extension
Le java Telegram API forniscono diverse utili estensioni, tra le quali il supporto ai comandi telegram. Innanzitutto dobbiamo inserire nel progetto la dipendenza alle telegrambots-extensions:
1 2 3 4 5 |
<dependency> <groupId>org.telegram</groupId> <artifactId>telegrambotsextensions</artifactId> <version>6.4.0</version> </dependency> |
Per creare un nuovo comando, dobbiamo semplicemente creare una nuova classe che estenda la classe org.telegram.telegrambots.extensions.bots.commandbot.commands.BotCommand
. Questa classe sarà caratterizzata dal metodo astratto execute()
responsabile della gestione del comando specificato. La caratteristica di tale metodo è che fornisce in modo immediato alcune informazioni utili all’esecuzione della logica del comando:
- Un oggetto
AbsSender
attraverso il quale potremo inviare il messaggio di risposta al client. - Gli oggetti
User
eChat
estratti dal messaggio originale. - Gli eventuali parametri ottenuti suddividendo la stringa che segue il comando utilizzando lo spazio come separatore.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class HelloCommand extends BotCommand { HelloCommand() { super("hello", "Say hallo word"); } @Override public void execute(AbsSender absSender, User user, Chat chat, String[] arguments) { SendMessage answer = new SendMessage(); answer.setChatId(chat.getId().toString()); answer.setText("Hello world!"); try { absSender.execute(answer); } catch (TelegramApiException e) { e.printStackTrace(); } } } |
Una volta implementate le classi che gestiranno i comandi che vogliamo che il bot riconosca, è necessario registrare tali classi in modo che vengano utilizzate dal bot. Per farlo è sufficiente estendere la classe TelegramLongPollingCommandBot
(appartenente alle extension API), che a sua volta estende la clase TelegramLongPollingBot
(vista nel precedente articolo), e che fornisce allo scopo il metodo register()
, da invocare su ciascuna classe che si vuole registrare.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class CommandsHandler extends TelegramLongPollingCommandBot { /* * Non utilizzare questo metodo per conservare username e token */ private final static String USERNAME = "JavaBoss"; private final static String TOKEN = "5912372293:AAEkUwJBtFePlHHWd44hN0RqWjMr2xs8K4c"; public CommandsHandler() { register(new HelloCommand()); } public void processNonCommandUpdate(Update update) { SendMessage echoMessage = new SendMessage(); echoMessage.setChatId(update.getMessage().getChatId()); echoMessage.setText("Command Unknown!"); try { execute(echoMessage); } catch (TelegramApiException e) { e.printStackTrace(); } } } |
Tale classe richiede anche l’implementazione del metodo astratto processNonCommandUpdate()
che è invocato ogni qualvolta il messaggio ricevuto dal bot non corrisponde a nessuno dei comandi registrati.
L’ultima operazione che ci resta da fare è di utilizzare le Telegram API per attivare il bot appena creato.
1 2 3 4 5 6 7 8 9 10 |
public class TelegramMain { public static void main(String[] args) { try { TelegramBotsApi botsApi = new TelegramBotsApi( DefaultBotSession.class ); botsApi.registerBot(new CommandsHandler()); } catch (TelegramApiException e) { e.printStackTrace(); } } } |
La figura seguente mostra l’interazione implementata dal bot in oggetto.
Il Codice Sorgente
Il codice sorgente del progetto è scaricabile qui telegram-bot.