Contenuti

Python, Fritz e l'elfo - parte 2

La situazione attuale è questa: c’è uno script che gira ogni 5 minuti, controlla l’ip della connessione esterna e se ci è stato dato un IP non pubblico, richiede una riconnessione.

Ma l’elfo non era soddisfatto: non c’è nessun feedback! Bisognava trovare un modo per comunicare che il provider ci ha costretti a lanciare una riconnessione…

Una volta avrei risolto con una bella email, ma insomma, siamo nel 2016 e l’email fa troppo vecchio. Ci vuole un servizio più istantaneo, come una chat. Da poco è stata inaugurata l'interfaccia API di Telegram e la possibilità di creare dei bot. L’elfo annuisce e io so cosa fare.

Le api sono facilmente richiamabili da script, basta avere un “token”, ovvero una stringa di testo che il suddetto script deve presentare ad ogni interazione con le api.

BOT revolution

Quindi prima di tutto bisogna creare un BOT ed ottenere un token. Per fare questo, dal proprio account Telegram si inizia una chat con “BotFather”, perché ci vuole un bot per fare un bot. Nella chat basta scrivere:

  /newbot

Alright, a new bot. How are we going to call it? Please choose a name for your bot.

 Whatever

Good. Now let’s choose a username for your bot. It must end in ‘bot’. Like this, for example: TetrisBot or tetris_bot.

 whateverbot

Done! Congratulations on your new bot. You will find it at telegram.me/whateverbot.You can now add a description, about section and profile picture for your bot, see /help for a list of commands. By the way, when you’ve finished creating your cool bot, ping our Bot Support if you want a better username for it. Just make sure the bot is fully operational before you do this.

Use this token to access the HTTP API:

18698123748978954278973894U

For a description of the Bot API, see this page: https://core.telegram.org/bots/api

Ora abbiamo un token. Ora il nostro script può essere autorizzato a comunicare a nome del bot.

Approccio a Telegram

Esiste un bel progetto per far parlare il mio script in Python con Telegram: telepot. Andiamo ad installarla:

pip install telepot

Il prossimo passo è capire il destinatario dei messaggi. Dall'homepage di Telepot scarichiamo ed eseguiamo questo script:

 1#!/usr/bin/python
 2import sys
 3import time
 4import pprint
 5import telepot
 6
 7def handle(msg):
 8 pprint.pprint(msg)
 9 # Do your stuff here ...
10
11# Getting the token from command-line is better than embedding it in code,
12# because tokens are supposed to be kept secret.
13TOKEN = sys.argv[1]
14
15bot = telepot.Bot(TOKEN)
16bot.message_loop(handle)
17print ('Listening ...')
18
19# Keep the program running.
20while 1:
21 time.sleep(10)

Eseguendo questo script (passare il token come parametro della linea di comando), il nostro bot diventerà un semplice “echo-test”: ripeterà ogni messaggio ricevuto. Premere ctr+c per interrompere l’esecuzione del bot. Lo scopo è di inviare una notifica a me e solo a me quando c’è un evento, ignorando qualsiasi testo io possa rispondere ed ignorando eventuali altri utenti. Aggiungiamo quindi un paio di righe nella funzione che gestisce i messaggi:

content_type, chat_type, chat_id = telepot.glance(msg)
pprint.pprint(chat_id)

Avviamo lo script e mandiamo un messaggio qualsiasi al bot. In questo modo otteniamo l’identificativo della chat tra noi e il bot.

Mettiamo mano al nostro script

Ecco quindi lo script aggiornato:

 1#!/usr/bin/python
 2from fritzconnection import FritzConnection
 3import telepot
 4import re
 5
 6fritzpass = 'lamiapassworddelrouter'
 7connection = FritzConnection(password=fritzpass)
 8chatid = 83889898329823
 9bottoken = '18698123748978954278973894U'
10ip = connection.call_action('WANPPPConnection', 'GetInfo')['NewExternalIPAddress']
11bot = telepot.Bot(bottoken)
12match = re.search('^100\.', ip)
13if match:
14  bot.sendMessage(chatid, 'Siamo stati nattati! Disconnetto temporaneamente...')
15  connection.reconnect()

Conclusione

Ok, mettere l’id della chat fisso nello script non è esattamente una soluzione elegante, ma per ora è sufficiente.