Oggi vogliamo creare un Bot Telegram che invia frasi motivazionali ogni ora utilizzando un LLM locale. Funziona su Windows, Linux o macOS con almeno 8GB RAM per modelli base. Per fare ciò abbiamo bisogno di:
- installare Ollama;
- scaricare e configurare un modello LLM;
- creare un bot su Telegram tramite BotFather;
- creare un ambiente Python virtuale con le librerie necessarie.
Questo approccio garantisce privacy totale poiché tutto avviene localmente sul tuo computer, senza dipendere da API cloud. Di seguito, una guida dettagliata passo-passo per principianti, con codice completo e spiegazioni su come e perché ogni componente funziona.
Ollama: configurazione e scelta del modello
Windows
Per installare Ollama su Windows puoi scaricare l’eseguibile EXE da qui, oppure puoi aprire PowerShell e digitare:
irm https://ollama.com/install.ps1 | iex
Linux
Per installare Ollama su un sistema operativo Linux, quello che devi fare è aprire il terminale e digitare:
curl -fsSL https://ollama.com/install.sh | sh
macOs
Per installare Ollama su un sistema operativo macOs hai tre modalità differenti:
- puoi scaricare il file dmg da qui
- puoi aprire il terminale e digitare
curl -fsSL https://ollama.com/install.sh | sh
- puoi aprire il terminale e digitare la formula di Homebrew
brew install ollama
Bisogna precisare che richiede macOs 14 Sonoma o le versioni successive.
Scegliamo il modello
La selezione del modello linguistico dipende dalle risorse hardware disponibili, specificamente dalla RAM di sistema e dalla VRAM della GPU. L’utilizzo di modelli sovradimensionati rispetto all’hardware causa latenze incompatibili con l’esecuzione asincrona dello script.
Viene riportata di seguito una tabella che aiuta a chiarire come bisogna orientarsi nella scelta del modello in base all’hardware a nostra disposizione (RAM, VRAM):
| Parametri del Modello | RAM/VRAM Minima | Modelli Ollama Compatibili | Destinazione Hardware |
| < 3 Miliardi (3B) | 4 GB | phi3, gemma:2b, qwen:1.8b | Sistemi con risorse limitate, esecuzione in background a basso impatto. |
| 7 – 8 Miliardi (7B-8B) | 8 GB | llama3, mistral, gemma:7b | PC standard. Bilanciamento tra velocità di inferenza e coerenza del testo. |
| 13 – 14 Miliardi (13B) | 16 GB | qwen:14b, llama2:13b | Workstation o architetture con memoria unificata (es. Apple Silicon). |
| 30+ Miliardi (30B+) | 32+ GB | llama3:70b, mixtral | Hardware server o configurazioni multi-GPU. |
Per frasi motivazionali in italiano, mistral produce risultati molto naturali. Se la macchina ha poca RAM, llama3.2:3b (versione 3 miliardi di parametri) è un ottimo compromesso qualità/velocità e gira in meno di 2 secondi anche su CPU.
Procedura di download
Ollama gestisce l’acquisizione dei modelli tramite interfaccia a riga di comando (CLI). Per scaricare i pesi del modello nel sistema senza avviare l’inferenza, bisogna eseguire nel terminale il comando:
ollama pull <nome_modello>
Ad esempio, se volessimo usare il modello di Mistral, dovremmo usare il comando:
ollama pull mistral
Per scaricare il modello (se non già presente sul nostro sistema) e allocarlo immediatamente in memoria, allora dobbiamo utilizzare il comando:
ollama run <nome_modello>
Telegram: come si crea un bot?
Per creare un Bot con BotFather devi seguire questi passaggi:
- Avvio di BotFather: Cerca
@BotFathernella barra di ricerca di Telegram e avvia la conversazione premendo il tasto Avvia o inviando il comando/start. - Creazione del bot: Invia il comando
/newbot. - Assegna un nome al bot: Inserisci il nome visualizzato del bot (es. Frasi Motivazionali). Questo nome può essere modificato in seguito e può contenere spazi.
- Scelta dello username: Inserisci lo username univoco del bot. Deve terminare obbligatoriamente con la parola
bot(es. FrasiMotivazionali_bot). Non può contenere spazi. - Archiviazione del Token: BotFather genererà un HTTP API Token, una stringa alfanumerica che bisogna necessariamente copiare e salvare; è necessaria per autenticare il bot e connetterlo a script o piattaforme esterne.
- Configurazione opzionale: Utilizza i comandi
/setdescriptionper la biografia del bot,/setuserpicper caricare un’immagine del profilo o/setcommandsper definire la lista dei comandi rapidi.
Python – Sporchiamoci le mani
Prerequisiti:
Devi avere installato Python (versione 3.10 o superiore) sul tuo computer. Se non ce l’hai, scaricalo dal sito ufficiale e installalo seguendo le istruzioni.
Prepariamo il nostro ambiente di lavoro. Per prima cosa dobbiamo creare il nostro ambiente virtuale (virtual environment) Python dove andremo ad installare tutte le nostre librerie:
- Andiamo sul Desktop e creiamo una nuova cartella e chiamiamola “Progetto_Motivazione”
- Apriamo un terminale e scriviamo
cd ~/Desktop/Progetto_Motivazioneper entrare nella cartella - Ora che ci troviamo all’interno, creiamo l’ambiente virtuale con
python -m venv progetto_motivazione - Attiviamo l’ambiente con
progetto_motivazione\Scripts\activatese state su Windows osource progetto_motivazione/bin/activatese state su Linux o MacOs
Ora che abbiamo attivato l’ambiente, siamo pronti ad installare le librerie che ci servono per creare lo script; in particolare, ci servirà la libreria python-telegram-bot per gestire le API di Telegram e ollama per comunicare con il modello locale. Per fare ciò le installiamo nel nostro ambiente con il comando pip install:
pip install "python-telegram-bot[job-queue]" ollama python-dotenv
Il comando pip install "python-telegram-bot[job-queue]" installa APScheduler (job scheduler asincrono) utile per inviare i messaggi al nostro bot ogni ora. Inoltre, la libreria ufficiale ollama-python espone un’interfaccia asincrona (AsyncClient) perfettamente compatibile con il runtime asyncio usato da python-telegram-bot v20+. Questo ci permette di fare la chiamata LLM senza bloccare il loop degli eventi del bot. Infine, la libreria python-dotenv è utile per caricare le variabili necessarie dal file .env che deve essere creato all’interno della cartella del progetto e che conterrà le seguenti informazioni:
TELEGRAM_TOKEN=il_tuo_token # Ottenuto in precedenza da @BotFather
CHAT_ID=il_tuo_id # ID del bot (ottenilo con @userinfobot)
OLLAMA_MODEL=il_modello_che_vuoi_usare # Il modello di Ollama scaricato in locale (es mistral, llama3.2:3b, ...)
ATTENZIONE: Il token API dà pieno controllo al bot. Non inserirlo mai direttamente nel codice sorgente; usa sempre variabili d’ambiente o un file .env escluso da git tramite .gitignore.
Creiamo un prompt che verrà usato dal modello per istruirlo su cosa deve fare, ad esempio potremmo pensare di utilizzare il seguente:
Sei un coach motivazionale. Genera una frase breve (max 100 parole), ispiratrice e positiva su produttività, successo o benessere. Inizia con una maiuscola e termina con un punto esclamativo. Rendila unica ogni volta.
Oppure potremmo usare un prompt del tipo:
Sei un coach motivazionale esperto. Il tuo unico compito è generare UNA singola frase motivazionale in italiano, originale e potente. La frase deve:
– Avere tra 20 e 60 parole
– Essere autentica, non banale
– Stimolare all’azione o alla riflessione profonda
– Essere priva di emoji e punteggiatura eccessiva
Rispondi SOLO con la frase, senza prefissi, virgolette o spiegazioni.
Perché funziona? I prompt “system” definiscono il ruolo del modello, riducendo allucinazioni e garantendo output concisi. Per generare efficientemente la singola frase in un contesto di conversazioni stateless, cioè dove non viene memorizzato lo stato, nello script useremo ollama.chat().
Una volta salvate queste informazioni, creiamo lo script python che andrà ad animare il nostro bot.
"""
Bot Telegram - Frasi Motivazionali con Ollama
==============================================
Requisiti:
pip install "python-telegram-bot[job-queue]" ollama python-dotenv
File .env necessario:
BOT_TOKEN=il_tuo_token
CHAT_ID=il_tuo_chat_id
OLLAMA_MODEL=il_tuo_modello
"""
import asyncio
import logging
import os
import ollama
from dotenv import load_dotenv
from telegram.ext import Application
# Carica le variabili da .env
load_dotenv()
TOKEN = os.environ["BOT_TOKEN"]
CHAT_ID = int(os.environ["CHAT_ID"])
MODELLO = os.getenv("OLLAMA_MODEL", "mistral")
# Imposta intervallo di tempo in secondi
INTERVALLO = 3600
logging.basicConfig(
format="%(asctime)s | %(levelname)s | %(message)s",
level=logging.INFO,
)
def genera_frase() -> str:
"""Chiama Ollama e restituisce una frase motivazionale."""
risposta = ollama.chat(
model=MODELLO,
messages=[
{
"role": "system",
"content": (
"Sei un coach motivazionale. "
"Genera UNA sola frase in italiano, breve (max 40 parole), "
"ispiratrice e originale. "
"Rispondi SOLO con la frase, senza virgolette né introduzioni."
),
},
{"role": "user", "content": "Dammi una frase motivazionale."},
],
)
return risposta["message"]["content"].strip()
async def invia_frase(context) -> None:
"""Job eseguito ogni ora: genera e invia la frase al CHAT_ID."""
frase = await asyncio.to_thread(genera_frase)
await context.bot.send_message(chat_id=CHAT_ID, text=f"Frase: {frase}")
logging.info(f"Frase inviata: {frase}")
def main():
app = Application.builder().token(TOKEN).build()
# Invia la prima frase dopo 5 secondi, poi ogni ora
app.job_queue.run_repeating(invia_frase, interval=INTERVALLO, first=5)
logging.info("Bot avviato.")
app.run_polling(drop_pending_updates=True)
if __name__ == "__main__":
main()
Spiegazione del codice
Importazioni
asyncioè la libreria standard di Python per la programmazione asincrona — il bot usa questa modalità per poter fare più cose contemporaneamente senza bloccarsi.loggingstampa messaggi informativi nel terminale mentre il bot gira.osserve a leggere le variabili d’ambiente.ollamaè il client Python per parlare con il modello locale.load_dotenvlegge il file.enve carica le variabili.Applicationè la classe principale di python-telegram-bot che gestisce tutto.
Configurazione
- La funzione
load_dotenv()apre il file.enve carica le variabili in memoria.os.environ["BOT_TOKEN"]legge la variabile — la sintassi con le parentesi quadre fa sì che Python si blocchi subito con un errore chiaro se la variabile manca, invece di fallire in modo misterioso più avanti. - Il
CHAT_IDviene convertito in intero conint()perché Telegram si aspetta un numero, non una stringa.os.getenv("OLLAMA_MODEL", "mistral")invece usa la seconda forma: se la variabile non c’è nel.env, usa"mistral"come valore predefinito.
La funzione genera_frase()
È una funzione normale (non async), perché ollama.chat() è una chiamata sincrona — aspetta la risposta prima di andare avanti. ollama.chat() accetta una lista di messaggi nello stesso formato usato da ChatGPT: il messaggio system dà le istruzioni al modello (il “personaggio” che deve interpretare), il messaggio user è la richiesta vera e propria. La risposta arriva come dizionario e risposta["message"]["content"] è il testo generato. .strip() rimuove eventuali spazi o ritorni a capo all’inizio e alla fine.
Il job che invia il messaggio: invia_frase()
Questa è una funzione async perché viene eseguita dentro il loop asincrono del bot. Il punto critico è asyncio.to_thread(genera_frase): poiché genera_frase() è lenta (Ollama può impiegare 2-5 secondi), se la chiamassimo direttamente bloccheremmo l’intero bot per quel tempo. asyncio.to_thread() sposta l’esecuzione in un thread separato, lasciando libero il bot di fare altro nel frattempo. await significa “aspetta che finisca, ma senza bloccare”. Dopodiché context.bot.send_message() invia il testo via API Telegram al CHAT_ID specificato.
Il main()
- Il metodo
Application.builder().token(TOKEN).build()costruisce l’oggetto principale del bot con il token. - Il metodo
job_queue.run_repeating()pianificainvia_fraseogni3600secondi (1 ora), con la prima esecuzione dopo5secondi dall’avvio — utile per verificare subito che tutto funzioni. - Invece,
run_polling()avvia il bot in modalità long polling: invia continuamente richieste ai server Telegram per sapere se sono arrivati nuovi messaggi o comandi, e mantiene il processo vivo. - Infine,
drop_pending_updates=Trueignora i messaggi arrivati mentre il bot era spento.
