Para hospedar um bot grammY 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 da PlayNHost (a partir de US$1,99 por mês), em que o painel instala seus pacotes, entrega o token ao seu código e reinicia o bot se ele travar. No nosso teste, um bot com grammY 1.46.0 usou cerca de 60 MB de memória no Node.js 22. O bot.start() do grammY usa 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:
- Em 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 Node.js.
- 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 Node.js Bot.
- Em Conectar ao Telegram, cole o token do @BotFather em Cole o token do seu bot, clique em Conectar, confira o nome do bot exibido e clique em Sim, continuar.
- Em Seu código, clique em Enviar arquivos e envie seu
package.jsone seuindex.jssemnode_modules, ou clique em Conectar o Git. Ainda sem código? Criar um bot inicial escreve um pequeno bot grammY para você. - Na página Bot, painel Código, confira se Arquivo de entrada é o arquivo que inicia seu bot (
index.jspor padrão). Clique em Salvar se você mudar. - Clique em Iniciar bot e abra Console. O npm instala o grammY na primeira inicialização, depois seu bot imprime
Logged in as @your_bote o indicador em Visão geral muda para Online no Telegram. - Na página Bot, painel Telegram, clique em Abrir no Telegram e envie
/startao seu bot.
Como criar o bot no @BotFather e o que fazem os passos do painel está explicado em Como hospedar um bot do Telegram. Esta página trata do próprio grammY: o que ele usa em um servidor e o que saber antes de hospedá-lo.
O que medimos
| Biblioteca | Versão | Memória em repouso | Do início à resposta do Telegram | Tamanho da instalação |
|---|---|---|---|---|
| grammY | 1.46.0 | 60 MB | 0,2 s | 3,0 MB |
| Telegraf | 4.16.3 | 60 MB | 0,2 s | 2,7 MB |
| node-telegram-bot-api | 2.3.0 | 63 MB | 0,2 s | 2,4 MB |
| Só o Node.js 22, sem biblioteca | 22.23.4 | 43 MB | nenhum | 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 Node.js 22 e o comando de inicialização do nosso tipo de bot Node.js, com o limite de memória do Node em 80 por cento), cada bot chamou o Telegram com um token falso, que o Telegram recusou. A memória é a memória residente 15 segundos depois dessa resposta, o tempo de inicialização vai do lançamento até a resposta, e cada valor é a mediana das execuções 2 a 4.
São valores mínimos: um bot sem conversas e sem dados ainda. Seu próprio código, o que ele guarda na memória e o número de conversas se somam a eles, então a biblioteca é uma pequena parte do plano STARTER de 0,5 GB.
Um bot grammY mínimo
Ele responde a /start, lê o token que o painel entrega e imprime uma linha de pronto. Coloque os dois arquivos na pasta principal do seu bot.
package.json
{
"name": "my-grammy-bot",
"private": true,
"main": "index.js",
"dependencies": {
"grammy": "^1.46.0"
}
}
index.js
const { Bot, GrammyError } = require("grammy");
const bot = new Bot(process.env.TELEGRAM_BOT_TOKEN);
bot.command("start", (ctx) => ctx.reply("Hello! I am running on PlayNHost."));
// Without this, an error in one command stops the whole bot.
bot.catch((err) => {
console.error(`Error while handling update ${err.ctx.update.update_id}:`, err.error);
});
// bot.start() only returns when the bot stops, so the ready line goes in onStart.
bot.start({
onStart: (me) => console.log(`Logged in as @${me.username}`),
}).catch((err) => {
if (err instanceof GrammyError && err.error_code === 401) {
console.log("Telegram did not accept the bot token. Paste the current one from @BotFather, then restart.");
} else {
console.error(err);
}
process.exit(1);
});
O painel entrega o token ao seu código como TELEGRAM_BOT_TOKEN, e também como BOT_TOKEN, TOKEN, TELEGRAM_TOKEN e TELOXIDE_TOKEN, então o process.env.BOT_TOKEN de outros exemplos também funciona. A linha Logged in as @your_bot é o que muda o indicador para Online no Telegram.
Se o token estiver errado
No nosso teste, com um token falso, o bot.start() do grammY parou com este erro:
GrammyError: Call to 'deleteWebhook' failed! (401: Unauthorized)
O bot.start() envia getMe e deleteWebhook ao mesmo tempo, então o erro nomeia a chamada que o Telegram recusou primeiro: em algumas de nossas execuções foi Call to 'getMe' failed! (401: Unauthorized). O grammY não tenta de novo um token recusado: o bot.start() falha na hora. O bot acima captura esse caso e imprime no lugar Telegram did not accept the bot token. Paste the current one from @BotFather, then restart., e o painel 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 grammY em um servidor
- A linha de pronto vai em
onStart. Obot.start()só retorna quando o bot para, então umconsole.logdepois deawait bot.start()nunca é impresso enquanto ele roda. O grammY chamaonStartcom os dados do seu bot logo antes de pedir ao Telegram as primeiras mensagens. - Um erro em um comando para o bot se você não definir
bot.catch. Sem ele, o grammY imprimeNo error handler was set!, para o polling e lança o erro, então o processo termina. Nosso painel reinicia um bot que travou em cerca de um minuto, mas até lá ele fica offline. Combot.catch, como acima, o erro é impresso e o bot continua. - Um webhook deixado no bot é removido para você. O
bot.start()chamadeleteWebhookantes de fazer polling e mantém as mensagens em espera, a menos que você passedrop_pending_updates: true. Isso importa quando você muda um bot de uma hospedagem que usava webhook: Como migrar um bot do Telegram para a PlayNHost. - Outra cópia do bot derruba esta. Em
409 Conflict(o mesmo token fazendo polling em outro lugar), obot.start()falha em vez de tentar de novo. O painel mostra Seu bot também está rodando em outro lugar: pare a cópia no seu PC ou na sua hospedagem antiga. Veja Como corrigir o erro 409 Conflict do bot do Telegram. - Erros de rede na inicialização são repetidos em silêncio. Se a primeira chamada ao Telegram falhar por causa da rede, o grammY tenta de novo com esperas cada vez maiores (até 20 minutos entre as tentativas na versão 1.46.0) e não imprime nada. Para ver essas tentativas, na página Bot, painel Ambiente, adicione a variável
DEBUGcom o valorgrammy*(Adicionar variável) e reinicie. - Versão do Node.js: o grammY 1.46.0 pede Node.js 12.20 ou 14.13.1 e mais novo. O Runtime no painel Código oferece Node.js 20, 22 (recommended), 24, 25 e 26.
- Limite de memória: o script de inicialização define
NODE_OPTIONS=--max-old-space-sizeem 80 por cento da memória do seu plano, para sobrar espaço ao resto do processo. Detalhes do script de inicialização do Node.js: Como hospedar um bot do Discord em Node.js.
Hospede você mesmo em uma VPS Linux
No Debian 12 ou 13, ou no Ubuntu 24.04, o pacote da distribuição basta para o grammY (o Debian 12 traz Node.js 18.20, o Debian 13 traz 20.19, o Ubuntu 24.04 traz 18.19):
sudo apt update
sudo apt install nodejs npm
node --version
Crie um usuário para o bot, copie seus arquivos e instale os pacotes:
sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp package.json index.js /opt/mybot/
sudo chown -R mybot: /opt/mybot
cd /opt/mybot && sudo -u mybot npm install --omit=dev
Mantenha o token fora do seu código, em um arquivo que só o root consiga 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=grammY Telegram bot
Wants=network-online.target
After=network-online.target
[Service]
User=mybot
WorkingDirectory=/opt/mybot
EnvironmentFile=/etc/mybot.env
ExecStart=/usr/bin/node index.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Inicie agora e a cada boot, e depois acompanhe a saída:
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo journalctl -u mybot -f
Restart=always inicia o bot de novo depois de uma falha ou de um process.exit(1). Pare antes qualquer outra cópia, ou o Telegram responde às duas com 409 Conflict.
Hospedar por conta própria ou usar um plano de bots
Em uma VPS que você mesmo gerencia, você cuida de:
- Atualizações e segurança do sistema operacional, e upgrades do Node.js.
- Executar
npm installdepois de cada mudança, o arquivo de serviço, o arquivo do token e as permissões dele. - Ler o
journalctlpara descobrir por que o bot parou. - Backups dos dados do bot.
Em troca, uma VPS executa 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ê:
- Um seletor de versão do Node.js e
npm installquandopackage.json, o arquivo de lock ou a versão do Node.js mudam. - O token, verificado no Telegram antes de ser salvo, guardado criptografado e entregue ao seu código.
- Reiniciar o bot depois de uma falha. Se ele falhar de novo em um minuto, fica parado e o Console diz o motivo.
- Avisos acima do Console que nomeiam a causa quando o Telegram recusa o token, outra cópia está rodando ou há um webhook definido, com um botão Remover webhook no painel Telegram.
- Envio de arquivos, deploys por Git e backups pelo painel.
Veja também Como usar um banco de dados MySQL com um bot grammY (mysql2).
Perguntas frequentes
Isso é o mesmo que o bot inicial do painel?
Quase. Em um servidor Node.js, Criar um bot inicial escreve index.js e package.json com grammY ^1.46.0: ele responde a /start com seu primeiro nome, imprime Logged in as @your_bot, captura erros com bot.catch e imprime uma linha simples quando o Telegram recusa o token. Mude como quiser e reinicie.
Preciso remover meu webhook antes do bot.start()?
Não. O bot.start() o remove com deleteWebhook antes de fazer polling, e as mensagens que estavam esperando são mantidas. Se o seu código antigo usava webhookCallback(bot, ...) com um servidor web, troque por bot.start(): esses planos ainda não têm um endereço HTTPS público para um webhook.
O bot.start() basta para um bot movimentado?
Para a maioria dos bots, sim. O bot.start() trata as mensagens uma depois da outra; as próprias notas do grammY dizem que serve para cerca de 5.000 mensagens por hora, e indicam o pacote @grammyjs/runner para mais do que isso, ou para comandos demorados, como grandes transferências de arquivos. O runner também usa long polling, então funciona nos nossos planos.
Posso rodar o grammY no Bun ou no Deno em vez do Node.js?
Sim. Ao fazer o pedido, escolha Bun ou Deno em vez de Node.js: nossa página de hospedagem de bots do Telegram lista o grammY para os dois. Os passos desta página são para o Node.js.
Pronto para manter seu bot grammY rodando o dia todo? Veja os planos em hospedagem de bots do Telegram.



