Metadata-Version: 2.4
Name: aioshad
Version: 1.0.2
Summary: Advanced asynchronous Python client/userbot library for a Shad account
Author: aioshad contributors
License: MIT
Keywords: shad,messenger,userbot,asyncio,python,account-client
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Framework :: AsyncIO
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27.0
Requires-Dist: h2>=4.0.0
Requires-Dist: cryptography>=42.0.0
Requires-Dist: Pillow>=10.0.0
Dynamic: license-file
Dynamic: requires-python

# 🟦 aioshad

## 🚀 اولین و بزرگ‌ترین کتابخانهٔ سلف در پیام‌رسان شاد

**aioshad** یک کتابخانهٔ Python و `asyncio` برای ساخت **Client / Self Account** روی پیام‌رسان شاد است.

> 🎯 هدف پروژه این است که توسعه‌دهنده بتواند به‌جای ساختن یک Bot API جداگانه، برنامه را روی **همان اکانتی که با آن وارد شاد شده است** اجرا کند.

<div align="center">

### 👤 توسعه‌دهنده
**ابوالفضل سلیمانی**

[GitHub](https://github.com/shanduzgil) · [Telegram](https://t.me/hacker_king_sog)

</div>

---

## ✨ ویژگی‌های اصلی

| بخش | قابلیت |
|---|---|
| 👤 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` |

---

# 📦 نصب

```bash
pip install aioshad
```

آخرین نسخه:

```bash
pip install -U aioshad
```

> Python موردنیاز پروژه: **3.11 یا بالاتر**.

---

# ⚡ شروع سریع

ساده‌ترین حالت استفاده از کتابخانه:

```python
import asyncio
from aioshad import Client

app = Client(
    "0937xxxxxxxx",
    session_directory="./sessions",
)

async def main():
    await app.start()

asyncio.run(main())
```

در اولین اجرا، فرآیند ورود انجام می‌شود و Session ذخیره خواهد شد. در اجراهای بعدی، کتابخانه از Session موجود استفاده می‌کند تا تا حد امکان از ورود مجدد جلوگیری شود.

---

# 👤 Self Account چگونه کار می‌کند؟

`aioshad` برای یک **اکانت کاربری شاد** طراحی شده است. یعنی هویت برنامه همان اکانتی است که Session آن ایجاد شده است.

```text
شماره تلفن
    ↓
Login / OTP
    ↓
Session
    ↓
Client
    ↓
اکانت واقعی شاد
```

پس ساختار استفاده شبیه یک Bot API مستقل نیست؛ عملیات اصلی از طریق Session اکانت اجرا می‌شوند.

---

# 🔐 Session

بهتر است Sessionها را در یک پوشهٔ جداگانه نگهداری کنید:

```python
app = Client(
    "0937xxxxxxxx",
    session_directory="./sessions",
)
```

در صورت نیاز می‌توان برای ذخیرهٔ Session از کلید رمزنگاری استفاده کرد:

```python
app = Client(
    "0937xxxxxxxx",
    session_directory="./sessions",
    session_encryption_key="یک-راز-قوی",
)
```

یا در محیط سیستم:

```bash
export AIOSHAD_SESSION_KEY="یک-راز-قوی"
```

### ⚠️ نکته امنیتی

فایل Session را مثل یک credential حساس در نظر بگیرید. آن را داخل Git، ZIP عمومی یا کانال عمومی منتشر نکنید.

---

# 🧠 Client

کلاس اصلی کتابخانه:

```python
from aioshad import Client

app = Client(phone_number, ...)
```

## سازندهٔ Client

```python
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:

```python
await app.connect()
```

## `start()`

اتصال + شروع Dispatcher و نگه‌داشتن برنامه تا زمان توقف:

```python
await app.start()
```

## `start_in_background()`

اتصال و اجرای Dispatcher بدون قفل‌کردن جریان اصلی برنامه:

```python
await app.start_in_background()
```

## `run_until_disconnected()`

روش جایگزین برای اجرای طولانی‌مدت:

```python
await app.run_until_disconnected()
```

## `stop()`

توقف Dispatcher، قابلیت‌های background، Transport و ذخیره Session:

```python
await app.stop()
```

## `is_connected`

بررسی وضعیت اتصال:

```python
if app.is_connected:
    print("Connected")
```

---

# 💬 ارسال پیام

## `send_message()`

```python
message = await app.send_message(
    object_guid="g0...",
    text="سلام شاد!",
)

print(message.id)
```

Signature:

```python
await app.send_message(
    object_guid: str,
    text: str = "",
    reply_to_message_id: str | None = None,
    file_inline: dict | None = None,
)
```

### Reply

```python
await app.send_message(
    "g0...",
    "پاسخ شما",
    reply_to_message_id="123456",
)
```

---

# ✏️ ویرایش پیام

```python
message = await app.edit_message(
    object_guid="g0...",
    message_id="123456",
    text="متن جدید",
)
```

---

# 🗑️ حذف پیام

## یک پیام

```python
await app.delete_message(
    object_guid="g0...",
    message_id="123456",
)
```

## چند پیام

```python
await app.delete_messages(
    object_guid="g0...",
    message_ids=["123", "124", "125"],
)
```

`delete_type` دو مقدار دارد:

```text
Global
Local
```

مثال:

```python
await app.delete_message(
    "g0...",
    "123456",
    delete_type="Local",
)
```

---

# 📁 فایل‌ها

## `upload_file()`

فایل را Upload می‌کند و اطلاعات فایل آپلودشده را برمی‌گرداند:

```python
info = await app.upload_file(
    "./files/example.pdf",
)

print(info)
```

ورودی می‌تواند Path یا `bytes` باشد:

```python
data = b"hello"

info = await app.upload_file(
    data,
    file_name="hello.txt",
    mime="txt",
)
```

Signature:

```python
await app.upload_file(
    file,
    file_name=None,
    mime=None,
    chunk_size=None,
)
```

> Upload در این نسخه فایل را ابتدا در حافظه آماده می‌کند؛ برای فایل‌های بسیار بزرگ مصرف RAM را در نظر بگیرید.

---

# 🖼️ ارسال تصویر

```python
await app.send_photo(
    "g0...",
    "./photo.jpg",
    caption="یک تصویر",
)
```

پشتیبانی از ورودی `str`، `bytes` و `Path` وجود دارد.

Reply با عکس:

```python
await app.send_photo(
    "g0...",
    "./photo.jpg",
    caption="پاسخ تصویری",
    reply_to_message_id="123456",
)
```

---

# 📄 ارسال فایل

```python
await app.send_file(
    "g0...",
    "./document.pdf",
    caption="فایل شما",
)
```

همچنین می‌توان نام فایل و MIME را مشخص کرد:

```python
await app.send_file(
    "g0...",
    b"hello world",
    file_name="hello.txt",
    mime="txt",
    caption="سلام",
)
```

---

# 👤 اطلاعات اکانت و کاربران

## `get_me()`

اطلاعات اکانت لاگین‌شده:

```python
me = await app.get_me()

print(me.guid)
print(me.name)
print(me.username)
print(me.bio)
```

## `get_user_info()`

```python
user = await app.get_user_info("u0...")
print(user.name)
```

### مدل `User`

`User` شامل این فیلدهاست:

```text
 guid
 name
 username
 bio
 phone
 is_verified
```

---

# ✍️ مدیریت پروفایل

## API مستقیم

```python
await app.update_profile(
    first_name="ابوالفضل",
    last_name="سلیمانی",
    bio="Powered by aioshad",
)
```

## `ProfileManager`

کتابخانه یک مدیر پروفایل آماده نیز دارد:

```python
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`، **تغییر دوره‌ای نام همان اکانت برای نمایش ساعت/تاریخ** است.

```python
from aioshad import Client, TimeName

app = Client(
    "0937xxxxxxxx",
    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`

```python
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 |

مثال:

```python
TimeName(
    format="🕒 {time} • {date}",
    timezone="Asia/Tehran",
    interval=60,
)
```

حداقل interval در نسخهٔ فعلی **۵ ثانیه** است.

## توقف TimeName

```python
await app.presence.stop_time_name()
```

---

# 🤖 Auto Reply

سیستم پاسخ خودکار روی همان حساب:

```python
app.autoreply.add(
    "سلام",
    "سلام! پیام شما دریافت شد.",
)

app.autoreply.set_default(
    "پیامت دریافت شد.",
)

await app.autoreply.enable()
```

غیرفعال‌سازی:

```python
await app.autoreply.disable()
```

### نکته

پاسخ‌دهی خودکار برای جلوگیری از پاسخ به پیام‌های ارسالی خود همان Session طراحی شده است.

---

# 🎯 Message Handler

دریافت پیام‌ها با Decorator:

```python
from aioshad import Client, filters

app = Client("0937xxxxxxxx")

@app.on_message(filters.command("ping"))
async def ping(message):
    await message.reply("pong")

asyncio.run(app.start())
```

Handler می‌تواند sync یا async باشد:

```python
@app.on_message(filters.text)
async def handler(message):
    print(message.text)
```

یا:

```python
@app.on_message(filters.text)
def handler(message):
    print(message.text)
```

Dispatcher نتیجهٔ Awaitable را در صورت وجود await می‌کند.

---

# 🧩 تمام Filterهای موجود

ماژول اصلی:

```python
from aioshad import filters
```

## فیلترهای پایه

| Filter | کاربرد |
|---|---|
| `filters.all` | همهٔ پیام‌ها |
| `filters.text` | پیام دارای متن |
| `filters.private` | چت خصوصی |
| `filters.group` | گروه |
| `filters.channel` | کانال |
| `filters.reply` | پیام Reply شده |
| `filters.edited` | پیام ویرایش‌شده |
| `filters.media` | پیام‌های Media |

---

## `command`

```python
@app.on_message(filters.command("start"))
async def start(message):
    await message.reply("شروع شد")
```

چند Command:

```python
filters.command(["start", "help"])
```

Prefixهای متعدد:

```python
filters.command(
    "start",
    prefixes=["/", "!", "."],
)
```

حساسیت به حروف:

```python
filters.command(
    "PING",
    case_sensitive=True,
)
```

---

# 🔎 RegexFilter

```python
@app.on_message(filters.regex(r"^hello\s+.+$"))
async def hello(message):
    await message.reply("Hello!")
```

با Flags:

```python
import re

filters.regex(r"hello", flags=re.IGNORECASE)
```

---

# 🔤 TextFilter

فقط پیام‌هایی که متن غیرخالی دارند:

```python
@app.on_message(filters.text)
async def text_message(message):
    print(message.text)
```

---

# 👤 PrivateFilter

```python
@app.on_message(filters.private)
async def private_message(message):
    await message.reply("پیام خصوصی دریافت شد")
```

---

# 👥 GroupFilter

```python
@app.on_message(filters.group)
async def group_message(message):
    print(message.chat_guid)
```

---

# 📢 ChannelFilter

```python
@app.on_message(filters.channel)
async def channel_message(message):
    print(message.text)
```

---

# ↩️ ReplyFilter

```python
@app.on_message(filters.reply)
async def replies(message):
    print(message.reply_to_message_id)
```

---

# ✏️ EditedFilter

```python
@app.on_message(filters.edited)
async def edited(message):
    print("پیام ویرایش شد:", message.text)
```

---

# 🆔 AuthorFilter

برای یک کاربر:

```python
filters.author("u0...")
```

برای چند کاربر:

```python
filters.author(["u0...", "u0..."])
```

مثال:

```python
@app.on_message(filters.author("u0..."))
async def from_user(message):
    print(message.text)
```

---

# 💬 ChatFilter

```python
filters.chat("g0...")
```

یا:

```python
filters.chat(["g0...", "c0..."])
```

---

# 🧵 ContainsFilter

```python
@app.on_message(filters.contains("سلام"))
async def contains(message):
    await message.reply("کلمهٔ سلام در پیام وجود داشت")
```

به‌صورت پیش‌فرض مقایسه Case-insensitive است.

```python
filters.contains(
    "HELLO",
    case_sensitive=True,
)
```

---

# ▶️ StartsWithFilter

```python
@app.on_message(filters.startswith("/"))
async def command_like(message):
    print(message.text)
```

---

# 🖼️ MediaFilter

فیلتر Media به‌صورت پیش‌فرض این نوع‌ها را بررسی می‌کند:

```text
photo
file
video
audio
voice
```

مثال:

```python
@app.on_message(filters.media)
async def media(message):
    print(message.message_type)
```

نوع‌های سفارشی:

```python
filters.media("photo", "video")
```

---

# 🛠️ CustomFilter

می‌توان Filter دلخواه ساخت:

```python
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 نیز قابل استفاده است:

```python
async def custom(message):
    return message.text.startswith("aioshad")

@app.on_message(filters.create(custom))
async def handler(message):
    ...
```

---

# 🔗 ترکیب Filterها

## AND — `&`

هر دو شرط باید برقرار باشند:

```python
@app.on_message(filters.private & filters.text)
async def private_text(message):
    print(message.text)
```

مثال پیشرفته:

```python
@app.on_message(
    filters.group & filters.contains("سلام")
)
async def group_hello(message):
    await message.reply("سلام گروه")
```

## OR — `|`

حداقل یکی از شروط:

```python
@app.on_message(
    filters.private | filters.group
)
async def chat_message(message):
    print(message.text)
```

## NOT — `~`

معکوس‌کردن یک شرط:

```python
@app.on_message(~filters.edited)
async def normal_message(message):
    print(message.text)
```

## ترکیب چندگانه

```python
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` است.

فیلدهای اصلی:

```text
id
author_guid
chat_guid
text
message_type
reply_to_message_id
is_edited
raw
```

## Reply

```python
await message.reply("سلام")
```

## Reply با عکس

```python
await message.reply_photo(
    "./image.jpg",
    caption="عکس",
)
```

## Reply با فایل

```python
await message.reply_file(
    "./document.pdf",
    caption="فایل",
)
```

## Edit

```python
await message.edit("متن جدید")
```

## Delete

```python
await message.delete()
```

یا:

```python
await message.delete(delete_type="Local")
```

## گرفتن Chat

```python
chat = await message.get_chat()
print(chat.title)
```

## گرفتن Author

```python
user = await message.get_author()
print(user.name)
```

## دسترسی به داده خام

```python
value = message.get("some_key")
```

یا:

```python
value = message["some_key"]
```

---

# 💬 کلاس Chat

`Chat` برای کار با یک گفت‌وگو استفاده می‌شود.

فیلدهای اصلی:

```text
guid
title
type
username
description
members_count
voice_chat_id
raw
```

## ارسال پیام از خود Chat

```python
chat = await app.get_chat_info("g0...")
await chat.send_message("سلام")
```

## ارسال عکس

```python
await chat.send_photo("./photo.jpg")
```

## ارسال فایل

```python
await chat.send_file("./file.pdf")
```

## تاریخچه

```python
messages = await chat.get_chat_history(limit=50)
```

## پیام‌ها

```python
messages = await chat.get_messages(limit=50)
```

## حذف پیام

```python
await chat.delete_message("123456")
```

یا:

```python
await chat.delete_messages(["123", "124"])
```

---

# 📚 مدیریت Chatها

## `get_chats()`

```python
result = await app.get_chats()
print(result)
```

## `get_chat_info()`

```python
chat = await app.get_chat_info("g0...")
```

## `get_chat_info_by_username()`

```python
chat = await app.get_chat_info_by_username("username")
```

---

# 🕘 تاریخچه و پیام‌ها

## `get_messages()`

```python
result = await app.get_messages(
    "g0...",
    limit=50,
)
```

پارامترهای صفحه‌بندی:

```python
await app.get_messages(
    "g0...",
    limit=50,
    sort="FromMax",
    max_id="1000",
    min_id="900",
)
```

## `get_chat_history()`

این متد خروجی را به فهرست `Message` تبدیل می‌کند:

```python
messages = await app.get_chat_history(
    "g0...",
    limit=50,
)

for message in messages:
    print(message.id, message.text)
```

---

# 🔄 Updateها

## `get_chats_updates()`

```python
updates = await app.get_chats_updates(state=0)
```

## `get_messages_updates()`

```python
updates = await app.get_messages_updates(
    "g0...",
    state=0,
)
```

Dispatcher داخلی نیز از updateهای چت برای دریافت پیام‌ها استفاده می‌کند.

---

# 📡 Dispatcher

Dispatcher مسئول دریافت Update و اجرای Handlerهاست.

ویژگی‌های اصلی:

- Polling دوره‌ای
- اجرای Filter قبل از Handler
- اجرای هم‌زمان Handlerها
- ثبت و حذف Handler
- جلوگیری از پردازش تکراری Messageهای دیده‌شده
- کنترل خطاهای متوالی
- توقف تمیز

## حذف Handler

```python
@app.on_message(filters.text)
async def my_handler(message):
    ...

app.remove_handler(my_handler)
```

`remove_handler()` تعداد Handlerهای حذف‌شده را برمی‌گرداند.

---

# ⏱️ Scheduler

برای اجرای Taskهای دوره‌ای:

```python
async def job():
    print("task running")

app.scheduler.every(60, job)
```

حداقل interval برابر **۵ ثانیه** است.

توقف تمام Taskها:

```python
await app.scheduler.cancel_all()
```

---

# 🛡️ Rate Limiting

`aioshad` در Transport از محدودسازی نرخ درخواست استفاده می‌کند.

تنظیم پیش‌فرض:

```text
5 requests / second
```

قابل تنظیم از طریق `ClientConfig`:

```python
from aioshad import Client, ClientConfig

config = ClientConfig(
    max_requests_per_second=3,
)

app = Client(
    "0937xxxxxxxx",
    config=config,
)
```

---

# ⚙️ ClientConfig

کلاس تنظیمات:

```python
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` |

مثال:

```python
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های پیش‌فرض پروژه:

```text
shadmessenger60.iranlms.ir
shadmessenger145.iranlms.ir
shadmessenger40.iranlms.ir
shadmessenger23.iranlms.ir
shadmessenger57.iranlms.ir
```

برای انتخاب Host دستی:

```python
app.set_messenger_host(
    "example-host"
)
```

> Hostهای واقعی سرویس ممکن است تغییر کنند. این فهرست مربوط به مقادیری است که در نسخهٔ فعلی پروژه تعریف شده‌اند.

---

# 🎙️ Voice Chat

متدهای زیر در Client وجود دارند:

```python
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

برای مسدود یا آزادکردن کاربر:

```python
await app.block_user("u0...")
```

و:

```python
await app.unblock_user("u0...")
```

این دو متد در Client به یک RPC احراز‌شدهٔ مربوط به Block متصل هستند.

---

# 🧰 Raw RPC

اگر یک متد Authenticated در wrapperهای سطح‌بالای `aioshad` وجود نداشته باشد، می‌توانید از `invoke()` استفاده کنید:

```python
result = await app.invoke(
    "METHOD_NAME",
    key="value",
)
```

مثال با داده‌های متعدد:

```python
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`:

```text
edit()
delete()
reply()
reply_photo()
reply_file()
get_chat()
get_author()
get()
__getitem__()
```

مثال کامل:

```python
@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`:

```text
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` یک مدل داده‌ای سبک است و فیلدهای زیر را ارائه می‌کند:

```text
guid
name
username
bio
phone
is_verified
```

---

# ⏰ API قابلیت‌ها

## `ProfileManager`

```text
set_name()
set_first_name()
set_last_name()
set_bio()
```

## `PresenceManager`

```text
start_time_name()
stop_time_name()
close()
```

## `AutoResponder`

```text
add()
set_default()
enable()
disable()
```

## `Scheduler`

```text
every()
cancel_all()
```

---

# 🧩 API Filter — Reference کامل

کلاس‌های موجود:

```text
Filter
AndFilter
OrFilter
InvertFilter
CustomFilter
CommandFilter
RegexFilter
TextFilter
PrivateFilter
GroupFilter
ChannelFilter
ReplyFilter
EditedFilter
AuthorFilter
ChatFilter
AllFilter
ContainsFilter
StartsWithFilter
MediaFilter
```

Aliasهای راحت نیز وجود دارند:

```text
command
regex
author
chat
create
text
private
group
channel
reply
edited
all
contains
startswith
media
```

---

# 🧯 مدیریت خطاها

استثناهای اصلی کتابخانه:

```python
from aioshad import (
    AioShadError,
    AuthenticationError,
    InvalidSessionError,
    RPCError,
    RateLimitError,
    UnsupportedMethodError,
)
```

ساختار کلی:

```text
AioShadError
├── AuthenticationError
│   └── InvalidSessionError
├── RateLimitError
├── UnsupportedMethodError
└── RPCError
```

نمونه:

```python
from aioshad import AuthenticationError, RPCError

try:
    await app.connect()
except AuthenticationError:
    print("خطای احراز هویت")
except RPCError as exc:
    print("RPC error:", exc)
```

---

# 🧪 یک نمونه پروژهٔ کامل

```python
import asyncio

from aioshad import Client, TimeName, filters

app = Client(
    "0937xxxxxxxx",
    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
```

---

# 🗂️ ساختار پروژه

ساختار نسخهٔ فعلی:

```text
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
```

---

# 🧠 معماری داخلی

```text
                    ┌─────────────────┐
                    │     Client      │
                    └────────┬────────┘
                             │
        ┌────────────────────┼────────────────────┐
        │                    │                    │
        ▼                    ▼                    ▼
   Dispatcher             Methods             Features
        │                    │            ┌──────┼──────┐
        │                    │            │      │      │
        ▼                    ▼            ▼      ▼      ▼
     Filters             Transport     Profile TimeName AutoReply
                             │
                    ┌────────┼────────┐
                    ▼        ▼        ▼
                  HTTP/2   Retry   Rate Limit
                             │
                             ▼
                           Shad
```

---

# 📋 وابستگی‌ها

پروژه به‌صورت رسمی این وابستگی‌ها را تعریف می‌کند:

```text
httpx >= 0.27.0
h2 >= 4.0.0
cryptography >= 42.0.0
Pillow >= 10.0.0
```

---

# 🧪 تست

برای اجرای تست‌های پروژه:

```bash
pytest
```

تست‌های موجود روی بخش‌های هسته مانند Session، Modelها، Filterها، Rate Limiter و Config متمرکزند.

تست زندهٔ شبکه به‌صورت پیش‌فرض نیازمند یک اکانت معتبر و سرویس فعال است.

---

# ⚠️ محدودیت‌ها و نکات سازگاری

`aioshad` مستقیماً به پروتکل و endpointهای شاد وابسته است. در نتیجه ممکن است با تغییر سمت سرویس، بعضی متدها نیاز به به‌روزرسانی داشته باشند.

چند نکتهٔ مهم:

- APIهای داخلی شاد ممکن است تغییر کنند.
- Hostهای سرویس ممکن است جابه‌جا یا غیرفعال شوند.
- رفتار Voice Chat به endpoint و payload فعال وابسته است.
- `invoke()` برای RPCهای جدید یا wrapperنشده وجود دارد.
- قابلیت‌های ادعاشده در این README بر اساس API موجود در نسخهٔ فعلی پروژه مستند شده‌اند؛ قابلیت‌هایی که در سورس وجود ندارند عمداً به‌عنوان API رسمی این نسخه معرفی نشده‌اند.

---

# 🔒 امنیت

برای استفادهٔ امن:

```text
✅ Session را خصوصی نگه دارید
✅ Token/Key را در کد عمومی نگذارید
✅ پوشهٔ sessions را به Git اضافه نکنید
✅ از Session اکانت دیگران استفاده نکنید
✅ Rate Limit را جدی بگیرید
```

پیشنهاد برای `.gitignore`:

```gitignore
sessions/
*.session
.env
```

---

# 📜 مجوز

این پروژه با مجوز **MIT** ارائه شده است.

---

# 👨‍💻 سازنده

## ابوالفضل سلیمانی

توسعه‌دهندهٔ پروژهٔ `aioshad`.

🔗 GitHub:

https://github.com/shanduzgil

📢 Telegram:

https://t.me/hacker_king_sog

---

# ⭐ پشتیبانی و توسعه

برای توسعهٔ پروژه، Issue و Pull Request را از طریق GitHub ارسال کنید:

**https://github.com/shanduzgil**

---

<div align="center">

### 🟦 aioshad

**Async Python Client / Self Account for Shad**

ساخته‌شده با ❤️ توسط **ابوالفضل سلیمانی**

</div>
