Pour héberger un bot Telegram.Bot (.NET) 24/7, vous le faites tourner sur une machine toujours allumée : un VPS Linux avec un service systemd qui le relance quand il s'arrête, ou un forfait bot sur l'hébergement de bots Telegram PlayNHost (à partir de 1,99 $US par mois), où vous envoyez votre projet C#, collez le token de @BotFather et appuyez sur Start. Dans notre test, un bot Telegram.Bot 22.10.3.3 a utilisé environ 61 Mo de mémoire sous .NET 8. Telegram.Bot reçoit les messages par long polling, ce dont nos forfaits ont besoin : ils n'ont pas encore d'adresse HTTPS publique pour un webhook. Les étapes sur PlayNHost :
- Sur la page hébergement de bots Telegram, cliquez sur Créer un serveur pour un forfait. Dans la fenêtre de commande, répondez à Pour quelle plateforme est votre bot ? par Telegram et choisissez C# (.NET).
- Ouvrez votre serveur dans le panel. La carte Configurer votre bot de la page Aperçu s’ouvre sur Connexion à Telegram ; sa première étape, Ce qui tourne, doit indiquer Ce bot fait tourner .NET Bot.
- À l'étape Connexion à Telegram, collez le token sous Collez le token de votre bot, cliquez sur Connexion, vérifiez le nom du bot affiché et cliquez sur Oui, continuer.
- À l'étape Votre code, cliquez sur Téléverser des fichiers et envoyez
Bot.csprojetProgram.csdans le dossier principal, sans les dossiersbinetobj, ou cliquez sur Connecter Git. - Sur la page Bot, volet Code, gardez Runtime sur .NET 8 (recommended) et laissez Fichier d’entrée vide.
- Cliquez sur Démarrer le bot et ouvrez Console. Le serveur compile votre projet, puis votre bot affiche
Logged in as @your_botet la pastille de la page Aperçu passe à En ligne sur Telegram. - Sur la page Bot, volet Telegram, cliquez sur Ouvrir dans Telegram et envoyez
/startà votre bot.
La création du bot dans @BotFather et les étapes du panel sont expliquées dans Comment héberger un bot Telegram, et le type de bot .NET en général (les deux façons d'envoyer les fichiers, les erreurs de compilation) dans Comment héberger un bot Discord C# (.NET). Cette page porte sur Telegram.Bot lui-même : ce qu'il consomme sur un serveur et ce qu'il faut savoir avant de l'héberger.
Ce que nous avons mesuré
| Bibliothèque | Version | Mémoire hors charge | Du démarrage à la réponse de Telegram, avec la compilation | Du lancement du programme à la réponse de Telegram |
|---|---|---|---|---|
| Telegram.Bot | 22.10.3.3 | 61 Mo | 1,5 s | 0,3 s |
| .NET 8 seul, sans bibliothèque | aucune | 24 Mo | 1,3 s (compilation et démarrage, sans appel) | aucun |
Comment : sur notre propre nœud, dans un conteneur jetable configuré comme un forfait bot de 1 Go (l'image .NET 8 et la commande de démarrage de notre type de bot .NET, qui exécute dotnet publish à chaque démarrage), le bot a appelé getMe de Telegram avec un faux token, que Telegram a refusé. La mémoire est la mémoire résidente 15 secondes après cette réponse, la première colonne de durée va du début de la compilation à la réponse, la seconde du lancement du programme, et chaque chiffre est la médiane des exécutions 2 à 4. La toute première compilation, qui télécharge aussi le paquet, a pris 5 secondes.
Ce sont des planchers : pas encore de discussions, pas de données et pas encore de polling. Votre propre code, ce qu'il garde en mémoire et le nombre de discussions s'y ajoutent. Pour éviter la compilation à chaque démarrage, vous pouvez envoyer les fichiers que vous avez publiés sur votre ordinateur au lieu du projet (voir le guide C# lié plus haut). Comparez ces chiffres avec les forfaits de l'hébergement de bots Telegram et choisissez selon ce que fait votre bot.
Un bot Telegram.Bot minimal
Il répond à /start, lit le token dans TELEGRAM_BOT_TOKEN (le panel le donne à votre code sous ce nom et aussi sous BOT_TOKEN, TOKEN, TELEGRAM_TOKEN et TELOXIDE_TOKEN) et affiche une ligne de confirmation. Deux fichiers dans le dossier principal :
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;
À chaque démarrage, le serveur exécute dotnet publish sur Bot.csproj et lance Bot.dll. La console affiche [PlayNHost] Building your bot (the first build downloads packages and can take a minute), puis [PlayNHost] Starting your bot, puis Logged in as @your_bot, la ligne qui fait passer la pastille à En ligne sur Telegram. Arrêtez d'abord toute copie que vous faites tourner sur votre ordinateur avec le vrai token, sinon les deux copies reçoivent des erreurs 409 Conflict de Telegram.
Si le token est incorrect
Dans notre test, avec un faux token, GetMe() de Telegram.Bot a échoué avec cette erreur :
ApiRequestException: Unauthorized
Le bot ci-dessus intercepte ce refus (code d'erreur 401), avant le polling et pendant celui-ci, et affiche à la place Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart., puis s'arrête avec le code de sortie 1. Le panel lit cette ligne et affiche la bannière Telegram n’a pas accepté le token de votre bot au-dessus de Console. Pour corriger, envoyez /mybots dans @BotFather, choisissez votre bot, puis API Token, et copiez de nouveau le token. Sur la page Bot, volet Telegram, cliquez sur Remplacer le token, collez-le, cliquez sur Enregistrer le token, puis sur Redémarrer maintenant.
Ce qu'il faut savoir sur Telegram.Bot sur un serveur
- Versions : Telegram.Bot 22.10.3.3 est sorti le 9 oct. 2026. Il cible .NET Standard 2.0 et .NET 6, et son README recommande .NET 8 ou plus récent, donc tout Runtime proposé par le panel (.NET 6, 8, 9 ou 10) le compile ; .NET 8 (recommended) correspond à
net8.0ci-dessus. - Les noms de méthodes ont perdu
Asyncdans la version 22. Ce sont maintenantGetMe()etSendMessage(); les tutoriels avecGetMeAsyncouSendTextMessageAsyncont été écrits pour d'anciennes versions, ces noms n'existent pas dans 22.10.3.3 et leur code ne compile pas. L'erreur de compilation se trouve juste au-dessus de[PlayNHost] The build failed. Read the errors above, fix them and press Start.dans Console. - Définir
OnMessagedémarre le polling. Dès qu'un gestionnaire est ajouté àOnMessage(ouOnUpdate), le client interroge Telegram en arrière-plan et demande tous les types de mises à jour. Ajoutez d'abord le gestionnaireOnError, comme ci-dessus. - Sans
OnError, les erreurs sont invisibles. Quand une interrogation échoue, Telegram.Bot transmet l'erreur àOnError; sans gestionnaire, il l'écrit dans la sortie de trace de .NET, qui n'arrive pas dans la console. Un bot dont le token a été révoqué, ou qu'une autre copie évince avec409 Conflict, semble alors tourner et ne répond à rien. Le gestionnaire ci-dessus affiche chaque erreur et, comme le texte propre à Telegram figure dans le message, le panel peut afficher Votre bot tourne aussi ailleurs ou Un webhook est défini sur votre bot. - Ralentissez après une erreur. La boucle de polling redemande juste après une requête échouée ; elle n'attend que le temps que prend votre gestionnaire
OnError. LeTask.Delayde 5 secondes ci-dessus évite qu'une erreur durable devienne un flot de requêtes. Les réponses429 Too Many Requestsde Telegram sont retentées pour vous quand Telegram demande d'attendre 60 secondes ou moins : par défaut, une requête est tentée jusqu'à 3 fois au total. - Un webhook n'est pas retiré pour vous. Le polling avec un webhook défini échoue avec
409 Conflict:can't use getUpdates method while webhook is active. Le bot ci-dessus appelleDeleteWebhook()avant le polling, ce qui conserve les messages en attente ; vous pouvez aussi cliquer sur Retirer le webhook dans le volet Telegram. Un webhook à vous demande une adresse HTTPS publique, que nos forfaits n'incluent pas encore. Si vous venez d'un hébergeur à webhook : Comment déplacer un bot Telegram vers PlayNHost. - N'attendez pas avec
Console.ReadLine(). Le premier bot du guide de la bibliothèque tourne jusqu'à ce que vous appuyiez sur Entrée. Sur un serveur, personne n'appuie sur Entrée, et sous systemd l'entrée du programme est vide par défaut, doncReadLine()revient aussitôt et le bot se termine. Attendez avecawait Task.Delay(Timeout.Infinite), comme ci-dessus. - Plantages : quand le bot se termine, comme celui ci-dessus avec un token refusé, le panel le relance aussitôt, en le compilant de nouveau d'abord. S'il s'arrête encore dans la minute qui suit, il reste arrêté et Console en donne la raison. Voir Corriger l’erreur 409 Conflict d’un bot Telegram pour les deux types de 409.
L'héberger vous-même sur un VPS Linux
Sur un VPS, compilez le bot sur votre ordinateur et ne faites tourner que le résultat sur le serveur. Publiez-le avec le SDK .NET 8 :
dotnet publish Bot.csproj -c Release -o publish
Sous Ubuntu 24.04, le runtime .NET 8 est dans les paquets propres à Ubuntu :
sudo apt update
sudo apt install dotnet-runtime-8.0
dotnet --list-runtimes
Créez un utilisateur pour le bot et copiez le dossier publish sur le serveur (par exemple avec scp -r), puis dans son dossier :
sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp -r publish/. /opt/mybot/
sudo chown -R mybot: /opt/mybot
Gardez le token hors de votre code, dans un fichier que seul root peut lire :
sudo sh -c 'echo "TELEGRAM_BOT_TOKEN=123456789:your-token" > /etc/mybot.env'
sudo chmod 600 /etc/mybot.env
Créez /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
Démarrez-le maintenant et à chaque démarrage de la machine, puis suivez sa sortie :
sudo systemctl daemon-reload
sudo systemctl enable --now mybot
sudo journalctl -u mybot -f
Restart=always relance le bot 5 secondes après qu'il s'est terminé ou a planté, mais pas après que vous l'avez arrêté avec systemctl stop. Pour mettre à jour, publiez de nouveau, copiez les nouveaux fichiers sur les anciens et exécutez sudo systemctl restart mybot. Sous Debian, .NET n'est pas dans les paquets propres à la distribution ; les instructions d'installation de Microsoft couvrent ce cas.
Auto-hébergement ou forfait bot
Sur un VPS que vous gérez vous-même, vous vous occupez de :
- Les mises à jour du système et la sécurité, ainsi que les mises à niveau du runtime .NET.
- La publication et la copie de chaque nouvelle version, du fichier de service, du fichier du token et de ses permissions.
- La lecture de
journalctlpour savoir pourquoi le bot s'est arrêté ou ne répond plus. - Les sauvegardes de tout ce que stocke votre bot.
En échange, un VPS fait tourner n'importe quoi, et vous pouvez lui donner un domaine en HTTPS pour un webhook.
Sur un forfait bot PlayNHost, le panel s'en charge pour vous :
- .NET 6, 8, 9 ou 10 depuis un sélecteur, et la compilation : envoyez le projet et appuyez sur Start.
- Le token, vérifié auprès de Telegram avant d'être enregistré, stocké chiffré et donné à votre code sous cinq noms.
- Le redémarrage du bot après un plantage. S'il replante dans la minute, il reste arrêté et Console en donne la raison.
- Un bouton Retirer le webhook dans le volet Telegram, et des bannières au-dessus de Console qui nomment la cause quand une ligne montre un token refusé, une autre copie ou un webhook.
- Envoi de fichiers, déploiements Git et sauvegardes depuis le panel.
Questions fréquentes
Mon bot Telegram.Bot tourne mais ne répond jamais. Pourquoi ?
Le plus souvent, le polling échoue sans que rien ne le dise : sans gestionnaire OnError, les erreurs vont dans la sortie de trace de .NET, pas dans la console. Ajoutez le gestionnaire du bot ci-dessus et redémarrez. Les causes habituelles sont une autre copie qui fait du polling avec le même token (409 Conflict), un webhook encore défini sur le bot, ou un token révoqué dans @BotFather.
Puis-je utiliser Telegram.Bot avec un webhook ici ?
Pas encore sur nos forfaits : un webhook demande une adresse HTTPS publique, qu'ils n'incluent pas. Le polling n'en demande aucune, car le bot demande lui-même à Telegram les nouveaux messages, et c'est ce que fait OnMessage.
La compilation à chaque démarrage ralentit-elle mon bot ?
Seulement le démarrage : dans notre test, il a pris 1,5 seconde avec la compilation contre 0,3 seconde pour le programme seul. Une fois lancé, le bot est identique. Pour éviter la compilation, publiez sur votre ordinateur et envoyez les fichiers du dossier publish au lieu du projet.
Quelle version de .NET choisir ?
.NET 8, la version recommandée, avec net8.0 dans votre projet comme ci-dessus. Telegram.Bot compile aussi sous .NET 6, 9 et 10 ; mettez la même version dans TargetFramework et dans Runtime. Un projet pour un .NET plus récent que le Runtime interrompt la compilation avec NETSDK1045 ; un projet pour un .NET plus ancien compile mais ne démarre pas, car ce .NET n'est pas installé dans l'image.
Prêt à faire tourner votre bot Telegram.Bot jour et nuit ? Découvrez les forfaits de l'hébergement de bots Telegram.



