Żeby hostować bota Telegram.Bot (.NET) 24/7, uruchamiasz go na maszynie, która jest stale włączona: na VPS z Linuxem z usługą systemd, która uruchamia go ponownie, gdy się zatrzyma, albo w planie botów w hostingu botów Telegram PlayNHost (od 1,99 USD miesięcznie), gdzie wgrywasz projekt w C#, wklejasz token od @BotFather i naciskasz Start. W naszym teście bot z Telegram.Bot 22.10.3.3 zużył około 61 MB pamięci na .NET 8. Telegram.Bot odbiera wiadomości przez long polling, a tego właśnie potrzebują nasze plany: nie mają jeszcze publicznego adresu HTTPS dla webhooka. Kroki w PlayNHost:
- Na stronie hostingu botów Telegram kliknij Utwórz serwer przy wybranym planie. W oknie zamówienia odpowiedz na Na jaką platformę jest Twój bot? wybierając Telegram i wybierz C# (.NET).
- 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 .NET Bot.
- W kroku Połącz z Telegramem wklej token pod Wklej token swojego bota, kliknij Połącz, sprawdź wyświetloną nazwę bota i kliknij Tak, dalej.
- W kroku Twój kod kliknij Prześlij pliki i prześlij
Bot.csprojorazProgram.csdo głównego folderu, bez folderówbiniobj, albo kliknij Połącz Git. - Na stronie Bot, w panelu Kod, zostaw Runtime na .NET 8 (recommended) i zostaw puste pole Plik startowy.
- Kliknij Uruchom bota i otwórz Console. Serwer buduje projekt, potem bot wypisuje
Logged in as @your_bot, a znacznik na stronie Przegląd zmienia się na Online w Telegramie. - 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 Jak hostować bota Telegram, a typ bota .NET ogólnie (oba sposoby wgrywania, błędy kompilacji) opisuje Jak hostować bota Discord w C# (.NET). Ta strona dotyczy samej biblioteki Telegram.Bot: co zużywa na serwerze i co warto wiedzieć, zanim ją zahostujesz.
Co zmierzyliśmy
| Biblioteka | Wersja | Pamięć bez obciążenia | Od startu do odpowiedzi Telegrama, z kompilacją | Od uruchomienia programu do odpowiedzi Telegrama |
|---|---|---|---|---|
| Telegram.Bot | 22.10.3.3 | 61 MB | 1,5 s | 0,3 s |
| Sam .NET 8, bez biblioteki | brak | 24 MB | 1,3 s (kompilacja i start, bez wywołania) | brak |
Jak: na naszym własnym węźle, w jednorazowym kontenerze ustawionym jak plan botów 1 GB (obraz .NET 8 i polecenie startowe naszego typu bota .NET, które przy każdym starcie uruchamia dotnet publish), bot wywołał getMe Telegrama z fałszywym tokenem, który Telegram odrzucił. Pamięć to pamięć rezydentna 15 sekund po tej odpowiedzi, pierwsza kolumna czasu biegnie od początku kompilacji do odpowiedzi, druga od uruchomienia programu, a każda wartość to mediana z uruchomień od 2 do 4. Sama pierwsza kompilacja, która pobiera też pakiet, trwała 5 sekund.
To wartości minimalne: jeszcze bez czatów, bez danych i bez pollingu. Twój własny kod, to, co trzyma w pamięci, i liczba czatów dochodzą do nich. Żeby pominąć kompilację przy każdym starcie, możesz zamiast projektu wgrać pliki opublikowane na własnym komputerze (zobacz przewodnik po C# podlinkowany wyżej). Porównaj liczby z planami w hostingu botów Telegram i wybierz według tego, co robi twój bot.
Minimalny bot Telegram.Bot
Odpowiada na /start, czyta token z TELEGRAM_BOT_TOKEN (panel przekazuje go twojemu kodowi pod tą nazwą, a także jako BOT_TOKEN, TOKEN, TELEGRAM_TOKEN i TELOXIDE_TOKEN) i wypisuje linię gotowości. Dwa pliki w głównym folderze:
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;
Przy każdym starcie serwer uruchamia dotnet publish dla Bot.csproj i startuje Bot.dll. Konsola pokazuje [PlayNHost] Building your bot (the first build downloads packages and can take a minute), potem [PlayNHost] Starting your bot, potem Logged in as @your_bot, czyli linię, która zmienia znacznik na Online w Telegramie. Najpierw zatrzymaj każdą kopię uruchomioną na twoim komputerze z prawdziwym tokenem, bo inaczej obie kopie dostają od Telegrama błędy 409 Conflict.
Gdy token jest błędny
W naszym teście z fałszywym tokenem GetMe() w Telegram.Bot zakończyło się takim błędem:
ApiRequestException: Unauthorized
Powyższy bot przechwytuje to odrzucenie (kod błędu 401), przed pollingiem i w jego trakcie, i zamiast tego wypisuje Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart., po czym kończy działanie z kodem wyjścia 1. Panel czyta tę linię i pokazuje baner Telegram nie przyjął tokena twojego bota nad Console. Aby to naprawić, wyślij w @BotFather /mybots, wybierz swojego bota, potem API Token i skopiuj token ponownie. Na stronie Bot, w panelu Telegram, kliknij Zastąp token, wklej go, kliknij Zapisz token, a potem Zrestartuj teraz.
Co warto wiedzieć o Telegram.Bot na serwerze
- Wersje: Telegram.Bot 22.10.3.3 ukazał się 9 paź 2026. Celuje w .NET Standard 2.0 i .NET 6, a jego README zaleca .NET 8 lub nowszy, więc każdy Runtime oferowany przez panel (.NET 6, 8, 9 lub 10) go kompiluje; .NET 8 (recommended) odpowiada
net8.0wyżej. - Nazwy metod straciły
Asyncw wersji 22. Teraz toGetMe()iSendMessage(); poradniki zGetMeAsynclubSendTextMessageAsyncpisano dla starszych wersji, tych nazw nie ma w 22.10.3.3, więc ich kod się nie kompiluje. Błąd kompilacji jest tuż nad[PlayNHost] The build failed. Read the errors above, fix them and press Start.w Console. - Ustawienie
OnMessageuruchamia polling. Gdy tylko dodasz obsługę doOnMessage(lubOnUpdate), klient odpytuje Telegram w tle i prosi o każdy typ aktualizacji. Najpierw dodaj obsługęOnError, jak wyżej. - Bez
OnErrorbłędy są niewidoczne. Gdy zapytanie pollingu się nie uda, Telegram.Bot przekazuje błąd doOnError; bez obsługi zapisuje go w danych śledzenia .NET, które nie trafiają do konsoli. Bot, któremu unieważniono token albo którego wypycha inna kopia z409 Conflict, wygląda wtedy na działającego i nie odpowiada na nic. Powyższa obsługa wypisuje każdy błąd, a ponieważ tekst Telegrama jest w komunikacie, panel może pokazać Twój bot działa też gdzie indziej albo Dla twojego bota ustawiono webhook. - Zwolnij po błędzie. Pętla pollingu pyta ponownie zaraz po nieudanym żądaniu; czeka tylko tyle, ile trwa twoja obsługa
OnError. OpóźnienieTask.Delaywyżej, równe 5 sekundom, chroni przed tym, by trwały błąd zmienił się w lawinę żądań. Odpowiedzi429 Too Many Requestsod Telegrama są ponawiane za ciebie, gdy Telegram prosi o czekanie do 60 sekund: domyślnie żądanie jest próbowane łącznie do 3 razy. - Webhook nie jest usuwany za ciebie. Polling z ustawionym webhookiem kończy się błędem
409 Conflict:can't use getUpdates method while webhook is active. Powyższy bot wywołujeDeleteWebhook()przed pollingiem, co zachowuje czekające wiadomości; możesz też kliknąć Usuń webhook w panelu Telegram. Własny webhook wymaga publicznego adresu HTTPS, którego nasze plany jeszcze nie mają. Przenosisz się z hostingu z webhookiem: Jak przenieść bota Telegram do PlayNHost. - Nie czekaj przez
Console.ReadLine(). Pierwszy bot z przewodnika biblioteki działa, dopóki nie naciśniesz Enter. Na serwerze nikt nie naciska Enter, a pod systemd wejście programu jest domyślnie puste, więcReadLine()wraca od razu i bot się kończy. Czekaj przezawait Task.Delay(Timeout.Infinite), jak wyżej. - Awarie: gdy bot się kończy, jak powyższy bot przy odrzuconym tokenie, panel od razu uruchamia go ponownie, najpierw budując go jeszcze raz. Jeśli zatrzyma się znowu w ciągu minuty, pozostaje zatrzymany, a Console podaje powód. Zobacz Jak naprawić błąd 409 Conflict bota Telegram, gdzie opisano dwa rodzaje 409.
Hostowanie samodzielnie na VPS z Linuxem
Na VPS zbuduj bota na własnym komputerze i uruchamiaj na serwerze tylko wynik. Opublikuj go za pomocą .NET 8 SDK:
dotnet publish Bot.csproj -c Release -o publish
Na Ubuntu 24.04 środowisko .NET 8 jest we własnych pakietach Ubuntu:
sudo apt update
sudo apt install dotnet-runtime-8.0
dotnet --list-runtimes
Utwórz użytkownika dla bota i skopiuj folder publish na serwer (na przykład za pomocą scp -r), a potem do jego folderu:
sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp -r publish/. /opt/mybot/
sudo chown -R mybot: /opt/mybot
Trzymaj token poza kodem, w pliku, który może czytać tylko root:
sudo sh -c 'echo "TELEGRAM_BOT_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env
Utwórz /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
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 5 sekund po tym, jak się zakończy lub padnie, ale nie po tym, jak zatrzymasz go przez systemctl stop. Żeby zaktualizować, opublikuj ponownie, skopiuj nowe pliki na stare i uruchom sudo systemctl restart mybot. W Debianie .NET nie ma we własnych pakietach dystrybucji; obejmują to instrukcje instalacji Microsoftu.
Samodzielny hosting czy plan botów
Na VPS, którym zarządzasz sam, zajmujesz się:
- Aktualizacjami systemu i bezpieczeństwem oraz aktualizacjami środowiska .NET.
- Publikowaniem i kopiowaniem każdej nowej kompilacji, plikiem usługi, plikiem tokena i jego uprawnieniami.
- Czytaniem
journalctl, by ustalić, dlaczego bot się zatrzymał lub przestał odpowiadać. - Kopiami zapasowymi wszystkiego, co zapisuje twój bot.
W zamian VPS uruchomi cokolwiek, a możesz mu przypisać domenę z HTTPS dla webhooka.
W planie botów PlayNHost robi to za ciebie panel:
- .NET 6, 8, 9 lub 10 z listy wyboru oraz kompilacja: wgraj projekt i naciśnij Start.
- Token, sprawdzony w Telegramie przed zapisaniem, przechowywany w postaci zaszyfrowanej i przekazywany twojemu kodowi pod pięcioma nazwami.
- Ponowne uruchomienie bota po awarii. Jeśli padnie znowu w ciągu minuty, pozostaje zatrzymany, a Console podaje powód.
- Przycisk Usuń webhook w panelu Telegram oraz banery nad Console, które nazywają przyczynę, gdy linia pokazuje odrzucony token, inną kopię lub webhook.
- Wgrywanie plików, wdrożenia z Gita i kopie zapasowe z panelu.
Częste pytania
Mój bot Telegram.Bot działa, ale nigdy nie odpowiada. Dlaczego?
Najczęściej polling zawodzi i nic o tym nie mówi: bez obsługi OnError błędy trafiają do danych śledzenia .NET, a nie do konsoli. Dodaj obsługę z powyższego bota i uruchom ponownie. Zwykłe przyczyny to inna kopia odpytująca z tym samym tokenem (409 Conflict), webhook wciąż ustawiony na bocie albo token unieważniony w @BotFather.
Czy mogę tu użyć Telegram.Bot z webhookiem?
Jeszcze nie w naszych planach: webhook wymaga publicznego adresu HTTPS, którego nie mają. Polling go nie wymaga, bo bot sam pyta Telegram o nowe wiadomości, i właśnie to robi OnMessage.
Czy kompilacja przy każdym starcie spowalnia mojego bota?
Tylko start: w naszym teście start z kompilacją trwał 1,5 sekundy wobec 0,3 sekundy dla samego programu. Gdy bot już działa, jest taki sam. Żeby pominąć kompilację, opublikuj na komputerze i wgraj pliki z folderu publish zamiast projektu.
Którą wersję .NET wybrać?
.NET 8, zalecaną, z net8.0 w projekcie, jak wyżej. Telegram.Bot kompiluje się też na .NET 6, 9 i 10; ustaw tę samą wersję w TargetFramework i w Runtime. Projekt dla nowszego .NET niż Runtime przerywa kompilację z NETSDK1045; projekt dla starszego .NET się kompiluje, ale nie startuje, bo tego .NET nie ma w obrazie.
Gotowy, by twój bot Telegram.Bot działał całą dobę? Zobacz plany w hostingu botów Telegram.



