Implementiamo un bot Telegram in Python per leggere e creare QRCode

telegram qrcode

Ciao a tutti,
questo è il primo articolo che scrivo per questo blog, quindi spero vi piaccia!

Qualche settimana fa, ho scritto un paio di articoli sul mio blog personale su come usare Python per leggere codici a barre dalle immagini, e su come integrare la lettura dei codici a barre all'interno di un bot Telegram.

Gli articoli sono piaciuti molto, e mi è stato chiesto se si potesse implementare codice simile ma per la lettura di QRCode! Da queste richieste è nata l'idea di questo articolo, e mi è sembrata la perfetta occasione per iniziare questa mia collaborazione con Alla fine del Palo!

Cosa faremo

Lo scopo di questo tutorial è quello di sviluppare un bot telegram in grado di leggere e scrivere codici QRcode. Il funzionamento che vogliamo ottenere è il seguente:

  1. Se l'utente manda al una foto, questo cerca all'interno dell'immagine la presenza di un codice QR, e risponde con il contenuto del codice in caso positivo.
  2. Se l'utente invia un testo al bot, questo lo embedda in un codice a barre e ne ritorna il contenuto.

Prerequisiti

Se volete leggere il tutorial senza provarlo, andate pure avanti, cercherò di essere il più chiaro possibile. Tuttavia, se volete riprodurlo da voi, è importante che conosciate (almeno a grandi linee) un paio di tecnologie che utilizzerò qui, e che sono state già ampiamente trattate in questo e nel mio blog.

Sviluppiamo il BOT

Per prima cosa, dobbiamo iniziare a sviluppare il nostro bot! Per fare il setup del progetto, io sono solito instanziare un virtualenv  per tenere il tutto pulito, e quindi installare la libreria telepot  per lo sviluppo di bot Telegram:

Notate che ho creato un ambiente virtuale con Python 3, usando il comando virtualenv -ppython3 env .

A questo punto, creiamo un nuovo file (chiamo ad esempio qr-bot.py ) e implementiamo uno scheletro del bot Telegram.

Questo semplice bot non fa altro che rispondere con la stringa "Sono un bot stupido!"  a qualsiasi messaggio in entrata. Se non sapete esattamente come funziona il codice, o come generare il vostro TOKEN, forse vi conviene prima di tutto dare un'occhiata qui oppure qui!

Lanciamo il bot con il comando  (env)$ python qr-bot.py  per vedere che tutto funzioni! Il risultato dovrebbe essere simile a quello della foto sotto!

Fin qui niente di nuovo, vediamo adesso come usare il bot per leggere e generare QRCode!

Generare codici QRCode

Partiamo dal secondo punto, banalmente perchè è leggermente più semplice, e vediamo come generare QRCode in Python e quindi inviarle a Telegram.

La prima parte è veramente semplice! Infatti, esiste una libreria Python molto semplice da utilizzare per eseguire questa operazione, che si chiama (pensate un po')  qrcode . Dobbiamo inoltre installare la libreria Pillow  per la gestione delle immagini in Python.

Per installarla, digitiamo nella shell di comando

L'utilizzo è altrettanto semplice! Dopo aver importato la libreria con

Per generare un qrcode con all'interno un testo contenuto in una variabile  msg basta instanziare un oggetto QRCode , aggiungerci il messaggio con il metodo  QRCode.add_data() e quindi generare il qrcode con il metodo QRCode.make() .

A questo punto, possiamo generare l'immagine contenente il qrcode con la linea di codice

Il codice è quasi pronto, ma dobbiamo gestire un piccolo intoppo: Telepot non è in grado di inviare (e ricevere) immagini contenute dentro delle variabili, ma lavora direttamente su File. Questo è una piccola scocciatura, perché richiede di leggere e scrivere dati su disco che potrebbero rimanere benissimo in RAM, ma, fortunatamente, Python3 ci viene incontro con una piccola soluzione, che si trova nel modulo standard  io.BytesIO : una libreria che permette di creare oggetti che funzionano come file in Python, ma che vivono all'interno della RAM e non del disco rigido.

Quello che dobbiamo fare, quindi, è generare un oggetto di tipo BytesIO , salvare l'immagine qr_image  all'interno di questo oggetto e saremo pronti a spedirlo con telepot. Il tutto, ricordandoci di importare il modulo io.BytesIO:

Siamo quasi pronti, ma prima mettiamo tutto all'interno di una funzione per migliorare la leggibilità del codice:

A questo punto, possiamo usare il metodo .sendPhoto  del nostro bot Telegram per inviare il qrcode generato! Quello che voglio fare, quindi, è far si che qualsiasi messaggio scritto venga mandato a Telegram sia embeddato bel QRCode. Modifichiamo quindi la funzione handle  in questo modo:

In particolare, nel caso in cui venga inviato un messaggio di tipo testuale ( if content_type == 'text': ) utilizziamo la funzione create_qr_code  appena implementata per generare un'immagine, e quindi la invio con il metodo bot.sendPhoto . Il risultato è mostrato qui sotto. Notate che non abbiamo usare direttamente la libreria Pillow . Tuttavia, questa è chiamata all'interno di qrcode , ma deve essere installata esplicitamente per poter far funzionare il tutto.

Leggere i codici QRCode

La lettura dei codici QRCode funziona in un modo simile, e sfrutta una libraria chiamata pyzbar . Quest'ultima è il wrapper Python di una libreria chiamata zbar , nata inizialmente per la lettura di codici a barre da immagini, ma che si è poi evoluta ed, al momento, include anche i qrcode. Per installarla, dobbiamo prima di tutto installare pyzbar

Ma, se lavoriamo su macOS o Linux, è anche necessario installare manualmente la libreria  zbar con i rispettivi comandi:

Fatto questo, siamo finalmente pronti ad implementare il codice.

Supponiamo di avere foto su file contenente un QRCode ( img_file ), per leggerla in Python, basta eseguire i seguenti comandi

La variabile qrcodes  è una lista contenente un elemento per ogni codice trovato nell'immagine. Un esempio di contenuto è riportato qui sotto:

Come vedete, troviamo nel campo data  il messaggio contenuto nel qrcode, mentre nel campo type , il tipo di codice (in quanto zbar  supporta anche codici a barre e altri tipo di codici).

Notate anche che questa volta usiamo il modulo PIL , che non è altro che la libreria Pillow  installa precedentemente.

Il problema, di nuovo, è passare l'immagine da telepot  a zbar . E anche stavolta ci viene d'aiuto il modulo BytesIO .

Implementiamo quindi una funzione che, a partire da un messaggio msg in telepot , scarica l'immagine con il metodo .download_file  e poi la analizza. Come sopra, invece che caricare l'immagine su file, sfruttiamo BytesIO  per salvarla su una variabile chiamata raw_img , e quindi apriamo questa immagine come se fosse un file e passiamola alla funzione decode  di pyzbar

A questo punto, non ci resta che usare questa funzione all'interno della funzione handle  del bot

In questo caso, se il  messaggio mandato è una foto, uso la funzione read_qrcodes  per leggere eventuali qrcode, e invio il contenuto codificato all'utente. Se non trovo qrcode, viene mandato il messaggio "Non ho trovato QRCode nella foto..." .

Il risultato è il seguente.

 

Conclusioni

Spero che il tutorial sia utile a qualcuno. Per dovere di cronaca, vi informo che è stato testato su un Mac con sistema operativo macOS 10.13 High Sierra! Se qualcuno lo prova su un altro tipo di sistema, mi faccia sapere se va liscio o se ci sono dei problemi!

Vi lascio il codice completo qui sotto:

 

Smanettone dai tempi delle medie, quando ancora la parola “Maker” non esisteva, è un super appassionato di Robnotica, Computer Vision e Programmazione (con un occhio speciale verso il Python). Gli hanno dato un Ph.D. in Robotica, ma probabilmente era uno scherzo!

Ha una startup, HotBlack Robotics, che si occupa di robotica di servizio!

Implementiamo un bot Telegram in Python per leggere e creare QRCode ultima modifica: 2018-02-22T11:11:07+00:00 da Ludovico Russo


Advertisment ad adsense adlogger