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 teloxide 24/7

Hosting de bots de TelegramUpdated Nov 6, 202614 min read

Para alojar un bot de teloxide 24/7 lo ejecutas en una máquina que siempre está encendida: un VPS Linux con un servicio systemd que lo vuelve a iniciar cuando se detiene, o un plan de bots en PlayNHost (desde US$1.99 al mes), donde subes el programa terminado y el panel le da el token y lo inicia de nuevo si falla. En nuestra prueba, un bot con teloxide 0.17.0 usó unos 13 MB de memoria. Un bot de Rust se compila en tu propio ordenador como un único programa Linux x86-64: en el servidor no se compila nada. Bot::from_env() de teloxide lee el token de TELOXIDE_TOKEN, un nombre que el panel define por ti. Los pasos en PlayNHost:

  1. Compila tu bot para Linux x86-64 en tu ordenador, como se muestra más abajo en Compílalo para Linux.
  2. En alojamiento de bots de Telegram, haz clic en Crear servidor en un plan. En la ventana del pedido, responde a ¿Para qué plataforma es tu bot? con Telegram y elige Rust.
  3. 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 Rust Bot.
  4. En Conectar con Telegram, pega el token de @BotFather en Pega el token de tu bot, haz clic en Conectar, comprueba el nombre del bot que se muestra y haz clic en Sí, continuar.
  5. En Tu código, haz clic en Subir archivos, luego en Files haz clic en Subir y elige tu programa, llamado bot. O deja que el servidor lo descargue: en la página Bot, panel Código, tarjeta Ajustes, pon en Enlace de descarga (opcional) un enlace https al programa y haz clic en Guardar.
  6. Haz clic en Iniciar bot y abre Console. Después de [PlayNHost] Starting your bot tu bot imprime Logged in as @your_bot, y el indicador de Resumen cambia 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.

Crear el bot en @BotFather y la tarjeta de configuración se explican en Cómo alojar un bot de Telegram. El tipo Rust Bot en sí (el Archivo de entrada, los Argumentos de inicio (opcional) y el enlace de descarga) es el mismo para bots de Discord y de Telegram: Cómo alojar un bot de Discord en Rust. Esta página trata de teloxide: qué usa en un servidor y qué conviene saber antes de alojarlo.

Lo que medimos

BibliotecaVersiónMemoria sin cargaDel inicio a la respuesta de la plataformaTamaño del programa
teloxide (Telegram)0.17.013 MB0.1 s3.0 MB
serenity (Discord)0.12.510 MB0.4 s13.4 MB

Cómo: en nuestro propio nodo, en un contenedor desechable configurado como un plan de bots de 1 GB con una CPU y la imagen de Debian en la que se ejecuta nuestro tipo Rust Bot, cada programa llamó a Telegram o a Discord con un token falso, que fue rechazado. La memoria es la memoria residente 15 segundos después de esa respuesta, el tiempo de inicio va desde el arranque hasta la respuesta, y cada cifra es la mediana de las ejecuciones 2 a 4. Ambos programas se compilaron con Rust estable y cargo build --release en esa misma imagen, con pkg-config y libssl-dev añadidos para la compilación; la compilación de teloxide tardó 107 s con una CPU, descargas incluidas, así que tómalo como una cifra aproximada.

Son valores mínimos: un programa sin chats y sin datos todavía. Tu propio código, lo que guarda en memoria y el número de chats se suman, así que un programa mínimo de teloxide usa una pequeña parte del plan STARTER de 0.5 GB.

Un bot mínimo con teloxide

Responde a /start, lee el token que le da el panel, imprime una línea de listo y dice claramente cuando Telegram rechaza el token. Crea un proyecto con cargo new bot y usa estos dos archivos. El nombre de paquete bot hace que el programa se llame bot, el Archivo de entrada predeterminado.

Cargo.toml

[package]
name = "bot"
version = "0.1.0"
edition = "2021"

[dependencies]
teloxide = { version = "0.17", features = ["macros"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
pretty_env_logger = "0.5"

src/main.rs

use teloxide::{prelude::*, utils::command::BotCommands, ApiError, RequestError};

#[derive(BotCommands, Clone)]
#[command(rename_rule = "lowercase")]
enum Command {
    /// Say hello.
    Start,
}

async fn answer(bot: Bot, msg: Message, cmd: Command) -> ResponseResult<()> {
    match cmd {
        Command::Start => {
            bot.send_message(msg.chat.id, "Hello! I am running on PlayNHost.").await?;
        }
    }
    Ok(())
}

#[tokio::main]
async fn main() {
    // Prints teloxide's errors, such as a 409 Conflict while polling. Without a logger they are silent.
    pretty_env_logger::init();

    // Reads TELOXIDE_TOKEN, which the panel sets from the token on the Telegram pane.
    let bot = Bot::from_env();

    match bot.get_me().await {
        Ok(me) => println!("Logged in as @{}", me.username()),
        Err(RequestError::Api(ApiError::InvalidToken)) => {
            println!("Telegram did not accept the bot token. Paste the current one from @BotFather, then restart.");
            std::process::exit(1);
        }
        Err(err) => {
            println!("Could not start the bot: {err}");
            std::process::exit(1);
        }
    }

    // Long polling: removes a webhook left on the bot, then asks Telegram for messages.
    Command::repl(bot, answer).await;
}

La línea Logged in as @your_bot es lo que cambia el indicador a En línea en Telegram. Command::repl se ejecuta hasta que se detiene el bot. El código sigue el ejemplo de comandos del propio repositorio de teloxide; pretty_env_logger es el logger que usan los ejemplos de teloxide.

Compílalo para Linux

El servidor ejecuta tu programa en Debian 13, con glibc 2.41 y OpenSSL 3. Un .exe de Windows o una compilación de macOS no se ejecuta ahí: la consola dice entonces [PlayNHost] bot is not a Linux program. Build it for Linux x86-64 (not Windows or macOS) and upload it again. Hay dos formas de compilar:

En Linux, con las funciones predeterminadas de teloxide

sudo apt install build-essential pkg-config libssl-dev
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo build --release

El programa es target/release/bot. Las funciones predeterminadas de teloxide usan native-tls, que en Linux enlaza el OpenSSL del sistema, así que la compilación necesita pkg-config y libssl-dev; el servidor tiene OpenSSL 3. Compila en Debian 12 o 13, o en Ubuntu 22.04 o 24.04: su glibc (2.36, 2.41, 2.35 y 2.39) no es más reciente que la del servidor. Un programa compilado en un sistema más nuevo, como Ubuntu 26.04 con glibc 2.43, puede pedir funciones que el servidor no tiene, y entonces se detiene al iniciar con un error que dice que no se encontró una versión GLIBC_. La compilación con musl lo evita.

Desde Windows, macOS o cualquier Linux: una compilación con musl

Un programa musl es un único archivo autocontenido que no depende de las bibliotecas del sistema del servidor. Cambia teloxide de OpenSSL a rustls, que no necesita OpenSSL y trae su propia lista de certificados de confianza. En Cargo.toml, sustituye la línea de teloxide por:

teloxide = { version = "0.17", default-features = false, features = ["macros", "ctrlc_handler", "rustls"] }

Mantén ctrlc_handler en la lista: teloxide solo compila repl con esa función. Después compila con cargo-zigbuild, que usa Zig como enlazador (al instalarlo con pip también se instala Zig):

rustup target add x86_64-unknown-linux-musl
pip install cargo-zigbuild
cargo zigbuild --release --target x86_64-unknown-linux-musl

El programa queda en target/x86_64-unknown-linux-musl/release/bot. teloxide 0.17 indica Rust 1.82 como mínimo, y los crates que usa pueden pedir uno más nuevo, así que ejecuta rustup update stable antes de compilar.

Si el token es incorrecto

En nuestra prueba, con un token falso, bot.get_me() devolvió este error (nuestro programa de prueba lo imprimió después del tipo del error):

teloxide::RequestError: A Telegram's error: Invalid bot token

teloxide convierte la respuesta Unauthorized de Telegram, y el Not Found que recibe un token mal formado, en ApiError::InvalidToken. El bot de arriba lo comprueba antes de empezar el polling, imprime Telegram did not accept the bot token. Paste the current one from @BotFather, then restart. y se detiene. Sin esa comprobación, Command::repl detiene el programa con un panic, Couldn't prepare dispatching context: Api(InvalidToken). El panel reconoce ambos y muestra el aviso Telegram no aceptó el token de tu bot sobre Console.

Para solucionarlo, 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.

Lo que debes saber de teloxide en un servidor

  • El nombre del token. Bot::from_env() lee TELOXIDE_TOKEN y entra en pánico con Cannot get the TELOXIDE_TOKEN env variable cuando falta. El panel lo define en cuanto se guarda un token en el panel Telegram, junto con TELEGRAM_BOT_TOKEN, BOT_TOKEN, TOKEN y TELEGRAM_TOKEN. from_env() también lee TELOXIDE_API_URL y TELOXIDE_PROXY cuando están definidas; no las pongas para hablar con Telegram directamente.
  • Sin logger, sin errores. teloxide informa de los problemas mediante el crate log, así que un programa sin logger no imprime nada cuando falla el polling. pretty_env_logger::init() muestra solo errores, lo que basta: cuando otra copia del bot hace polling con el mismo token, la consola recibe una línea que termina en An error from the update listener: Api(TerminatedByOtherGetUpdates) y el panel muestra Tu bot también se está ejecutando en otro sitio. Para más detalle, en la página Bot, panel Entorno, añade la variable RUST_LOG con el valor info (Añadir variable) y reinicia.
  • El polling nunca se rinde. Cuando falla la petición de mensajes a Telegram, teloxide espera y lo intenta de nuevo, duplicando la espera de 1 segundo hasta 64 segundos, o el tiempo que Telegram pida tras 429 Too Many Requests. Una segunda copia del bot o un token revocado mientras se ejecuta no detiene el programa: sigue funcionando pero recibe pocos mensajes o ninguno, y solo el error registrado muestra el motivo: Api(TerminatedByOtherGetUpdates) para una segunda copia, Api(InvalidToken) para un token revocado. Consulta Solucionar el error 409 Conflict de un bot de Telegram.
  • Un webhook que quedó en el bot se quita por ti. repl y Dispatcher::dispatch() inician long polling con un timeout de 10 segundos y primero llaman a deleteWebhook cuando hay un webhook definido, conservando los mensajes que esperaban. Las funciones webhooks de teloxide necesitan una dirección HTTPS pública, que nuestros planes aún no incluyen, así que usa repl o dispatch().
  • Una parada limpia. El panel detiene un bot de Rust con Ctrl+C (SIGINT). repl activa el manejador de Ctrl+C de teloxide, que detiene el polling e indica a Telegram qué mensajes ya recibió, para que el siguiente inicio no los reciba otra vez. Con tu propio Dispatcher, añade .enable_ctrlc_handler() al builder, como hacen los ejemplos de teloxide.
  • Actualizaciones. El tipo Rust Bot no tiene campo Paquetes ni fuente Git: tus crates van dentro del programa. Para actualizar, borra el programa antiguo en Files, sube la nueva compilación y reinicia. Con un enlace de descarga, publica la nueva compilación en ese enlace, borra el programa en Files y pulsa Iniciar.

Alójalo tú mismo en un VPS Linux

Copia el programa compilado al VPS; allí no hace falta Rust. Un programa compilado con las funciones predeterminadas necesita OpenSSL 3, que tienen Debian 12 y 13 y Ubuntu 22.04 y 24.04, y una glibc al menos tan nueva como la del sistema donde compilaste. La compilación con musl no necesita ninguna de las dos cosas.

Crea un usuario para el bot, pon el programa en su carpeta y guarda el token en un archivo que solo root pueda leer:

sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo install -o mybot -m 755 bot /opt/mybot/bot
sudo sh -c 'echo "TELOXIDE_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env

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

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

[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/opt/mybot/bot
Restart=always
RestartSec=5
KillSignal=SIGINT

[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

KillSignal=SIGINT hace que systemctl stop envíe Ctrl+C, que el manejador de teloxide captura para una parada limpia; el valor por defecto de systemd, SIGTERM, termina el programa al instante. Restart=always inicia el bot de nuevo tras un fallo o una salida. Detén antes cualquier otra copia, o Telegram responderá con 409 Conflict.

Autoalojamiento o un plan de bots

En un VPS que gestionas tú:

  • Actualizaciones y seguridad del sistema operativo, y versiones de OpenSSL y glibc que coincidan con tu compilación.
  • Copiar cada nueva compilación, el archivo de servicio, el archivo del token y sus permisos.
  • Leer journalctl para saber por qué se detuvo el bot.
  • Copias de seguridad de los datos del 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:

  • Una imagen de Debian que ejecuta un programa Linux x86-64, y una comprobación al iniciar que lo avisa cuando el archivo es una compilación de Windows o macOS.
  • Subida en Files, o un enlace de descarga que el servidor obtiene al iniciar.
  • El token, comprobado con Telegram, guardado cifrado y entregado a tu programa como TELOXIDE_TOKEN.
  • Reinicio del bot tras un fallo. Si vuelve a fallar en un minuto, queda detenido y Console explica por qué.
  • Avisos sobre Console que indican la causa cuando Telegram rechaza el token o se está ejecutando otra copia, y un botón Quitar webhook en el panel Telegram.

Preguntas frecuentes

¿Por qué mi bot de teloxide no imprime nada?

teloxide escribe a través del crate log y no imprime nada hasta que se configura un logger. Llama a pretty_env_logger::init() (u otro logger) al principio de main, como hace el bot de arriba. Tus propias líneas println! siempre aparecen en Console.

¿Necesito la función de webhooks de teloxide?

No. Un webhook necesita una dirección HTTPS pública, que nuestros planes aún no incluyen. repl y dispatch() usan long polling, que no necesita dirección: el bot pide a Telegram los mensajes nuevos. También quitan un webhook que un host anterior dejó en el bot.

¿Puede el servidor compilar mi código Rust?

No. El tipo Rust Bot ejecuta un programa terminado y no compila nada, así que toda la memoria de tu plan va al bot. Compila en tu ordenador, o en un flujo de GitHub Actions, adjunta el programa a una release y pon el enlace del archivo en Enlace de descarga (opcional).

¿Un bot de teloxide usa menos memoria que uno de Python?

Compara las cifras: en la misma prueba python-telegram-bot 22.8 usó 44 MB y aiogram 3.31.0 usó 173 MB, frente a 13 MB de teloxide. Los tres caben en el plan STARTER de 0.5 GB con margen para tu propio código, así que elige el lenguaje en el que quieras escribir.

¿Listo para ejecutar tu bot de teloxide todo el día? Mira los planes en alojamiento de bots de Telegram.

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

NUESTROS ÚLTIMOS BLOGS