Metadata-Version: 2.1
Name: robka
Version: 2.3.2
Summary: A professional and localized Python library for interacting with Rubika Bot API, compatible with various systems.
Home-page: https://github.com/Mahdy-Ahmadi/robka
Author: Mahdy Ahmadi
Author-email: mahdiahmadi.1208@gmail.com
Maintainer: Mahdy Ahmadi
Maintainer-email: mahdiahmadi.1208@gmail.com
License: UNKNOWN
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.6
Description-Content-Type: text/markdown

# 📚 Robka Bot Python Library Documentation (فارسی)

## معرفی
`robka` یک کتابخانه پایتون برای تعامل با API ربات روبیکا است. این کتابخانه به شما کمک می‌کند ربات‌هایی مشابه تلگرام با پشتیبانی از پیام‌ها، دکمه‌های اینلاین، کی‌پدهای چت و مدیریت کال‌بک‌ها ایجاد کنید. این نسخه بهبود یافته و فارسی‌سازی شده از کتابخانه اصلی است که برای توسعه‌دهندگان ایرانی طراحی شده است.

## نصب
برای نصب `robka`، می‌توانید از pip استفاده کنید:

`pip install robka==2.3.0
```

اگر `importlib.metadata` در دسترس نباشد، به صورت خودکار `importlib-metadata` نصب می‌شود.

## شروع به کار
```python
from robka import Robot
from robka.context import Message

bot = Robot(token="توکن_شما_اینجا")

@bot.on_message(commands=["start"])
def start(bot: Robot, message: Message):
    message.reply("سلام! خوش آمدید!")

bot.run()
```

## مدیریت پیام‌ها
می‌توانید پیام‌های متنی ورودی را با استفاده از `@bot.on_message()` مدیریت کنید:

```python
@bot.on_message(commands=["hello"])
def greet(bot: Robot, message: Message):
    message.reply("سلام کاربر عزیز 👋")
```

می‌توانید فیلترها را نیز اضافه کنید.

## مدیریت دکمه‌های کال‌بک

```python
from robka.keypad import ChatKeypadBuilder

@bot.on_message(commands=["gender"])
def gender(bot: Robot, message: Message):
    keypad = ChatKeypadBuilder().row(
        ChatKeypadBuilder().button(id="male", text="👨 مرد"),
        ChatKeypadBuilder().button(id="female", text="👩 زن")
    ).build()
    message.reply_keypad("جنسیت خود را انتخاب کنید:", keypad)

@bot.on_callback("male")
def on_male(bot: Robot, message: Message):
    message.reply("شما مرد هستید")

@bot.on_callback("female")
def on_female(bot: Robot, message: Message):
    message.reply("شما زن هستید")
```

## سازنده دکمه‌های اینلاین

```python
from robka.button import InlineBuilder

builder = InlineBuilder().row(
    InlineBuilder().button_simple(id="info", text="اطلاعات")
).build()
```

## بررسی عضویت کاربر در کانال

```python
channel_guid = "c0xABCDEF..."

@bot.on_message(commands=["check"])
def check(bot: Robot, message: Message):
    if bot.check_join(channel_guid, message.chat_id):
        message.reply("✅ شما عضو کانال هستید")
    else:
        message.reply("❌ لطفاً ابتدا در کانال عضو شوید")
```

## متدهای کاربردی

| متد | توضیحات |
| --- | --- |
| `get_chat(chat_id)` | دریافت اطلاعات چت |
| `get_name(chat_id)` | دریافت نام کاربر |
| `get_username(chat_id)` | دریافت نام‌کاربری |
| `send_message(...)` | ارسال پیام متنی |
| `edit_message_text(...)` | ویرایش پیام |
| `delete_message(...)` | حذف پیام |
| `send_location(...)` | ارسال موقعیت مکانی |
| `send_poll(...)` | ارسال نظرسنجی |
| `send_contact(...)` | ارسال مخاطب |
| `forward_message(...)` | فوروارد پیام |

## پشتیبانی از Inline Query

```python
@bot.on_inline_query()
def inline(bot: Robot, message: InlineMessage):
    message.answer("نتیجه اینلاین")
```

## انواع دکمه‌ها

انواع دکمه‌های اینلاین پشتیبانی شده عبارتند از:

*   `Simple`
*   `Payment`
*   `Calendar`
*   `Location`
*   `CameraImage`, `CameraVideo`
*   `GalleryImage`, `GalleryVideo`
*   `File`, `Audio`, `RecordAudio`
*   `MyPhoneNumber`, `MyLocation`
*   `Textbox`, `Barcode`, `Link`

برای اطلاعات بیشتر به `InlineBuilder` مراجعه کنید.

## کی‌پد چت پویا

```python
builder = ChatKeypadBuilder()
keypad = builder.row(
    builder.button(id="play", text="🎮 بازی کن"),
    builder.button(id="exit", text="❌ خروج")
).build()
```

## تنظیم دستورات

```python
bot.set_commands([
    {"command": "start", "description": "شروع"},
    {"command": "help", "description": "راهنما"}
])
```

## به‌روزرسانی خودکار Offset

به‌روزرسانی‌های ربات با استفاده از `get_updates()` مدیریت می‌شوند و `offset_id` به صورت داخلی مدیریت می‌شود.

## ویژگی‌های پیشرفته

- `update_bot_endpoint()` – تنظیم webhook یا polling
- `remove_keypad()` – حذف صفحه‌کلید چت
- `edit_chat_keypad()` – ویرایش یا افزودن صفحه‌کلید چت

# مرجع متدهای ربات Robka

مستندات مربوط به متدهای اصلی کلاس `Robot` در کتابخانه Robka.

## پیام‌ها و هندلرها

### `on_message(filters=None, commands=None)`
**توضیح:** ثبت هندلر برای پیام‌های ورودی.
- `filters`: تابع شرطی برای فیلتر پیام‌ها (اختیاری)
- `commands`: لیست دستورهایی که شروع با `/` هستند (اختیاری)

### `on_callback(button_id=None)`
**توضیح:** ثبت هندلر برای دکمه‌های فشرده‌شده
- `button_id`: آیدی دکمه‌ای که باید هندل شود (اختیاری)

### `on_inline_query()`
**توضیح:** ثبت هندلر برای پیام‌های اینلاین (inline query)

## ارسال پیام

### `send_message(...)`
**توضیح:** ارسال پیام متنی به چت
- `chat_id`: آیدی چت مقصد _(str)_ ✅
- `text`: محتوای پیام _(str)_ ✅
- `chat_keypad`: کی‌پد معمولی _(dict)_
- `inline_keypad`: کی‌پد اینلاین _(dict)_
- `reply_to_message_id`: پاسخ به پیام خاص _(str)_
- `disable_notification`: بدون نوتیف _(bool)_
- `chat_keypad_type`: حالت کی‌پد *("New" | "Removed")*

## ارسال فایل‌ها

### متدهای مشترک (فایل، موزیک، ویس، گیف، عکس):
- `send_document(...)`
- `send_music(...)`
- `send_voice(...)`
- `send_gif(...)`
- `send_image(...)`

**پارامترهای اصلی:**
- `chat_id`: آیدی چت
- `path`: مسیر فایل یا URL (اختیاری)
- `file_id`: اگر فایل قبلاً آپلود شده باشد
- `text`: کپشن فایل
- `file_name`: نام فایل
- `inline_keypad`, `chat_keypad`, `reply_to_message_id`, `disable_notification`, `chat_keypad_type`

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

### `get_me()`
دریافت اطلاعات ربات

### `get_chat(chat_id)`
دریافت اطلاعات یک چت

### `get_name(chat_id)`
دریافت نام مخاطب بر اساس `first_name` و `last_name`

### `get_username(chat_id)`
دریافت نام کاربری چت (در صورت وجود)

### `check_join(channel_guid, chat_id)`
بررسی عضویت کاربر در کانال خاص

### `remove_keypad(chat_id)`
حذف کی‌پد معمولی چت

### `edit_chat_keypad(chat_id, chat_keypad)`
ویرایش یا اضافه کردن کی‌پد چت

### `edit_message_text(chat_id, message_id, text)`
ویرایش متن پیام ارسال‌شده

### `edit_inline_keypad(chat_id, message_id, inline_keypad)`
ویرایش کی‌پد اینلاین پیام

### `delete_message(chat_id, message_id)`
حذف پیام از چت

### `send_poll(chat_id, question, options)`
ارسال نظرسنجی به چت

### `send_location(chat_id, latitude, longitude, ...)`
ارسال موقعیت مکانی به چت

### `send_contact(chat_id, first_name, last_name, phone_number)`
ارسال مخاطب به چت

### `forward_message(from_chat_id, message_id, to_chat_id)`
فروارد کردن پیام از یک چت به چت دیگر

### `set_commands(bot_commands)`
تنظیم دستورات رسمی ربات (برای `/help` و ...)

### `update_bot_endpoint(url, type)`
تنظیم وب‌هوک یا polling برای دریافت پیام‌ها

## مدیریت فایل و آپلود

### `get_upload_url(media_type)`
دریافت آدرس آپلود فایل برای انواع مختلف: File, Image, Voice, Music, Gif

### `upload_media_file(upload_url, name, path)`
آپلود فایل از مسیر محلی یا URL به Rubika و دریافت `file_id`

## دریافت بروزرسانی‌ها

### `get_updates(offset_id=None, limit=None)`
دریافت بروزرسانی‌ها (برای polling)

# مستندات کلاس `Message` و API پاسخ مدیا Robka

## معرفی کلاس `Message`

کلاس `Message` در کتابخانه Robka ابزاری کلیدی برای مدیریت پیام‌های دریافتی در ربات است. این کلاس، قابلیت‌هایی همچون پاسخ به پیام، ارسال مدیا، حذف یا ویرایش پیام، و استفاده از صفحه‌کلید و دکمه‌های اینلاین را فراهم می‌کند.

## مشخصات کلاس `Message`

```python
Message(bot, chat_id, message_id, sender_id, text=None, raw_data=None)
```

### پارامترها:

| پارامتر | توضیح |
|---|---|
| `bot` | نمونه‌ی شی ربات |
| `chat_id` | شناسه چت |
| `message_id` | آیدی پیام |
| `sender_id` | شناسه فرستنده |
| `text` | متن پیام |
| `raw_data` | داده‌ی خام پیام (دیکشنری دریافتی از API) |

### ویژگی‌ها (Attributes):

- `reply_to_message_id` – اگر پیام در پاسخ ارسال شده باشد، آیدی پیام اولیه
- `file`, `sticker`, `poll`, `contact_message`, `location`, ... – داده‌های مربوطه اگر وجود داشته باشند

## متدهای پاسخ‌دهی

### `reply(text: str, **kwargs)`

پاسخ متنی به پیام با قابلیت ارسال دکمه و گزینه‌های اضافی.

### `reply_poll(question, options, **kwargs)`

ارسال نظرسنجی در پاسخ به پیام.

### `reply_document(...)`

ارسال فایل یا سند با متن اختیاری و دکمه.

### `reply_image(...)`

ارسال تصویر با قابلیت reply همراه دکمه‌های chat یا inline.

### `reply_music(...)`

ارسال موزیک در پاسخ.

### `reply_voice(...)`

ارسال پیام صوتی (voice).

### `reply_gif(...)`

ارسال گیف در پاسخ به پیام.

### `reply_location(latitude, longitude, **kwargs)`

ارسال لوکیشن در پاسخ.

### `reply_contact(first_name, last_name, phone_number, **kwargs)`

ارسال مخاطب در پاسخ.

## پاسخ با دکمه‌ها

### `reply_keypad(text, keypad, **kwargs)`

ارسال پیام با صفحه‌کلید چتی (ChatKeypad).

### `reply_inline(text, inline_keypad, **kwargs)`

ارسال پیام با دکمه‌های شیشه‌ای (Inline).

## پاسخ با فایل‌ها و استیکر

### `reply_sticker(sticker_id, **kwargs)`

ارسال استیکر در پاسخ به پیام.

### `reply_file(file_id, **kwargs)`

ارسال فایل بر اساس File ID.

## ویرایش و حذف

### `edit(new_text)`

ویرایش متن پیام.

### `delete()`

حذف پیام فعلی.

## مثال کاربردی کامل

```python
@bot.on_message()
def handler(bot: Robot, message: Message):
    # پاسخ با تصویر و دکمه‌های مختلف
    message.reply_image(
        path="https://s6.uupload.ir/files/sample.png",
        text="📷 تصویر پاسخ‌داده‌شده با دکمه‌ها",
        inline_keypad=inline_keypad
    )

    message.reply_image(
        path="https://s6.uupload.ir/files/sample.png",
        text="📷 تصویر دوم با صفحه‌کلید",
        chat_keypad=chat_keypad,
        chat_keypad_type="New"
    )

@bot.on_callback()
def callback_handler(bot: Robot, message: Message):
    data = message.aux_data.button_id
    if data == "btn_male":
        message.reply("سلام آقا 👨")
    elif data == "btn_female":
        message.reply("سلام خانم 👩")
    else:
        message.reply(f"دکمه ناشناخته: {data}")
```

## نکته

تمامی متدهای `reply_*` به‌صورت خودکار پیام جدید را در پاسخ به پیام اصلی ارسال می‌کنند (`reply_to_message_id` به‌صورت داخلی تنظیم می‌شود).

## مثال کاربردی کامل

```python
from robka import Robot
from robka.keypad import ChatKeypadBuilder
from robka.button import InlineBuilder
from robka.context import Message

chat_keypad = ChatKeypadBuilder().row(
    ChatKeypadBuilder().button(id="btn_female", text="زن"),
    ChatKeypadBuilder().button(id="btn_male", text="مرد")
).build()

inline_keypad = (
    InlineBuilder()
    .row(
        InlineBuilder().button_simple("btn_bets", "button1"),
        InlineBuilder().button_simple("btn_rps", "button2")
    )
    .row(
        InlineBuilder().button_simple("btn_chatid", "butthon3")
    )
    .build()
)

bot = Robot("توکن شما")

@bot.on_message()
def handler(bot: Robot, message: Message):
    message.reply_image(
        path="https://s6.uupload.ir/files/chatgpt_image_jul_20,_2025,_10_22_47_pm_oiql.png",
        text="📷 عکس ریپلای شده دکمه شیشه ای",
        inline_keypad=inline_keypad
    )

    message.reply_image(
        path="https://s6.uupload.ir/files/chatgpt_image_jul_20,_2025,_10_22_47_pm_oiql.png",
        text="📷 عکس ریپلای شده دکمه کیبوردی",
        chat_keypad=chat_keypad,
        chat_keypad_type="New"
    )

@bot.on_callback()
def callback_handler(bot: Robot, message: Message):
    data = message.aux_data.button_id
    if data == "btn_male":
        message.reply("سلام مرد")
    elif data == "btn_female":
        message.reply("سلام زن")
    else:
        message.reply(f"دکمه ناشناخته: {data}")

bot.run()
```

## مستندات کلاس `InlineBuilder`

کلاس `InlineBuilder` برای ساخت دکمه‌های اینلاین استفاده می‌شود که در پیام‌های ربات قابل استفاده هستند.

### روش استفاده

```python
from robka.button import InlineBuilder

builder = InlineBuilder()
inline_keypad = builder.row(
    builder.button_simple("btn_1", "دکمه ۱"),
    builder.button_simple("btn_2", "دکمه ۲")
).build()
```

### دکمه‌های پشتیبانی‌شده

- `button_simple(id, text)` – دکمه ساده
- `button_payment(id, title, amount, description=None)` – پرداخت
- `button_calendar(id, title, type_, ...)` – انتخاب تاریخ
- `button_location(id, type_, image_url, ...)` – ارسال موقعیت مکانی
- `button_string_picker(...)` – انتخاب گزینه از لیست
- `button_number_picker(...)` – انتخاب عدد از بازه
- `button_textbox(...)` – فیلد ورود متنی
- `button_selection(...)` – انتخاب چندگزینه‌ای پیشرفته
- `button_camera_image(...)`, `button_camera_video(...)`
- `button_gallery_image(...)`, `button_gallery_video(...)`
- `button_file(...)`, `button_audio(...)`, `button_record_audio(...)`
- `button_my_phone_number(...)`, `button_my_location(...)`
- `button_ask_my_phone_number(...)`, `button_ask_location(...)`
- `button_barcode(...)`
- `button_link(id, title, url)` – لینک خارجی

### ساخت نهایی

```python
keypad = builder.build()
```

خروجی به صورت دیکشنری با کلید `rows` خواهد بود که می‌توانید در متد `send_message` یا `reply_*` استفاده کنید.

## مستندات کلاس `ChatKeypadBuilder`

کلاس `ChatKeypadBuilder` برای ساخت صفحه‌کلید چتی (chat keypad) استفاده می‌شود.

### روش استفاده

```python
from robka.keypad import ChatKeypadBuilder

keypad = ChatKeypadBuilder().row(
    ChatKeypadBuilder().button("btn_1", "دکمه ۱"),
    ChatKeypadBuilder().button("btn_2", "دکمه ۲")
).build()
```

### متدها

- `button(id, text, type="Simple")` – ساخت یک دکمه ساده یا از نوع خاص
- `row(*buttons)` – افزودن یک ردیف به کیبورد (دکمه‌ها باید با `button()` ساخته شوند)
- `build(resize_keyboard=True, on_time_keyboard=False)` – ساخت خروجی نهایی برای ارسال به کاربر

### خروجی `build()`

```json
{
  "rows": [
    {"buttons": [
      {"id": "btn_1", "type": "Simple", "button_text": "دکمه ۱"},
      {"id": "btn_2", "type": "Simple", "button_text": "دکمه ۲"}
    ]}
  ],
  "resize_keyboard": true,
  "on_time_keyboard": false
}
```

# مستندات پروژه: تایمر پیام در ربات Robka

این پروژه یک ربات بر پایه کتابخانه‌ی `robka` است که به کاربر امکان می‌دهد با استفاده از کی‌پد، یک تایمر تنظیم کرده و پس از پایان تایمر، پیامی برای او ارسال شود. تمرکز اصلی این مستند، بر روی کلاس `Job` است که برای زمان‌بندی اجرای دستورات استفاده شده است.

## ساختار کلی پروژه
- استفاده از کتابخانه `robka` برای ارتباط با Rubika Bot API
- تعریف یک کی‌پد با گزینه‌های تاخیر زمانی مختلف (۱۰ الی ۱۵۰ ثانیه)
- استفاده از کلاس `Job` برای مدیریت اجرای زمان‌بندی‌شده یک تابع
- نمایش شمارش معکوس با به‌روزرسانی مداوم پیام

## کلاس `Job` چیست؟
کلاس `Job` در فایل `robka.jobs` تعریف شده و هدف آن اجرای یک تابع خاص پس از گذشت یک بازه زمانی مشخص است.

### نحوه استفاده:
```python
from robka.jobs import Job

job = Job(delay_in_seconds, callback_function)
```

### پارامترها:
| پارامتر | نوع | توضیح |
|---|---|---|
| `delay_in_seconds` | `int` | مدت زمانی که باید قبل از اجرای تابع منتظر بماند |
| `callback_function` | `function` | تابعی که بعد از پایان زمان باید اجرا شود |

### ویژگی‌ها:
- اجرای غیرهمزمان (با استفاده از Thread داخلی)
- مناسب برای سناریوهایی مانند تایمرها، یادآورها و اعلان‌های زمان‌بندی شده

## مثال از استفاده در پروژه:

```python
def delayed_send():
    if user_id not in active_jobs:
        return
    bot.send_message(
        message.chat_id,
        f"✅ کاربر {user_id} : زمان {seconds} ثانیه گذشت و دستور اجرا شد! ⏰"
    )
    active_jobs.pop(user_id, None)

job = Job(seconds, delayed_send)
active_jobs[user_id] = job
```

در این مثال، پس از انتخاب تاخیر زمانی توسط کاربر، یک شی از کلاس `Job` ساخته می‌شود که تابع `delayed_send` را پس از `seconds` ثانیه اجرا می‌کند.

## تابع `countdown_edit`
این تابع تایمر فعال را به صورت زنده باقیمانده زمان را به‌روزرسانی می‌کند:
```python
def countdown_edit(chat_id, message_id, duration_sec):
    # اجرای یک Thread برای به‌روزرسانی پیام در هر ثانیه
```

## نمونه کد ساخته شده
```python
from robka import Robot
from robka.context import Message
from robka.keypad import ChatKeypadBuilder
from robka.jobs import Job
from datetime import datetime, timedelta
import threading
import time

bot = Robot("token")

active_jobs = {}

def build_delay_keypad():
    delays = [10, 20, 30, 40, 50, 60, 75, 90, 120, 150]
    builder = ChatKeypadBuilder()
    buttons = []
    for sec in delays:
        buttons.append(builder.button(id=f"delay_{sec}", text=f"⏳ بعد از {sec} ثانیه"))
    buttons.append(builder.button(id="cancel", text="❌ انصراف"))
    
    rows = [buttons[i:i+3] for i in range(0, len(buttons), 3)]
    keypad = ChatKeypadBuilder()
    for row in rows:
        builder.row(*row)
    return builder.build()

@bot.on_message(commands=["timer"])
def timer_command(bot: Robot, message: Message):
    keypad = build_delay_keypad()
    message.reply_keypad("لطفاً زمان تاخیر را انتخاب کنید:", keypad)

@bot.on_callback()
def callback_handler(bot: Robot, message: Message):
    data = message.aux_data.button_id
    user_id = message.chat_id

    if data.startswith("delay_"):
        seconds = int(data.split("_")[1])
        if user_id in active_jobs and active_jobs[user_id].is_alive():
            active_jobs[user_id].cancel()

        message.reply(f"تایمر {seconds} ثانیه‌ای برای شما تنظیم شد. پیام شما پس از پایان زمان ارسال خواهد شد.")

        # Send initial countdown message
        countdown_message = message.reply(f"⏰ زمان باقی‌مانده: {seconds} ثانیه")
        
        def delayed_send():
            if user_id not in active_jobs:
                return
            bot.send_message(
                message.chat_id,
                f"✅ کاربر {user_id} : زمان {seconds} ثانیه گذشت و دستور اجرا شد! ⏰"
            )
            active_jobs.pop(user_id, None)

        job = Job(seconds, delayed_send)
        active_jobs[user_id] = job
        job.start()

        # Start countdown update thread
        threading.Thread(target=countdown_edit, args=(bot, countdown_message.chat_id, countdown_message.message_id, seconds, user_id)).start()

    elif data == "cancel":
        if user_id in active_jobs and active_jobs[user_id].is_alive():
            active_jobs[user_id].cancel()
            message.reply("❌ تایمر لغو شد.")
            active_jobs.pop(user_id, None)
        else:
            message.reply("تایمری برای لغو وجود ندارد.")

def countdown_edit(bot, chat_id, message_id, duration_sec, user_id):
    start_time = datetime.now()
    end_time = start_time + timedelta(seconds=duration_sec)

    while True:
        if user_id not in active_jobs or not active_jobs[user_id].is_alive():
            break # Job was cancelled or completed

        remaining_time = (end_time - datetime.now()).total_seconds()
        if remaining_time <= 0:
            bot.edit_message_text(chat_id, message_id, "⏰ زمان به پایان رسید!")
            break
        
        bot.edit_message_text(chat_id, message_id, f"⏰ زمان باقی‌مانده: {int(remaining_time)} ثانیه")
        time.sleep(1)

bot.run()
```





