Un bot Telegram come pro memoria e archivio
Avevo bisogno di due cose semplici: qualcuno che mi ricordasse le cose al momento giusto e un posto dove ritrovarle dopo. Un bot Telegram fa entrambe, perché Telegram c'è già sul telefono e non richiede di costruire un'interfaccia.
#Come si parla con Telegram
Un bot è un account speciale. Lo si crea con @BotFather, che consegna un token. Il token è la sola credenziale: chi lo ha può comandare il bot, quindi va tenuto fuori dal repository.
Da lì tutto passa da HTTPS. Ogni metodo è una chiamata a un indirizzo con questa forma:
1curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage" \
2 -d chat_id=<CHAT_ID> \
3 -d text="Ciao"
Si parla in due direzioni.
- Il bot scrive. Si chiamano metodi come
sendMessage,sendPollopinChatMessage, indicando la chat con il suochat_id. - Il bot ascolta. Ogni messaggio, comando o voto è un update. Ci sono due modi per riceverli.
I due modi di ricevere gli update:
| Modo | Come funziona | Quando ha senso |
| --- | --- | --- |
| getUpdates (polling) | Il bot chiede a Telegram se c'è qualcosa di nuovo, a ripetizione. | Sviluppo locale, nessun indirizzo pubblico. |
| setWebhook | Telegram fa una POST a un indirizzo HTTPS tuo, a ogni update. | Server raggiungibile da internet, nessun processo sempre acceso. |
Con il webhook non c'è niente da tenere in esecuzione: arriva una richiesta, la gestisci, rispondi 200. Telegram permette anche di impostare un secret_token, che rimanda in un header a ogni chiamata, per verificare che la richiesta venga davvero da lui.
#La scelta tecnica
L'applicazione era già Laravel, quindi il bot vive lì dentro invece di diventare un servizio a parte. Uso irazasyed/telegram-bot-sdk, che nasconde le chiamate HTTP dietro una facciata Telegram.
Le parti sono tre:
- Una rotta
POSTpubblica riceve il webhook e lo passa al gestore dei comandi dell'SDK. Le query inline per ora rispondono solo che non sono supportate. - Una classe per comando, in
app/Console/Commands/Telegram/, registrata inconfig/telegram.php. Ognuna dichiara nome e alias, per esempio/calcetto, e la logica nel metodohandle(). - Lo scheduler di Laravel per tutto ciò che deve partire da solo, senza che nessuno scriva al bot.
Il token e l'indirizzo del webhook stanno nel file .env, letti solo dalla configurazione.
Due tabelle tengono lo stato:
bot_chatselenca le chat che il bot conosce. Il comando/startregistra la chat conenabled = false: il bot non agisce finché non viene abilitata a mano. È una guardia semplice contro chi aggiunge il bot dove non deve.bot_messagesricorda cosa è già stato inviato: chat, id del messaggio, compito, anno e settimana.
#Pro memoria e archivio nella pratica
L'esempio più concreto è il sondaggio settimanale del calcetto. Il sabato alle 08:00 il comando soccer:send pubblica nelle chat abilitate un sondaggio con i giorni della settimana successiva. Il sondaggio viene fissato in alto e quello della settimana precedente viene sganciato.
Ogni invio viene scritto in bot_messages. Questo è l'archivio, ed è anche ciò che rende il pro memoria affidabile:
- se per la settimana esiste già un messaggio, il bot non ne crea un secondo ma risponde con un rimando a quello esistente;
- se qualcuno chiede
/calcettoa mano, ottiene lo stesso sondaggio e non un duplicato; - il messaggio passato resta ritrovabile per chat, anno e settimana.
Il comando può essere richiamato anche a mano, con next o con il numero della settimana ISO.
#Per chiudere
Lo schema è questo: un invio automatico e un registro di ciò che è partito. Un webhook, una classe per comando, lo scheduler e due tabelle bastano per un pro memoria che non si ripete e non si perde.