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 TelegramBots (Java) 24/7

Hosting de bots de TelegramUpdated Nov 6, 202614 min read

Para alojar un bot de TelegramBots (Java) 24/7 lo ejecutas en una máquina que siempre está encendida: un VPS Linux con un servicio systemd que lo vuelve a arrancar cuando se detiene, o un plan de bots en el alojamiento de bots de Telegram de PlayNHost (desde US$1.99 al mes), donde subes un jar ejecutable, pegas el token de @BotFather y pulsas Start. En nuestra prueba, un bot con TelegramBots 10.3.0, la biblioteca Java de rubenlagus, usó unos 91 MB de memoria con Java 21 y recibió la respuesta de Telegram 1,5 segundos después de lanzarlo. Usa su módulo de long polling: nuestros planes aún no tienen una dirección HTTPS pública para un webhook. Los pasos en PlayNHost:

  1. En la página de alojamiento 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 Java.
  2. En tu ordenador, compila el bot con el pom.xml de abajo: mvn package escribe target/bot.jar, con TelegramBots dentro.
  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 Java Bot.
  4. En Conectar con Telegram, pega el token en Pega el token de tu bot, haz clic en Conexión, comprueba el nombre del bot que aparece y haz clic en Sí, continuar.
  5. En Tu código, haz clic en Subir archivos y sube bot.jar a la carpeta principal.
  6. En la página Bot, panel Código, comprueba que Archivo de entrada sea bot.jar y que Entorno de ejecución sea Java 21 (recommended), o Java 17 o 25. Si cambias el Archivo de entrada, haz clic en Guardar a su lado; un nuevo Entorno de ejecución se guarda en cuanto lo eliges.
  7. Haz clic en Iniciar bot y abre Console. Cuando tu bot imprima Logged in as @your_bot, el indicador de Resumen pasa a En línea en Telegram.
  8. En la página Bot, panel Telegram, haz clic en Abrir en Telegram y envía /start a tu bot.

Cómo crear el bot en @BotFather y los pasos del panel se explican en Cómo alojar un bot de Telegram. Esta página trata de TelegramBots en sí: qué usa en un servidor y qué conviene saber antes de alojarlo.

Qué medimos

BibliotecaVersiónMemoria sin cargaDel lanzamiento a la respuesta de TelegramTamaño del jar
TelegramBots (rubenlagus)10.3.091 MB1,5 s9,6 MB
Solo Java 21, sin biblioteca21.0.12.138 MBninguna0,0 MB

Cómo: en nuestro propio nodo, en un contenedor desechable configurado como un plan de bots de 1 GB (la imagen de Java 21 y el comando java exacto de nuestro tipo de bot Java), 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, el tiempo de arranque va del lanzamiento a la respuesta y cada cifra es la mediana de las ejecuciones 2 a 4.

Son mínimos: aún sin chats, sin datos y sin polling. Tu propio código, lo que guarda en memoria y el número de chats se suman, y el script de arranque deja que el heap de Java crezca hasta el 80 por ciento del plan (ver abajo). Compara las cifras con los planes de alojamiento de bots de Telegram y elige según lo que haga tu bot.

Un bot mínimo con TelegramBots

Responde a /start, lee el token de TELEGRAM_BOT_TOKEN (el panel se lo entrega 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:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>bot</artifactId>
  <version>1.0</version>
  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.telegram</groupId>
      <artifactId>telegrambots-longpolling</artifactId>
      <version>10.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.telegram</groupId>
      <artifactId>telegrambots-client</artifactId>
      <version>10.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-simple</artifactId>
      <version>2.0.12</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>bot</finalName>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.7.1</version>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <appendAssemblyId>false</appendAssemblyId>
          <archive>
            <manifest>
              <mainClass>Bot</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

src/main/java/Bot.java

import org.telegram.telegrambots.client.okhttp.OkHttpTelegramClient;
import org.telegram.telegrambots.longpolling.TelegramBotsLongPollingApplication;
import org.telegram.telegrambots.longpolling.util.DefaultLongPollingUpdateConsumer;
import org.telegram.telegrambots.meta.api.methods.GetMe;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.generics.TelegramClient;

public class Bot extends DefaultLongPollingUpdateConsumer {
    private final TelegramClient client;

    Bot(TelegramClient client) {
        this.client = client;
    }

    @Override
    public void consume(Update update) {
        if (update.hasMessage() && update.getMessage().hasText()
                && update.getMessage().getText().startsWith("/start")) {
            SendMessage reply = SendMessage.builder()
                    .chatId(update.getMessage().getChatId())
                    .text("Hello! I am running on PlayNHost.")
                    .build();
            try {
                client.execute(reply);
            } catch (TelegramApiException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        String token = System.getenv("TELEGRAM_BOT_TOKEN");
        if (token == null || token.isBlank()) {
            System.out.println("No TELEGRAM_BOT_TOKEN found. Paste your bot token on the Bot page, then restart.");
            System.exit(1);
        }

        TelegramClient client = new OkHttpTelegramClient(token);
        User me = null;
        try {
            me = client.execute(new GetMe());
        } catch (TelegramApiRequestException e) {
            if (e.getErrorCode() != null && e.getErrorCode() == 401) {
                System.out.println("Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart.");
                System.exit(1);
            }
            throw e;
        }

        try (TelegramBotsLongPollingApplication app = new TelegramBotsLongPollingApplication()) {
            // Long polling: registerBot removes a webhook left on the bot, then asks Telegram for messages.
            app.registerBot(token, new Bot(client));
            System.out.println("Logged in as @" + me.getUserName());
            Thread.currentThread().join();
        }
    }
}

Compílalo con Maven 3.9 y un JDK 17 o más reciente, y prueba el jar en tu ordenador:

mvn package
java -jar target/bot.jar

Sin token imprime No TELEGRAM_BOT_TOKEN found. y se detiene, lo que demuestra que el jar arranca y encuentra su clase principal. Sube target/bot.jar. Detén cualquier copia que ejecutes en tu ordenador con el token real antes de iniciar la del servidor, o las dos copias recibirán errores 409 Conflict de Telegram.

La llamada getMe comprueba el token antes de que empiece el polling y da el nombre de usuario del bot para la línea de listo. Logged in as @your_bot es la línea que cambia el indicador a En línea en Telegram.

Si el token es incorrecto

En nuestra prueba, con un token falso, la llamada getMe de TelegramBots falló con este error:

TelegramApiRequestException: Error executing org.telegram.telegrambots.meta.api.methods.GetMe query: [401] Unauthorized

El bot de arriba captura ese rechazo (código de error 401) e imprime en su lugar Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart. El panel lee esa línea y muestra el aviso Telegram no aceptó el token de tu bot sobre Console. Para solucionarlo, en @BotFather envía /mybots, elige tu bot y luego API Token, y copia de nuevo el token. 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é saber de TelegramBots en un servidor

  • Versiones: TelegramBots 10.3.0 salió el 7 de sep de 2026 y admite la Bot API 10.3 de Telegram. Necesita Java 17 o más reciente, así que cualquier Entorno de ejecución que ofrece el panel (Java 17, 21 o 25) lo ejecuta.
  • Dos paquetes, a diferencia de los tutoriales antiguos. Desde la versión 7.0.0 (marzo de 2024) la biblioteca se divide en telegrambots-longpolling, que recibe mensajes, y telegrambots-client, que los envía. Los tutoriales que extienden TelegramLongPollingBot se escribieron para el paquete antiguo telegrambots, publicado por última vez como 6.9.7.1; esa clase no está en 10.3.0, así que su código no compila con ella.
  • Usa long polling. La biblioteca también tiene un módulo de webhook, pero un webhook necesita una dirección HTTPS pública, que nuestros planes aún no incluyen. registerBot del módulo de long polling llama a deleteWebhook antes de empezar, así que un webhook que quedó de un host anterior se elimina y los mensajes en espera se conservan. Si vienes de un host con webhook: Cómo mover un bot de Telegram a PlayNHost.
  • Añade una biblioteca de logs o la biblioteca queda en silencio. TelegramBots registra mediante SLF4J. Sin un proveedor SLF4J en tu jar, SLF4J imprime una advertencia una vez y luego descarta cada línea de log de la biblioteca, incluidos los errores del polling. El pom.xml de arriba añade slf4j-simple, que escribe las líneas de la biblioteca de nivel INFO y superior en la salida de error estándar, así que aparecen en la Console.
  • Los errores de polling se reintentan, no se lanzan. Cuando falla una llamada getUpdates, TelegramBots registra Error received from Telegram GetUpdates Request, retrying in ... millis y lo intenta de nuevo, así que el proceso sigue en marcha. La espera empieza en cerca de medio segundo y crece a la mitad cada vez hasta cerca de un minuto (con una dispersión aleatoria, hasta 90 segundos); cuando pasan 15 minutos sin una llamada correcta, espera 15 minutos entre intentos. Por eso, tras corregir la causa, reinicia el bot en vez de esperar. Solo el código de estado HTTP, en la línea Caused by del stack trace de debajo, indica qué falló; la descripción propia de Telegram no se imprime. Como registerBot ya eliminó cualquier webhook, un 409 ahí significa casi seguro que otra copia del bot está haciendo polling con el mismo token: detenla. Mira Solucionar el error 409 Conflict de un bot de Telegram.
  • La lección oficial, actualizada: implementa LongPollingSingleThreadUpdateConsumer, que 10.3.0 marca como obsoleta a favor de la clase DefaultLongPollingUpdateConsumer usada arriba; ambas procesan las actualizaciones de una en una en un hilo de fondo. Su línea de listo, MyAmazingBot successfully started!, no cambia el indicador a En línea en Telegram: imprime una línea que empiece por Logged in as, como arriba.
  • Mantén main() esperando. El polling corre en los hilos propios de la biblioteca; la lección termina main() con Thread.currentThread().join() para que el programa no acabe, y el bot de arriba hace lo mismo.
  • Límite de memoria: el script de arranque ejecuta Java con -XX:MaxRAMPercentage=80.0 y el recolector de basura G1, así que el heap puede usar hasta el 80 por ciento de la memoria de tu plan. Si se llena, Java imprime java.lang.OutOfMemoryError y el panel muestra Tu bot se quedó sin memoria.
  • Un jar, nada instalado en el servidor. El tipo de bot Java inicia java -jar sobre tu Archivo de entrada y no tiene campo Paquetes, así que todo debe ir dentro del jar. Sube un jar nuevo para actualizar el bot.

Alójalo tú mismo en un VPS Linux

Un VPS solo necesita un entorno de ejecución de Java, porque compilas el jar en tu propio ordenador. En Debian 13 o Ubuntu 24.04 instala Java 21; Debian 12 trae Java 17, que también ejecuta el jar de arriba:

sudo apt update
sudo apt install openjdk-21-jre-headless
java -version

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

sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp bot.jar /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=TelegramBots Telegram bot
Wants=network-online.target
After=network-online.target

[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/usr/bin/java -XX:MaxRAMPercentage=80.0 -jar /opt/mybot/bot.jar
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Arráncalo ahora y en cada inicio, y luego sigue su salida:

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

Restart=always vuelve a arrancar el bot 5 segundos después de que termine o se caiga, pero no si lo detienes con systemctl stop. En un VPS, -XX:MaxRAMPercentage es una parte de la memoria de toda la máquina, así que redúcelo si allí corren otros programas. Para actualizar, copia el jar nuevo sobre el antiguo y ejecuta sudo systemctl restart mybot.

Alojarlo tú mismo o un plan de bots

En un VPS que gestionas tú te encargas de:

  • Las actualizaciones y la seguridad del sistema operativo, y las actualizaciones de Java.
  • Copiar cada jar nuevo, el archivo de servicio, el archivo del token y sus permisos.
  • Leer journalctl para saber por qué el bot se detuvo o dejó de responder.
  • Las 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 lo hace por ti:

  • Java 17, 21 o 25 desde un selector, con el límite de heap y el recolector de basura ya configurados.
  • 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 menos de un minuto, queda detenido y Console dice por qué.
  • Un botón Quitar webhook en el panel Telegram y avisos sobre Console que nombran la causa, como un token rechazado o la falta de memoria.
  • Subida desde el navegador y copias de seguridad desde el panel.

Preguntas frecuentes

Mi bot de TelegramBots funciona pero no responde nada y no imprime nada. ¿Por qué?

Lo más habitual es que el jar no tenga proveedor SLF4J, así que las líneas de error de la propia biblioteca se descartan mientras sigue reintentando. Añade slf4j-simple como en el pom.xml de arriba, compila de nuevo y mira Console. Un 409 repetido significa que otra copia del bot está haciendo polling con el mismo token; un 401 repetido significa que el token se revocó en @BotFather. Después de arreglarlo, reinicia el bot: la espera de TelegramBots entre intentos puede llegar a 15 minutos.

¿Puedo usar el módulo de webhook de TelegramBots?

Todavía no en nuestros planes: un webhook necesita una dirección HTTPS pública, que no incluyen. El long polling no necesita ninguna, porque el bot pide a Telegram los mensajes nuevos. Usa telegrambots-longpolling como en esta página.

¿TelegramBots necesita un plan mayor que un bot de Python o Node.js?

No por la biblioteca en sí. En la misma prueba, ejecutada del mismo modo, TelegramBots usó 91 MB, python-telegram-bot 22.8 usó 44 MB, grammY 1.46.0 usó 60 MB y aiogram 3.31.0 usó 173 MB, todos muy por debajo de los 0,5 GB del plan más pequeño. Lo que tu bot guarda en memoria decide el resto. En Java, la memoria también depende del heap: el script de arranque deja que crezca hasta el 80 por ciento del plan, y el recolector de basura decide cuánto de eso usa.

¿Qué versión de Java elijo?

Java 21, la recomendada, salvo que tu propio código necesite 25. TelegramBots 10.3.0 necesita Java 17 o más reciente. Compila con un release no más nuevo que el Entorno de ejecución que elijas: un jar compilado para un Java más nuevo se detiene con UnsupportedClassVersionError.

¿Listo para tener tu bot de TelegramBots funcionando a todas horas? Mira los planes en alojamiento de bots de Telegram.

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

NUESTROS ÚLTIMOS BLOGS