NUOVO 📢 Offerta di lancio limitata: fino al 70% di sconto sul tuo primo mese, per tutti i giochi!Vedi i piani

Come ospitare un bot Telegram.Bot (.NET) 24/7 su un VPS o un piano

Hosting di bot TelegramUpdated Nov 6, 202613 min read

Per ospitare un bot Telegram.Bot (.NET) 24/7 lo fai girare su una macchina sempre accesa: un VPS Linux con un servizio systemd che lo riavvia quando si ferma, oppure un piano bot su PlayNHost, hosting per bot Telegram (da 1,99 US$ al mese), dove carichi il tuo progetto C#, incolli il token di @BotFather e premi Start. Nel nostro test un bot con Telegram.Bot 22.10.3.3 ha usato circa 61 MB di memoria con .NET 8. Telegram.Bot riceve i messaggi con il long polling, ed è ciò che serve ai nostri piani: non hanno ancora un indirizzo HTTPS pubblico per un webhook. I passaggi su PlayNHost:

  1. Nella pagina hosting per bot Telegram, fai clic su Crea server su un piano. Nella finestra dell'ordine, rispondi a Per quale piattaforma è il tuo bot? con Telegram e scegli C# (.NET).
  2. Apri il tuo server nel pannello. La scheda Configura il tuo bot in Panoramica si apre su Connetti a Telegram; il suo primo passaggio, Cosa viene eseguito, dovrebbe dire Questo bot esegue .NET Bot.
  3. In Connetti a Telegram, incolla il token sotto Incolla il token del bot, fai clic su Collega, controlla il nome del bot mostrato e fai clic su Sì, continua.
  4. In Il tuo codice, fai clic su Carica i file e carica Bot.csproj e Program.cs nella cartella principale, senza le cartelle bin e obj, oppure fai clic su Collega Git.
  5. Nella pagina Bot, riquadro Codice, lascia Runtime su .NET 8 (recommended) e lascia vuoto File di avvio.
  6. Fai clic su Avvia il bot e apri Console. Il server compila il progetto, poi il bot stampa Logged in as @your_bot e l'indicatore in Panoramica passa a Online su Telegram.
  7. Nella pagina Bot, riquadro Telegram, fai clic su Apri in Telegram e invia al bot /start.

La creazione del bot in @BotFather e i passaggi nel pannello sono spiegati in Come ospitare un bot Telegram, e il tipo di bot .NET in generale (i due modi di caricare i file, gli errori di compilazione) in Come ospitare un bot Discord in C# (.NET). Questa pagina riguarda Telegram.Bot in sé: cosa usa su un server e cosa sapere prima di ospitarlo.

Cosa abbiamo misurato

LibreriaVersioneMemoria senza caricoDall'avvio alla risposta di Telegram, con la compilazioneDall'avvio del programma alla risposta di Telegram
Telegram.Bot22.10.3.361 MB1,5 s0,3 s
.NET 8 da solo, senza librerianessuna24 MB1,3 s (compilazione e avvio, nessuna chiamata)nessuno

Come: sul nostro nodo, in un container usa e getta configurato come un piano bot da 1 GB (l'immagine .NET 8 e il comando di avvio del nostro tipo di bot .NET, che esegue dotnet publish a ogni avvio), il bot ha chiamato getMe di Telegram con un token falso, che Telegram ha rifiutato. La memoria è la memoria residente 15 secondi dopo quella risposta, la prima colonna dei tempi va dall'inizio della compilazione alla risposta, la seconda dall'avvio del programma, e ogni valore è la mediana delle esecuzioni da 2 a 4. La primissima compilazione, che scarica anche il pacchetto, ha richiesto 5 secondi.

Sono valori minimi: ancora nessuna chat, nessun dato e nessun polling. Il tuo codice, ciò che conserva in memoria e il numero di chat si sommano. Per evitare la compilazione a ogni avvio, puoi caricare i file che hai pubblicato sul tuo computer al posto del progetto (vedi la guida C# collegata sopra). Confronta i numeri con i piani di hosting per bot Telegram e scegli in base a ciò che fa il tuo bot.

Un bot Telegram.Bot minimo

Risponde a /start, legge il token da TELEGRAM_BOT_TOKEN (il pannello lo passa al tuo codice con quel nome e anche come BOT_TOKEN, TOKEN, TELEGRAM_TOKEN e TELOXIDE_TOKEN) e stampa una riga di pronto. Due file nella cartella principale:

Bot.csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Telegram.Bot" Version="22.10.3.3" />
  </ItemGroup>
</Project>

Program.cs

using Telegram.Bot;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types;

const string TokenRefused = "Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart.";

string? token = Environment.GetEnvironmentVariable("TELEGRAM_BOT_TOKEN");
if (string.IsNullOrWhiteSpace(token))
{
    Console.WriteLine("No TELEGRAM_BOT_TOKEN found. Paste your bot token on the Bot page, then restart.");
    return 1;
}

var bot = new TelegramBotClient(token);

User me;
try
{
    me = await bot.GetMe();
}
catch (ApiRequestException e) when (e.ErrorCode == 401)
{
    Console.WriteLine(TokenRefused);
    return 1;
}

// Long polling only: remove a webhook left on the bot. Messages that wait are kept.
await bot.DeleteWebhook();

// Without an OnError handler, polling errors never reach the console. Set it before OnMessage.
bot.OnError += async (exception, source) =>
{
    if (exception is ApiRequestException { ErrorCode: 401 })
    {
        Console.WriteLine(TokenRefused);
        Environment.Exit(1);
    }
    Console.WriteLine($"Polling error ({source}): {exception.Message}");
    await Task.Delay(TimeSpan.FromSeconds(5));
};

// Setting OnMessage starts polling in the background.
bot.OnMessage += async (message, type) =>
{
    if (message.Text?.StartsWith("/start") == true)
    {
        await bot.SendMessage(message.Chat, "Hello! I am running on PlayNHost.");
    }
};

Console.WriteLine($"Logged in as @{me.Username}");
await Task.Delay(Timeout.Infinite);
return 0;

A ogni avvio il server esegue dotnet publish su Bot.csproj e avvia Bot.dll. La console mostra [PlayNHost] Building your bot (the first build downloads packages and can take a minute), poi [PlayNHost] Starting your bot, poi Logged in as @your_bot, la riga che porta l'indicatore a Online su Telegram. Ferma prima ogni copia che esegui sul tuo computer con il token vero, altrimenti le due copie ricevono errori 409 Conflict da Telegram.

Se il token è sbagliato

Nel nostro test, con un token falso, GetMe() di Telegram.Bot è fallito con questo errore:

ApiRequestException: Unauthorized

Il bot qui sopra intercetta quel rifiuto (codice di errore 401), prima del polling e durante, e stampa invece Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart., poi si ferma con codice di uscita 1. Il pannello legge quella riga e mostra il banner Telegram non ha accettato il token del bot sopra Console. Per risolvere, in @BotFather invia /mybots, scegli il tuo bot, poi API Token, e copia di nuovo il token. Nella pagina Bot, riquadro Telegram, fai clic su Sostituisci il token, incollalo, fai clic su Salva il token e poi su Riavvia ora.

Cosa sapere su Telegram.Bot su un server

  • Versioni: Telegram.Bot 22.10.3.3 è uscito il 9 ott 2026. Punta a .NET Standard 2.0 e .NET 6, e il suo README consiglia .NET 8 o successivo, quindi ogni Runtime offerto dal pannello (.NET 6, 8, 9 o 10) lo compila; .NET 8 (recommended) corrisponde a net8.0 qui sopra.
  • I nomi dei metodi hanno perso Async nella versione 22. Ora sono GetMe() e SendMessage(); i tutorial con GetMeAsync o SendTextMessageAsync sono stati scritti per versioni precedenti, quei nomi non esistono in 22.10.3.3 e il loro codice non compila. L'errore di compilazione è subito sopra [PlayNHost] The build failed. Read the errors above, fix them and press Start. in Console.
  • Impostare OnMessage avvia il polling. Appena aggiungi un gestore a OnMessage (o OnUpdate), il client interroga Telegram in background e chiede ogni tipo di aggiornamento. Aggiungi prima il gestore OnError, come sopra.
  • Senza OnError, gli errori sono invisibili. Quando una richiesta di polling fallisce, Telegram.Bot passa l'errore a OnError; senza gestore lo scrive nell'output di traccia di .NET, che non arriva alla console. Un bot il cui token è stato revocato, o che un'altra copia scalza con 409 Conflict, sembra in esecuzione e non risponde a nulla. Il gestore qui sopra stampa ogni errore e, poiché il testo di Telegram è nel messaggio, il pannello può mostrare Il tuo bot è in esecuzione anche altrove o Sul tuo bot è impostato un webhook.
  • Rallenta dopo un errore. Il ciclo di polling riprova subito dopo una richiesta fallita; aspetta solo il tempo che impiega il tuo gestore OnError. Il Task.Delay da 5 secondi qui sopra evita che un errore persistente diventi un flusso di richieste. Le risposte 429 Too Many Requests di Telegram vengono ritentate per te quando Telegram chiede di attendere 60 secondi o meno: per impostazione predefinita una richiesta viene tentata fino a 3 volte in tutto.
  • Un webhook non viene rimosso per te. Il polling con un webhook impostato fallisce con 409 Conflict: can't use getUpdates method while webhook is active. Il bot qui sopra chiama DeleteWebhook() prima del polling, il che conserva i messaggi in attesa; puoi anche fare clic su Rimuovi il webhook nel riquadro Telegram. Un webhook tuo richiede un indirizzo HTTPS pubblico, che i nostri piani non includono ancora. Se vieni da un host con webhook: Come spostare un bot Telegram su PlayNHost.
  • Non aspettare con Console.ReadLine(). Il primo bot nella guida della libreria resta in esecuzione finché non premi Invio. Su un server nessuno preme Invio, e sotto systemd l'input del programma è vuoto per impostazione predefinita, quindi ReadLine() ritorna subito e il bot termina. Aspetta con await Task.Delay(Timeout.Infinite), come sopra.
  • Arresti anomali: quando il bot termina, come fa il bot qui sopra con un token rifiutato, il pannello lo riavvia subito, ricompilandolo prima. Se si ferma di nuovo entro un minuto, resta fermo e Console ne dice il motivo. Vedi Come risolvere l’errore 409 Conflict di un bot Telegram per i due tipi di 409.

Ospitarlo da solo su un VPS Linux

Su un VPS, compila il bot sul tuo computer e fai girare sul server solo il risultato. Pubblicalo con l'SDK .NET 8:

dotnet publish Bot.csproj -c Release -o publish

Su Ubuntu 24.04 il runtime .NET 8 è nei pacchetti propri di Ubuntu:

sudo apt update
sudo apt install dotnet-runtime-8.0
dotnet --list-runtimes

Crea un utente per il bot e copia la cartella publish sul server (per esempio con scp -r), poi nella sua cartella:

sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp -r publish/. /opt/mybot/
sudo chown -R mybot: /opt/mybot

Tieni il token fuori dal codice, in un file che solo root può leggere:

sudo sh -c 'echo "TELEGRAM_BOT_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env

Crea /etc/systemd/system/mybot.service:

[Unit]
Description=Telegram.Bot Telegram bot
Wants=network-online.target
After=network-online.target

[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/usr/bin/dotnet /opt/mybot/Bot.dll
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Avvialo subito e a ogni avvio della macchina, poi segui il suo output:

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo journalctl -u mybot -f

Restart=always riavvia il bot 5 secondi dopo che è terminato o è andato in crash, ma non dopo che lo hai fermato con systemctl stop. Per aggiornare, pubblica di nuovo, copia i nuovi file sopra i vecchi ed esegui sudo systemctl restart mybot. Su Debian, .NET non è nei pacchetti propri della distribuzione; le istruzioni di installazione di Microsoft lo coprono.

Auto-hosting o piano bot

Su un VPS che gestisci tu, ti occupi di:

  • Aggiornamenti del sistema operativo e sicurezza, e aggiornamenti del runtime .NET.
  • Pubblicare e copiare ogni nuova build, il file del servizio, il file del token e i suoi permessi.
  • Leggere journalctl per capire perché il bot si è fermato o ha smesso di rispondere.
  • Backup di tutto ciò che il tuo bot salva.

In cambio un VPS esegue qualsiasi cosa, e puoi dargli un dominio con HTTPS per un webhook.

Su un piano bot PlayNHost il pannello lo fa per te:

  • .NET 6, 8, 9 o 10 da un selettore, e la compilazione: carica il progetto e premi Start.
  • Il token, verificato con Telegram prima di essere salvato, conservato cifrato e passato al tuo codice con cinque nomi.
  • Il riavvio del bot dopo un crash. Se va in crash di nuovo entro un minuto, resta fermo e Console ne dice il motivo.
  • Un pulsante Rimuovi il webhook nel riquadro Telegram, e banner sopra Console che indicano la causa quando una riga mostra un token rifiutato, un'altra copia o un webhook.
  • Caricamento file, deploy Git e backup dal pannello.

Domande frequenti

Il mio bot Telegram.Bot è in esecuzione ma non risponde mai. Perché?

Il più delle volte il polling fallisce e nessuno lo segnala: senza un gestore OnError, gli errori vanno nell'output di traccia di .NET, non nella console. Aggiungi il gestore del bot qui sopra e riavvia. Le cause abituali sono un'altra copia che fa polling con lo stesso token (409 Conflict), un webhook ancora impostato sul bot o un token revocato in @BotFather.

Posso usare Telegram.Bot con un webhook qui?

Non ancora sui nostri piani: un webhook richiede un indirizzo HTTPS pubblico, che non includono. Il polling non ne richiede, perché il bot chiede a Telegram i nuovi messaggi, ed è ciò che fa OnMessage.

La compilazione a ogni avvio rallenta il mio bot?

Solo l'avvio: nel nostro test l'avvio ha richiesto 1,5 secondi con la compilazione contro 0,3 secondi per il solo programma. Una volta in esecuzione, il bot è lo stesso. Per evitare la compilazione, pubblica sul tuo computer e carica i file della cartella publish al posto del progetto.

Quale versione di .NET devo scegliere?

.NET 8, quella consigliata, con net8.0 nel progetto come sopra. Telegram.Bot compila anche su .NET 6, 9 e 10; imposta la stessa versione in TargetFramework e in Runtime. Un progetto per un .NET più recente del Runtime interrompe la compilazione con NETSDK1045; uno per un .NET più vecchio compila ma non si avvia, perché quel .NET non è installato nell'immagine.

Pronto a far girare il tuo bot Telegram.Bot a ogni ora? Guarda i piani di hosting per bot Telegram.

Il tuo bot è già ospitato altrove? Spostalo da noi

ULTIMI ARTICOLI