تطوير البوتات
مرجع Bot API
جمعنا هنا كل الطرق التي تقبلها واجهة HTTP Bot API في Pabal، والكائنات التي تتبادلها، والأخطاء، دون استثناء. وهي متوافقة مع Bot API الخاصة بـ Telegram.
تستخدم واجهة HTTP Bot API في Pabal صيغة العناوين والطلبات والاستجابات والأخطاء نفسها المستخدمة في Telegram Bot API. ولا يذكر هذا المستند إلا ما يقبله Pabal فعلاً، والطرق غير المذكورة هنا تعيد 404 Not Found: method not found. وإن كانت هذه أول مرة لك، فابدأ بـدرس إنشاء البوت.
إرسال الطلبات
https://pabal.me/bot<token>/<method>
- فعل HTTP: يعمل
GETوPOSTكلاهما. - المعاملات تُرسل بإحدى أربع طرق — سلسلة الاستعلام (
?chat_id=1&text=hi)، وapplication/x-www-form-urlencoded، وapplication/json، وmultipart/form-dataعند رفع الملفات. ويمكنك المزج بينها. - المعاملات التي هي كائنات (
reply_markup،commands،allowed_updates) تُمرَّر كما هي كائناتٍ ومصفوفاتٍ في جسم JSON، وكسلسلة JSON في النموذج أو سلسلة الاستعلام. - أسماء الطرق لا تميّز بين الأحرف الكبيرة والصغيرة (
sendMessage=sendmessage). - حجم الجسم حتى 12MB (وإذا تجاوزه فالنتيجة
413). - تنزيل الملفات له عنوان منفصل:
https://pabal.me/file/bot<token>/<file_path>(getFile).
الاستجابات والأخطاء
الاستجابة دائماً بصيغة JSON. عند النجاح تصل HTTP 200 مع result، وعند الفشل تصل حالة HTTP المعنية مع error_code مطابق لها، وdescription يقرؤه البشر.
{"ok": true, "result": { … }}{"ok": false, "error_code": 400, "description": "Bad Request: chat not found"}| error_code | متى | أمثلة على description |
|---|---|---|
400 | المعاملات خاطئة | Bad Request: chat not found، Bad Request: message text is empty، Bad Request: message is not modified: …، Bad Request: message to edit not found، Bad Request: wrong file identifier/HTTP URL specified، Bad Request: query is too old and response timeout expired or query ID is invalid |
401 | الرمز المميّز خاطئ | Unauthorized |
403 | لا صلاحية للإرسال | Forbidden: bot can't initiate conversation with a user، Forbidden: bot is not a member of the group chat |
404 | طريقة أو ملف غير موجود | Not Found: method not found |
409 | استدعاء getUpdates مع وجود webhook | Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first |
413 | الجسم يتجاوز 12MB | Request Entity Too Large |
500 | خطأ داخلي في الخادم | Internal Server Error |
لا يفرض Pabal حالياً حداً لمعدل الطلبات (429 Too Many Requests)، لكنه قد يُضاف مستقبلاً، لذا اكتب شيفرتك بحيث إذا استلمت 429 انتظرت parameters.retry_after ثانية ثم أعادت الإرسال.
استلام التحديثات
استخدم إحدى الطريقتين، إذ لا يمكن استخدامهما معاً.
getUpdates
POST/bot<token>/getUpdates
تجلب التحديثات المنتظرة (الاستطلاع الطويل). وإذا كان webhook مضبوطاً فالنتيجة 409.
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
offset | Integer | اختياري | التحديثات التي رقمها يساوي هذا الرقم أو يزيد عليه فقط. وما هو أصغر منه يُحذف باعتباره «مُستلَماً». مرّر update_id + 1 لآخر تحديث عالجته. |
limit | Integer | اختياري | من 1 إلى 100، والافتراضي 100 |
timeout | Integer | اختياري | عدد ثواني الانتظار، من 0 إلى 50، والافتراضي 0. ننصح بقيمة بين 25 و30. |
allowed_updates | Array of String | يُتجاهل | يُقبل لكنه لا يُستخدم. ولتصفية الأنواع، صفّها بعد الاستلام. |
القيمة المعادة: Array of Update
setWebhook
POST/bot<token>/setWebhook
لاستلام التحديثات على عنوان HTTPS. والشرح المفصّل في مستند Webhooks.
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
url | String | نعم | عنوان https:// عام. والسلسلة الفارغة تحذف webhook |
secret_token | String | اختياري | من 1 إلى 256 حرفاً، A-Z a-z 0-9 _ -. يُرسل في ترويسة الطلب X-Telegram-Bot-Api-Secret-Token |
allowed_updates | Array of String | اختياري | من بين message، edited_message، callback_query. إذا تُركت فارغة فكلها |
drop_pending_updates | Boolean | اختياري | إهمال التحديثات المنتظرة |
max_connections | Integer | اختياري | من 1 إلى 100، والافتراضي 40. تُحفظ فقط، والتسليم تحديث واحد في كل مرة لكل بوت |
certificate | InputFile | غير مدعوم | 400 — استخدم شهادة عامة |
ip_address | String | يُتجاهل |
القيمة المعادة: True
deleteWebhook
POST/bot<token>/deleteWebhook
تحذف webhook وتعود إلى getUpdates. وتنجح حتى لو لم يكن هناك webhook.
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
drop_pending_updates | Boolean | اختياري | إهمال التحديثات المنتظرة |
القيمة المعادة: True
getWebhookInfo
GET/bot<token>/getWebhookInfo
حالة webhook. بلا معاملات. وإذا لم يكن هناك webhook فإن url سلسلة فارغة.
القيمة المعادة: WebhookInfo
الطرق
| الطريقة | ما تفعله |
|---|---|
getMe | معلومات البوت نفسه |
sendMessage | إرسال نص (مع الأزرار) |
sendPhoto | إرسال صورة |
editMessageText | تعديل نص رسالة مرسلة وأزرارها |
editMessageCaption | تعديل وصف الصورة |
editMessageReplyMarkup | تعديل الأزرار فقط |
deleteMessage | حذف رسالة |
answerCallbackQuery | الرد على ضغط زر |
sendChatAction | إظهار «يكتب الآن» (يُقبل الطلب فقط) |
getChat | معلومات المحادثة |
getFile | مسار تنزيل صورة مستلمة |
setMyCommands · getMyCommands · deleteMyCommands | قائمة الأوامر |
logOut · close | للتوافق (لا تفعل شيئاً) |
getUpdates · setWebhook · deleteWebhook · getWebhookInfo | استلام التحديثات (أعلاه) |
chat_id
في المحادثة الفردية معرّف الشخص (عدد موجب)، وفي المجموعة الأساسية معرّف المجموعة (عدد سالب)، أو اسم مستخدم الشخص ("@hana_lee"). ويمكن معرفة كل ذلك من chat.id في التحديث. أما معرّفات القنوات والمجموعات الخارقة (-100…) فغير موجودة بعد (400 chat not found).
getMe
GET/bot<token>/getMe
تُستخدم للتحقق من صحة الرمز المميّز. بلا معاملات.
القيمة المعادة: User — ويُضاف للبوت can_join_groups (true)، وcan_read_all_group_messages (true)، وsupports_inline_queries (false)، وcan_connect_to_business (false)، وhas_main_web_app (false).
sendMessage
POST/bot<token>/sendMessage
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
chat_id | Integer أو String | نعم | المحادثة المرسل إليها (انظر المربع أعلاه) |
text | String | نعم | من 1 إلى 4,096 حرفاً. يُرسل النص كما هو |
reply_markup | InlineKeyboardMarkup · ReplyKeyboardMarkup · ReplyKeyboardRemove · ForceReply | اختياري | الأزرار |
disable_notification | Boolean | اختياري | الإرسال دون صوت |
parse_mode، entities، reply_parameters، link_preview_options … | يُتجاهل | تُقبل لكنها لا تُستخدم. ولا يُطبّق أي تنسيق |
القيمة المعادة: الرسالة المرسلة Message
للإرسال إلى شخص يجب أن يكون هو من بدأ المحادثة مع البوت (403 Forbidden: bot can't initiate conversation with a user). وللإرسال إلى مجموعة يجب أن يكون البوت عضواً فيها.
sendPhoto
POST/bot<token>/sendPhoto
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
chat_id | Integer أو String | نعم | المحادثة المرسل إليها |
photo | InputFile أو String | نعم | ملف مرفوع بصيغة multipart/form-data (حتى 10MB، بصيغ JPEG وPNG وGIF)، أو file_id لصورة استلمتها من قبل. عناوين URL غير مدعومة بعد |
caption | String | اختياري | من 0 إلى 1,024 حرفاً |
reply_markup | مثل sendMessage | اختياري | |
disable_notification | Boolean | اختياري |
القيمة المعادة: الرسالة المرسلة Message (مع file_id جديد في photo)
editMessageText
POST/bot<token>/editMessageText
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
chat_id | Integer أو String | نعم | المحادثة التي فيها الرسالة |
message_id | Integer | نعم | الرسالة المراد تعديلها (مما أرسله البوت) |
text | String | نعم | النص الجديد، من 1 إلى 4,096 حرفاً |
reply_markup | InlineKeyboardMarkup | اختياري | الأزرار الجديدة. إذا حذفته تختفي الأزرار (كما في Telegram) |
inline_message_id | String | غير مدعوم | 400 لعدم وجود الوضع المضمّن (inline) |
القيمة المعادة: الرسالة المعدّلة Message. ينعكس التعديل فوراً في التطبيق، والرسائل التي يعدّلها الأشخاص تصل إلى البوت على شكل edited_message.
إذا كان النص والأزرار مطابقين لما سبق فالنتيجة 400 Bad Request: message is not modified: …، وإذا حاولت تعديل رسالة غيرك فالنتيجة 400 Bad Request: message can't be edited.
editMessageCaption
POST/bot<token>/editMessageCaption
المعاملات: chat_id، وmessage_id، وcaption (من 0 إلى 1,024 حرفاً، وحذفه يمسح الوصف)، وreply_markup. القيمة المعادة: الرسالة المعدّلة Message.
editMessageReplyMarkup
POST/bot<token>/editMessageReplyMarkup
تُبقي النص كما هو وتغيّر الأزرار فقط. المعاملات: chat_id، وmessage_id، وreply_markup (حذفه يمسح الأزرار). القيمة المعادة: الرسالة المعدّلة Message.
deleteMessage
POST/bot<token>/deleteMessage
المعاملات: chat_id، وmessage_id. تحذف الرسالة من طرفي المحادثة. وإذا لم تكن الرسالة موجودة فالنتيجة 400 Bad Request: message to delete not found. القيمة المعادة: True.
answerCallbackQuery
POST/bot<token>/answerCallbackQuery
ترد على زر ضغطه شخص (CallbackQuery). ويمكنك الرد خلال 10 ثوانٍ ومرة واحدة فقط.
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
callback_query_id | String | نعم | قيمة callback_query.id من التحديث |
text | String | اختياري | نص يظهر لحظات أعلى الشاشة |
show_alert | Boolean | اختياري | إذا كانت true يظهر النص في نافذة فيها زر تأكيد |
url | String | اختياري | عنوان يفتحه التطبيق |
cache_time | Integer | اختياري | عدد الثواني التي يتذكر فيها التطبيق هذا الرد |
القيمة المعادة: True. وإذا تأخرت كثيراً أو كنت قد رددت من قبل فالنتيجة 400 Bad Request: query is too old and response timeout expired or query ID is invalid.
sendChatAction
POST/bot<token>/sendChatAction
تُقبل للتوافق وتعيد True، لكنها لا تُظهر بعدُ «يكتب الآن…» في التطبيق.
getChat
GET/bot<token>/getChat?chat_id=…
المعامل: chat_id (رقم). إذا كان شخصاً فذلك الشخص، وإذا كانت مجموعة فلا يشمل إلا المجموعات التي البوت عضو فيها. القيمة المعادة: Chat. وإذا لم تكن موجودة أو لم يكن مسموحاً برؤيتها فالنتيجة 400 Bad Request: chat not found.
getFile
GET/bot<token>/getFile?file_id=…
تحصل بواسطة file_id لصورة مستلمة على مسار تنزيلها. القيمة المعادة: File. ثم تنزّلها من هذا العنوان.
https://pabal.me/file/bot<token>/<file_path>
وfile_id هو أيضاً إذن بالحصول على تلك الصورة. وإذا كانت القيمة خاطئة فالنتيجة 400 Bad Request: wrong file identifier/HTTP URL specified.
setMyCommands
POST/bot<token>/setMyCommands
| المعامل | النوع | إلزامي | الوصف |
|---|---|---|---|
commands | Array of BotCommand | نعم | 100 أمر كحد أقصى |
language_code | String | اختياري | تُحفظ كقائمة خاصة بتلك اللغة. والتطبيق لا يعرض حالياً إلا القائمة الافتراضية التي لا رمز لغة لها |
scope | BotCommandScope | يُتجاهل |
القيمة المعادة: True. وإذا خالفت الأوامر القواعد فالنتيجة 400 Bad Request: BOT_COMMAND_INVALID.
getMyCommands
GET/bot<token>/getMyCommands
المعامل: language_code (اختياري). القيمة المعادة: Array of BotCommand.
deleteMyCommands
POST/bot<token>/deleteMyCommands
المعامل: language_code (اختياري). تُفرغ تلك القائمة. القيمة المعادة: True.
logOut · close
في Telegram تُستخدم هاتان الطريقتان عند الانتقال إلى خادم Bot API محلي. وبما أنه لا يوجد في Pabal مكان يُنتقل إليه، فهما تُقبلان فقط وتعيدان True. ولإبطال الرمز المميّز استخدم الأمر /revoke لدى BotFather.
الكائنات
تعني اختياري بجانب الحقل أنه قد لا يكون موجوداً. أما حقول Telegram الأخرى غير المذكورة هنا فلا يرسلها Pabal.
Update
تحديث جديد واحد. يحتوي على update_id وواحد من الحقول الثلاثة أدناه.
| الحقل | النوع | الوصف |
|---|---|---|
update_id | Integer | رقم يزيد بمقدار 1. يُستخدم في offset الخاص بـ getUpdates |
message اختياري | Message | رسالة جديدة إلى البوت (محادثة فردية، أو كل الرسائل في مجموعة البوت عضو فيها) |
edited_message اختياري | Message | رسالة عُدّلت |
callback_query اختياري | CallbackQuery | ضغط زر مضمّن |
User
| الحقل | النوع | الوصف |
|---|---|---|
id | Integer | معرّف المستخدم (لا معنى له إلا داخل هذا الخادم) |
is_bot | Boolean | true إذا كان بوتاً |
first_name | String | الاسم. وللحسابات المحذوفة Deleted Account |
last_name اختياري | String | اسم العائلة |
username اختياري | String | اسم المستخدم (دون @) |
Chat
| الحقل | النوع | الوصف |
|---|---|---|
id | Integer | للشخص معرّفه (عدد موجب)، وللمجموعة الأساسية عدد سالب |
type | String | private أو group |
title اختياري | String | اسم المجموعة (group) |
first_name، last_name، username اختياري | String | اسم الطرف الآخر واسم المستخدم الخاص به (private) |
Message
| الحقل | النوع | الوصف |
|---|---|---|
message_id | Integer | رقم الرسالة داخل هذه المحادثة |
from اختياري | User | المرسل |
chat | Chat | المحادثة التي فيها الرسالة |
date | Integer | وقت الإرسال (بثواني يونكس) |
edit_date اختياري | Integer | وقت آخر تعديل |
text اختياري | String | النص (موجود دائماً ما لم تكن رسالة صورة) |
entities اختياري | Array of MessageEntity | الأوامر والإشارات وعناوين URL والوسوم داخل النص |
photo اختياري | Array of PhotoSize | الصورة (في Pabal عنصر واحد هو الأصل) |
caption اختياري | String | وصف الصورة |
caption_entities اختياري | Array of MessageEntity | الأوامر والإشارات وعناوين URL والوسوم داخل الوصف |
reply_markup اختياري | InlineKeyboardMarkup | الأزرار المضمّنة المرفقة بالرسالة |
MessageEntity
| الحقل | النوع | الوصف |
|---|---|---|
type | String | bot_command، mention، url، hashtag |
offset | Integer | موضع البداية (بوحدات ترميز UTF-16) |
length | Integer | الطول (بوحدات ترميز UTF-16) |
يستخرجها الخادم من النص تلقائياً ويضيفها. أما كيانات التنسيق مثل الغامق والمائل فغير موجودة بعد.
PhotoSize
| الحقل | النوع | الوصف |
|---|---|---|
file_id | String | المعرّف المستخدم للتنزيل (getFile) ولإعادة الإرسال (sendPhoto) |
file_unique_id | String | القيمة نفسها للصورة نفسها حتى لو اختلف البوت. ولا يصلح للتنزيل |
width، height | Integer | الأبعاد بالبكسل |
file_size | Integer | بالبايت |
File
| الحقل | النوع | الوصف |
|---|---|---|
file_id، file_unique_id | String | مثل PhotoSize |
file_size | Integer | بالبايت |
file_path | String | بالشكل photos/<file_id>.jpg. أضِفه بعد /file/bot<token>/ لتنزيل الملف |
CallbackQuery
| الحقل | النوع | الوصف |
|---|---|---|
id | String | المعرّف الذي تمرّره إلى answerCallbackQuery |
from | User | الشخص الذي ضغط الزر |
message اختياري | Message | الرسالة المرفق بها الزر |
chat_instance | String | قيمة تمثّل تلك المحادثة |
data اختياري | String | قيمة callback_data الخاصة بالزر |
InlineKeyboardMarkup
inline_keyboard: Array of Array of InlineKeyboardButton — المصفوفة الخارجية هي الصفوف، والداخلية هي أزرار الصف الواحد. والحد الأقصى 100 صف و100 زر في الرسالة الواحدة.
InlineKeyboardButton
| الحقل | النوع | الوصف |
|---|---|---|
text | String | نص الزر |
callback_data أحدهما | String | القيمة التي تذهب إلى البوت عند الضغط، من 1 إلى 64 بايت |
url أحدهما | String | العنوان الذي يُفتح عند الضغط |
الأنواع الأخرى مثل switch_inline_query وweb_app وlogin_url وpay غير متاحة بعد (400).
ReplyKeyboardMarkup
| الحقل | النوع | الوصف |
|---|---|---|
keyboard | Array of Array of KeyboardButton | لوحة الأزرار أسفل حقل الإدخال |
resize_keyboard، one_time_keyboard، is_persistent، selective اختياري | Boolean | ملاءمة الحجم · الإخفاء بعد استخدام واحد · الظهور الدائم · لأشخاص محددين فقط |
input_field_placeholder اختياري | String | النص الإرشادي في حقل الإدخال |
KeyboardButton
سلسلة نصية واحدة، أو كائن فيه text والحقلان الاختياريان request_contact (إرسال جهة اتصالي) وrequest_location (إرسال موقعي، Boolean).
ReplyKeyboardRemove
{"remove_keyboard": true} — يُخفي لوحة الأزرار. وselective اختياري.
ForceReply
{"force_reply": true} — يفتح التطبيق حقل الإدخال في وضع الرد على هذه الرسالة. وselective وinput_field_placeholder اختياريان.
BotCommand
| الحقل | النوع | الوصف |
|---|---|---|
command | String | من 1 إلى 32 حرفاً من الأحرف اللاتينية الصغيرة والأرقام والشرطة السفلية (دون /) |
description | String | من 1 إلى 256 حرفاً |
WebhookInfo
| الحقل | النوع | الوصف |
|---|---|---|
url | String | عنوان webhook، أو سلسلة فارغة إن لم يوجد |
has_custom_certificate | Boolean | دائماً false |
pending_update_count | Integer | عدد التحديثات التي تنتظر التسليم |
ip_address اختياري | String | عنوان IP الذي أُرسل إليه آخر مرة |
last_error_date اختياري | Integer | وقت آخر فشل (بثواني يونكس) |
last_error_message اختياري | String | سبب آخر فشل (القائمة) |
max_connections اختياري | Integer | القيمة التي مرّرتها إلى setWebhook |
allowed_updates اختياري | Array of String | القيمة التي مرّرتها إلى setWebhook |
الاختلافات عن Telegram Bot API
- أنواع التحديثات: لا يصل إلا
messageوedited_messageوcallback_query. ولا توجد منشورات القنوات، ولا الاستعلامات المضمّنة، ولا المدفوعات، ولا الاستطلاعات، ولا تغييرات الأعضاء (my_chat_member) وما شابهها. - التنسيق: يُتجاهل
parse_modeوentitiesويُرسل النص كما هو. ولا يُعرض تلقائياً إلا الأوامر والإشارات وعناوين URL والوسوم. - أنواع المحادثات: المحادثات الفردية والمجموعات الأساسية فقط. ولا توجد قنوات ولا مجموعات خارقة ولا مواضيع منتديات.
- الوسائط: الصور فقط. ولا توجد مستندات ولا فيديو ولا صوت ولا ملصقات ولا ألبومات، ولا الإرسال عبر URL.
- البوتات في المجموعات: لا يوجد وضع خصوصية، فيستلم البوت كل رسائل المجموعة.
- قائمة الانتظار: التحديثات التي لم تُجلب تُحفظ في الذاكرة حتى آخر 1,000 تحديث لكل بوت، وتضيع عند إعادة تشغيل الخادم (بينما يحتفظ بها Telegram مدة 24 ساعة).
- Webhook: يُرسل تحديثاً واحداً في كل مرة بالترتيب (و
max_connectionsتُحفظ فقط)، ولا تُقبل الشهادات الموقّعة ذاتياً، ولا قيود على المنفذ. - المعرّفات: معرّفات المستخدمين والرسائل والملفات لا معنى لها إلا داخل هذا الخادم. ولعدم وجود قنوات ومجموعات خارقة، لا توجد كذلك معرّفات بالشكل
-100…. - الطرق غير الموجودة: ما ليس في القائمة أعلاه (
forwardMessage،copyMessage،sendDocument،sendPoll،getChatMember،banChatMember،answerInlineQuery…) يعيد404 Not Found: method not found.