Ctrl K

ربات بساز، بدون هیچ کتابخانه‌ای

Bot API گیت‌بین یک رابط HTTP ساده‌ست. هر متد فقط یک درخواست معمولیه و با هر زبانی کار می‌کنه: Python، Node.js، PHP یا حتی curl. .

آخرین بروزرسانی: ۲۴ مهر ۱۴۰۵ (۲۰۲۶/۱۰/۱۶) بروزرسانی توسط Kourosh
گ
گروه تستربات: my_bot
/info
POST getGroupInfo { "ok": true, "result": { "id": -1001234567890, "type": "supergroup", "title": "گروه تست" } }
/admins

شروع سریع

از ساخت ربات تا اولین پیام، سه قدم.

  1. توکن بگیر. توی گیت‌بین به @BotFather پیام بده، دستور /newbot رو بزن، اسم و یوزرنیم ربات رو وارد کن. توکنی شبیه 1234567890:ABCdef... می‌گیری.
  2. درخواست‌ها رو به این آدرس بفرست:
    https://api.mramirhoseini.ir/botYOUR_TOKEN/METHOD
    https://api.mramirhoseini.ir/file/botYOUR_TOKEN/FILE_PATH
    به‌جای YOUR_TOKEN توکن خودت و به‌جای METHOD اسم متد رو بذار. درخواست می‌تونه GET یا POST باشه.
  3. اولین درخواست رو بزن. اول getMe رو صدا بزن تا مطمئن بشی توکن درسته، بعد یه پیام بفرست. کد همه‌ی زبان‌ها پایینه.
import requests

TOKEN = "YOUR_BOT_TOKEN"
BASE = f"https://api.mramirhoseini.ir/bot{TOKEN}"

def call(method, params=None, files=None):
    r = requests.post(f"{BASE}/{method}", data=params, files=files, timeout=40)
    return r.json()

print(call("getMe"))
print(call("sendMessage", {"chat_id": 123456789, "text": "سلام!"}))
اگه می‌خوای کتابخانه‌ی requests رو نصب کنی و سرورت داخل ایرانه، از mirror ایرانی استفاده کن:
pip install requests --index-url https://mirror-pypi.runflare.com/simple/ --trusted-host mirror-pypi.runflare.com
توی همه‌ی نمونه‌های این صفحه تابع call همین تابعیه که بالا تعریف شد.

درخواست، پاسخ و خطاها

ورودی

پارامترها به‌صورت query string (در GET) یا form-data (در POST). برای ارسال فایل از multipart/form-data استفاده کن.

خروجی

همیشه JSON با کدگذاری UTF-8. متدهای اطلاعاتی و مدیریتی جدید، JSON مرتب (با تورفتگی) برمی‌گردونن.

پروتکل

فقط HTTPS. توکن بخشی از آدرسه، پس درخواست‌ها رو هیچ‌جا لاگ یا منتشر نکن.

ساختار پاسخ

اگه ok برابر true بود، نتیجه توی result قرار داره. اگه false بود، علت خطا توی description نوشته شده.

{
  "ok": true,
  "result": { "message_id": 42 }
}
{
  "ok": false,
  "error_code": 400,
  "description": "CHAT_ID_INVALID"
}

خطاهای رایج

پیام خطامعنی و راه‌حل
CHAT_ID_INVALIDشناسه‌ی چت درست نیست یا ربات به اون چت دسترسی نداره. ببین ربات عضو گروه هست و شناسه با -100 شروع می‌شه.
USER_ID_INVALIDشناسه‌ی کاربر نامعتبره.
USERNAME_INVALIDیوزرنیم خالی یا نامعتبره.
USERNAME_NOT_OCCUPIEDکاربری یا رباتی با این یوزرنیم پیدا نشد.
MESSAGE_ID_INVALIDپیام پیدا نشد؛ شناسه اشتباهه یا پیام قبلاً حذف شده.
MESSAGE_EMPTYمتن پیام خالیه.
MESSAGE_TOO_LONGمتن پیام از حد مجاز بلندتره.
BOT_INVALIDربات یا توکن معتبر نیست.
METHOD_NOT_FOUNDاسم متد اشتباهه یا این متد روی سرور فعال نیست.

فرمت chat_id

نوع چتشناسه
123456789چت خصوصی با یک کاربر: عدد مثبت.
-1001234567890گروه، سوپرگروه و کانال: عدد منفی که با -100 شروع می‌شه.

برای پیدا کردن شناسه‌ی گروه، یک پیام توی گروه بفرست و با getUpdates مقدار message.chat.id رو بخون.

همه‌ی متدها

تست‌شده: روی سرور امتحان شده و جواب می‌ده تست‌نشده: وجود داره ولی هنوز امتحان نشده جدید اضافه‌شده در بروزرسانی ۲۴ مهر ۱۴۰۵
نمونه‌ی پاسخ‌ها برای نشون دادن ساختارن. بسته به داده‌ی واقعی، فیلدهای بیشتری هم ممکنه ببینی.

تغییر نام متدها

اسم سه متد ساده‌تر شد. اسم‌های قبلی هم هنوز کار می‌کنن، پس کدهای قدیمی و کتابخانه‌های آماده خراب نمی‌شن.

اسم جدیداسم قبلیکار
sendImagesendPhotoارسال عکس
sendFilesendDocumentارسال فایل
editMessageeditMessageTextویرایش متن پیام

ربات در گروه و کانال

چند نکته که برای کار با گروه‌ها لازمه بدونی.

  • ربات باید عضو گروه باشه. برای banMember و unbanMember باید ادمین هم باشه.
  • شناسه‌ی گروه‌ها و کانال‌ها منفیه و با -100 شروع می‌شه.
  • اگه ربات به دستورهای گروه جواب نداد، دستور رو همراه یوزرنیم ربات بنویس: /info@my_bot.
  • getInfoByUsername فقط کاربر و ربات رو پیدا می‌کنه، نه گروه و کانال. برای گروه از getGroupInfo با chat_id استفاده کن.
  • ویرایش و حذف پیام توی چت خصوصی، گروه و کانال کار می‌کنه.

بن کردن کاربر با ریپلای

msg = update["message"]
reply = msg.get("reply_to_message")

if msg.get("text", "").startswith("/ban") and reply:
    result = call("banMember", {
        "chat_id": msg["chat"]["id"],
        "user_id": reply["from"]["id"],
    })
    print(result)

یک ربات کامل

ربات پایین با long polling کار می‌کنه و فقط با requests نوشته شده. دستورهای /start، /info، /admins و /ban رو هم توی چت خصوصی و هم توی گروه جواب می‌ده. قبل از بن، چک می‌کنه کسی که دستور رو زده ادمین باشه.

import json
import os
import time

import requests

TOKEN = os.environ["BOT_TOKEN"]  # توکن رو از متغیر محیطی بخون
BASE = f"https://api.mramirhoseini.ir/bot{TOKEN}"


def call(method, params=None, files=None):
    try:
        r = requests.post(f"{BASE}/{method}", data=params, files=files, timeout=40)
        return r.json()
    except requests.RequestException:
        return {"ok": False, "description": "network error"}


def say(chat_id, text):
    return call("sendMessage", {"chat_id": chat_id, "text": text[:4000]})


def is_admin(chat_id, user_id):
    res = call("getGroupAdmins", {"chat_id": chat_id})
    if not res.get("ok"):
        return False
    return any((a.get("user_id") or a.get("id")) == user_id for a in res["result"])


def handle(msg):
    text = msg.get("text", "")
    if not text.startswith("/"):
        return
    chat_id = msg["chat"]["id"]
    user_id = msg["from"]["id"]
    cmd = text.split()[0].split("@")[0].lower()

    if cmd == "/start":
        say(chat_id, "سلام! دستورها: /info /admins /ban")
    elif cmd == "/info":
        say(chat_id, json.dumps(call("getGroupInfo", {"chat_id": chat_id}),
                                ensure_ascii=False, indent=2))
    elif cmd == "/admins":
        say(chat_id, json.dumps(call("getGroupAdmins", {"chat_id": chat_id}),
                                ensure_ascii=False, indent=2))
    elif cmd == "/ban":
        reply = msg.get("reply_to_message")
        if not reply:
            say(chat_id, "روی پیام کاربر ریپلای کن و /ban بزن.")
        elif not is_admin(chat_id, user_id):
            say(chat_id, "فقط ادمین‌ها می‌تونن بن کنن.")
        else:
            res = call("banMember", {"chat_id": chat_id, "user_id": reply["from"]["id"]})
            say(chat_id, "بن شد." if res.get("ok") else f"خطا: {res.get('description')}")


offset = 0
print("ربات در حال اجراست...")
while True:
    res = call("getUpdates", {"offset": offset, "timeout": 25})
    if not res.get("ok"):
        time.sleep(5)
        continue
    for update in res["result"]:
        offset = update["update_id"] + 1
        if "message" in update:
            handle(update["message"])
export BOT_TOKEN="YOUR_BOT_TOKEN"
python3 bot.py

Webhook

به‌جای polling می‌تونی آدرس سرور خودت رو ثبت کنی تا آپدیت‌ها مستقیم بهش بیاد. آدرس باید HTTPS باشه.

curl "https://api.mramirhoseini.ir/botYOUR_TOKEN/setWebhook?url=https://your-domain.com/webhook"

curl "https://api.mramirhoseini.ir/botYOUR_TOKEN/deleteWebhook"
اگه setWebhook خطای METHOD_NOT_FOUND داد، یعنی روی این سرور فعال نیست و باید از getUpdates استفاده کنی.

نکات امنیتی

  • توکن رو هرگز توی گیت، چت، اسکرین‌شات یا کد عمومی نذار. هر کسی که توکن رو داشته باشه، کنترل کامل ربات رو داره.
  • توکن رو از متغیر محیطی بخون، نه مستقیم از توی کد:
import os

TOKEN = os.environ["BOT_TOKEN"]
  • اگه توکن لو رفت، همون لحظه توی @BotFather دستور /revoke رو بزن و توکن جدید بگیر.
  • قبل از اجرای دستورهای مدیریتی مثل /ban، ادمین بودن کاربر رو با getGroupAdmins چک کن.
  • ورودی کاربرها رو قبل از استفاده بررسی کن و خروجی خطاها رو بدون توکن لاگ کن.
  • برای Webhook فقط از HTTPS استفاده کن.

محدودیت‌ها و نکات شناخته‌شده

  • banMember: پشتیبانی از پارامتر until_date (بن موقت) هنوز تأیید نشده. فرض کن بن دائمیه.
  • getInfoByUsername فقط کاربر و ربات رو برمی‌گردونه.
  • متدهای banMember، unbanMember، leaveGroup، leaveChannel، answerCallbackQuery، getFile و deleteWebhook هنوز تست نشدن؛ روی یک گروه آزمایشی امتحانشون کن.
  • تا بروزرسانی ۲۴ مهر ۱۴۰۵، ویرایش و حذف پیام فقط توی چت خصوصی کار می‌کرد و توی گروه خطای CHAT_ID_INVALID می‌داد. حالا گروه و کانال هم پشتیبانی می‌شن.
مشکلی دیدی؟ اسم متد، پارامترهایی که فرستادی و متن خطا (بدون توکن) رو برای ما بفرست.

تغییرات

۲۴ مهر ۱۴۰۵

بروزرسانی توسط Kourosh
  • متدهای جدید: getBotInfo، getServiceInfo، getUserInfo، getInfoByUsername، getGroupInfo، getChannelInfo، getGroupAdmins، banMember، unbanMember، leaveGroup و leaveChannel.
  • نام‌های ساده‌تر sendImage، sendFile و editMessage (اسم‌های قبلی هم کار می‌کنن).
  • خروجی JSON مرتب برای متدهای جدید.
  • ویرایش و حذف پیام در گروه و کانال اضافه شد.
  • نمونه‌کدها بدون کتابخانه‌ی گیت بین بازنویسی شدن (Python، curl، Node.js و PHP)، و ظاهر مستندات تازه شد.

۱۶ مهر ۱۴۰۵

نسخه‌ی اولیه‌ی مستندات
  • ۱۰ متد پایه و نمونه کد با کتابخانه‌ی گیت بین.

مستندات رسمی

Mramirhoseini.ir/bots/api