جديد 📢 عرض الإطلاق لفترة محدودة: خصم حتى 70% على شهرك الأول في كل لعبة.عرض الباقات

استضافة بوت Telegram.Bot (.NET) على مدار الساعة 24/7 على VPS أو باقة

استضافة بوتات TelegramUpdated Nov 6, 202611 min read

لاستضافة بوت Telegram.Bot (.NET) على مدار الساعة 24/7 تشغّله على جهاز يبقى قيد التشغيل دائمًا: إما VPS لينكس مع خدمة systemd تعيد تشغيله عندما يتوقف، وإما باقة بوتات في استضافة بوتات Telegram من PlayNHost (بدءًا من US$1.99 شهريًا)، حيث ترفع مشروع C# الخاص بك وتلصق الرمز من @BotFather وتضغط Start. في اختبارنا استهلك بوت يستخدم Telegram.Bot 22.10.3.3 نحو 61 ميغابايت من الذاكرة على .NET 8. يستقبل Telegram.Bot الرسائل عبر long polling، وهذا ما تحتاجه باقاتنا: ليس لديها بعد عنوان HTTPS عام لاستخدام webhook. الخطوات على PlayNHost:

  1. في صفحة استضافة بوتات Telegram، انقر أنشئ سيرفرًا على إحدى الباقات. في نافذة الطلب أجب عن لأي منصة بوتك؟ باختيار Telegram ثم اختر C# (.NET).
  2. افتح سيرفرك في اللوحة. تُفتح بطاقة إعداد بوتك في نظرة عامة عند الاتصال بـ Telegram؛ ويجب أن تعرض خطوتها الأولى، ما الذي يعمل، العبارة يشغّل هذا البوت .NET Bot.
  3. في الاتصال بـ Telegram، الصق الرمز تحت الصق رمز بوتك، وانقر ربط، وتحقق من اسم البوت الظاهر ثم انقر نعم، متابعة.
  4. في كودك، انقر رفع الملفات وارفع Bot.csproj وProgram.cs إلى المجلد الرئيسي، من دون مجلدي bin وobj، أو انقر ربط Git.
  5. في صفحة بوت، قسم الكود، أبقِ بيئة التشغيل على .NET 8 (recommended) واترك ملف البدء فارغًا.
  6. انقر تشغيل البوت وافتح Console. يبني السيرفر مشروعك، ثم يطبع بوتك Logged in as @your_bot وتتحول الشارة في نظرة عامة إلى متصل في Telegram.
  7. في صفحة بوت، قسم Telegram، انقر افتح في Telegram وأرسل إلى بوتك /start.

إنشاء البوت في @BotFather وخطوات اللوحة مشروحان في كيف تستضيف بوت Telegram، ونوع بوت .NET عمومًا (طريقتا الرفع وأخطاء البناء) في كيف تستضيف بوت Discord بلغة C# (.NET). تتناول هذه الصفحة Telegram.Bot نفسها: ما تستهلكه على السيرفر وما يجب معرفته قبل استضافتها.

ما الذي قسناه

المكتبةالإصدارالذاكرة بلا حملمن البدء إلى رد Telegram، مع البناءمن تشغيل البرنامج إلى رد Telegram
Telegram.Bot22.10.3.361 ميغابايت1.5 ث0.3 ث
.NET 8 وحده، بلا مكتبةلا يوجد24 ميغابايت1.3 ث (البناء والبدء، دون استدعاء)لا يوجد

الطريقة: على عقدتنا الخاصة، في حاوية مؤقتة مضبوطة مثل باقة بوتات بسعة 1 غيغابايت (صورة .NET 8 وأمر البدء لنوع بوت .NET لدينا، الذي ينفذ dotnet publish عند كل بدء)، استدعى البوت getMe لدى Telegram برمز مزيف فرفضه Telegram. الذاكرة هي الذاكرة المقيمة بعد 15 ثانية من ذلك الرد، ويمتد عمود الزمن الأول من بداية البناء حتى الرد، والثاني من تشغيل البرنامج، وكل رقم هو وسيط التشغيلات من 2 إلى 4. أول بناء على الإطلاق، الذي نزّل الحزمة أيضًا، استغرق 5 ثوانٍ.

هذه حدود دنيا: لا محادثات ولا بيانات ولا polling بعد. يضاف إليها كودك الخاص وما يحتفظ به في الذاكرة وعدد المحادثات. لتجاوز البناء عند كل بدء، يمكنك رفع الملفات التي نشرتها على حاسوبك بدل المشروع (راجع دليل C# المرتبط أعلاه). قارن الأرقام بالباقات في استضافة بوتات Telegram واختر بحسب ما يفعله بوتك.

بوت Telegram.Bot بسيط

يرد على /start ويقرأ الرمز من TELEGRAM_BOT_TOKEN (تعطيه اللوحة لكودك بهذا الاسم وأيضًا باسم BOT_TOKEN وTOKEN وTELEGRAM_TOKEN وTELOXIDE_TOKEN) ويطبع سطر الجاهزية. ملفان في المجلد الرئيسي:

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;

عند كل بدء ينفذ السيرفر dotnet publish على Bot.csproj ويشغّل Bot.dll. تعرض وحدة التحكم [PlayNHost] Building your bot (the first build downloads packages and can take a minute) ثم [PlayNHost] Starting your bot ثم Logged in as @your_bot، وهو السطر الذي يحوّل الشارة إلى متصل في Telegram. أوقف أولًا أي نسخة تشغّلها على حاسوبك بالرمز الحقيقي، وإلا تتلقى النسختان أخطاء 409 Conflict من Telegram.

إذا كان الرمز خاطئًا

في اختبارنا، ومع رمز مزيف، فشل الاستدعاء GetMe() في Telegram.Bot بهذا الخطأ:

ApiRequestException: Unauthorized

يلتقط البوت أعلاه هذا الرفض (رمز الخطأ 401) قبل الاستعلام وأثناءه، ويطبع بدلًا منه Telegram did not accept the bot token. Paste the current one from @BotFather on the Bot page, then restart.، ثم يتوقف برمز الخروج 1. تقرأ اللوحة ذلك السطر وتعرض الشريط لم يقبل Telegram رمز بوتك فوق Console. للإصلاح، أرسل في @BotFather الأمر /mybots، واختر بوتك، ثم API Token، وانسخ الرمز مرة أخرى. في صفحة بوت، قسم Telegram، انقر استبدال الرمز، والصقه، وانقر حفظ الرمز، ثم إعادة التشغيل الآن.

ما يجب معرفته عن Telegram.Bot على السيرفر

  • الإصدارات: صدر Telegram.Bot 22.10.3.3 في 9 أكتوبر 2026. يستهدف .NET Standard 2.0 و.NET 6، ويوصي ملف README باستخدام .NET 8 أو أحدث، ولذلك يبنيه أي بيئة التشغيل تعرضه اللوحة (.NET 6 أو 8 أو 9 أو 10)؛ و.NET 8 (recommended) يطابق net8.0 أعلاه.
  • فقدت أسماء الدوال Async في الإصدار 22. أصبحت GetMe() وSendMessage()؛ والدروس التي تستخدم GetMeAsync أو SendTextMessageAsync كُتبت لإصدارات أقدم، وهذه الأسماء غير موجودة في 22.10.3.3 فلا يُبنى كودها. يظهر خطأ البناء فوق [PlayNHost] The build failed. Read the errors above, fix them and press Start. مباشرة في Console.
  • تعيين OnMessage يبدأ الاستعلام. بمجرد إضافة معالج إلى OnMessage (أو OnUpdate) يستعلم العميل من Telegram في الخلفية ويطلب كل أنواع التحديثات. أضف معالج OnError أولًا كما في الأعلى.
  • من دون OnError تبقى الأخطاء غير مرئية. عندما يفشل استعلام يمرر Telegram.Bot الخطأ إلى OnError؛ وإن لم يوجد معالج يكتبه في مخرجات التتبع الخاصة بـ .NET التي لا تصل إلى الطرفية. فالبوت الذي أُلغي رمزه، أو الذي تزيحه نسخة أخرى بخطأ 409 Conflict، يبدو قيد التشغيل ولا يرد على شيء. يطبع المعالج أعلاه كل خطأ، ولأن نص Telegram نفسه موجود في الرسالة تستطيع اللوحة عرض بوتك يعمل في مكان آخر أيضًا أو تم تعيين webhook لبوتك.
  • أبطئ بعد الخطأ. تسأل حلقة الاستعلام من جديد فور فشل الطلب؛ ولا تنتظر إلا بقدر ما يستغرقه معالج OnError لديك. يمنع Task.Delay لمدة 5 ثوانٍ أعلاه أن يتحول خطأ دائم إلى سيل من الطلبات. وردود 429 Too Many Requests من Telegram تُعاد محاولتها عنك عندما يطلب Telegram الانتظار 60 ثانية أو أقل: افتراضيًا يُجرَّب الطلب حتى 3 مرات في المجموع.
  • لا يُزال الـ webhook عنك تلقائيًا. يفشل الاستعلام مع وجود webhook بالخطأ 409 Conflict: can't use getUpdates method while webhook is active. يستدعي البوت أعلاه DeleteWebhook() قبل الاستعلام، مما يحفظ الرسائل المنتظرة؛ ويمكنك أيضًا النقر على إزالة الـ webhook في قسم Telegram. يحتاج webhook خاص بك إلى عنوان HTTPS عام، وباقاتنا لا تتضمنه بعد. إذا كنت تنتقل من استضافة تستخدم webhook: كيف تنقل بوت Telegram إلى PlayNHost.
  • لا تنتظر باستخدام Console.ReadLine(). أول بوت في دليل المكتبة يستمر في العمل حتى تضغط Enter. على السيرفر لا أحد يضغط Enter، وتحت systemd يكون إدخال البرنامج فارغًا افتراضيًا، فيعود ReadLine() فورًا وينتهي البوت. انتظر باستخدام await Task.Delay(Timeout.Infinite) كما في الأعلى.
  • الأعطال: عندما ينتهي البوت، كما يفعل البوت أعلاه عند رفض الرمز، تعيد اللوحة تشغيله فورًا وتبنيه من جديد أولًا. وإذا توقف مرة أخرى خلال دقيقة من ذلك يبقى متوقفًا وتذكر Console السبب. راجع إصلاح خطأ 409 Conflict في بوت Telegram لمعرفة نوعي 409.

استضفه بنفسك على VPS لينكس

على VPS ابنِ البوت على حاسوبك ولا تشغّل على السيرفر إلا الناتج. انشره باستخدام .NET 8 SDK:

dotnet publish Bot.csproj -c Release -o publish

على Ubuntu 24.04 توجد بيئة تشغيل .NET 8 في حزم Ubuntu نفسها:

sudo apt update
sudo apt install dotnet-runtime-8.0
dotnet --list-runtimes

أنشئ مستخدمًا للبوت وانسخ المجلد publish إلى السيرفر (مثلًا باستخدام scp -r)، ثم إلى مجلده:

sudo useradd --system --create-home --home-dir /opt/mybot mybot
sudo cp -r publish/. /opt/mybot/
sudo chown -R mybot: /opt/mybot

أبقِ الرمز خارج كودك، في ملف لا يستطيع قراءته إلا root:

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

أنشئ /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

شغّله الآن وعند كل إقلاع، ثم تابع مخرجاته:

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

Restart=always يعيد تشغيل البوت بعد 5 ثوانٍ من انتهائه أو انهياره، لكن ليس بعد أن توقفه بالأمر systemctl stop. للتحديث، انشر من جديد، وانسخ الملفات الجديدة فوق القديمة ونفّذ sudo systemctl restart mybot. على Debian لا يوجد .NET في حزم التوزيعة نفسها؛ وتغطي تعليمات التثبيت من Microsoft ذلك.

الاستضافة الذاتية أم باقة بوتات

على VPS تديره بنفسك تتولى:

  • تحديثات نظام التشغيل والأمان، وترقيات بيئة تشغيل .NET.
  • نشر كل بناء جديد ونسخه، وملف الخدمة، وملف الرمز وصلاحياته.
  • قراءة journalctl لمعرفة سبب توقف البوت أو توقفه عن الرد.
  • النسخ الاحتياطية لكل ما يخزنه بوتك.

في المقابل يشغّل الـ VPS أي شيء، ويمكنك ربطه بنطاق مع HTTPS لاستخدام webhook.

في باقة بوتات PlayNHost تتولى اللوحة ذلك عنك:

  • .NET 6 أو 8 أو 9 أو 10 من قائمة اختيار، والبناء: ارفع المشروع واضغط Start.
  • الرمز، يُتحقق منه لدى Telegram قبل حفظه، ويُخزَّن مشفرًا ويُعطى لكودك بخمسة أسماء.
  • إعادة تشغيل البوت بعد الانهيار. وإذا انهار مرة أخرى خلال دقيقة يبقى متوقفًا وتذكر Console السبب.
  • زر إزالة الـ webhook في قسم Telegram، وشرائط فوق Console تسمّي السبب عندما يُظهر سطر رمزًا مرفوضًا أو نسخة أخرى أو webhook.
  • الرفع ونشر Git والنسخ الاحتياطية من اللوحة.

أسئلة شائعة

بوت Telegram.Bot الخاص بي يعمل لكنه لا يرد أبدًا. لماذا؟

في الغالب يفشل الاستعلام ولا يخبرك شيء: من دون معالج OnError تذهب الأخطاء إلى مخرجات التتبع الخاصة بـ .NET لا إلى الطرفية. أضف المعالج من البوت أعلاه وأعد التشغيل. الأسباب المعتادة نسخة أخرى تستعلم بالرمز نفسه (409 Conflict)، أو webhook ما زال معيّنًا على البوت، أو رمز أُلغي في @BotFather.

هل يمكنني استخدام Telegram.Bot مع webhook هنا؟

ليس بعد في باقاتنا: يحتاج webhook إلى عنوان HTTPS عام وهي لا تتضمنه. أما الاستعلام فلا يحتاج إلى شيء منه، لأن البوت يطلب من Telegram الرسائل الجديدة، وهذا ما يفعله OnMessage.

هل يبطئ البناء عند كل بدء بوتي؟

البدء فقط: في اختبارنا استغرق البدء 1.5 ثانية مع البناء مقابل 0.3 ثانية للبرنامج وحده. وبعد أن يعمل يكون البوت كما هو. لتجاوز البناء انشر على حاسوبك وارفع ملفات المجلد publish بدل المشروع.

أي إصدار من .NET أختار؟

.NET 8، وهو الموصى به، مع net8.0 في مشروعك كما في الأعلى. يُبنى Telegram.Bot أيضًا على .NET 6 و9 و10؛ اضبط الإصدار نفسه في TargetFramework وفي بيئة التشغيل. المشروع الموجّه إلى .NET أحدث من بيئة التشغيل يوقف البناء بالخطأ NETSDK1045؛ والموجّه إلى .NET أقدم يُبنى لكنه لا يبدأ، لأن ذلك الإصدار غير مثبت في الصورة.

هل أنت مستعد لتشغيل بوت Telegram.Bot على مدار الساعة؟ اطلع على الباقات في استضافة بوتات Telegram.

بوتك مستضاف في مكان آخر بالفعل؟ انقله إلينا

أحدث مقالات المدونة