Automazione con BOT Telegram

by luca
50 comments

Il progetto che oggi vi presento è una sorta di proof of concept che vuole dimostrare la possibilità di controllare da remoto sensori ed attuatori (ad esempio dei relay) tramite Telegram.

Telegram è una applicazione di messaggistica, simile al più famoso Whatsapp. A giugno, gli sviluppatori di Telegram hanno annunciato la disponibilità  di API per sviluppare dei bot.

Un bot è un programma che può agire (parzialmente) come un utente reale: ricevere/inviare messaggi, partecipare alle chat di gruppo… i bot ad esempio sono molto utilizzati nei canali IRC.

La mia idea è stata quindi sviluppare un bot, in esecuzione su un Raspberry Pi, che riceva comandi tramite una chat Telegram. Alla scheda Rasbperry ho collegato un sensore di temperatura / umidità e un modulo con due relay. Ecco un breve filmato che illustra il progetto (sottotitoli italiani disponibili!):

[youtube id=”uwlThnyeh9s” width=”600″ height=”350″]

Funzionamento

Il funzionamento del bot è riassunto nello schema seguente:

bot-0

L’utente, tramite l’app Telegram installata sul proprio smartphone, inizia una chat con l’utente “bot”; i messaggi vengono inviati ai server di Telegram. Il programma in esecuzione sulla Raspberry può ricevere i messaggi in due modi:

  • polling, ogni tot secondi il programma verifica se vi sono nuovi messaggi e li scarica
  • webhook, il programma comunica a Telegram un indirizzo web a cui notificare i nuovi messaggi

La seconda soluzione richiede la disponibilità di un indirizzo IP pubblico e configurazioni (NAT) sul router di collegamento ad Internet, per questo ho optato per il più semplice polling.

Creiamo il bot

Il primo passo per sviluppare un bot è crearlo all’interno di Telegram. Esiste un apposito bot a cui inviare tutti i comandi di creazione e configurazione: BotFather:

telebot-1

Iniziamo la creazione di un nuovo bot inviando al BotFather il comando /newbot. Ci verrà chiesto il nome (display name) del nuovo bot e il suo username. Se la creazione del bot ha successo, ci verrà restituito un authorization token che dovremo inserire nel nostro programma:

telebot-2

Installazione

Ho sviluppato il bot in linguaggio javascript, utilizzando Node.js come environment per eseguirlo (per l’installazione di Node.js su Raspberry vi rimando all’ottima guida di Adafruit). Il programma utilizza 3 librerie:

[checklist]

  • node-dht-sensor, per la lettura dei dati di umidità e temperatura dal sensore DHT11
  • onoff, per il controllo dei PIN digitali di Raspberry
  • node-telegram-bot, per il collegamento alle API Telegram

[/checklist]

L’installazione delle librerie è semplicissima grazie a NPM (Node Package Manager). Create una nuova cartella che conterrà il codice del bot e le sue librerie; entrate in tale cartella e digitate il comando:

npm install node-dht-sensor onoff node-telegram-bot

All’interno della cartella copiate quindi il sorgente javascript del bot, disponibile nel mio repository su Github. Il codice è commentato e dovrebbe essere di facile lettura: per qualsiasi dubbio scrivete un commento a questo articolo!

Ricordatevi di modificare il token del bot inserendo quello che vi avrà restituito BotFather:

bot_token

Per lanciare il bot, sarà sufficiente digitare:

sudo node bot.js

bot_launch

Utilizzo

I comandi disponibili sono:

[checklist]

  • /getouts, visualizza lo stato dei due relay
  • /setout1 ON|OFF/setout2 ON|OFF, imposta una delle due uscite a ON o OFF
  • /gettemp, visualizza la temperatura attuale
  • /gethum, visualizza l’umidità attuale

[/checklist]

bot3

Sicurezza

I bot di Telegram sono pubblici, quindi qualsiasi utente può inviare loro dei comandi. Per fare in modo che il bot sia utilizzabile solo dal mio utente, ho aggiunto nel codice un controllo sull’ID dell’utente che invia i messaggi:

bot_security

Per conoscere il proprio ID, è possibile utilizzare un piccolo bot, sempre su Github, che risponde ad ogni messaggio con il messaggio originale (echo) e l’ID del mittente:

bot_security2 Elettronica

Il setup del mio esempio prevede un sensore temperatura/umidità DHT11 e un modulo con due relay. Ho collegato i due moduli ai PIN di espansione (1 per il sensore, 2 per i relay, oltre all’alimentazione) di Raspberry Pi:

bot1 bot2

Nel programma ho definito i corretti PINs:

bot_pins

What’s next

Questo progetto vuole essere un punto di inizio, che dimostra come sia possibile sviluppare un bot per inviare comandi tramite Telegram.

Le API di Telegram offrono diverse funzioni avanzate, come ad esempio la possibilità di elencare i comandi possibili, di cambiare l’immagine di avatar del bot o quella di personalizzare la tastiera dell’app: nel nostro esempio all’invio del comando /setout1 si potrebbe richiedere all’utente lo stato (ON|OFF) di tale uscita, visualizzando sull’app i due pulsanti di scelta.

Related Posts

50 comments

haxon 15 ottobre 2015 - 16:22

Did you know that Openhab has this functionality as well? Someone made an addon for telegram interaction.

It might be not as much fun as doing it yourself, but you could give it a shot 😉

Reply
luca 16 ottobre 2015 - 07:44

Hi, thanks I didn’t know the OpenHab project, very interesting!

Reply
sparviero 21 ottobre 2015 - 09:16

for(i = 0; i < authorized_users.length; iè++)

nel tuo bog.js c'e' un errore alla linea 112, capita anche a me di premere 20 tasti consecutivamente con le ditone che mi ritrovo ;o)

Reply
luca 21 ottobre 2015 - 10:59

grazie mille! lo sistemo subito 😉

Reply
Beppe 12 novembre 2015 - 14:00

Ciao Luca.
non ho capito se per installare telegram sul raspberry serve un altro numero di telefono, e se la creazione della bot va fatta sul raspberry.
puoi spiegarmi in stampatello per favore.
sono un po lento….
grazie.

Reply
luca 13 novembre 2015 - 08:27

Ciao Beppe, il bot “gira” su Raspberry: è un programmino che lanci (volendo puoi farlo partire non appena dai corrente al Raspberry). Per funzionare non ti serve un altro numero di telefono ma devi “registrare” il tuo bot come spiegato nell’articolo per ottenere da Telegram un “token” (un codice identificativo) che è simile al numero di telefono per gli utenti “veri”.

Reply
Claudio Mussoni 28 dicembre 2015 - 09:47

Ciao Luca, ho un po’ di confusione sulle librerie. Le hai scritte tu oppure fanno parte di un progetto che hai trovato per il Raspberry ? Dove le posso trovare ?
Mille grazie

Reply
luca 28 dicembre 2015 - 10:08

Ciao Claudio, le librerie per Node.js si trovano qui: https://www.npmjs.com/

Reply
Claudio Mussoni 28 dicembre 2015 - 15:13

Gentilissimo, grazie.
Claudio

Reply
lxs 20 gennaio 2016 - 14:12

Ciao luca, quando provo ad installare le librerie mi da questi errori dove sbaglio?

npm install node-dht-sensor onoff node-telegram-bot \
> node-dht-sensor@0.0.8 install /home/pi/TelegramBot/node/node_modules/node-dht-sensor
> ./check-bcm2835

—————————————————————————-
Library BCM2835 not found!
Make sure you follow instructions at http://www.airspayce.com/mikem/bcm2835/
to install the BCM2835 library on your system.
—————————————————————————-
|[…]

Reply
luca 23 gennaio 2016 - 09:39

Ciao! Come ti dice l’errore, ti mancano le librerie BCM2835 per Node, segui le istruzioni al link indicato

Reply
Juan Bracamonte 21 gennaio 2016 - 14:03

Ciao Luca, quando si tenta di installare la linea di NPM me il seguente errore mio raspbian getta, può essere? Sono bloccato qui per giorni

gyp ERR! stack Error: ENOSPC, mkdir ‘/home/pi/node_modules/node-dht-sensor/.node-gyp’
[…]

Reply
luca 23 gennaio 2016 - 09:38

ciao! sembra un problema di permessi… davvero strano se lo lanci da root: puoi provare a partire con una immagine Raspbian “pulita”?

Reply
Stefano 24 gennaio 2016 - 15:34

Consigli su qualche tutorial per imparare ad usare NODE.js ?
Grazie !

Reply
luca 24 gennaio 2016 - 21:20

Ciao Stefano, io ho iniziato con questo: http://www.nodebeginner.org/

Reply
Luigi 27 gennaio 2016 - 13:32

Ok, facendo qualche ricerca ho capito che ciò che hai scritto è per un comando seguito da on oppure off, ho capito come implementare il cambiamento di tastiera, si trova in send messagge quindi oltre chat id e text andrebbe scritto reply_markup:
e come argomento ci va direttamente un array di array contenente [[‘ON’][‘OFF’]]?

case message.text == “/testonoff”:
bot.sendMessage({
chat_id: message.chat.id,
text: ‘on o off?’, //test per tastiera
reply_markup: [[“ON”,”OFF”]],
});
break;
se è giusto, come riesco a indicare la condizione ad esempio if(replay_markup == ‘ON’) then ?
Grazie della disponibilità, mi saresti di grandissimo aiuto

Reply
luca 31 gennaio 2016 - 13:32

Ciao Luigi, la tastiera personalizzata è solo lato “client”, quello che tu leggi in risposta è comunque il testo “ON” o “OFF”, il confronto va sempre fatto sulla variabile message.text

Reply
daniele 16 febbraio 2016 - 14:31

ciao Luca,complimenti per l ottima guida che hai scritto,trovo davvero molto interessante l utilizzo di telegram per comunicare con il piccolo raspberry.
Sono riuscito a far funzionare tutto subito grazie alle spiegazioni semplici ed efficaci …sono riuscito ad aggiungere al tuo bot(modificandolo) altre uscite per collegare dei relè aggiuntivi ….sarebbe interessante aggiungere la possibilita di ricevere in chat tramite un comando anche una foto scattata da una webcam o magari da un ip cam…. è da molto che sto cercando su internet qualche tutorial ma …zero.(nn sono un esperto in progr)
magari vista la tua esperienza potresti implementarlo in questo progetto …
Grazie ciao ciao

Reply
luca 17 febbraio 2016 - 08:56

Ciao Daniele! ottimo suggerimento, mi metto al lavoro 😉

Reply
daniele 17 febbraio 2016 - 10:36

…Grande !!!

Reply
Davide 20 febbraio 2016 - 12:23

Ciao, complimenti per la guida!
Volevo chiederti se era possibile fare la stessa cosa con un sensore di temperatura differente, il DS18B20?

Per caso conosci qualche guida?

Grazie

Reply
luca 20 febbraio 2016 - 12:53

Ciao! Assolutamente sì, devi solo cambiare il “modulo” che si interfaccia al sensore… ecco un tutorial

Reply
Davide 23 febbraio 2016 - 08:32

Grazie mille! ti faccio ancora una domanda: ho provato il tuo sorgente javascript sul mio raspberry e funziona perfettamente ma il problema è che dopo molte ore non risponde più ai comandi su telegram e sono costretto a riavviarlo. Secondo te quale potrebbe essere il problema?
Grazie

Reply
luca 25 febbraio 2016 - 20:11

ma il bot resta attivo o si chiude/crasha?

Reply
Davide 26 febbraio 2016 - 17:24

Penso di aver capito il problema ma non so come risolverlo. Capita che la connessione internet cada per un tempo limitato e penso sia questo quello che faccia saltare tutto

Vinicius Fernandes Affonso 4 marzo 2016 - 18:35

i have problem with 1 line bot.js

pi@raspberrypi:~ $ sudo python ~/bot/bot.js
File “/home/pi/bot/bot.js”, line 1
// Authorized users, replace with your real IDs
^
SyntaxError: invalid syntax

Reply
luca 4 marzo 2016 - 20:10

Hi! you’re using the python interpreter while the code runs on node.js

Reply
Vinicius Fernandes Affonso 4 marzo 2016 - 21:06

now its work 😉

Reply
haerul nurdiana 2 aprile 2016 - 17:18

Hi Luca, I have problem
where i can get authorized user ?

Reply
luca 4 aprile 2016 - 07:51

Hi! Run the “userid.js” bot, you can download it from Github. When you write a command to the bot, it outputs on the console your user ID

Reply
jose 20 aprile 2016 - 18:12

Luca, Thanks for the tutorial. I am confused on the polling or webhook. Where is the loop or event polling the telegram server every 2 seconds in the bot.js listing? Or how this works?
Please let me know where can I find details . Thanks in advance !

Reply
luca 21 aprile 2016 - 16:02

Hi Jose, all the interaction between your bot and telegram is performed by the Bot library I’m using, no external code is required.

Reply
jose 22 aprile 2016 - 19:23

Luca Thanks a lot again. I’ve installed on RPI running ArchLinux and works perfect. Only problem the DHT module was not possible to install I’ve tried several times and on the middle of the install the RPI gets extremely slow and almost hungs and I must do hard reset. This is not an issue for me as I do not have that sensor, I will try using the npm for the DS18b20.
Concerning my previous question, then the polling seems to be the default as the script never mentioned it right ?

Reply
willy 28 aprile 2016 - 19:40

Salve trovo molto interessante il suo progetto.
Avrei una domanda, io non sono esperto, sarebbe possibile col bot BotFather, eseguire una operazione di conferma (positiva o negativa), ad una richiesta che arriva su un canale telegram, in cui si chiede di cliccare su SI o NO?
E fare eseguire tale operazione più volte al giorno, e solo quando in quel canale viene richiesta la conferma? In quanto dopo la conferma ritorna sempre un messaggio di sistema di accettazione avvenuta.

Reply
luca 2 maggio 2016 - 07:49

Salve Willy… dipende: se la richiesta è diretta ad un particolare utente no, un BOT non può sostituirsi all’utente. Se invece si tratta di inviare in un canale – a cui il bot è collegato – un messaggio in maniera periodica sì, è possibile.

Reply
Nicola 10 dicembre 2016 - 00:36

Progetto molto interessante, non sono molto esperto ma ho visto che comandare 4 relè è molto semplice editando leggeremente il file. Volevo estendere il controllo a due sensori uno interno DHT 11 e uno esterno DHT 22 è possibile?
Grazie mille.

Reply
luca 11 dicembre 2016 - 17:40

Ciao! Assolutamente sì, ti basta definire due variabili tipo SensorLib e inizializzarle correttamente (indicando il PIN a cui hai collegato i due sensori e il “modello”, quindi 11 e 22)

Reply
Luis M 25 dicembre 2016 - 05:24

Hi, I was testing your code, it was working fine but then I don’t understand why I get this message everytime

home/pi/relaybot/node_modules/node-telegram-bot/lib/Bot.js:221
if (msg.message.text && msg.message.text.charAt(0) === ‘/’) {

Reply
luca 27 dicembre 2016 - 08:51

hi, do you mean that you get an error/warning message on that line?

Reply
Giuseppe Natella 11 maggio 2017 - 22:15

Ciao Luca complimenti, volevo chiederti non capisco come installare le librerie mi daresti un aiuto ne sarei felice grazie

Reply
luca 12 maggio 2017 - 11:29

Ciao Giuseppe, le librerie si installano semplicemente con il comando npm install node-dht-sensor onoff node-telegram-bot

Reply
Giuseppe Natella 12 maggio 2017 - 13:23

Grazie x la risposta rapida ho installato le librerie npm ho creato una cartella in /home/pi ed ho digitato nella cartella npm install node-dht-sensor onoff node-telegram-bot pero mi da degli errori nel installazione tutto da terminale ovviamente putty

Reply
luca 12 maggio 2017 - 15:51

ciao, quali errori ti da? Il tuo Raspberry è collegato ad Internet per scaricare i vari pacchetti?

Reply
Giuseppe Natella 12 maggio 2017 - 19:05

si ho un Raspberry pi 3 è connesso riesce ad installare solo la libreria node-telegram-bot poi con le altre escono err in rosso con descrizione e gyp in rosso, ho seguito alla lettera la tua guida molto dettagliata ma niente dopo ci riprovo perchè sarebbe un peccato non riuscirci perchè mi piace

Reply
Giuseppe Natella 12 maggio 2017 - 19:40

Ciao Luca cmq ho riprovato sle librerie node-telegram-bot onoff sono installate il problema è con
node-dht-sensor non riesce ad installarsi mi da molti errori non posso elecarti ci vorebbe piu spazio

Reply
Giuseppe Natella 13 maggio 2017 - 14:43

Ciao Luca buone notizie sono riuscito ad installare il tutto è funziona il problema erano le librerie node,js e npm ho trovato un link dove ho fatto l’aggiornamento grazie fai nuovi progetti stiamo in attesa ciao.

Reply
marco 15 aprile 2018 - 17:15

Ciao, puoi dirmi come hai risolto? anche io ho il tuo stesso problema e vorrei risolvere.

Grazie mille

Reply
EnricoTV 23 agosto 2017 - 16:45

Ciao Luca,
complimenti per il sito, io invece sono più o meno neofita quindi prima di cimentarmi con il rischio di perdere tempo, vorrei sapere se è fattibile il bot di telegram che ho in mente.
In sostanza ho un sito internet (in realtà è fatto con wordpress) dove siamo in 5 amministratori, vorremmo la possibilità di poter sfruttare un bot telegram che permetta ai visitatori di scriverci da telegram in un gruppo dove siamo tutti e 5 presenti più il visitatore del momento.
A primo avviso si potrebbe pensare che basti un gruppo, ma in realtà non è possibile in quanto se i visitatori fossero più di uno, ognuno vedrebbe quello che scrive l’altro creando enorme confusione.
Il bot in sostanza dovrebbe poter esser sviluppato in due modi:
1- in modo che inoltri tutti i messaggi che il visitatore invia, ad un gruppo dove ci sono i 5 amministratori che rispondendo dal gruppo a sua volta i messaggi vengono inoltrati al visitatore in questione;
2- oppure in modo che crei ogni volta un nuovo gruppo telegram con i 5 amministratori più il visitatore in questione. Poi all’uscita del visitatore però il gruppo dovrebbe eliminarsi (anche se potremmo farlo manualmente ogni volta)
Vorrei sapere se in primis è fattibile e poi quale via più semplice mi consigliate di percorrere (ed il grado di difficoltà che ha).
Grazie infinite,
Enrico

Reply
luca 24 agosto 2017 - 08:58

Ciao Enrico, esistono già diverse soluzioni pronte, una che ho visto usata su diversi siti WordPress è ChatBro

Reply
EnricoTV 25 agosto 2017 - 10:33

Ciao Luca,
avevo già provato ChatBro e purtroppo fa quello che non volevo, crea un gruppo unico tra tutti i visitatori, noi 5 invece abbiamo bisogno che ogni visitatore non veda cosa scrivono gli altri, altrimenti si creerebbe troppa confusione.

Reply

Rispondi a Nicola Cancel Reply

15 + undici =