NOWOŚĆ 📢 Ograniczona oferta na start: do 70% zniżki na pierwszy miesiąc, na każdą grę!Zobacz plany

Jak hostować bota grammY 24/7

Hosting botów TelegramUpdated Nov 6, 202610 min read

Aby hostować bota grammY 24/7, uruchamiasz go na maszynie, która jest zawsze włączona: na VPS z Linuksem z usługą systemd, która startuje go ponownie po zatrzymaniu, albo w planie dla botów w PlayNHost (od 1,99 USD miesięcznie), gdzie panel instaluje twoje pakiety, przekazuje kodowi token i uruchamia bota ponownie po awarii. W naszym teście bot grammY 1.46.0 zużywał około 60 MB pamięci na Node.js 22. bot.start() w grammY używa long pollingu, a właśnie tego potrzebują nasze plany: nie mają jeszcze publicznego adresu HTTPS dla webhooka. Kroki w PlayNHost:

  1. Na stronie hostingu botów Telegram kliknij Utwórz serwer przy wybranym planie. W oknie zamówienia na pytanie Na jaką platformę jest Twój bot? odpowiedz Telegram i wybierz Node.js.
  2. Otwórz swój serwer w panelu. Karta Skonfiguruj swojego bota na stronie Przegląd otwiera się na Połącz z Telegramem; jej pierwszy krok, Co działa, powinien pokazywać Ten bot uruchamia Node.js Bot.
  3. W Połącz z Telegramem wklej token z @BotFather w polu Wklej token swojego bota, kliknij Połączenie, sprawdź wyświetloną nazwę bota i kliknij Tak, dalej.
  4. W Twój kod kliknij Prześlij pliki i prześlij package.json oraz index.js bez node_modules albo kliknij Połącz Git. Nie masz jeszcze kodu? Utwórz bota startowego napisze dla ciebie małego bota grammY.
  5. Na stronie Bot, w panelu Kod, sprawdź, czy Plik startowy to plik uruchamiający twojego bota (domyślnie index.js). Jeśli go zmienisz, kliknij Zapisz.
  6. Kliknij Uruchom bota i otwórz Console. Przy pierwszym starcie npm instaluje grammY, potem bot wypisuje Logged in as @your_bot, a znacznik w sekcji Przegląd zmienia się na Online w Telegramie.
  7. Na stronie Bot, w panelu Telegram, kliknij Otwórz w Telegramie i wyślij botowi /start.

Tworzenie bota w @BotFather i kroki w panelu opisuje artykuł Jak hostować bota Telegram. Ta strona dotyczy samego grammY: czego używa na serwerze i co warto wiedzieć przed hostowaniem.

Co zmierzyliśmy

BibliotekaWersjaPamięć w spoczynkuOd startu do odpowiedzi TelegramaRozmiar instalacji
grammY1.46.060 MB0,2 s3,0 MB
Telegraf4.16.360 MB0,2 s2,7 MB
node-telegram-bot-api2.3.063 MB0,2 s2,4 MB
Sam Node.js 22, bez biblioteki22.23.443 MBbrakbrak

Jak mierzyliśmy: na naszym własnym węźle, w jednorazowym kontenerze skonfigurowanym jak plan dla botów 1 GB (obraz Node.js 22 i polecenie startowe naszego typu bota Node.js, z limitem pamięci Node ustawionym na 80 procent), każdy bot wywołał Telegram z fałszywym tokenem, który Telegram odrzucił. Pamięć to pamięć rezydentna 15 sekund po tej odpowiedzi, czas startu liczymy od uruchomienia do odpowiedzi, a każda wartość to mediana uruchomień od 2 do 4.

To wartości minimalne: bot bez czatów i bez danych. Dochodzą do nich twój własny kod, to, co trzyma w pamięci, i liczba czatów, więc biblioteka to niewielka część planu STARTER o pojemności 0,5 GB.

Minimalny bot grammY

Odpowiada na /start, odczytuje token przekazany przez panel i wypisuje linię gotowości. Umieść oba pliki w głównym folderze bota.

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);
});

Panel przekazuje kodowi token jako TELEGRAM_BOT_TOKEN, a także jako BOT_TOKEN, TOKEN, TELEGRAM_TOKEN i TELOXIDE_TOKEN, więc process.env.BOT_TOKEN z innych przykładów też zadziała. To linia Logged in as @your_bot zmienia znacznik na Online w Telegramie.

Jeśli token jest błędny

W naszym teście, z fałszywym tokenem, bot.start() w grammY zatrzymał się z takim błędem:

GrammyError: Call to 'deleteWebhook' failed! (401: Unauthorized)

bot.start() wysyła getMe i deleteWebhook jednocześnie, więc błąd wskazuje wywołanie, które Telegram odrzucił jako pierwsze: w niektórych naszych uruchomieniach było to Call to 'getMe' failed! (401: Unauthorized). grammY nie ponawia odrzuconego tokena: bot.start() kończy się błędem od razu. Powyższy bot przechwytuje ten przypadek i zamiast tego wypisuje Telegram did not accept the bot token. Paste the current one from @BotFather, then restart., a panel pokazuje baner Telegram nie przyjął tokena twojego bota nad Console. Aby to naprawić, w @BotFather wyślij /mybots, wybierz swojego bota, potem API Token i skopiuj token jeszcze raz. Na stronie Bot, w panelu Telegram, kliknij Zastąp token, wklej go, kliknij Zapisz token, a potem Zrestartuj teraz.

Co warto wiedzieć o grammY na serwerze

  • Linia gotowości należy do onStart. bot.start() kończy działanie dopiero, gdy bot się zatrzymuje, więc console.log po await bot.start() nigdy się nie wypisze, dopóki bot działa. grammY wywołuje onStart z danymi twojego bota tuż przed pierwszym pobraniem wiadomości z Telegrama.
  • Błąd w komendzie zatrzymuje bota, jeśli nie ustawisz bot.catch. Bez niego grammY wypisuje No error handler was set!, zatrzymuje polling i zgłasza błąd, więc proces się kończy. Nasz panel uruchamia bota po awarii ponownie w ciągu około minuty, ale do tego czasu jest offline. Z bot.catch, jak powyżej, błąd jest wypisywany, a bot działa dalej.
  • Webhook pozostawiony na bocie zostanie usunięty za ciebie. bot.start() wywołuje deleteWebhook przed pollingiem i zachowuje oczekujące wiadomości, chyba że przekażesz drop_pending_updates: true. Ma to znaczenie, gdy przenosisz bota od hostingu, który używał webhooka: Jak przenieść bota Telegram do PlayNHost.
  • Druga kopia bota zatrzymuje tę. Przy 409 Conflict (ten sam token pobiera wiadomości gdzie indziej) bot.start() kończy się błędem zamiast ponawiać. Panel pokazuje Twój bot działa też gdzie indziej: zatrzymaj kopię na swoim komputerze lub starym hostingu. Zobacz Jak naprawić błąd 409 Conflict bota Telegram.
  • Błędy sieci przy starcie są po cichu ponawiane. Jeśli pierwsze wywołanie Telegrama nie uda się z powodu sieci, grammY próbuje ponownie z coraz dłuższymi przerwami (do 20 minut między próbami w wersji 1.46.0) i nic nie wypisuje. Aby zobaczyć te próby, na stronie Bot, w panelu Środowisko, dodaj zmienną DEBUG o wartości grammy* (Dodaj zmienną) i zrestartuj bota.
  • Wersja Node.js: grammY 1.46.0 wymaga Node.js 12.20 lub 14.13.1 i nowszego. Runtime w panelu Kod oferuje Node.js 20, 22 (recommended), 24, 25 i 26.
  • Limit pamięci: skrypt startowy ustawia NODE_OPTIONS=--max-old-space-size na 80 procent pamięci twojego planu, żeby reszta procesu miała miejsce. Szczegóły skryptu startowego Node.js: Jak hostować bota Discord w Node.js.

Hostowanie samodzielnie na VPS z Linuksem

Na Debianie 12 lub 13 albo Ubuntu 24.04 wystarczy pakiet z dystrybucji (Debian 12 ma Node.js 18.20, Debian 13 ma 20.19, Ubuntu 24.04 ma 18.19):

sudo apt update
sudo apt install nodejs npm
node --version

Utwórz użytkownika dla bota, skopiuj pliki i zainstaluj pakiety:

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

Trzymaj token poza kodem, w pliku czytelnym tylko dla roota:

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

Utwórz plik /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

Uruchom go teraz i przy każdym starcie systemu, a potem śledź jego wyjście:

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

Restart=always uruchamia bota ponownie po awarii lub po process.exit(1). Najpierw zatrzymaj każdą inną kopię, bo inaczej Telegram odpowie obu błędem 409 Conflict.

Własny serwer czy plan dla botów

Na VPS, którym zarządzasz sam, odpowiadasz za:

  • Aktualizacje i bezpieczeństwo systemu oraz aktualizacje Node.js.
  • Uruchamianie npm install po każdej zmianie, plik usługi, plik z tokenem i jego uprawnienia.
  • Czytanie journalctl, żeby sprawdzić, dlaczego bot się zatrzymał.
  • Kopie zapasowe danych bota.

W zamian VPS uruchomi wszystko, a możesz mu przypisać domenę z HTTPS dla webhooka.

W planie dla botów PlayNHost panel robi to za ciebie:

  • Wybór wersji Node.js oraz npm install, gdy zmieni się package.json, plik blokady lub wersja Node.js.
  • Token, sprawdzany w Telegramie przed zapisem, przechowywany w postaci zaszyfrowanej i przekazywany twojemu kodowi.
  • Ponowne uruchomienie bota po awarii. Jeśli padnie znowu w ciągu minuty, zostaje zatrzymany, a Console podaje powód.
  • Banery nad Console, które wskazują przyczynę, gdy Telegram odrzuca token, działa inna kopia lub ustawiony jest webhook, z przyciskiem Usuń webhook w panelu Telegram.
  • Wgrywanie plików, wdrożenia z Gita i kopie zapasowe z poziomu panelu.

Zobacz też Jak używać bazy danych MySQL z botem grammY (mysql2).

Częste pytania

Czy to to samo, co bot startowy z panelu?

Prawie. Na serwerze Node.js Utwórz bota startowego zapisuje index.js i package.json z grammY ^1.46.0: odpowiada na /start twoim imieniem, wypisuje Logged in as @your_bot, przechwytuje błędy przez bot.catch i wypisuje zwykłą linię, gdy Telegram odrzuca token. Zmień go dowolnie i zrestartuj.

Czy muszę usunąć webhook przed bot.start()?

Nie. bot.start() usuwa go przez deleteWebhook przed pollingiem, a oczekujące wiadomości zostają zachowane. Jeśli twój stary kod używał webhookCallback(bot, ...) z serwerem WWW, zamień to na bot.start(): te plany nie mają jeszcze publicznego adresu HTTPS dla webhooka.

Czy bot.start() wystarczy dla bardzo obciążonego bota?

Dla większości botów tak. bot.start() obsługuje wiadomości jedna po drugiej; według własnych uwag grammY nadaje się do około 5.000 wiadomości na godzinę, a przy większym ruchu lub przy komendach trwających długo, na przykład przy dużych transferach plików, odsyła do pakietu @grammyjs/runner. Runner też używa long pollingu, więc działa w naszych planach.

Czy mogę uruchomić grammY na Bun lub Deno zamiast Node.js?

Tak. Przy zamówieniu wybierz Bun lub Deno zamiast Node.js: nasza strona hostingu botów Telegram wymienia grammY dla obu. Kroki na tej stronie dotyczą Node.js.

Gotowy, by twój bot grammY działał całą dobę? Zobacz plany na stronie hostingu botów Telegram.

Twój bot działa już gdzie indziej? Przenieś go do nas

NASZE OSTATNIE WPISY