Com programar un bot de Telegram amb Python

16 de Agosto de 2017 · 11 min de lectura

Logo APSL

Introducció

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.

Programant el nostre primer bot

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:

  1. Envia el missatge /newbot a @BotFather (prèviament t'hauràs d'haver fet un compte a Telegram si encara no el tens).
  2. Et demanarà que li diguis el nom que es mostrarà del bot. Escriu el nom que més t'agradi i prem la tecla d'enviar.
  3. Et demanarà que li diguis un nom d'usuari pel bot, que ha d'acabar en "Bot" o "_bot". Novament, escriu el nom que vulguis i prem la tecla d'enviar.

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 un try/except. Per a més informació consulta la documentació de python.

Com fer quasi qualsevol cosa amb un bot:

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.

Ajuntar diverses funcions

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

¿He de tenir l'ordinador sempre encès per poder utilitzar el bot?

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.

¿Què més pot fer un bot?

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:

  • Recordar-te els esdeveniments del dia: Un bot que t’avisa cada matí dels esdeveniments que tens apuntat al calendari.
  • Ajudar-te a trobar pis: Un bot que es connecta cada dia a una API d’una Inmobiliària / portal web de venda de pisos i t’avisa si troba algun pis amb certes característiques.
  • Avisar-te quan hi ha nous articles del teu interès: Un bot que consumeix RSS i t’avisa quan publiquen un nou article, o que t'avisa quan es publica un nou vídeo al canal de youtube que t’agrada.
  • Predicció del temps: Un bot que t'envia la predicció del temps.
  • Traducció: Un bot que tradueix els texts que li envies.
  • Calcular distàncies entre dos llocs, coordenades, temps de trajecte…: Un bot que fa càlculs geogràfics.
  • Seguiment d’enviament de paquets: Un bot que t'envia un missatge cada dia amb l'estat del teu paquet o al que pots consultar l'estat d'un paquet en un moment determinat.
  • Transport públic: Un bot que prediu el temps que li falta al següent autobús.

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?

Documentació i recursos rellevants:

Comparte este artículo
Etiquetas
Artículos recientes