16 de Agosto de 2017 · 11 min de lectura
En aquest article explicarem amb exemples com fer un xat bot amb Telegram sense necessitat de tenir molts de coneixements tècnics. Amb uns coneixements bàsics de Python o d’un altre llenguatge de programació no hauria de ser difícil seguir l'explicació.
Què és un xat bot?
Un bot és un programa informàtic que efectua tasques repetitives automàticament a través d’Internet, i un xat bot, més concretament, és aquell bot capaç de respondre a un xat de forma automàtica.
Com ens pot ajudar?
Un xat bot pot enviar-te missatges sense interacció, com enviar-te un missatge cada matí amb la predicció del temps, o amb enllaços als continguts nous d’una web en concret, però també és possible que respongui als teus missatges, o inclús que donades certes circumstàncies t’avisi.
Bots de Telegram
Telegram és una aplicació de missatgeria instantània (xat) gratuïta nascuda a l’estiu del 2013 que compta amb una part del codi (la part de client) alliberada com a Open Source i que compta amb aplicacions d'escriptori, web i mòbil. L’estiu del 2015 va lliurar una plataforma en forma d’API perquè qualsevol desenvolupador pogués crear bots i damunt aquesta API han aparegut moltes llibreries en diferents llenguatges que en faciliten l’ús. Per realitzar els exemples utilitzarem la llibreria python-telegram-bot, però en realitat existeixen alternatives escrites amb Python (aquí i aquí), JavaScript+node, PHP o fins i tot Go.
Preparatius previs:
Notes: És recomanable (però no necessari) instal·lar les dependències dins d’un entorn virtual. Pots trobar més informació a la documentació de virtualenv. Per instal·lar les dependències utilitzarem l'eina anomenada pip i per programar el bot utilitzarem la versió 3.5 de Python, encara que la llibreria python-telegram-bot permet utilitzar Python des de la versió 2.7.
Per poder utilitzar i programar el bot de Telegram hem d’instal·lar la llibreria python-telegram-bot. Pots trobar com fer-ho a la web del projecte, però bàsicament es resumeix en executar: pip install python-telegram-bot
al terminal.
Abans de poder utilitzar un bot l'hem de donar d'alta i obtenir un token que identifiqui el nostre bot. La forma d'obtenir aquest token i crear el bot és bastant divertida, perquè implica interactuar amb un bot de Telegram anomenat The BotFather.
Per fer-ho segueix les següents passes:
/newbot
a @BotFather (prèviament t'hauràs d'haver fet un compte a Telegram si encara no el tens).Al missatge que rebràs hi trobaràs un token, que no és més que un conjunt de lletres, números i símbols. Guarda aquest token perquè aviat el necessitaràs. El BotFather permet realitzar altres accions com establir una imatge de perfil pel bot o una descripció. Si vols saber-ne detalls, escriu /help
.
"Hello Bot"
El primer bot que programarem serà un que senzillament respon a una cridada nostra. Així doncs, quan escriguis /saluda
el bot et contestarà "Sóc aquí :)" de tal forma que podràs verificar la connexió entre el bot i tu. Aquí tens el codi necessari:
python
from telegram.ext import Updater, CommandHandler
updater = Updater(token='AQUI HI VA EL TEU TOKEN')
dispatcher = updater.dispatcher
def saluda(bot, update):
missatge = 'Sóc aquí :)'
bot.send_message(chat_id=update.message.chat_id, text=missatge)
saluda_handler = CommandHandler('saluda', saluda)
dispatcher.add_handler(saluda_handler)
updater.start_polling()
Amb només 9 línies de codi hem construït un amic que ens contestarà quan el cridem. Aquest codi és la base de tots els bots de Telegram i pots utilitzar-lo com a plantilla.
Vegem què fa cada línia de codi:
[lín. 1] Importem Updater
i CommandHandler
de la llibreria python-telegram-bot
.
[líns. 3-4] Creem una instància de l'Updater (l' "actualitzador") utilitzant el token, i per facilitar la lectura del codi assignem el seu dispatcher a la variable dispatcher
.
[líns. 6-8] Definim una funció amb el nom que desitgem (en aquest cas saluda()
) que rebrà dos paràmetres bot i update. Aquesta funció és la que guarda el comportament que desitgem. Si volem que envii un missatge de text, hem d'escriure una línia del tipus bot.send_message(chat_id=update.message.chat_id, text=missatge)
, on especificarem el missatge a la variable text
. Per cada comportament que vulguem afegir al bot haurem de crear una funció semblant a aquesta.
[lín. 10] Utilitzam el CommandHandler
per associar la funció amb la paraula que desitgem (en aquest cas hem escollit la paraula 'saluda'
).
[lín. 12] Afegim el handler al dispatcher.
[lín. 14] Fem que el bot (en concret l'updater) es posi en funcionament.
En qualsevol cas, qualsevol bot tindrà la mateixa estructura. L'únic punt realment important són les funcions que hi afegim (com la funció saluda()
), que permetran dotar de comportament al nostre bot.
Per comprovar que el codi funciona guarda el seu contingut dins d'un arxiu bot.py (afegint-hi el teu token que t'ha facilitat el BotFather) i executa'l mitjançant el terminal amb python3 bot.py
.
Ara obri el xat amb el teu bot (pots fer-ho prement el nom del nou bot al xat de BotFather) i escriu: /saluda
. El resultat hauria de ser semblant al següent:
Si has arribat fins aquí: Enhorabona! Ja tens el teu primer bot i la base per tot el que vulguis fer.
"Hello Bot" amb el nom que desitgis
És possible que vulguem demanar una cosa al nostre bot passant-li alguna informació addicional perquè elabori la seva resposta. A continuació expliquem un exemple senzill i clàssic: saludar amb un nom.
El codi necessari és el mateix que l'anterior afegint el paràmetre args
a la funció, corregint el text, i afegint el paràmetre pass_args=True
quan instanciam el CommandHandler
.
python
from telegram.ext import Updater, CommandHandler
updater = Updater(token='AQUI HI VA EL TEU TOKEN')
dispatcher = updater.dispatcher
def saluda_nom(bot, update, args):
missatge = 'Hola '+args[0]+'!'
bot.send_message(chat_id=update.message.chat_id, text=missatge)
saluda_nom_handler = CommandHandler('saluda_nom', saluda_nom, pass_args=True)
dispatcher.add_handler(saluda_nom_handler)
updater.start_polling()
La variable args
és una llista de les paraules que s'han escrit tot just després de /saluda_nom
. Per accedir a aquestes paraules, amb Python, podem fer-ho directament així: args[0]
, args[1]
, etc. recordant que el primer element és l'element 0
.
Pots provar d'executar el fitxer i enviar-li un missatge com /saluda_nom Marc
i el resultat hauria de ser semblant a aquest:
Nota: Per evitar errors convindria controlar el cas de
IndexError
amb untry
/except
. Per a més informació consulta la documentació de python.
Bot que interacciona amb el món exterior
Per augmentar considerablement les possibilitats dels bots (i fer-les quasi infinites), és possible integrar-los amb altres serveis i connectar-los a APIs web.
Per explicar-ho breument, les API, de l’anglès Application Programming Interface, són un conjunt de normes i mètodes definits de forma abstracta que permeten que diferents components de software es puguin comunicar sense haver de conèixer els detalls d’implementació dels altres. En el cas de les APIs web, es basa en enviar un missatge HTTP amb paràmetres i rebre una resposta en un format fàcil d’interpretar per un programa informàtic (com un arxiu json o un xml).
Les APIs poden ser públiques o privades i poden ser gratuïtes o de pagament, però afortunadament moltes de les plataformes més comunes compten amb APIs web públiques i gratuïtes que podràs utilitzar amb poques restriccions: Twitter, Google Maps, Google Analitycs, Facebook, Youtube, LinkedIn, Amazon, Flickr, Pinterest, Kayak, FedEx...
Per facilitar la tasca de connectar-se a una API resulta molt útil una llibreria de Python anomenada requests. L'haurem d'instal·lar mitjançant l'ordre: pip install requests
.
Exemple de connexió a una API:
python
import requests
def obtenir_equivalencia(quantitat, divisa_entrada, divisa_sortida):
url = "http://api.fixer.io/latest"
p = {"base": divisa_entrada}
resposta = requests.get(url, params=p)
tipus_canvi = resposta.json()
equivalencia = tipus_canvi["rates"][divisa_sortida]
total = float(equivalencia) * float(quantitat)
resultat = str(quantitat)+" "+divisa_entrada+" equival a: "+str(total)+" "+divisa_sortida
return resultat
L'estructura, en el cas d'aquelles APIs web que no necessiten cap tipus d'autorització, sempre és similar. Pots usar aquest codi com a base per fer els teus.
L'explicació del codi és la següent:
[lín.1] Importem la llibreria requests.
[lín. 3] Comencem a definir la funció, que prendrà 3 paràmetres: la quantitat, la divisa d'entrada i la divisa de sortida.
[lín. 4] Definim la URL a la que farem la petició.
[lín. 5] definim els paràmetres en forma de diccionari Python.
[líns. 7-8] Realitzem la petició i acte seguit parsejam la resposta a tipus json.
[lín. 10] Obtenim el camp que volem utilitzar accedint al json com si fos un diccionari.
[lín. 12] Realitzem les operacions que considerem adients.
[líns. 13-14] Retornem el resultat, en aquest cas és una cadena de texte (ja que el voldrem enviar-la com a missatge per Telegram).
Per provar-ho guarda el codi a un arxiu anomenat divises.py, al mateix directori que l'arxiu bot.py, i afegeix canvia el codi de l'arxiu bot.py perquè quedi de la següent manera:
python
from telegram.ext import Updater, CommandHandler
from divises import obtenir_equivalencia
updater = Updater(token='AQUI HI VA EL TEU TOKEN')
dispatcher = updater.dispatcher
def conversio(bot, update, args):
missatge = obtenir_equivalencia(args[0], args[1], args[2])
bot.send_message(chat_id=update.message.chat_id, text=missatge)
conversio_handler = CommandHandler('conversio', conversio, pass_args=True)
dispatcher.add_handler(conversio_handler)
updater.start_polling()
Executa l'arxiu bot.py mitjançant python3 bot.py
i prova d'introduir al xat /conversio 1 EUR USD
. El bot es respondrà amb l'equivalència:
Nota: Aquesta API accepta les següents divises: AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, GBP, HKD, HRK, HUF, IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, NZD, PHP, PLN, RON, RUB, SEK, SGD, THB, TRY, ZAR, EUR.
Evidentment, un bot pot realitzar més d'una funció. El codi resultant d'ajuntar les tres funcions en un sol bot (una mica refactoritzat) seria el següent:
python
from telegram.ext import Updater, CommandHandler
from divises import obtenir_equivalencia
updater = Updater(token='AQUI HI VA EL TEU TOKEN')
dispatcher = updater.dispatcher
def saluda(bot, update):
missatge = 'Sóc aquí :)'
bot.send_message(chat_id=update.message.chat_id, text=missatge)
def saluda_nom(bot, update, args):
missatge = 'Hola '+args[0]+'!'
bot.send_message(chat_id=update.message.chat_id, text=missatge)
def conversio(bot, update, args):
missatge = obtenir_equivalencia(args[0], args[1], args[2])
bot.send_message(chat_id=update.message.chat_id, text=missatge)
handlers = [CommandHandler('saluda', saluda),
CommandHandler('saluda_nom', saluda_nom, pass_args=True),
CommandHandler('conversio', conversio, pass_args=True)]
for handler in handlers:
dispatcher.add_handler(handler)
updater.start_polling()
Pots descarregar el codi del bot al següent enllaç:
https://github.com/noviluni/telegram-bot-example
La resposta és sí i no. No és necessari si comptes amb un servidor o algun sistema capaç d'executar codi Python connectat sempre a la xarxa com un NAS, una Raspberry Pi, etc.. Si estàs interessat en el tema dels servidors i vols saber quin utilitzar, pots consultar aquest apartat de la documentació de python-telegram-bot on donen diverses alternatives per hospedar un bot de Telegram: Where to host Telegram Bots.
Els bots de Telegram es poden programar perquè enviïn missatges a una determinada hora, perquè si envies un text amb una paraula determinada reaccionin o fins i tot pots fer que enviïn una imatge o un arxiu de so.
Per aprofundir-ne més és recomanable visitar la documentació de la llibreria python-telegram-bot.
Idees i recursos per fer bots:
En el moment en què connectes un bot a una API web les possibilitats es disparen. Aquí pots veure algunes idees que són totalment factibles de fer:
A més, per totes aquelles webs que no compten amb una API pública, és possible utilitzar scraping. Pots introduir-t'hi investigant les següents llibreries de Python: Beautiful Soup, Scrapy i Selenium.
Arribat a aquest punt, un bot de Telegram pot, fins i tot, enviar-te imatges fruit d'una interacció amb un sistema d'intel·ligència artificial o enviar-te missatges de veu generats amb una API de text to speech.
Per obtenir més idees de bots i per veure el que ha fet la comunitat pots visitar la Telegram Bot Store.
Ús de bots de Telegram a APSL
Actualment a APSL utilitzem diferents bots. Un d’ells ens diu cada matí “bon dia”, ens avisa quan falten 15 minuts perquè tanquin els menús, ens avisa a l’hora de dinar i reacciona davant certs comentaris, recordant alguna anècdota graciosa. Per altra part, tenim un altre bot amb el qual fem una llista de tots els que volem anar a un determinat lloc a dinar. Cada dia ens mostra el menú i afegint senzillament “+1”, ens apunta a la llista.
Ben contrari al que pot parèixer, els bots de Telegram no ens distreuen, sinó que ens permeten estar concentrats, perquè sabem que quan sigui hora d'anar a dinar ens avisarà.
Moltes gràcies per haver llegit fins aquí! Esperem que ara no tingueu cap excusa per fer un bot a casa (i de pas, vos animem a aprendre més Python). Si teniu cap dubte o necessiteu ajuda podeu fer un comentari i intentarem ajudar-vos tot el que puguem.
I a tu... se t'acut alguna idea de bot interessant que se'ns hagi passat per alt?