Nuova sezione libri disponibile!

I chatbot possono Parlare? Sviluppiamo un bot telegram che manda messaggi vocali

Ludovico Russo

lettura in 5 minuti

In un precedente Articolo ho utilizzato le API messe a disposizione da Google per la sintesi vocale. In particolare, in quell'articolo abbiamo visto come usare gTTS per generare file vocali a partire da una stringa di testo.

In questo articolo, vediamo come utilizzare questa funzionalità per fare in modo che sia un bot Telegram ad inviare, tramite messaggio vocale, l'output delle API gTTS.

Configurare il tutto

Ormai non vi sto a tediare sulla fase di configurazione. Ricordiamoci però di creare un ambiente virutale (in Python 3) e di installare i pacchetti Telepot e gTTS, come visto nei miei precedenti tutorial.

Prima di cominciare, però, vi propongo una best practice molto veloce per configurare il bot telegram (ed in particolare il Token), di cui non vi ho mai parlato ma che sto utilizzando molto.

Creiamo, per inizializzare il bot, due file: bot.py che conterrà il nostro bot vero e proprio ed un file config.py, in cui andremo ad inserire tutte le informazioni di configurazione (nel caso di bot semplici, solo il TOKEN), in modo che queste siano facilmente reperibili.

Il file di configurazione, quindi, avrà la seguente forma:


# config.py

TOKEN = "*** inserisci il tuo token qui ***"

A questo punto, nel bot principale, non dovremo far altro che importare config e usare config.TOKEN. Questo semplifica di tanto la vita nel momento in cui il progetto diventa grande e servono altre variabili di configurazione, o quando volete tenere lo scheletro del vostro progetto ed utilizzarlo con diversi TOKEN.

Primo test: messaggio vocale statico

Per prima cosa, implementiamo un semplice bot che sia in grado di inviare, come messaggio vocale, un file audio generato precedentemente da noi, come visto nel tutorial precedente. Nel mio caso, utilizzerò il file saluti.mp3.

Spostiamo il file nella stessa cartella in cui si trova il robot. A questo punto, possiamo utilizzare il metodo .sendVoice() che telepot mette a disposizione, la cui funzione è molto simile al classico .sendMessage(), con l'unica differenza che il primo prende in ingresso un oggetto di tipo file invece che un stringa, ed invia un messaggio vocale con il contenuto di questo file.

Per utilizzarlo, andiamo ad implementare un semplicissimo bot (riprendo l'esempio del mio primo articolo sul tema), come di seguito:

# file bot.py

import config
import telepot
import io

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)
    if content_type == 'text':
        bot.sendMessage(chat_id, 'ciao, sono un bot molto stupido!')
        bot.sendMessage(chat_id, 'Ma so mandare messaggi vocali!')
        with open('saluti.mp3', 'rb') as file:
            bot.sendVoice(chat_id, file)


bot = telepot.Bot(config.TOKEN)
bot.message_loop(on_chat_message)

import time
while True:
    time.sleep(10)

In particolare, le linee di codice che contengono novità sono queste:

# file bot.py

# ...
def on_chat_message(msg):
        # ...
        with open('saluti.mp3', 'rb') as file:
            bot.sendVoice(chat_id, file)

# ...

Queste due linee aprono il file saluti.mp3 e lo caricano il lettura nell'oggetto file, che poi viene inviato tramite bot.sendVoice(chat_id, file) all'utente.

Il risultato è mostrato in figura:

Pirmo Messaggio Vocale

Generare messaggi dinamicamente

A questo punto, non ci resta che generare messaggi vocali in modo dinamico, per rendere pi√Ļ interattivo il robot. Per farlo, dobbiamo sfruttare la libraria gTTS come visto qui.

Il modo pi√Ļ semplice per farlo √® il seguente:

  1. Generare un file audio e salvarlo su disco,
  2. Leggere il file da disco ed inviarlo tramite .sendVoice()

Tuttavia in questo caso abbiamo un overhead non indifferente per la lettura e consequenziale scrittura su disco, inoltre, nel caso il bot venga lanciato in modalit√† multithread per la gestione di molti utenti, la gestione contemporanea di due (o pi√Ļ) utenti potrebbe creare problemi, in quanto andrebbero a scrivere contemporaneamente sullo stesso file. Per questo motivo, la soluzione migliore √® quello di gestire il tutto in RAM.

Ho già discusso questo problema in alcuni miei precedenti posto:

  1. Nel post Sviluppiamo un bot Telegram che legge i codici a barre degli alimenti ho discusso il problema inverso (che si risolve allo stesso modo), in cui l'utente invia un file (in quel caso un'immagine) al bot, e questo deve processare l'immagine senza salvarla su disco.
  2. Nel mio posto Implementiamo un bot Telegram in Python per leggere e creare QRCode ospitato nel blog Alla Fine del Palo, ho discusso di un problema simile per la creazione e l'invio di immagini da parte del bot verso l'utente.

La soluzione, come già visto, è sfruttare la libraria io di Python3, ed in particolare l'oggetto BytesIO, che non fa altro che emulare un file gestito completamente in memoria RAM, quindi come una normale variabile.

Per farlo, implementiamo una funzione in grado di creare un file audio e salvarlo dentro una variabiale di tipo BytesIO:

# ...
import io
from gtts import gTTS

def generate_vocal_msg(text):
    tts = gTTS(text=text, lang="it")
    vocal_file = io.BytesIO()
    tts.write_to_fp(vocal_file)
    vocal_file.seek(0)
    return vocal_file

# ...

Come vedete, questa funzione prende una stringa text e la converte in voce sintetizzata tramite la libraria gtts. La novità è che, una volta ottenuto l'oggetto tts, sfruttiamo il metodo write_to_fp per salvare i dati all'interno di un oggetto di tipo file. Questo oggetto è vocal_file, che è proprio un simil-file creato da io.BytesIO.

Per ultimo, è nessario "riavvolgere" l'oggetto vocal_file create tramite il metodo vocal_file.seek(0), in questo modo, chi lo leggerà lo vedrà dall'inizio, come se fosse stato appena aperto.

A questo punto, possiamo utilizzare la funzione generate_vocal_msg per generare dinamicamente il nostro messaggio vocale. Nel semplice esempio di seguito, converto in vocale il messaggio che arriva dall'utente:

# ...

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)
    if content_type == 'text':
        bot.sendMessage(chat_id, 'ciao, sono un bot molto stupido!')
        bot.sendMessage(chat_id, 'Ma so mandare messaggi vocali!')
        bot.sendMessage(chat_id, 'Ecco, ti leggo cosa hai scritto:')
        bot.sendVoice(chat_id, generate_vocal_msg(msg['text']))

# ...

Proviamo quindi il bot, vedrete che sarà in grado di "leggere" quello che gli scrivete! Provare per credere!!

Invio messaggio dinamicamente

Conclusioni

Come pensate possa essere utilizzata in modo utile questa capacità dei bot di generare messaggi vocali? Ditemelo nei commenti.

Intanto, trovate sotto il codice completo che ho sviluppato!

# file bot.py

import config

import telepot
import io
from gtts import gTTS


def generate_vocal_msg(text):
    vocal_file = io.BytesIO()
    tts = gTTS(text=text, lang="it")
    tts.write_to_fp(vocal_file)
    vocal_file.seek(0)
    return vocal_file

def on_chat_message(msg):
    content_type, chat_type, chat_id = telepot.glance(msg)
    if content_type == 'text':
        bot.sendMessage(chat_id, 'ciao, sono un bot molto stupido!')
        bot.sendMessage(chat_id, 'Ma so mandare messaggi vocali!')
        bot.sendMessage(chat_id, 'Ecco, ti leggo cosa hai scritto:')
        bot.sendVoice(chat_id, generate_vocal_msg(msg['text']))


bot = telepot.Bot(config.TOKEN)
bot.message_loop(on_chat_message)

import time
while True:
    time.sleep(10)

Ti è piaciuto questo post?

Registrati alla newsletter per rimanere sempre aggiornato!

Ci tengo alla tua privacy. Leggi di pi√Ļ sulla mia Privacy Policy.

Ti potrebbe anche interessare

HB Cloud Tutorial #1 - Uso dei Led
Iniziamo ad utilizzare la piattaforma di Cloud Robotics
HB Cloud Tutorial #2 - Uso dei Bottoni
Rieccomi con il secondo tutorial legato all'uso dei bottoni per il robot **DotBot-ROS**. In questo tutorial, vedremo come configurare ed utilizzare in Python un bottone attaccato ad un pin GPIO del Raspberry Pi 3.
HB Cloud Tutorial #3 - I Motori
I Motori sono una delle parti essenziali dei robot. In questo tutorial, vederemo come è possibile in modo semplice ed intuitivo implementare un programma in Python che controlla i motori in base a comandi inviati via Wifi al Robot.
Inviare Goals alla Navigation Stack - versione nodo ROS Python
Inviare un goal all ROS navigation stack utilizzando un nodo Python
Controllare siBOT dalla piattaforma HBR
Come controllare il manipolatore siBOT utilizzando la piattaforma HBR
Sviluppare un rilevatore di fiamma con la visione artificiale
Sviluppare un rilevatore di fiamma con la visione artificiale
Scriviamo un Blog in Python e Flask
Tutorial su come implementare, a partire da zero, un blog personale utilizzando Python e Flask! Prima parte!
Un laboratorio di Fisica con Arduino e Python
Primi esperimenti con Arduino e Python per realizzare un semplice laboratorio di fisica sfruttando la potenza di Python e la versatilità di Arduino
Canopy: una Pythonica alternativa a Matlab
Presento questo interessante tool python che può essere considerato una buona alternativa a Matlab per l'analisi dei dati!
Spyder, un'altra alternativa in Python a Matlab
Una velocissima prova del tool interattivo Spyder per l'analisi scientifica in Python
Simuliamo il moto parabolico in Python e Spyder
Un piccolo tutorial per iniziare ad utilizzare Spyder con Python
Python + Arduino = Nanpy
Programmare Arduino in Python con Nanpy
Utilizzo di Nanpy con il sensore di temperatura/umidità della famiglia DHT
Come utilizzare Nanpy col sensore DHT di temperatura e Umidità
Accendere led con Arduino e Telegram
Un bot telegram in grado di controllare Arduino realizzato da 3 ragazzi del Liceo Stampacchia
Implementiamo un bot Telegram con Python
Una semplice guida per iniziare a muovere i primi passi nello sviluppo di chatbot Telegram con Python
Pillole di Python: pyscreenshot
Una semplice tutorial che mostra il funzionamento della libreria pyscreenshot
Python Decorators
Introduzione ai decoratori in Python
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 1
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Implementiamo un bot Telegram con Python - I Comandi
Vediamo come gestire i comandi del nostro bot in Telegram
4 (+1) Libri su Python (in Inglese) da cui imparare
Una lista di libri su Python (in Inglese) da cui ho imparato a programmare
Virtualenv: gestiamo meglio le dipendenze in Python
A cosa servono e come si utilizzano i virtualenv Python
Leggere i codici a barre con OpenCV e zbar in Python
Come usare Python per leggere i codici a barre degli alimenti e ricavarne alcune informazioni utili
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 2
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Sviluppiamo un bot Telegram che legge i codici a barre degli alimenti
Implementiamo un bot Telegram in grado di leggere ed analizzare le immagini per la lettura ed interpretazione dei codici a barre
TDD con Flask e PyTest per lo sviluppo di API REST. Parte 3
Tutorial su come usare il Test Driver Development (TDD) con Flask e PyTest per sviluppare delle semplici API REST
Divertiamoci sviluppando UI da terminale con ASCIIMATICS
Le UI da terminale fanno molto anni '80, però sono sempre diventerti da implementare. Oggi vi voglio introdurre ad una semplice libreria per creare questo tipo di applicazione.
Sviluppiamo un Robot con tecnologie Open Source
Inizio una serie di videoguide, in cui voglio introdurvi al mondo della robotica di servizio in modo pratico, facendo vedere come è possibilile, sfruttando tecnologie completamente Open Source, quali Arduino, Raspberry Pi, ROS e Docker, costruire un piccolo robot di Servizio.
Parliamo come GMaps: come creare file audio con gtts (Google Text to Speech) in Python
gtts è una libreria in Python per sfruttare le API di Google Text to Speech per generare file audio dal testo
Robot Open Source - Introduzione a Docker
√ą disponibile il video "Introduzione a Docker".
Robot Open Source - Docker e Raspberry
√ą disponibile il video "Docker e Raspberry".
Un bot telegram che invia messaggi al verificarsi di eventi sui GPIO del Raspberry Pi
Mandare un messaggio tramite telegram quando il un GPIO del Raspberry cambia stato è possibile, ecco come!