NOVO 📢 Oferta de lançamento limitada: até 70% de desconto no seu primeiro mês, em todos os jogos!Ver planos

Como hospedar um bot Telegram.Bot (.NET) 24/7 em uma VPS ou plano

Hospedagem de bot do TelegramUpdated Nov 6, 202613 min read

Para hospedar um bot Telegram.Bot (.NET) 24/7, você o executa em uma máquina que fica sempre ligada: uma VPS Linux com um serviço systemd que o inicia de novo quando ele para, ou um plano de bots na hospedagem de bots do Telegram da PlayNHost (a partir de US$1,99 por mês), onde você envia seu projeto em C#, cola o token do @BotFather e aperta Start. No nosso teste, um bot com Telegram.Bot 22.10.3.3 usou cerca de 61 MB de memória no .NET 8. O Telegram.Bot recebe mensagens por long polling, que é o que nossos planos precisam: eles ainda não têm um endereço HTTPS público para um webhook. Os passos na PlayNHost:

  1. Na página de hospedagem de bots do Telegram, clique em Criar servidor em um plano. Na janela do pedido, responda Para qual plataforma é o seu bot? com Telegram e escolha C# (.NET).
  2. Abra seu servidor no painel. O cartão Configurar seu bot em Visão geral abre em Conectar ao Telegram; o primeiro passo, O que roda, deve dizer Este bot roda .NET Bot.
  3. Em Conectar ao Telegram, cole o token em Cole o token do seu bot, clique em Conectar, confira o nome do bot exibido e clique em Sim, continuar.
  4. Em Seu código, clique em Enviar arquivos e envie Bot.csproj e Program.cs para a pasta principal, sem as pastas bin e obj, ou clique em Conectar o Git.
  5. Na página Bot, painel Código, mantenha Runtime em .NET 8 (recommended) e deixe Arquivo de entrada vazio.
  6. Clique em Iniciar bot e abra Console. O servidor compila seu projeto, depois seu bot imprime Logged in as @your_bot e o indicador em Visão geral passa para Online no Telegram.
  7. Na página Bot, painel Telegram, clique em Abrir no Telegram e envie /start ao seu bot.

Como criar o bot no @BotFather e os passos do painel estão explicados em Como hospedar um bot do Telegram, e o tipo de bot .NET em geral (as duas formas de enviar arquivos, erros de compilação) em Como hospedar um bot do Discord em C# (.NET). Esta página trata do Telegram.Bot em si: o que ele usa em um servidor e o que saber antes de hospedá-lo.

O que medimos

BibliotecaVersãoMemória sem cargaDo início à resposta do Telegram, com a compilaçãoDa execução do programa à resposta do Telegram
Telegram.Bot22.10.3.361 MB1,5 s0,3 s
.NET 8 sozinho, sem bibliotecanenhuma24 MB1,3 s (compilação e início, sem chamada)nenhum

Como: no nosso próprio nó, em um contêiner descartável configurado como um plano de bots de 1 GB (a imagem do .NET 8 e o comando de início do nosso tipo de bot .NET, que executa dotnet publish a cada início), o bot chamou getMe do Telegram com um token falso, que o Telegram recusou. A memória é a memória residente 15 segundos depois dessa resposta, a primeira coluna de tempo vai do começo da compilação até a resposta, a segunda da execução do programa, e cada valor é a mediana das execuções 2 a 4. A primeiríssima compilação, que também baixa o pacote, levou 5 segundos.

Esses são valores mínimos: ainda sem chats, sem dados e sem polling. Seu próprio código, o que ele guarda na memória e o número de chats se somam a eles. Para pular a compilação a cada início, você pode enviar os arquivos que publicou no seu próprio computador em vez do projeto (veja o guia de C# linkado acima). Compare os números com os planos da hospedagem de bots do Telegram e escolha de acordo com o que seu bot faz.

Um bot Telegram.Bot mínimo

Ele responde a /start, lê o token de TELEGRAM_BOT_TOKEN (o painel o entrega ao seu código com esse nome e também como BOT_TOKEN, TOKEN, TELEGRAM_TOKEN e TELOXIDE_TOKEN) e imprime uma linha de pronto. Dois arquivos na pasta principal:

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 cada início, o servidor executa dotnet publish em Bot.csproj e inicia Bot.dll. O console mostra [PlayNHost] Building your bot (the first build downloads packages and can take a minute), depois [PlayNHost] Starting your bot, depois Logged in as @your_bot, a linha que muda o indicador para Online no Telegram. Pare antes qualquer cópia que você rode no seu computador com o token real, ou as duas cópias recebem erros 409 Conflict do Telegram.

Se o token estiver errado

No nosso teste, com um token falso, GetMe() do Telegram.Bot falhou com este erro:

ApiRequestException: Unauthorized

O bot acima captura essa recusa (código de erro 401), antes do polling e durante ele, e imprime Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart. no lugar, depois para com código de saída 1. O painel lê essa linha e mostra o aviso O Telegram não aceitou o token do seu bot acima de Console. Para corrigir, no @BotFather envie /mybots, escolha seu bot, depois API Token, e copie o token de novo. Na página Bot, painel Telegram, clique em Substituir token, cole-o, clique em Salvar token e depois em Reiniciar agora.

O que saber sobre o Telegram.Bot em um servidor

  • Versões: o Telegram.Bot 22.10.3.3 saiu em 9 out. 2026. Ele tem como alvo .NET Standard 2.0 e .NET 6, e o README recomenda .NET 8 ou mais recente, então qualquer Runtime que o painel oferece (.NET 6, 8, 9 ou 10) o compila; .NET 8 (recommended) corresponde a net8.0 acima.
  • Os nomes dos métodos perderam Async na versão 22. Agora são GetMe() e SendMessage(); tutoriais com GetMeAsync ou SendTextMessageAsync foram escritos para versões antigas, esses nomes não existem na 22.10.3.3 e o código deles não compila. O erro de compilação está logo acima de [PlayNHost] The build failed. Read the errors above, fix them and press Start. em Console.
  • Definir OnMessage inicia o polling. Assim que um manipulador é adicionado a OnMessage (ou OnUpdate), o cliente consulta o Telegram em segundo plano e pede todos os tipos de atualização. Adicione primeiro o manipulador OnError, como acima.
  • Sem OnError, os erros ficam invisíveis. Quando uma consulta falha, o Telegram.Bot passa o erro para OnError; sem manipulador, ele o escreve na saída de rastreamento do .NET, que não chega ao console. Um bot cujo token foi revogado, ou que outra cópia expulsa com 409 Conflict, parece estar rodando e não responde a nada. O manipulador acima imprime cada erro e, como o texto do próprio Telegram vai na mensagem, o painel pode mostrar Seu bot também está rodando em outro lugar ou Há um webhook configurado no seu bot.
  • Desacelere após um erro. O laço de polling pergunta de novo logo após uma requisição que falhou; ele espera só o tempo que seu manipulador OnError levar. O Task.Delay de 5 segundos acima evita que um erro persistente vire uma enxurrada de requisições. As respostas 429 Too Many Requests do próprio Telegram são repetidas para você quando o Telegram pede para esperar 60 segundos ou menos: por padrão, uma requisição é tentada até 3 vezes no total.
  • Um webhook não é removido por você. O polling com um webhook definido falha com 409 Conflict: can't use getUpdates method while webhook is active. O bot acima chama DeleteWebhook() antes do polling, o que mantém as mensagens em espera; você também pode clicar em Remover webhook no painel Telegram. Um webhook seu precisa de um endereço HTTPS público, que nossos planos ainda não incluem. Se você vem de uma hospedagem com webhook: Como migrar um bot do Telegram para a PlayNHost.
  • Não espere com Console.ReadLine(). O primeiro bot do guia da biblioteca continua rodando até você apertar Enter. Em um servidor ninguém aperta Enter, e sob o systemd a entrada do programa é vazia por padrão, então ReadLine() retorna na hora e o bot termina. Espere com await Task.Delay(Timeout.Infinite), como acima.
  • Quedas: quando o bot termina, como o bot acima faz com um token recusado, o painel o inicia de novo na hora, compilando-o outra vez antes. Se ele parar de novo em até um minuto, fica parado e Console diz o motivo. Veja Como corrigir o erro 409 Conflict do bot do Telegram para os dois tipos de 409.

Hospede você mesmo em uma VPS Linux

Em uma VPS, compile o bot no seu próprio computador e rode só o resultado no servidor. Publique-o com o SDK do .NET 8:

dotnet publish Bot.csproj -c Release -o publish

No Ubuntu 24.04, o runtime do .NET 8 está nos pacotes do próprio Ubuntu:

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

Crie um usuário para o bot e copie a pasta publish para o servidor (por exemplo com scp -r), depois para a pasta dele:

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

Mantenha o token fora do seu código, em um arquivo que só o root pode ler:

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

Crie /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

Inicie-o agora e a cada boot, depois acompanhe a saída dele:

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

Restart=always inicia o bot de novo 5 segundos depois que ele termina ou cai, mas não depois que você o para com systemctl stop. Para atualizar, publique de novo, copie os arquivos novos por cima dos antigos e execute sudo systemctl restart mybot. No Debian, o .NET não está nos pacotes da própria distribuição; as instruções de instalação da Microsoft cobrem isso.

Hospedagem própria ou plano de bots

Em uma VPS que você mesmo gerencia, cabe a você cuidar de:

  • Atualizações do sistema operacional e segurança, e upgrades do runtime do .NET.
  • Publicar e copiar cada nova compilação, o arquivo do serviço, o arquivo do token e suas permissões.
  • Ler journalctl para descobrir por que o bot parou ou deixou de responder.
  • Backups de tudo o que seu bot armazena.

Em troca, uma VPS roda qualquer coisa, e você pode dar a ela um domínio com HTTPS para um webhook.

Em um plano de bots da PlayNHost, o painel faz isso por você:

  • .NET 6, 8, 9 ou 10 em um seletor, e a compilação: envie o projeto e aperte Start.
  • O token, verificado com o Telegram antes de ser salvo, guardado criptografado e entregue ao seu código com cinco nomes.
  • Reiniciar o bot depois de uma queda. Se ele cair de novo em até um minuto, fica parado e Console diz o motivo.
  • Um botão Remover webhook no painel Telegram e avisos acima de Console que apontam a causa quando uma linha mostra um token recusado, outra cópia ou um webhook.
  • Envio de arquivos, deploys por Git e backups pelo painel.

Perguntas frequentes

Meu bot Telegram.Bot roda, mas nunca responde. Por quê?

Na maioria das vezes o polling falha e nada avisa: sem um manipulador OnError, os erros vão para a saída de rastreamento do .NET, não para o console. Adicione o manipulador do bot acima e reinicie. As causas habituais são outra cópia fazendo polling com o mesmo token (409 Conflict), um webhook ainda definido no bot ou um token revogado no @BotFather.

Posso usar o Telegram.Bot com um webhook aqui?

Ainda não nos nossos planos: um webhook precisa de um endereço HTTPS público, que eles não incluem. O polling não precisa de nenhum, porque o bot pede ao Telegram as mensagens novas, e é isso que OnMessage faz.

A compilação a cada início deixa meu bot lento?

Só o início: no nosso teste, o início levou 1,5 segundo com a compilação contra 0,3 segundo só com o programa. Depois que está rodando, o bot é o mesmo. Para pular a compilação, publique no seu computador e envie os arquivos da pasta publish em vez do projeto.

Qual versão do .NET devo escolher?

.NET 8, a recomendada, com net8.0 no seu projeto como acima. O Telegram.Bot também compila no .NET 6, 9 e 10; defina a mesma versão em TargetFramework e em Runtime. Um projeto para um .NET mais novo que o Runtime interrompe a compilação com NETSDK1045; um para um .NET mais antigo compila, mas não inicia, porque esse .NET não está instalado na imagem.

Pronto para deixar seu bot Telegram.Bot rodando o dia todo? Veja os planos da hospedagem de bots do Telegram.

Seu bot já está em outro lugar? Traga-o para nós

NOSSOS ÚLTIMOS ARTIGOS