🟦 aioshad
🚀 اولین و بزرگترین کتابخانهٔ سلف در پیامرسان شاد
aioshad یک کتابخانهٔ Python و asyncio برای ساخت Client / Self Account روی پیامرسان شاد است.
🎯 هدف پروژه این است که توسعهدهنده بتواند بهجای ساختن یک Bot API جداگانه، برنامه را روی همان اکانتی که با آن وارد شاد شده است اجرا کند.
✨ ویژگیهای اصلی
| بخش | قابلیت |
|---|---|
| 👤 Account | ورود با شماره، نگهداری Session و اجرای API روی همان اکانت |
| 💬 Messages | ارسال، ویرایش، حذف و Reply |
| 📎 Files | Upload و ارسال فایل |
| 🖼️ Photos | Upload، thumbnail و ارسال تصویر |
| 👤 Profile | تغییر نام، نام خانوادگی و Bio |
| ⏰ TimeName | نمایش ساعت/تاریخ کنار نام همان اکانت |
| 🤖 Auto Reply | پاسخ خودکار بر اساس متن دریافتی |
| 🎯 Filters | Command، Regex، Text، Private، Group، Channel، Media و ... |
| 🧩 Filter Logic | ترکیب فیلترها با &، ` |
| 🔄 Dispatcher | دریافت Update و اجرای Handlerها |
| ⏱️ Scheduler | اجرای Taskهای دورهای |
| 🛡️ Rate Limit | محدودسازی نرخ درخواستها |
| 🌐 Network | HTTP/2، Retry، Backoff و Host Failover |
| 🔐 Session | Session قابل ذخیره و رمزنگاریشده |
| 🎙️ Voice Chat | متدهای موجود برای Voice Chat در پروتکل پایه |
| 🧰 Raw RPC | فراخوانی متدهای Authenticated که wrapper ندارند |
| 🧱 Typed Models | مدلهای Message، Chat و User |
📦 نصب
pip install aioshad
آخرین نسخه:
pip install -U aioshad
Python موردنیاز پروژه: 3.11 یا بالاتر.
⚡ شروع سریع
سادهترین حالت استفاده از کتابخانه:
import asyncio
from aioshad import Client
app = Client(
"0905xxxxxxxx",
session_directory="./sessions",
)
async def main():
await app.start()
asyncio.run(main())
در اولین اجرا، فرآیند ورود انجام میشود و Session ذخیره خواهد شد. در اجراهای بعدی، کتابخانه از Session موجود استفاده میکند تا تا حد امکان از ورود مجدد جلوگیری شود.
👤 Self Account چگونه کار میکند؟
aioshad برای یک اکانت کاربری شاد طراحی شده است. یعنی هویت برنامه همان اکانتی است که Session آن ایجاد شده است.
شماره تلفن
↓
Login / OTP
↓
Session
↓
Client
↓
اکانت واقعی شاد
پس ساختار استفاده شبیه یک Bot API مستقل نیست؛ عملیات اصلی از طریق Session اکانت اجرا میشوند.
🔐 Session
بهتر است Sessionها را در یک پوشهٔ جداگانه نگهداری کنید:
app = Client(
"0905xxxxxxxx",
session_directory="./sessions",
)
در صورت نیاز میتوان برای ذخیرهٔ Session از کلید رمزنگاری استفاده کرد:
app = Client(
"0905xxxxxxxx",
session_directory="./sessions",
session_encryption_key="یک-راز-قوی",
)
یا در محیط سیستم:
export AIOSHAD_SESSION_KEY="یک-راز-قوی"
⚠️ نکته امنیتی
فایل Session را مثل یک credential حساس در نظر بگیرید. آن را داخل Git، ZIP عمومی یا کانال عمومی منتشر نکنید.
🧠 Client
کلاس اصلی کتابخانه:
from aioshad import Client
app = Client(phone_number, ...)
سازندهٔ Client
Client(
phone_number: str,
session_directory: str = ".",
messenger_host: str | None = None,
*,
config: ClientConfig | None = None,
session_encryption_key: str | None = None,
)
پارامترها
| پارامتر | توضیح |
|---|---|
phone_number |
شماره اکانت |
session_directory |
محل ذخیره Session |
messenger_host |
Host سفارشی در صورت نیاز |
config |
تنظیمات ClientConfig |
session_encryption_key |
کلید رمزنگاری Session |
🔌 چرخهٔ اتصال
connect()
اتصال به سرویس و آمادهسازی Session:
await app.connect()
start()
اتصال + شروع Dispatcher و نگهداشتن برنامه تا زمان توقف:
await app.start()
start_in_background()
اتصال و اجرای Dispatcher بدون قفلکردن جریان اصلی برنامه:
await app.start_in_background()
run_until_disconnected()
روش جایگزین برای اجرای طولانیمدت:
await app.run_until_disconnected()
stop()
توقف Dispatcher، قابلیتهای background، Transport و ذخیره Session:
await app.stop()
is_connected
بررسی وضعیت اتصال:
if app.is_connected:
print("Connected")
💬 ارسال پیام
send_message()
message = await app.send_message(
object_guid="g0...",
text="سلام شاد!",
)
print(message.id)
Signature:
await app.send_message(
object_guid: str,
text: str = "",
reply_to_message_id: str | None = None,
file_inline: dict | None = None,
)
Reply
await app.send_message(
"g0...",
"پاسخ شما",
reply_to_message_id="123456",
)
✏️ ویرایش پیام
message = await app.edit_message(
object_guid="g0...",
message_id="123456",
text="متن جدید",
)
🗑️ حذف پیام
یک پیام
await app.delete_message(
object_guid="g0...",
message_id="123456",
)
چند پیام
await app.delete_messages(
object_guid="g0...",
message_ids=["123", "124", "125"],
)
delete_type دو مقدار دارد:
Global
Local
مثال:
await app.delete_message(
"g0...",
"123456",
delete_type="Local",
)
📁 فایلها
upload_file()
فایل را Upload میکند و اطلاعات فایل آپلودشده را برمیگرداند:
info = await app.upload_file(
"./files/example.pdf",
)
print(info)
ورودی میتواند Path یا bytes باشد:
data = b"hello"
info = await app.upload_file(
data,
file_name="hello.txt",
mime="txt",
)
Signature:
await app.upload_file(
file,
file_name=None,
mime=None,
chunk_size=None,
)
Upload در این نسخه فایل را ابتدا در حافظه آماده میکند؛ برای فایلهای بسیار بزرگ مصرف RAM را در نظر بگیرید.
🖼️ ارسال تصویر
await app.send_photo(
"g0...",
"./photo.jpg",
caption="یک تصویر",
)
پشتیبانی از ورودی str، bytes و Path وجود دارد.
Reply با عکس:
await app.send_photo(
"g0...",
"./photo.jpg",
caption="پاسخ تصویری",
reply_to_message_id="123456",
)
📄 ارسال فایل
await app.send_file(
"g0...",
"./document.pdf",
caption="فایل شما",
)
همچنین میتوان نام فایل و MIME را مشخص کرد:
await app.send_file(
"g0...",
b"hello world",
file_name="hello.txt",
mime="txt",
caption="سلام",
)
👤 اطلاعات اکانت و کاربران
get_me()
اطلاعات اکانت لاگینشده:
me = await app.get_me()
print(me.guid)
print(me.name)
print(me.username)
print(me.bio)
get_user_info()
user = await app.get_user_info("u0...")
print(user.name)
مدل User
User شامل این فیلدهاست:
guid
name
username
bio
phone
is_verified
✍️ مدیریت پروفایل
API مستقیم
await app.update_profile(
first_name="ابوالفضل",
last_name="سلیمانی",
bio="Powered by aioshad",
)
ProfileManager
کتابخانه یک مدیر پروفایل آماده نیز دارد:
await app.profile.set_name("aioshad")
await app.profile.set_first_name("AioShad")
await app.profile.set_last_name("Client")
await app.profile.set_bio("Async Shad Client")
⏰ TimeName
یکی از قابلیتهای اصلی aioshad، تغییر دورهای نام همان اکانت برای نمایش ساعت/تاریخ است.
from aioshad import Client, TimeName
app = Client(
"0905xxxxxxxx",
session_directory="./sessions",
)
async def main():
await app.connect()
await app.presence.start_time_name(
TimeName(
format="⏰ {time}",
timezone="Asia/Tehran",
interval=60,
)
)
await app.run_until_disconnected()
asyncio.run(main())
تنظیمات TimeName
TimeName(
format="⏰ {time}",
timezone="Asia/Tehran",
interval=60,
preserve_first_name=False,
)
Placeholderها
| Placeholder | مقدار |
|---|---|
{time} |
ساعت 24 ساعته مثل 18:45 |
{time_12} |
ساعت 12 ساعته |
{date} |
تاریخ YYYY-MM-DD |
{day} |
نام روز |
{timestamp} |
Unix timestamp |
مثال:
TimeName(
format="🕒 {time} • {date}",
timezone="Asia/Tehran",
interval=60,
)
حداقل interval در نسخهٔ فعلی ۵ ثانیه است.
توقف TimeName
await app.presence.stop_time_name()
🤖 Auto Reply
سیستم پاسخ خودکار روی همان حساب:
app.autoreply.add(
"سلام",
"سلام! پیام شما دریافت شد.",
)
app.autoreply.set_default(
"پیامت دریافت شد.",
)
await app.autoreply.enable()
غیرفعالسازی:
await app.autoreply.disable()
نکته
پاسخدهی خودکار برای جلوگیری از پاسخ به پیامهای ارسالی خود همان Session طراحی شده است.
🎯 Message Handler
دریافت پیامها با Decorator:
from aioshad import Client, filters
app = Client("0905xxxxxxxx")
@app.on_message(filters.command("ping"))
async def ping(message):
await message.reply("pong")
asyncio.run(app.start())
Handler میتواند sync یا async باشد:
@app.on_message(filters.text)
async def handler(message):
print(message.text)
یا:
@app.on_message(filters.text)
def handler(message):
print(message.text)
Dispatcher نتیجهٔ Awaitable را در صورت وجود await میکند.
🧩 تمام Filterهای موجود
ماژول اصلی:
from aioshad import filters
فیلترهای پایه
| Filter | کاربرد |
|---|---|
filters.all |
همهٔ پیامها |
filters.text |
پیام دارای متن |
filters.private |
چت خصوصی |
filters.group |
گروه |
filters.channel |
کانال |
filters.reply |
پیام Reply شده |
filters.edited |
پیام ویرایششده |
filters.media |
پیامهای Media |
command
@app.on_message(filters.command("start"))
async def start(message):
await message.reply("شروع شد")
چند Command:
filters.command(["start", "help"])
Prefixهای متعدد:
filters.command(
"start",
prefixes=["/", "!", "."],
)
حساسیت به حروف:
filters.command(
"PING",
case_sensitive=True,
)
🔎 RegexFilter
@app.on_message(filters.regex(r"^hello\s+.+$"))
async def hello(message):
await message.reply("Hello!")
با Flags:
import re
filters.regex(r"hello", flags=re.IGNORECASE)
🔤 TextFilter
فقط پیامهایی که متن غیرخالی دارند:
@app.on_message(filters.text)
async def text_message(message):
print(message.text)
👤 PrivateFilter
@app.on_message(filters.private)
async def private_message(message):
await message.reply("پیام خصوصی دریافت شد")
👥 GroupFilter
@app.on_message(filters.group)
async def group_message(message):
print(message.chat_guid)
📢 ChannelFilter
@app.on_message(filters.channel)
async def channel_message(message):
print(message.text)
↩️ ReplyFilter
@app.on_message(filters.reply)
async def replies(message):
print(message.reply_to_message_id)
✏️ EditedFilter
@app.on_message(filters.edited)
async def edited(message):
print("پیام ویرایش شد:", message.text)
🆔 AuthorFilter
برای یک کاربر:
filters.author("u0...")
برای چند کاربر:
filters.author(["u0...", "u0..."])
مثال:
@app.on_message(filters.author("u0..."))
async def from_user(message):
print(message.text)
💬 ChatFilter
filters.chat("g0...")
یا:
filters.chat(["g0...", "c0..."])
🧵 ContainsFilter
@app.on_message(filters.contains("سلام"))
async def contains(message):
await message.reply("کلمهٔ سلام در پیام وجود داشت")
بهصورت پیشفرض مقایسه Case-insensitive است.
filters.contains(
"HELLO",
case_sensitive=True,
)
▶️ StartsWithFilter
@app.on_message(filters.startswith("/"))
async def command_like(message):
print(message.text)
🖼️ MediaFilter
فیلتر Media بهصورت پیشفرض این نوعها را بررسی میکند:
photo
file
video
audio
voice
مثال:
@app.on_message(filters.media)
async def media(message):
print(message.message_type)
نوعهای سفارشی:
filters.media("photo", "video")
🛠️ CustomFilter
میتوان Filter دلخواه ساخت:
def long_message(message):
return len(message.text) > 50
@app.on_message(filters.create(long_message))
async def long_text(message):
await message.reply("پیام طولانی بود")
تابع async نیز قابل استفاده است:
async def custom(message):
return message.text.startswith("aioshad")
@app.on_message(filters.create(custom))
async def handler(message):
...
🔗 ترکیب Filterها
AND — &
هر دو شرط باید برقرار باشند:
@app.on_message(filters.private & filters.text)
async def private_text(message):
print(message.text)
مثال پیشرفته:
@app.on_message(
filters.group & filters.contains("سلام")
)
async def group_hello(message):
await message.reply("سلام گروه")
OR — |
حداقل یکی از شروط:
@app.on_message(
filters.private | filters.group
)
async def chat_message(message):
print(message.text)
NOT — ~
معکوسکردن یک شرط:
@app.on_message(~filters.edited)
async def normal_message(message):
print(message.text)
ترکیب چندگانه
handler_filter = (
(filters.private | filters.group)
& filters.text
& ~filters.edited
)
@app.on_message(handler_filter)
async def handler(message):
print(message.text)
📨 کلاس Message
پیامی که به Handler داده میشود از نوع Message است.
فیلدهای اصلی:
id
author_guid
chat_guid
text
message_type
reply_to_message_id
is_edited
raw
Reply
await message.reply("سلام")
Reply با عکس
await message.reply_photo(
"./image.jpg",
caption="عکس",
)
Reply با فایل
await message.reply_file(
"./document.pdf",
caption="فایل",
)
Edit
await message.edit("متن جدید")
Delete
await message.delete()
یا:
await message.delete(delete_type="Local")
گرفتن Chat
chat = await message.get_chat()
print(chat.title)
گرفتن Author
user = await message.get_author()
print(user.name)
دسترسی به داده خام
value = message.get("some_key")
یا:
value = message["some_key"]
💬 کلاس Chat
Chat برای کار با یک گفتوگو استفاده میشود.
فیلدهای اصلی:
guid
title
type
username
description
members_count
voice_chat_id
raw
ارسال پیام از خود Chat
chat = await app.get_chat_info("g0...")
await chat.send_message("سلام")
ارسال عکس
await chat.send_photo("./photo.jpg")
ارسال فایل
await chat.send_file("./file.pdf")
تاریخچه
messages = await chat.get_chat_history(limit=50)
پیامها
messages = await chat.get_messages(limit=50)
حذف پیام
await chat.delete_message("123456")
یا:
await chat.delete_messages(["123", "124"])
📚 مدیریت Chatها
get_chats()
result = await app.get_chats()
print(result)
get_chat_info()
chat = await app.get_chat_info("g0...")
get_chat_info_by_username()
chat = await app.get_chat_info_by_username("username")
🕘 تاریخچه و پیامها
get_messages()
result = await app.get_messages(
"g0...",
limit=50,
)
پارامترهای صفحهبندی:
await app.get_messages(
"g0...",
limit=50,
sort="FromMax",
max_id="1000",
min_id="900",
)
get_chat_history()
این متد خروجی را به فهرست Message تبدیل میکند:
messages = await app.get_chat_history(
"g0...",
limit=50,
)
for message in messages:
print(message.id, message.text)
🔄 Updateها
get_chats_updates()
updates = await app.get_chats_updates(state=0)
get_messages_updates()
updates = await app.get_messages_updates(
"g0...",
state=0,
)
Dispatcher داخلی نیز از updateهای چت برای دریافت پیامها استفاده میکند.
📡 Dispatcher
Dispatcher مسئول دریافت Update و اجرای Handlerهاست.
ویژگیهای اصلی:
- Polling دورهای
- اجرای Filter قبل از Handler
- اجرای همزمان Handlerها
- ثبت و حذف Handler
- جلوگیری از پردازش تکراری Messageهای دیدهشده
- کنترل خطاهای متوالی
- توقف تمیز
حذف Handler
@app.on_message(filters.text)
async def my_handler(message):
...
app.remove_handler(my_handler)
remove_handler() تعداد Handlerهای حذفشده را برمیگرداند.
⏱️ Scheduler
برای اجرای Taskهای دورهای:
async def job():
print("task running")
app.scheduler.every(60, job)
حداقل interval برابر ۵ ثانیه است.
توقف تمام Taskها:
await app.scheduler.cancel_all()
🛡️ Rate Limiting
aioshad در Transport از محدودسازی نرخ درخواست استفاده میکند.
تنظیم پیشفرض:
5 requests / second
قابل تنظیم از طریق ClientConfig:
from aioshad import Client, ClientConfig
config = ClientConfig(
max_requests_per_second=3,
)
app = Client(
"0905xxxxxxxx",
config=config,
)
⚙️ ClientConfig
کلاس تنظیمات:
from aioshad import ClientConfig
مقادیر اصلی نسخهٔ فعلی:
| گزینه | مقدار پیشفرض |
|---|---|
timeout |
30.0 |
poll_interval |
1.5 |
error_backoff |
3.0 |
max_consecutive_errors |
10 |
max_requests_per_second |
5.0 |
retry_attempts |
3 |
upload_chunk_size |
131072 |
app_version |
4.4.26 |
platform |
Web |
package |
web.shad.ir |
language |
fa |
مثال:
config = ClientConfig(
timeout=45,
poll_interval=2,
retry_attempts=5,
max_requests_per_second=4,
)
🌐 Network و Host
کتابخانه Transport خود را دارد و برای ارتباط شبکهای از HTTP/2 استفاده میکند.
قابلیتهای لایهٔ شبکه:
- Timeout
- Retry
- Backoff
- Rate Limit
- Host Failover
- Upload Chunk
Hostهای پیشفرض پروژه:
shadmessenger60.iranlms.ir
shadmessenger145.iranlms.ir
shadmessenger40.iranlms.ir
shadmessenger23.iranlms.ir
shadmessenger57.iranlms.ir
برای انتخاب Host دستی:
app.set_messenger_host(
"example-host"
)
Hostهای واقعی سرویس ممکن است تغییر کنند. این فهرست مربوط به مقادیری است که در نسخهٔ فعلی پروژه تعریف شدهاند.
🎙️ Voice Chat
متدهای زیر در Client وجود دارند:
await app.create_voice_chat("g0...")
await app.join_voice_chat(
"g0...",
voice_chat_id="...",
sdp_offer_data="...",
)
await app.leave_voice_chat(
"g0...",
voice_chat_id="...",
)
await app.get_voice_chat_participants(
"g0...",
voice_chat_id="...",
)
await app.discard_voice_chat(
"g0...",
voice_chat_id="...",
)
await app.set_voice_chat_state(
"g0...",
voice_chat_id="...",
activity="Speaking",
)
Chat نیز wrapperهای مربوط به Join/Leave/Participants را ارائه میکند.
جزئیات SDP و رفتار نهایی Voice Chat به پروتکل/endpoint فعال شاد وابسته است.
🚫 Block / Unblock
برای مسدود یا آزادکردن کاربر:
await app.block_user("u0...")
و:
await app.unblock_user("u0...")
این دو متد در Client به یک RPC احرازشدهٔ مربوط به Block متصل هستند.
🧰 Raw RPC
اگر یک متد Authenticated در wrapperهای سطحبالای aioshad وجود نداشته باشد، میتوانید از invoke() استفاده کنید:
result = await app.invoke(
"METHOD_NAME",
key="value",
)
مثال با دادههای متعدد:
result = await app.invoke(
"METHOD_NAME",
object_guid="g0...",
limit=50,
)
این API عمداً generic است تا برای متدهای جدید پروتکل لازم نباشد هستهٔ Client تغییر کند.
نام Method و پارامترهای RPC باید مطابق endpoint و payload واقعی سرویس باشد؛
aioshadبرای RPCهای ناشناخته payload حدسی تولید نمیکند.
🧱 API کامل Client — Reference
تمام متدهای عمومی Client در نسخهٔ فعلی:
| متد | خروجی | کاربرد |
|---|---|---|
connect() |
Client |
اتصال/احراز هویت |
start() |
None |
شروع کامل Client |
start_in_background() |
None |
شروع بدون idle داخلی |
run_until_disconnected() |
None |
اجرای طولانیمدت |
stop() |
None |
توقف تمیز |
on_message() |
Handler | ثبت Message Handler |
remove_handler() |
int |
حذف Handler |
send_message() |
Message |
ارسال پیام |
edit_message() |
Message |
ویرایش پیام |
delete_messages() |
dict |
حذف چند پیام |
delete_message() |
dict |
حذف یک پیام |
upload_file() |
dict |
Upload فایل |
send_photo() |
Message |
ارسال عکس |
send_file() |
Message |
ارسال فایل |
get_user_info() |
User |
اطلاعات کاربر |
get_me() |
User |
اطلاعات حساب فعلی |
update_profile() |
bool |
تغییر پروفایل |
get_chats() |
dict |
دریافت Chatها |
get_messages() |
dict |
دریافت پیامها |
get_chats_updates() |
dict |
دریافت updateهای چت |
get_messages_updates() |
dict |
دریافت updateهای پیام |
get_chat_history() |
list[Message] |
تاریخچهٔ Chat |
register_device() |
dict |
ثبت/بررسی Device |
get_chat_info() |
Chat |
اطلاعات Chat |
get_chat_info_by_username() |
Chat |
Chat با Username |
join_voice_chat() |
dict |
Join Voice Chat |
leave_voice_chat() |
dict |
Leave Voice Chat |
get_voice_chat_participants() |
dict |
Participants |
create_voice_chat() |
dict |
ساخت Voice Chat |
discard_voice_chat() |
dict |
حذف/Discard Voice Chat |
set_voice_chat_state() |
dict |
تغییر وضعیت Voice Chat |
invoke() |
dict |
RPC خام |
block_user() |
dict |
Block |
unblock_user() |
dict |
Unblock |
set_messenger_host() |
None |
تعیین Host |
🧩 API کلاس Message — Reference
متدهای عمومی Message:
edit()
delete()
reply()
reply_photo()
reply_file()
get_chat()
get_author()
get()
__getitem__()
مثال کامل:
@app.on_message(filters.command("demo"))
async def demo(message):
await message.edit("پیام ویرایش شد")
await message.reply("Reply")
chat = await message.get_chat()
user = await message.get_author()
print(chat.title)
print(user.name)
💬 API کلاس Chat — Reference
متدهای عمومی Chat:
send_message()
send_photo()
send_file()
get_chat_history()
get_messages()
delete_messages()
delete_message()
join_voice_chat()
leave_voice_chat()
get_voice_chat_participants()
get()
__getitem__()
👤 API کلاس User
User یک مدل دادهای سبک است و فیلدهای زیر را ارائه میکند:
guid
name
username
bio
phone
is_verified
⏰ API قابلیتها
ProfileManager
set_name()
set_first_name()
set_last_name()
set_bio()
PresenceManager
start_time_name()
stop_time_name()
close()
AutoResponder
add()
set_default()
enable()
disable()
Scheduler
every()
cancel_all()
🧩 API Filter — Reference کامل
کلاسهای موجود:
Filter
AndFilter
OrFilter
InvertFilter
CustomFilter
CommandFilter
RegexFilter
TextFilter
PrivateFilter
GroupFilter
ChannelFilter
ReplyFilter
EditedFilter
AuthorFilter
ChatFilter
AllFilter
ContainsFilter
StartsWithFilter
MediaFilter
Aliasهای راحت نیز وجود دارند:
command
regex
author
chat
create
text
private
group
channel
reply
edited
all
contains
startswith
media
🧯 مدیریت خطاها
استثناهای اصلی کتابخانه:
from aioshad import (
AioShadError,
AuthenticationError,
InvalidSessionError,
RPCError,
RateLimitError,
UnsupportedMethodError,
)
ساختار کلی:
AioShadError
├── AuthenticationError
│ └── InvalidSessionError
├── RateLimitError
├── UnsupportedMethodError
└── RPCError
نمونه:
from aioshad import AuthenticationError, RPCError
try:
await app.connect()
except AuthenticationError:
print("خطای احراز هویت")
except RPCError as exc:
print("RPC error:", exc)
🧪 یک نمونه پروژهٔ کامل
import asyncio
from aioshad import Client, TimeName, filters
app = Client(
"0905xxxxxxxx",
session_directory="./sessions",
)
@app.on_message(filters.command("ping"))
async def ping(message):
await message.reply("pong 🏓")
@app.on_message(filters.private & filters.text)
async def private_text(message):
print("Private:", message.text)
@app.on_message(filters.media)
async def media(message):
print("Media:", message.message_type)
async def main():
await app.connect()
# تغییر نام بر اساس زمان
await app.presence.start_time_name(
TimeName(
format="⏰ {time}",
timezone="Asia/Tehran",
interval=60,
)
)
# پاسخ خودکار
app.autoreply.add("سلام", "سلام! 👋")
await app.autoreply.enable()
await app.run_until_disconnected()
try:
asyncio.run(main())
except KeyboardInterrupt:
pass
🗂️ ساختار پروژه
ساختار نسخهٔ فعلی:
aioshad/
├── aioshad/
│ ├── __init__.py
│ ├── client.py
│ ├── config.py
│ ├── crypto.py
│ ├── dispatcher.py
│ ├── errors.py
│ ├── features.py
│ ├── filters.py
│ ├── methods.py
│ ├── network.py
│ ├── rate_limit.py
│ ├── session.py
│ ├── py.typed
│ └── types/
│ ├── __init__.py
│ ├── chat.py
│ ├── message.py
│ └── user.py
│
├── examples/
│ ├── selfbot.py
│ └── time_name.py
│
├── tests/
│ └── test_core.py
│
├── pyproject.toml
├── setup.py
├── requirements.txt
├── MANIFEST.in
├── CHANGELOG.md
├── LICENSE
└── README.md
🧠 معماری داخلی
┌─────────────────┐
│ Client │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
Dispatcher Methods Features
│ │ ┌──────┼──────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
Filters Transport Profile TimeName AutoReply
│
┌────────┼────────┐
▼ ▼ ▼
HTTP/2 Retry Rate Limit
│
▼
Shad
📋 وابستگیها
پروژه بهصورت رسمی این وابستگیها را تعریف میکند:
httpx >= 0.27.0
h2 >= 4.0.0
cryptography >= 42.0.0
Pillow >= 10.0.0
🧪 تست
برای اجرای تستهای پروژه:
pytest
تستهای موجود روی بخشهای هسته مانند Session، Modelها، Filterها، Rate Limiter و Config متمرکزند.
تست زندهٔ شبکه بهصورت پیشفرض نیازمند یک اکانت معتبر و سرویس فعال است.
⚠️ محدودیتها و نکات سازگاری
aioshad مستقیماً به پروتکل و endpointهای شاد وابسته است. در نتیجه ممکن است با تغییر سمت سرویس، بعضی متدها نیاز به بهروزرسانی داشته باشند.
چند نکتهٔ مهم:
- APIهای داخلی شاد ممکن است تغییر کنند.
- Hostهای سرویس ممکن است جابهجا یا غیرفعال شوند.
- رفتار Voice Chat به endpoint و payload فعال وابسته است.
invoke()برای RPCهای جدید یا wrapperنشده وجود دارد.- قابلیتهای ادعاشده در این README بر اساس API موجود در نسخهٔ فعلی پروژه مستند شدهاند؛ قابلیتهایی که در سورس وجود ندارند عمداً بهعنوان API رسمی این نسخه معرفی نشدهاند.
🔒 امنیت
برای استفادهٔ امن:
✅ Session را خصوصی نگه دارید
✅ Token/Key را در کد عمومی نگذارید
✅ پوشهٔ sessions را به Git اضافه نکنید
✅ از Session اکانت دیگران استفاده نکنید
✅ Rate Limit را جدی بگیرید
پیشنهاد برای .gitignore:
sessions/
*.session
.env
📜 مجوز
این پروژه با مجوز MIT ارائه شده است.
👨💻 سازنده
ابوالفضل سلیمانی
توسعهدهندهٔ پروژهٔ aioshad.
🔗 GitHub:
📢 Telegram:
⭐ پشتیبانی و توسعه
برای توسعهٔ پروژه، Issue و Pull Request را از طریق GitHub ارسال کنید:
Lifecycle (1.0.5)
import asyncio
from aioshad import Client
app = Client(
phone_number="0905xxxxxxxx",
session_directory="./sessions",
)
async def main():
await app.start()
if __name__ == "__main__":
asyncio.run(main())
برای اجرای background:
await app.start_in_background()
# application work
await app.stop()
connect() اتصال را آماده میکند؛ start() چرخهٔ کامل اجرا را شروع میکند؛
run_until_disconnected() برای اجرای طولانیمدت است؛ و stop() باید shutdown را کامل کند.
Changelog
v1.0.14
- 🎉 Stable release
- 🐛 TimeName:
preserve_first_name=Trueworks correctly - 🐛 TimeName:
stop_time_name()restores the original first name - 🐛 TimeName: added
time_full(HH:MM:SS) format variable - 🐛 TimeName:
intervalminimum enforced at 60s (shad rate limit) - 🐛 TimeName: automatic retry with backoff on
TOO_REQUESTS - 🐛 Scheduler.every: works as a decorator:
@scheduler.every(30) - 🐛 filters.media: instance (no
()needed) - 🐛 filters.command(prefixes="/"): works without
commands - 🐛 Clearer
TypeErrorfor filter classes without() - 🐛 Add missing
import re(methods.py, features.py) - 🐛 Replace deprecated
asyncio.iscoroutinefunction - 🔇 Reduce
httpxlog verbosity
⚠️ اصالت نسخه
این تنها نسخهٔ رسمی و اصلی کتابخانهٔ
aioshadاست.سازنده: Abolfazl Solimane مخزن رسمی: https://github.com/shanduzgil نسخهٔ رسمی روی PyPI: aioshad
در صورت مشاهدهٔ پکیجها یا مخازن مشابه با نامهای متفاوت یا نسخههای نامعتبر، آنها توسط این پروژه تأیید نشدهاند و ممکن است شامل کد مخرب، جاسوسی یا نسخهٔ دستکاریشده باشند. فقط از منابع بالا نصب کنید.
Changelog — نسخه 1.0.14
- بازطراحی README با لوگوی اصلی پروژه
- افزودن واترمارک اصالت و هشدار درباره نسخههای جعلی
- بهروزرسانی لینک مستندات رسمی
- بهبود متادیتای PyPI (license، urls، package-data)
- رفع ناهماهنگی نسخه در
__init__.py - تعویض نمونههای شماره تلفن به فرمت بهروز
Release files for aioshad 1.0.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aioshad-1.0.14.tar.gz | 1.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aioshad-1.0.14-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.0 MB
Release files / aioshad-1.0.14.tar.gz
| Download URL | aioshad-1.0.14.tar.gz |
|---|---|
| Size | 1.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2e3a0d13e6d2d588ad6beba1202a114556738022d0c03ab442ce62e061eb2e93
|
|
BLAKE2b-256 checksum How to use checksums |
ea706237154d64c0476103390ed487442020ffd1caa058bdfe81f546f32e9208
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / aioshad-1.0.14-py3-none-any.whl
| Download URL | aioshad-1.0.14-py3-none-any.whl |
|---|---|
| Size | 1.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4941de16ac9a6e054e6b7b5a467ebf85d7c6af033b67254b8deea4889f6ed2d2
|
|
BLAKE2b-256 checksum How to use checksums |
ce9d3250eb4f3b6d36a227f691d9b1998d5817fd4b982b00e0cd96cc9e35c06b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|