توسعه سریع و مدرن ربات و کلاینت در پیامرسان بله با پایتون
Aiobale یک کتابخانه پیشرفته، کاملاً ناهمگام (Async/Await) و بر پایه پروتکل بومی وبسوکت و باینری پروتوباف پیامرسان بله است که امکان ساخت انواع رباتهای کاربری (Userbot)، رباتهای رسمی، پنلهای مدیریت خودکار و ابزارهای دادهکاوی را با بالاترین سرعت و کمترین مصرف منابع فراهم میکند.
کاملاً Async/Await
طراحیشده بر پایه asyncio پایتون با توان پردازش همزمان هزاران رویداد در ثانیه با حداقل مصرف رم و پردازنده.
مجیک فیلتر هوشمند (F)
فیلترگذاری شبیه به Aiogram با عبارتهای قدرتمند F.text.startswith(...) و فیلترهای ترکیبی منطقی.
پوشش ۷۹+ متد RPC
دسترسی به تمام قابلیتهای پیامرسان بله شامل پیامها، گروهها، کانالها، ریاکشنها، فایلها و استاتوس.
مدلهای داده Pydantic
اعتبارسنجی خودکار دادهها با تایپ هینتینگ ۱۰۰٪ سازگار با تمامی IDEها نظیر VS Code و PyCharm.
نصب و پیشنیازها (Installation)
راهنمای راهاندازی و نصب کتابخانه Aiobale روی سیستمعاملهای مختلف
برای استفاده از Aiobale، به پایتون نسخه 3.8 یا بالاتر (سازگار تا پایتون 3.14) نیاز دارید.
نصب با pip
# نصب مستقیم از سورس یا پکیج
pip install aiobale-py
# یا نصب با ابزار سریع uv
uv pip install aiobale-py
aiohttp، pydantic، blackboxprotobuf و aiofiles به صورت خودکار نصب میشوند.
اولین ربات در ۵ دقیقه (Quickstart)
ساخت یک ربات اکو (Echo Bot) هوشمند در پیامرسان بله
نمونه کد زیر یک ربات اکو ساده ایجاد میکند که به تمام پیامهای متنی دریافتی پاسخ همان پیام را میدهد:
import asyncio
from aiobale import Client, Dispatcher, F
from aiobale.types import Message
from aiobale.filters import IsText
# ساخت دیسپچر و کلاینت
dp = Dispatcher()
client = Client(dp, session_file="my_bot")
@dp.message(F.text == "/start")
async def start_handler(message: Message):
await message.reply("سلام! به ربات Aiobale خوش آمدید.")
@dp.message(IsText())
async def echo_handler(message: Message):
await message.reply(f"شما گفتید: {message.text}")
async def main():
print("در حال اتصال به سرور بله...")
await client.start()
if __name__ == "__main__":
asyncio.run(main())
در اولین اجرای این اسکریپت در ترمینال، کنسول از شما شماره تلفن و کد پیامکشده را میپرسد و سشن ذخیره میشود تا در اجراهای بعدی بدون نیاز به لاگین مجدد متصل شود.
احراز هویت و مدیریت سشن (Authentication)
راهنمای انواع روشهای لاگین، کار با توکنها و فایلهای سشن
۱. ورود با شماره تلفن و CLI
میتوانید شماره تلفن را مستقیماً در کد پاس دهید تا فقط کد تایید پیامکشده در ترمینال پرسیده شود، یا بدون شماره فراخوانی کنید تا ورود کامل تعاملی باشد:
from aiobale import Client
# ۱. پاس دادن مستقیم شماره در کد (پرسش فقط برای کد تایید پیامکی)
client = Client(session_file="my_account", phone_number="09123456789")
# ۲. یا لاگین تعاملی کامل با پرسش شماره و کد در ترمینال
# client = Client(session_file="my_account")
if __name__ == "__main__":
client.run()
۲. ورود با توکن JWT از پیش موجود
در صورتی که توکن حساب کاربری را دارید، میتوانید آن را به صورت مستقیم به کلاینت پاس دهید:
from aiobale import Client
MY_JWT_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# راهاندازی با توکن مستقیم بدون نیاز به فایل سشن روی دیسک
client = Client(session_file=None, token=MY_JWT_TOKEN)
۳. محیطهای Headless و داکر (Docker & CI)
در صورتی که برنامه در محیط بدون ورودی ترمینال اجرا شود (مانند Docker یا دیمونهای پسزمینه)، در صورت نبود توکن خطای واضح AiobaleError پرتاب میشود تا از فریز شدن پروسس جلوگیری شود.
معماری کلاینت و چرخه حیات (Client Architecture)
بررسی کلاس Client، تنظیمات اتصال، پراپرتیها و هندلینگ قطعی اتصال
پارامترهای کانفیگوریشن کلاینت
| پارامتر | نوع داده (Type) | پیشفرض | توضیحات |
|---|---|---|---|
dispatcher |
Optional[Dispatcher] |
None |
آبجکت دیسپچر مسئول مدیریت و هدایت رویدادها |
session_file |
Union[str, Path, bytes, None] |
"./session.bale" |
مسیر فایل ذخیرهسازی نشست یا None برای نشست حافظهای |
token |
Optional[str] |
None |
توکن JWT معتبر جهت اتصال مستقیم |
user_agent |
Optional[str] |
None |
عنوان کلاینت یا User-Agent اختصاصی |
show_update_errors |
bool |
False |
نمایش خطاهای رخداده در جریان پردازش آپدیتها در لاگ |
چرخه حیات و متدهای کلاینت
| متد / پراپرتی | نوع | توضیحات |
|---|---|---|
client.start() |
async | برقراری اتصال سوکت، لاگین، دریافت اطلاعات اکانت و آغاز حلقه آپدیتها |
client.stop() |
async | قطع ایمن سوکت، ذخیره وضعیت و توقف کلاینت |
client.me |
پراپرتی | آبجکت اطلاعات حساب لاگینشده (شامل نام، آیدی، شماره تلفن و...) |
client.id |
پراپرتی | آیدی عددی کاربر متصلشده (در صورت عدم اتصال مقدار None) |
client.token |
پراپرتی | توکن JWT فعال برای درخواستهای HTTP و آپلود/دانلود مدیا |
دیسپچر و مسیریابی رویدادها (Dispatcher & Routers)
سیستم قدرتمند هدایت و دریافت رویدادها با قابلیت ماژولار و تزریق وابستگی
انواع رویدادهای پشتیبانیشده در دیسپچر
| دکوراتور هندلر | نوع ورودی (Event Object) | زمان تحریک (Trigger) |
|---|---|---|
@dp.message(*filters) |
Message |
دریافت پیام جدید در پیوی، گروه یا کانال |
@dp.message_edited(*filters) |
Message |
ویرایش شدن متن یا کپشن پیام ارسالی قبلی |
@dp.message_deleted(*filters) |
SelectedMessages |
حذف شدن یک یا چند پیام |
@dp.user_blocked(*filters) |
UserBlocked |
بلاک شدن کاربر توسط شما یا طرف مقابل |
@dp.user_unblocked(*filters) |
UserUnblocked |
آنبلاک شدن کاربر |
@dp.group_message_pinned(*filters) |
PinnedMessage |
پین شدن پیام جدید در گروه یا کانال |
@dp.group_pin_removed(*filters) |
UnpinnedMessage |
حذف پیام پینشده از سرگروه |
@dp.username_changed(*filters) |
UsernameChanged |
تغییر نام کاربری (آیدی @) گروه یا کانال |
@dp.about_changed(*filters) |
AboutChanged |
تغییر بیوگرافی یا توضیحات گروه/کانال |
ساختار پروژههای بزرگ با Router
برای تفکیک کدهای بات در فایلهای مجزا (مثلاً هندلرهای ادمین، هندلرهای کاربری، هندلرهای مدیا)، از روترها استفاده کنید:
from aiobale import Router, F
from aiobale.types import Message
admin_router = Router()
@admin_router.message(F.text == "/panel")
async def admin_panel(msg: Message):
await msg.reply("به پنل مدیریت خوش آمدید.")
from aiobale import Client, Dispatcher
from handlers.admin import admin_router
dp = Dispatcher()
# الحاق روتر ادمین به دیسپچر اصلی
dp.include_router(admin_router)
client = Client(dp, session_file="bot")
تزریق وابستگی خودکار (Dependency Injection)
در هر هندلر میتوانید علاوه بر آبجکت رویداد (مثلاً msg: Message)، آبجکت client: Client یا هر متغیر دلخواه تزریقشده را به عنوان آرگومان تعریف کنید تا سیستم آن را به صورت خودکار مقداردهی کند.
فیلترها و Magic Filter (Filters & F)
کنترل دقیق و گزینش هوشمند رویدادها با فیلترهای جادویی و منطقی
استفاده از Magic Filter (`F`)
با آبجکت F میتوانید بدون نیاز به نوشتن توابع جداگانه، شرطهای پیچیده را مستقیماً تعریف کنید:
from aiobale import F
from aiobale.enums import ChatType
# تطابق دقیق متن
@dp.message(F.text == "ping")
async def on_ping(msg): await msg.reply("pong")
# شروع با پیشوند خاص
@dp.message(F.text.startswith("/calc"))
async def on_calc(msg): ...
# شرط روی نوع چت و فرستنده
@dp.message(F.chat.type == ChatType.GROUP, F.sender_id == 123456)
async def on_admin_in_group(msg): ...
# بررسی وجود سند یا تصویر
@dp.message(F.content.document)
async def on_document(msg): ...
فیلترهای پیشساخته (Built-in Filters)
| فیلتر | عملکرد |
|---|---|
IsText() |
فقط پیامهای متنی عادی |
IsDocument() |
پیامهای حاوی فایل یا مدیا |
IsGift() |
پیامهای بسته هدیه / عیدی بله |
IsMedia() |
بررسی میکند که آیا پیام حاوی هرگونه رسانه (تصویر، داکیومنت، وویس، ویدیو، صوت یا گیف) است یا خیر. |
TextEquals("hello", ignore_case=True) |
تطابق دقیق متن پیام با یکی از عبارات تعیینشده (با امکان نادیدهگرفتن بزرگی/کوچکی حروف). |
TextContains("keyword", ignore_case=True) |
بررسی وجود یک زیررشته خاص در متن پیام ارسالی کاربر. |
TextStartsWith("!") / TextEndsWith("?") |
بررسی شروع شدن یا خاتمه یافتن متن پیام با پیشوند یا پسوند خاص. |
IsPrivate() |
پیامهای دریافتی از چتهای دونفره (پیوی) |
IsGroupOrChannel() |
پیامهای گروهها، ابرگروهها یا کانالها |
ChatTypeFilter(ChatType.GROUP) |
فیلتر بر اساس نوع اختصاصی چت |
RegexFilter(r"^/ban\s+(\d+)") |
استخراج و انطباق عبارات منظم (RegEx) |
ترکیب منطقی فیلترها (Logic Operators)
با توابع and_f, or_f, invert_f میتوانید فیلترها را ترکیب کنید:
from aiobale.filters import and_f, or_f, invert_f, IsText, IsPrivate
# پیام متنی باشد و در پیوی باشد
@dp.message(and_f(IsText(), IsPrivate()))
async def private_text_only(msg): ...
# پیام غیرمتنی باشد (معکوس کردن)
@dp.message(invert_f(IsText()))
async def media_only(msg): ...
ساخت فیلتر سفارشی (Custom Filter)
from aiobale.filters.base import Filter
from aiobale.types import Message
class AdminOnly(Filter):
def __init__(self, admin_ids: list[int]):
self.admin_ids = admin_ids
async def __call__(self, message: Message) -> bool:
return message.sender_id in self.admin_ids
@dp.message(AdminOnly([111222, 333444]))
async def admin_handler(msg: Message):
await msg.reply("دسترسی ادمین تایید شد.")
ماشین وضعیت و میدلورها (FSM & Middlewares)
مدیریت گفتگوهای چندمرحلهای، فرمها، سبد خرید و پایپلاین رهگیری پیامها
۱. تعریف مراحل با StatesGroup و FSMContext
با ارثبری از StatesGroup وضعیتهای گفتگو را تعریف کنید و در هندلرها با state: FSMContext دادهها را ذخیره و فراخوانی نمایید:
from aiobale import Client, Dispatcher, F
from aiobale.fsm import State, StatesGroup, FSMContext
from aiobale.types import Message
class OrderForm(StatesGroup):
choosing_item = State()
choosing_quantity = State()
dp = Dispatcher()
@dp.message(F.text == "/order")
async def start_order(msg: Message, state: FSMContext):
await state.set_state(OrderForm.choosing_item)
await msg.reply("نام محصول را وارد کنید:")
@dp.message(OrderForm.choosing_item)
async def item_chosen(msg: Message, state: FSMContext):
await state.update_data(item_name=msg.text)
await state.set_state(OrderForm.choosing_quantity)
await msg.reply("تعداد مورد نظر را وارد کنید:")
@dp.message(OrderForm.choosing_quantity)
async def quantity_chosen(msg: Message, state: FSMContext):
data = await state.get_data()
item = data.get("item_name")
await state.clear()
await msg.reply(f"سفارش شما برای {msg.text} عدد {item} ثبت شد!")
۲. استوریجهای پایدار: SQLiteStorage
به طور پیشفرض دادههای FSM در رم ذخیره میشوند. برای جلوگیری از پاک شدن وضعیت کاربران هنگام ریاستارت، از SQLiteStorage استفاده کنید:
from aiobale import Dispatcher, SQLiteStorage
# ذخیره دائمی وضعیتها در دیتابیس SQLite
storage = SQLiteStorage("fsm_data.db")
dp = Dispatcher(storage=storage)
۳. پایپلاین میدلورها (BaseMiddleware)
برای کنترل نرخ درخواستها (Rate Limiting)، آمارگیری، احراز هویت و لاگینگ قبل از اجرای هر هندلر:
from aiobale import Dispatcher, BaseMiddleware
from typing import Any, Callable, Dict, Awaitable
class LoggingMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Any, Dict[str, Any]], Awaitable[Any]],
event: Any,
data: Dict[str, Any]
) -> Any:
print(f"دریافت رویداد: {event}")
result = await handler(event, data)
print("پردازش هندلر به اتمام رسید.")
return result
dp = Dispatcher()
dp.middleware(LoggingMiddleware())
ابزارهای پیشرفته (Advanced Utilities)
کیبورد سازها، پارسر دستورات، کالبک فکتوری و اجرای همزمان چنداکانت
۱. کیبورد سازهای زنجیرهای (Keyboard Builders)
ساخت سریع کیبوردهای شیشهای و معمولی با متدهای متوالی و چینش ماتریسی دلخواه:
from aiobale.utils.keyboard import InlineKeyboardBuilder, ReplyKeyboardBuilder
# کیبورد شیشهای (Inline)
builder = InlineKeyboardBuilder()
builder.button(text="🌐 وبسایت رسمی", url="https://aiobale.ir")
builder.button(text="دکمه ۱", callback_data="cb_1")
builder.button(text="دکمه ۲", callback_data="cb_2")
inline_kb = builder.as_markup(2, 1) # سطر اول ۲ تا، سطر دوم ۱ دکمه
# کیبورد معمولی (Reply)
reply = ReplyKeyboardBuilder()
reply.button(text="👤 پروفایل کاربری")
reply.button(text="🛍️ فروشگاه")
reply_kb = reply.as_markup(2)
۲. فیلتر پیشرفته دستورات (Command Filter & CommandObject)
پارس خودکار نام دستور، پیشوند (مانند / یا !) و آرگومانهای ارسالی با تزریق به هندلر:
from aiobale import Command, CommandObject
from aiobale.types import Message
@dp.message(Command("ban", "kick", prefix="/!"))
async def admin_command(msg: Message, command: CommandObject):
print(command.prefix) # پیشوند استفاده شده مثلا '!'
print(command.command) # نام دستور مثلا 'ban'
print(command.args) # رشته کامل آرگومانها
print(command.args_list) # لیست آرگومانها به صورت تکتک
await msg.reply(f"دستور {command.command} دریافت شد.")
۳. کالبک فکتوری با مدلهای تایپشده (CallbackData)
تعریف ساختار دادهای تمیز برای دکمهها و فیلترگذاری بدون پردازش دستی رشتهها:
from aiobale import CallbackData, F
class ProductCB(CallbackData, prefix="product"):
action: str
product_id: int
# تولید دیتای دکمه: product:view:99
data_str = ProductCB(action="view", product_id=99).pack()
@dp.message(ProductCB.filter(F.action == "view"))
async def on_view_product(event, callback_data: ProductCB):
print(f"شناسه محصول: {callback_data.product_id}")
۴. مدیریت و اجرای همزمان چنداکانت (ClientManager)
راهاندازی دهها اکانت یا ربات همزمان در یک رویداد واحد پایتون:
from aiobale import ClientManager, Dispatcher
dp = Dispatcher()
manager = ClientManager(dp)
manager.add_client(session_file="account1", phone_number="09121111111")
manager.add_client(session_file="account2", token="JWT_TOKEN_...")
if __name__ == "__main__":
manager.run_all()
۵. ابزار خط فرمان اختصاصی (aiobale CLI)
با استفاده از دستور aiobale در ترمینال میتوانید قالب استاندارد ربات بسازید یا فایلهای سشن را بررسی کنید:
# ساخت یک پروژه ربات جدید و ماژولار با معماری استاندارد
aiobale startproject my_bale_bot
# مشاهده جزئیات کاربر، توکن و تاریخ انقضا از فایل سشن
aiobale info my_bale_bot.bale
۶. صفحهبندی هوشمند دکمههای اینلاین (KeyboardPaginator)
ساخت آسان کاتالوگ محصولات، لیست کانالها و منوهای چندصفحهای با دکمههای ناوبری قبلی/بعدی:
from aiobale.utils import KeyboardPaginator
products = ["کتاب پایتون", "کتاب جنگو", "کتاب رست", "کتاب هوش مصنوعی"]
paginator = KeyboardPaginator(items=products, page_size=2, callback_prefix="shop")
# تولید کیبورد اینلاین برای صفحه اول
markup_page_1 = paginator.get_page(page=1)
۷. صفبندی ارسال پیام و کنترل ریتلیمیت (MessageThrottler)
ارسال امن و پرسرعت پیامهای انبوه (Broadcast) به هزاران کاربر بدون مواجهه با خطای Flood Wait سرور بله:
from aiobale.utils import MessageThrottler
from aiobale.enums import ChatType
throttler = MessageThrottler(rate_limit=0.05) # حداکثر ۲۰ پیام در ثانیه
async def send_news(user_id):
await client.send_message(user_id, ChatType.USER, "پیام اطلاعرسانی ویژه 📢")
# ارسال همگانی همراه با کالبک درصد پیشرفت
report = await throttler.broadcast(send_news, user_ids_list)
print(f"موفق: {report.success_count} / ناموفق: {report.failure_count}")
۸. نوار درصد پیشرفت دانلود و آپلود (create_progress_bar)
نمایش گرافیکی سرعت و درصد پیشرفت انتقال فایل در کنسول بدون نیاز به پکیجهای اضافی:
from aiobale.utils import create_progress_bar
progress_cb = create_progress_bar("آپلود ویدیو")
file_info = await client.upload_file("movie.mp4", progress_callback=progress_cb)
۹. سرور وبهوک غیرهمگام (AiohttpWebhookServer)
برای دریافت رویدادها از طریق وبهوک در سرورهای لینوکسی و ابری به جای استفاده از Long Polling:
from aiobale import Client, Dispatcher, AiohttpWebhookServer
dp = Dispatcher()
client = Client(dp, token="YOUR_JWT_TOKEN")
# راهاندازی وبهوک سرور روی پورت ۸۰۸۰ با کلید امنیتی اختصاصی
webhook = AiohttpWebhookServer(
client=client,
path="/webhook",
secret_token="secret_key_123"
)
if __name__ == "__main__":
webhook.run(host="0.0.0.0", port=8080)
مکالمه خطی و تعاملی (Conversation Wizard)
طراحی فرمها و گفتوگوهای چندمرحلهای به صورت مستقیم با استفاده از Async Context Manager بدون نیاز به تعریف دستی ماشینهای وضعیت پیچیده.
from aiobale import Client, Dispatcher, F, Conversation
from aiobale.types import Message
dp = Dispatcher()
client = Client(dp, session_file="my_bot")
@dp.message(F.text == "/start")
async def start_wizard(msg: Message, client: Client):
# شروع یک مکالمه ایزوله برای این چت
async with client.conversation(msg.chat.id, timeout=120) as conv:
await conv.send_message("سلام! لطفاً نام و نام خانوادگی خود را وارد کنید:")
# انتظار برای دریافت پاسخ بعدی از کاربر
name_msg = await conv.get_response(timeout=60)
await conv.send_message(f"خوش آمدی {name_msg.text}! حالا سن خود را وارد کن:")
age_msg = await conv.get_response(timeout=60)
await conv.send_message(
f"ثبتنام شما تکمیل شد! ✅\nنام: {name_msg.text}\nسن: {age_msg.text}"
)
if __name__ == "__main__":
client.run()
| متد / ویژگی | پارامترها | توضیحات |
|---|---|---|
conv.get_response() |
timeout: Optional[float] = None |
منتظر پیام بعدی از سمت این چت میماند و شیء Message را بازمیگرداند. |
conv.send_message() |
text, reply_markup=None |
پیام متنی جدیدی در قالب این مکالمه ارسال میکند. |
conv.send_photo() |
photo, caption=None |
تصویر (مسیر فایل، بایت یا BytesIO) را به کاربر ارسال میکند. |
conv.send_document() |
file, caption=None |
فایل یا سندی را در مکالمه ارسال میکند. |
conv.close() |
- | مکالمه را لغو کرده و صف پیامها را آزاد میکند. |
پیمایش تاریخچه پیامها (iter_messages)
خواندن صفحهبندیشده و روان تاریخچه پیامهای یک چت، گروه یا کانال به صورت AsyncGenerator با مدیریت خودکار تکرارها و حافظه پکتها.
from aiobale import Client
from aiobale.enums import ChatType
client = Client(session_file="backup_session")
async def read_chat_history(target_chat_id: int):
print("در حال خواندن ۱۰۰ پیام اخیر چت...")
async for msg in client.iter_messages(
chat_id=target_chat_id,
chat_type=ChatType.PRIVATE,
limit=100,
chunk_size=20
):
if msg.text:
print(f"[{msg.date}] کاربر {msg.sender_id}: {msg.text}")
elif msg.document:
print(f"[{msg.date}] فایل پیوست: {msg.document.name} (حجم: {msg.document.size} بایت)")
if __name__ == "__main__":
import asyncio
asyncio.run(read_chat_history(123456789))
مرجع متدهای پیامرسانی (Messaging API)
ارسال انواع پیام، تصویر، فایل، ویرایش، حذف، پین و تاریخچه چت
| نام متد | نوع | پارامترهای اصلی | توضیحات |
|---|---|---|---|
send_message |
async | chat_id, text, reply_to, quoted_message |
ارسال پیام متنی با پشتیبانی از ریپلای نقلقولی |
send_photo / send_document |
async | chat_id, file, caption, reply_to |
ارسال تصویر یا فایل از مسیر دیسک یا باینری |
send_voice / send_video / send_audio |
async | chat_id, file, duration, caption |
ارسال ویس یا ویدیوی پلیر با پیشنمایش |
update_message |
async | chat_id, message_id, text |
ویرایش متن پیام ارسالشده قبلی |
delete_message |
async | chat_id, message_ids |
حذف یک یا چند پیام برای طرفین |
forward_message |
async | from_chat_id, to_chat_id, message_ids |
فوروارد پیامها به چت دیگر |
load_history |
async | chat_id, limit, offset_id |
دریافت لیست تاریخچه پیامهای چت |
load_dialogs |
async | limit, offset_date |
دریافت لیست گفتگوها و چتهای فعال کاربر |
clear_chat / delete_chat |
async | chat_id |
پاکسازی یا حذف کامل گفتگوی یک چت |
نمونه کد پیامرسانی کامل
# ارسال پیام متنی با متد مستقیم کلاینت
sent = await client.send_message(
chat_id=123456789,
text="سلام! این یک پیام آزمایشی است."
)
# ارسال عکس با کپشن
await client.send_photo(
chat_id=123456789,
file="./images/banner.png",
caption="بنر جدید کانال"
)
# ویرایش پیام
await client.update_message(
chat_id=123456789,
message_id=sent.message_id,
text="این متن ویرایش شد."
)
# پین کردن پیام
await client.pin_message(
chat_id=123456789,
message_id=sent.message_id
)
گروهها و کانالها (Groups & Channels API)
مدیریت کامل اعضا، دسترسیها، بن/کیک، لینک دعوت و ارتقا به ادمین
| متد | پارامترها | کاربرد |
|---|---|---|
create_group |
title, about, members |
ساخت گروه یا کانال جدید |
get_full_group |
group_id |
دریافت اطلاعات کامل، آمار اعضا، توضیحات و پرمیشنها |
load_members |
group_id, limit |
دریافت لیست اعضای گروه به همراه رولها |
kick_user / unban_user |
group_id, user_id |
اخراج کاربر از گروه یا رفع مسدودیت |
make_user_admin / remove_user_admin |
group_id, user_id |
ارتقا به مدیر یا خلع مقام ادمینی |
set_member_permissions |
group_id, user_id, permissions |
تنظیم دقیق دسترسیهای یک عضو (ارسال پیام، رسانه، دعوت و...) |
get_group_invite_url / revoke_invite_url |
group_id |
تولید یا باطل کردن لینک دعوت گروه |
join_group / leave_group |
invite_token یا group_id |
عضویت از طریق لینک یا خروج از گروه |
کاربران و مخاطبین (Users & Contacts API)
مدیریت لیست مخاطبین، جستجو، بلاک/آنبلاک و ویرایش پروفایل کاربری
| متد | پارامترها | کاربرد |
|---|---|---|
get_contacts |
— | دریافت لیست تمام مخاطبین ذخیرهشده |
add_contact / remove_contact |
user_id, name |
افزودن یا حذف مخاطب از دفترچه تلفن |
search_contact |
query |
جستجوی نام کاربری یا شماره در بله |
block_user / unblock_user |
user_id |
مسدودسازی یا رفع مسدودی کاربر |
edit_name / edit_about / edit_nickname |
name / about / nickname |
تغییر نام نمایشی، بیوگرافی یا آیدی کاربری (@) |
واکنشها، آمار و وضعیت آنلاین (Reactions & Presence)
ثبت ریاکشن به پیامها، دریافت تعداد بازدیدها و تغییر حالت تایپینگ
| متد | دسته | کاربرد |
|---|---|---|
message_set_reaction(chat_id, msg_id, reaction) |
Abacus | ثبت ریاکشن اموجی روی یک پیام |
get_messages_views(chat_id, message_ids) |
Abacus | دریافت تعداد بازدیدهای پستهای کانال یا گروه |
typing(chat_id, typing_type) |
Presence | نمایش وضعیت در حال تایپ، ضبط صدا، ارسال ویدیو و... |
stop_typing(chat_id) |
Presence | متوقف ساختن نمایش وضعیت تایپ |
set_online(is_online) |
Presence | تغییر وضعیت آنلاین/آفلاین بودن اکانت |
دانلود و آپلود فایل و رسانه (Files & Media API)
آپلود و دانلود پرسرعت با بافرینگ خودکار، تشخیص نوع رسانه و چانکبندی
| متد | ورودیها | خروجی | توضیحات |
|---|---|---|---|
upload_file(file, chunk_size=4096) |
مسیر فایل روی دیسک، بایتها یا شیء فایل باز | FileUploadInfo |
آپلود داده به فایل سرور بله و دریافت شناسه اختصاصی و هش دسترسی |
download_file(file_id, access_hash) |
file_id, access_hash |
bytes |
دانلود مستقیم و باینری تمام انواع اسناد، تصاویر و ویدیوها |
کیفپول، حساب بانکی و بستههای هدیه (Wallet & Kifpool API)
استعلام موجودی کیفپول، شماره حساب و کارت، ارسال بسته هدیه (عیدی) و باز کردن پاکت پول
| متد | پارامترها | توضیحات و کاربرد |
|---|---|---|
get_wallet() |
- | دریافت موجودی ریالی، شماره حساب، شماره کارت (PAN) و توکن کیفپول کاربر |
send_gift() |
chat_id, chat_type, amount, message, gift_count, giving_type |
ارسال بسته هدیه مالی / عیدی به چت خصوصی، گروه یا کانال با تعیین سهمیه و نحوه تقسیم |
open_gift() |
message, token |
باز کردن بسته هدیه ارسالی در چت و دریافت سهم ریالی به کیفپول |
مثال: استعلام موجودی کیفپول و ارسال بسته هدیه
from aiobale import Client, Dispatcher, F
from aiobale.enums import ChatType, GivingType
dp = Dispatcher()
client = Client(dp, session_file="wallet_bot")
@dp.message(F.text == "/balance")
async def check_balance(msg):
wallet_resp = await client.get_wallet()
wallet = wallet_resp.wallet
await msg.reply(
f"💰 موجودی کیفپول شما: {wallet.balance:,} ریال\n"
f"💳 شماره کارت متصل: {wallet.pan or 'نامشخص'}\n"
f"🏦 شماره حساب: {wallet.account or 'نامشخص'}"
)
@dp.message(F.text == "/send_gift")
async def send_gift_pack(msg):
# ارسال عیدی ۱۰,۰۰۰ تومانی بین ۵ نفر به صورت تصادفی/شانسی
await client.send_gift(
chat_id=msg.chat.id,
chat_type=msg.chat.type,
amount=100000,
message="عیدی اعضای گروه 🎁",
gift_count=5,
giving_type=GivingType.RANDOM
)
await msg.reply("بسته هدیه با موفقیت ارسال شد!")
مجلات، پستها و آپووت (Magazine & Upvotes API)
لایک/آپووت پستهای عمومی، لغو رأی، دریافت لیست رأیدهندگان و ارسال گزارش تخلف
| متد | پارامترها | توضیحات و کاربرد |
|---|---|---|
upvote_post() |
chat_id, message_id |
ثبت رأی مثبت / آپووت برای پستهای بخش مجله و کانالها |
revoke_upvoted_post() |
chat_id, message_id |
لغو رأی قبلی ثبتشده روی یک پست |
get_message_upvoters() |
chat_id, message_id |
دریافت لیست و مشخصات کاربرانی که به پست رأی دادهاند |
send_report() |
chat_id, report_reason |
ارسال گزارش تخلف یا اسپم برای یک چت یا پیام به پشتیبانی |
مرجع تایپها و مدلهای داده (Types Reference)
مدلهای داده Pydantic و متدهای شورتکات در کلاس Message
متدهای کمکی کلاس Message
در داخل هر هندلر پیام، آبجکت Message دارای متدهای اختصاصی است که نیاز به پاس دادن دستی chat_id را حذف میکند:
@dp.message()
async def handler(msg: Message):
# ریپلای کردن روی همین پیام
await msg.reply("پاسخ در ریپلای")
# ارسال پیام در همین چت بدون ریپلای
await msg.answer("پیام مستقیم")
# ارسال عکس در همین چت
await msg.answer_photo("./photo.jpg", caption="توضیحات")
# حذف همین پیام
await msg.delete()
# ویرایش متن پیام (در صورتی که توسط خود کلاینت ارسال شده باشد)
await msg.edit_text("متن جدید")
# پین کردن پیام
await msg.pin()
مدلهای چت و کاربر (Chat, User, Member)
فیلدهای اصلی مدلهای داده:
Chat: دارای فیلدهایid,type(از جنس ChatType),title.User / FullUser: دارای فیلدهایid,name,nickname,about,avatar,phone.Member: دارای فیلدهایuser_id,role,inviter_id,permissions.
مرجع ثابتها و انامها (Enums Reference)
ثابتهای استاندارد پکیج برای انواع چت، نوع دسترسی و وضعیتها
| نام Enum | مقادیر شاخص | کاربرد |
|---|---|---|
ChatType |
PRIVATE = 1, GROUP = 2, CHANNEL = 3 |
تفکیک نوع گفتگو در فیلترها و منطق ربات |
PeerType |
USER = 1, GROUP = 2 |
شناسایی نوع مخاطب در پروتکل شبکه |
TypingMode |
TEXT = 1, VOICERECORDING = 2, CHOOSINGGIF = 9 |
ارسال استاتوس به طرف مقابل |
AuthErrors |
NUMBER_BANNED, RATE_LIMIT, INVALID |
شناسایی خطاهای احراز هویت در لاگین |
پروژههای عملی و کاربردی (Real-World Recipes)
کدهای آماده و قابل اجرای ۵ ربات کاربردی در دنیای واقعی
پروژه ۲: ربات ضدلینک و مدیریت گروه (Group Moderation)
import re
from aiobale import Client, Dispatcher, F
from aiobale.types import Message
from aiobale.enums import ChatType
dp = Dispatcher()
client = Client(dp, session_file="mod_bot")
LINK_PATTERN = re.compile(r"(https?://|ble\.ir/|t\.me/|eitaa\.com/)")
# حذف پیامهای حاوی لینک تبلیغاتی در گروهها
@dp.message(F.chat.type == ChatType.GROUP)
async def anti_link_guard(msg: Message, client: Client):
if msg.text and LINK_PATTERN.search(msg.text):
# حذف پیام متخلف
await msg.delete()
print(f"پیام حاوی لینک از کاربر {msg.sender_id} حذف شد.")
@dp.message(F.text.startswith("/ban"), F.chat.type == ChatType.GROUP)
async def ban_command(msg: Message, client: Client):
if msg.replied_to:
target_user = msg.replied_to.sender_id
await client.kick_user(msg.chat.id, target_user)
await msg.answer(f"کاربر {target_user} از گروه اخراج شد.")
if __name__ == "__main__":
client.run()
پروژه ۳: ربات دانلودر و فورواردکننده مدیا (Media Bot)
from aiobale import Client, Dispatcher, F
from aiobale.types import Message
dp = Dispatcher()
client = Client(dp, session_file="media_bot")
@dp.message(F.content.document)
async def download_doc_handler(msg: Message, client: Client):
doc = msg.content.document
await msg.reply(f"در حال دریافت فایل {doc.name}...")
# دانلود مستقیم فایل
file_bytes = await client.download_file(
file_id=doc.file_id,
access_hash=doc.access_hash
)
await msg.reply(f"فایل با حجم {len(file_bytes)} بایت با موفقیت ذخیره شد.")
if __name__ == "__main__":
client.run()
پروژه ۴: ربات برودکست و ارسال به کانال (Broadcaster)
import asyncio
from aiobale import Client
CHANNELS = [100001, 100002, 100003]
async def broadcast_news(text: str):
client = Client(session_file="sender")
await client.start()
for ch_id in CHANNELS:
try:
await client.send_message(chat_id=ch_id, text=text)
print(f"پیام با موفقیت به {ch_id} ارسال شد.")
await asyncio.sleep(1) # جلوگیری از ریتلیمیت
except Exception as e:
print(f"خطا در ارسال به {ch_id}: {e}")
await client.stop()
if __name__ == "__main__":
asyncio.run(broadcast_news("اطلاعیه رسمی جدید در کانالها منتشر شد."))
پروژه ۵: معماری ربات چندماژوله و پیشرفته
from aiobale import Client, Dispatcher, Router, F
from aiobale.types import Message
user_router = Router()
admin_router = Router()
@user_router.message(F.text == "/help")
async def user_help(msg: Message):
await msg.reply("راهنمای کاربر: دستورات مجاز /start و /about")
@admin_router.message(F.text == "/stats")
async def admin_stats(msg: Message, client: Client):
dialogs = await client.load_dialogs(limit=50)
await msg.reply(f"تعداد چتهای فعال: {len(dialogs.chats)}")
dp = Dispatcher()
dp.include_router(user_router)
dp.include_router(admin_router)
client = Client(dp, session_file="modular_bot")
if __name__ == "__main__":
client.run()
فهرست پروژهها و نمونههای آماده (Examples Showcase)
در پوشه examples/ مخزن، ۶ اسکریپت آماده، استاندارد و خودآموز برای سناریوهای مختلف قرار دارد که میتوانید مستقیماً اجرا کنید.
| فایل نمونه | موضوع و عملکرد | قابلیتهای پوشش داده شده |
|---|---|---|
01_auth_and_echo.py |
ربات اکو و ورود تعاملی با CLI | احراز هویت پیامکی، ساخت سشن، هندلرهای پایه پیام، متد reply() |
02_fsm_registration.py |
فرم ثبتنام چندمرحلهای با دیتابیس ماندگار | StatesGroup، State، FSMContext و SQLiteStorage |
03_shop_and_wallet.py |
کاتالوگ محصولات، کیبورد فروشگاهی و کیف پول بله | ReplyKeyboardMarkup، CallbackData، send_gift() |
04_webhook_and_server.py |
راهاندازی ربات با معماری وبهوک | AiohttpWebhookServer، امنیت با secret_token، هندل لایو |
05_rate_limiting_and_middleware.py |
کنترل نرخ ارسال و میدلور ضداسپم | MessageThrottler، زنجیره میدلورهای Pre/Post |
06_pagination_and_keyboards.py |
کیبوردهای شیشهای داینامیک و صفحهبندی محصولات | KeyboardPaginator، دکمههای ناوبری قبلی/بعدی |
مدیریت خطاها و عیبیابی (Troubleshooting)
راهنمای جامع رفع خطاهای متداول شبکه، سشن و توکن
| خطا (Error / Exception) | علت وقوع | راهکار رفع |
|---|---|---|
AuthErrors.NUMBER_BANNED |
شماره واردشده در سیستم بله مسدود یا بن شده است | با پشتیبانی بله تماس بگیرید یا از شماره دیگری استفاده نمایید |
AuthErrors.RATE_LIMIT |
درخواستهای لاگین مکرر در بازه کوتاه | چند دقیقه صبر کرده و مجدداً اقدام فرمایید |
AiobaleError: Authentication token is required... |
اجرا در داکر یا محیط Headless بدون ارسال توکن | پارامتر token="..." را مستقیماً به Client پاس دهید |
ConnectionResetError / Socket Closed |
قطعی موقت اینترنت یا اتصال شبکه | کلاینت به صورت پیشفرض تلاش مجدد خودکار (Auto Reconnect) را انجام میدهد |