NUEVO 📢 Oferta de lanzamiento limitada: ¡hasta un 70% de descuento en tu primer mes, en todos los juegos!Ver planes

Cómo alojar un bot de Telegram.Bot (.NET) 24/7 en un VPS o un plan

Hosting de bots de TelegramUpdated Nov 6, 202613 min read

Para alojar un bot de Telegram.Bot (.NET) 24/7 lo ejecutas en una máquina que siempre está encendida: un VPS Linux con un servicio de systemd que lo vuelve a iniciar cuando se detiene, o un plan de bots en el hosting de bots de Telegram de PlayNHost (desde US$1.99 al mes), donde subes tu proyecto en C#, pegas el token de @BotFather y pulsas Start. En nuestra prueba, un bot con Telegram.Bot 22.10.3.3 usó unos 61 MB de memoria con .NET 8. Telegram.Bot recibe los mensajes con long polling, que es lo que necesitan nuestros planes: todavía no tienen una dirección HTTPS pública para un webhook. Los pasos en PlayNHost:

  1. En la página de hosting de bots de Telegram, haz clic en Crear servidor en un plan. En la ventana del pedido, responde ¿Para qué plataforma es tu bot? con Telegram y elige C# (.NET).
  2. Abre tu servidor en el panel. La tarjeta Configura tu bot en Resumen se abre en Conectar con Telegram; su primer paso, Qué se ejecuta, debería decir Este bot ejecuta .NET Bot.
  3. En Conectar con Telegram, pega el token en Pega el token de tu bot, haz clic en Conectar, comprueba el nombre del bot que aparece y haz clic en Sí, continuar.
  4. En Tu código, haz clic en Subir archivos y sube Bot.csproj y Program.cs a la carpeta principal, sin las carpetas bin y obj, o haz clic en Conectar Git.
  5. En la página Bot, panel Código, deja el Entorno de ejecución en .NET 8 (recommended) y deja vacío Archivo de entrada.
  6. Haz clic en Iniciar bot y abre Console. El servidor compila tu proyecto, después tu bot imprime Logged in as @your_bot y el indicador de Resumen pasa a En línea en Telegram.
  7. En la página Bot, panel Telegram, haz clic en Abrir en Telegram y envía a tu bot /start.

Cómo crear el bot en @BotFather y los pasos del panel se explican en Cómo alojar un bot de Telegram, y el tipo de bot .NET en general (las dos formas de subir, errores de compilación) en Cómo alojar un bot de Discord en C# (.NET). Esta página trata de Telegram.Bot en sí: qué usa en un servidor y qué conviene saber antes de alojarlo.

Qué medimos

BibliotecaVersiónMemoria sin cargaDel inicio a la respuesta de Telegram, con la compilaciónDel arranque del programa a la respuesta de Telegram
Telegram.Bot22.10.3.361 MB1,5 s0,3 s
.NET 8 solo, sin bibliotecaninguna24 MB1,3 s (compilación e inicio, sin llamada)ninguno

Cómo: en nuestro propio nodo, en un contenedor desechable configurado como un plan de bots de 1 GB (la imagen de .NET 8 y el comando de inicio de nuestro tipo de bot .NET, que ejecuta dotnet publish en cada inicio), el bot llamó a getMe de Telegram con un token falso, que Telegram rechazó. La memoria es la memoria residente 15 segundos después de esa respuesta, la primera columna de tiempo va desde el inicio de la compilación hasta la respuesta, la segunda desde el arranque del programa, y cada cifra es la mediana de las ejecuciones 2 a 4. La primera compilación de todas, que además descarga el paquete, tardó 5 segundos.

Son cifras mínimas: todavía sin chats, sin datos y sin polling. Tu propio código, lo que guarda en memoria y el número de chats se suman a ellas. Para evitar la compilación en cada inicio, puedes subir los archivos que publicaste en tu propio ordenador en lugar del proyecto (mira la guía de C# enlazada arriba). Compara las cifras con los planes de hosting de bots de Telegram y elige según lo que haga tu bot.

Un bot mínimo con Telegram.Bot

Responde a /start, lee el token de TELEGRAM_BOT_TOKEN (el panel se lo da a tu código con ese nombre y también como BOT_TOKEN, TOKEN, TELEGRAM_TOKEN y TELOXIDE_TOKEN) e imprime una línea de listo. Dos archivos en la carpeta 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;

En cada inicio el servidor ejecuta dotnet publish sobre Bot.csproj e inicia Bot.dll. La consola muestra [PlayNHost] Building your bot (the first build downloads packages and can take a minute), luego [PlayNHost] Starting your bot y luego Logged in as @your_bot, la línea que pone el indicador en En línea en Telegram. Detén antes cualquier copia que ejecutes en tu ordenador con el token real, o las dos copias recibirán errores 409 Conflict de Telegram.

Si el token es incorrecto

En nuestra prueba, con un token falso, GetMe() de Telegram.Bot falló con este error:

ApiRequestException: Unauthorized

El bot de arriba captura ese rechazo (código de error 401), antes del polling y durante él, e imprime en su lugar Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart., y después se detiene con el código de salida 1. El panel lee esa línea y muestra el aviso Telegram no aceptó el token de tu bot sobre Console. Para arreglarlo, en @BotFather envía /mybots, elige tu bot, luego API Token y copia el token de nuevo. En la página Bot, panel Telegram, haz clic en Reemplazar token, pégalo, haz clic en Guardar token y luego en Reiniciar ahora.

Qué conviene saber de Telegram.Bot en un servidor

  • Versiones: Telegram.Bot 22.10.3.3 salió el 9 de oct. de 2026. Apunta a .NET Standard 2.0 y .NET 6, y su README recomienda .NET 8 o posterior, así que cualquier Entorno de ejecución que ofrezca el panel (.NET 6, 8, 9 o 10) lo compila; .NET 8 (recommended) coincide con net8.0 de arriba.
  • Los nombres de los métodos perdieron Async en la versión 22. Ahora son GetMe() y SendMessage(); los tutoriales con GetMeAsync o SendTextMessageAsync se escribieron para versiones anteriores, esos nombres no existen en 22.10.3.3 y su código no compila. El error de compilación está justo encima de [PlayNHost] The build failed. Read the errors above, fix them and press Start. en Console.
  • Asignar OnMessage inicia el polling. En cuanto se añade un manejador a OnMessage (o a OnUpdate), el cliente consulta Telegram en segundo plano y pide todos los tipos de actualización. Añade primero el manejador OnError, como arriba.
  • Sin OnError, los errores son invisibles. Cuando falla una consulta, Telegram.Bot pasa el error a OnError; si no hay manejador, lo escribe en la salida de traza de .NET, que no llega a la consola. Un bot cuyo token fue revocado, o al que otra copia desplaza con 409 Conflict, parece estar en marcha y no responde. El manejador de arriba imprime cada error y, como el texto propio de Telegram va en el mensaje, el panel puede mostrar Tu bot también se está ejecutando en otro sitio o Hay un webhook configurado en tu bot.
  • Frena tras un error. El bucle de polling vuelve a preguntar justo después de una petición fallida; solo espera lo que tarde tu manejador OnError. El Task.Delay de 5 segundos de arriba evita que un error persistente se convierta en un chorro de peticiones. Las respuestas 429 Too Many Requests de Telegram se reintentan por ti cuando Telegram pide esperar 60 segundos o menos: por defecto una petición se intenta hasta 3 veces en total.
  • Un webhook no se quita solo. El polling con un webhook configurado falla con 409 Conflict: can't use getUpdates method while webhook is active. El bot de arriba llama a DeleteWebhook() antes del polling, lo que conserva los mensajes en espera; también puedes hacer clic en Quitar webhook en el panel Telegram. Un webhook propio necesita una dirección HTTPS pública, que nuestros planes todavía no incluyen. Si vienes de un hosting con webhook: Cómo mover un bot de Telegram a PlayNHost.
  • No esperes con Console.ReadLine(). El primer bot de la guía de la biblioteca sigue funcionando hasta que pulsas Enter. En un servidor nadie pulsa Enter, y con systemd la entrada del programa está vacía por defecto, así que ReadLine() vuelve de inmediato y el bot termina. Espera con await Task.Delay(Timeout.Infinite), como arriba.
  • Caídas: cuando el bot termina, como hace el bot de arriba con un token rechazado, el panel lo inicia de nuevo enseguida, compilándolo otra vez antes. Si se detiene otra vez en el plazo de un minuto, se queda detenido y Console dice por qué. Mira Solucionar el error 409 Conflict de un bot de Telegram para los dos tipos de 409.

Alójalo tú mismo en un VPS Linux

En un VPS, compila el bot en tu propio ordenador y ejecuta solo el resultado en el servidor. Publícalo con el SDK de .NET 8:

dotnet publish Bot.csproj -c Release -o publish

En Ubuntu 24.04 el runtime de .NET 8 está en los paquetes propios de Ubuntu:

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

Crea un usuario para el bot y copia la carpeta publish al servidor (por ejemplo con scp -r), y luego a su carpeta:

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

Mantén el token fuera de tu código, en un archivo que solo root pueda leer:

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

Inícialo ahora y en cada arranque, y luego sigue su salida:

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

Restart=always vuelve a iniciar el bot 5 segundos después de que termine o se cierre con un fallo, pero no después de que lo detengas con systemctl stop. Para actualizar, publica otra vez, copia los archivos nuevos sobre los antiguos y ejecuta sudo systemctl restart mybot. En Debian, .NET no está en los paquetes propios de la distribución; las instrucciones de instalación de Microsoft lo cubren.

Alojamiento propio o un plan de bots

En un VPS que gestionas tú mismo te encargas de:

  • Las actualizaciones del sistema operativo y la seguridad, y las actualizaciones del runtime de .NET.
  • Publicar y copiar cada nueva compilación, el archivo del servicio, el archivo del token y sus permisos.
  • Leer journalctl para saber por qué el bot se detuvo o dejó de responder.
  • Copias de seguridad de todo lo que guarde tu bot.

A cambio, un VPS ejecuta cualquier cosa, y puedes darle un dominio con HTTPS para un webhook.

En un plan de bots de PlayNHost el panel hace esto por ti:

  • .NET 6, 8, 9 o 10 desde un selector, y la compilación: sube el proyecto y pulsa Start.
  • El token, comprobado con Telegram antes de guardarlo, almacenado cifrado y entregado a tu código con cinco nombres.
  • Reiniciar el bot tras una caída. Si vuelve a caerse en el plazo de un minuto, se queda detenido y Console dice por qué.
  • Un botón Quitar webhook en el panel Telegram, y avisos sobre Console que nombran la causa cuando una línea muestra un token rechazado, otra copia o un webhook.
  • Subida de archivos, despliegues con Git y copias de seguridad desde el panel.

Preguntas frecuentes

Mi bot de Telegram.Bot funciona pero nunca responde. ¿Por qué?

Lo más habitual es que el polling falle y nada lo avise: sin un manejador OnError, los errores van a la salida de traza de .NET, no a la consola. Añade el manejador del bot de arriba y reinicia. Las causas habituales son otra copia haciendo polling con el mismo token (409 Conflict), un webhook que sigue configurado en el bot o un token revocado en @BotFather.

¿Puedo usar Telegram.Bot con un webhook aquí?

Todavía no en nuestros planes: un webhook necesita una dirección HTTPS pública, que no incluyen. El polling no necesita ninguna, porque el bot pide a Telegram los mensajes nuevos, y eso es lo que hace OnMessage.

¿La compilación en cada inicio ralentiza mi bot?

Solo el inicio: en nuestra prueba el inicio tardó 1,5 segundos con la compilación frente a 0,3 segundos solo con el programa. Una vez en marcha, el bot es igual. Para evitar la compilación, publica en tu ordenador y sube los archivos de la carpeta publish en lugar del proyecto.

¿Qué versión de .NET debo elegir?

.NET 8, la recomendada, con net8.0 en tu proyecto como arriba. Telegram.Bot también compila en .NET 6, 9 y 10; pon la misma versión en TargetFramework y en Entorno de ejecución. Un proyecto para un .NET más reciente que el Entorno de ejecución detiene la compilación con NETSDK1045; uno para un .NET más antiguo compila pero no arranca, porque ese .NET no está instalado en la imagen.

¿Listo para tener tu bot de Telegram.Bot funcionando a todas horas? Mira los planes de hosting de bots de Telegram.

¿Ya tienes tu bot en otro proveedor? Tráelo con nosotros

NUESTROS ÚLTIMOS BLOGS