برای مشاهده مستندات کامل و آخرین نسخه راهنما، لطفاً به آدرس زیر مراجعه کنید:
github.com/Mahdy-Ahmadi)
rubka is a Python library to interact with the Rubika Bot API. This library helps you create Telegram-like bots with support for messages, inline buttons, chat keypads, and callback handling.
pip install rubkaIf importlib.metadata is not available, it installs importlib-metadata automatically.
from rubka import Robot
from rubka.context import Message
bot = Robot(token="YOUR_TOKEN_HERE")
@bot.on_message(commands=["start"])
def start(bot: Robot, message: Message):
message.reply("سلام! خوش آمدید!")
bot.run()You can handle incoming text messages using @bot.on_message():
@bot.on_message(commands=["hello"])
def greet(bot: Robot, message: Message):
message.reply("سلام کاربر عزیز 👋")You can also add filters.
from rubka.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("شما زن هستید")from rubka.button import InlineBuilder
builder = InlineBuilder().row(
InlineBuilder().button_simple(id="info", text="اطلاعات")
).build()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("❌ لطفاً ابتدا در کانال عضو شوید")| Method | Description |
|---|---|
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(...) |
فوروارد پیام |
@bot.on_inline_query()
def inline(bot: Robot, message: InlineMessage):
message.answer("نتیجه اینلاین")Supported inline button types include:
SimplePaymentCalendarLocationCameraImage,CameraVideoGalleryImage,GalleryVideoFile,Audio,RecordAudioMyPhoneNumber,MyLocationTextbox,Barcode,Link
See InlineBuilder for more.
builder = ChatKeypadBuilder()
keypad = builder.row(
builder.button(id="play", text="🎮 بازی کن"),
builder.button(id="exit", text="❌ خروج")
).build()bot.set_commands([
{"command": "start", "description": "شروع"},
{"command": "help", "description": "راهنما"}
])Bot updates are handled using get_updates() and offset_id is managed internally.
update_bot_endpoint()– تنظیم webhook یا pollingremove_keypad()– حذف صفحهکلید چتedit_chat_keypad()– ویرایش یا افزودن صفحهکلید چت
مستندات مربوط به متدهای اصلی کلاس Robot در کتابخانه Rubka.
توضیح: ثبت هندلر برای پیامهای ورودی.
filters: تابع شرطی برای فیلتر پیامها (اختیاری)commands: لیست دستورهایی که شروع با/هستند (اختیاری)
توضیح: ثبت هندلر برای دکمههای فشردهشده
button_id: آیدی دکمهای که باید هندل شود (اختیاری)
توضیح: ثبت هندلر برای پیامهای اینلاین (inline query)
توضیح: ارسال پیام متنی به چت
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
دریافت اطلاعات ربات
دریافت اطلاعات یک چت
دریافت نام مخاطب بر اساس first_name و last_name
دریافت نام کاربری چت (در صورت وجود)
بررسی عضویت کاربر در کانال خاص
حذف کیپد معمولی چت
ویرایش یا اضافه کردن کیپد چت
ویرایش متن پیام ارسالشده
ویرایش کیپد اینلاین پیام
حذف پیام از چت
ارسال نظرسنجی به چت
ارسال موقعیت مکانی به چت
ارسال مخاطب به چت
فروارد کردن پیام از یک چت به چت دیگر
تنظیم دستورات رسمی ربات (برای /help و ...)
تنظیم وبهوک یا polling برای دریافت پیامها
دریافت آدرس آپلود فایل برای انواع مختلف: File, Image, Voice, Music, Gif
آپلود فایل از مسیر محلی یا URL به Rubika و دریافت file_id
دریافت بروزرسانیها (برای polling)
کلاس Message در کتابخانه Rubka ابزاری کلیدی برای مدیریت پیامهای دریافتی در ربات است. این کلاس، قابلیتهایی همچون پاسخ به پیام، ارسال مدیا، حذف یا ویرایش پیام، و استفاده از صفحهکلید و دکمههای اینلاین را فراهم میکند.
Message(bot, chat_id, message_id, sender_id, text=None, raw_data=None)| پارامتر | توضیح |
|---|---|
bot |
نمونهی شی ربات |
chat_id |
شناسه چت |
message_id |
آیدی پیام |
sender_id |
شناسه فرستنده |
text |
متن پیام |
raw_data |
دادهی خام پیام (دیکشنری دریافتی از API) |
reply_to_message_id– اگر پیام در پاسخ ارسال شده باشد، آیدی پیام اولیهfile,sticker,poll,contact_message,location, ... – دادههای مربوطه اگر وجود داشته باشند
پاسخ متنی به پیام با قابلیت ارسال دکمه و گزینههای اضافی.
ارسال نظرسنجی در پاسخ به پیام.
ارسال فایل یا سند با متن اختیاری و دکمه.
ارسال تصویر با قابلیت reply همراه دکمههای chat یا inline.
ارسال موزیک در پاسخ.
ارسال پیام صوتی (voice).
ارسال گیف در پاسخ به پیام.
ارسال لوکیشن در پاسخ.
ارسال مخاطب در پاسخ.
ارسال پیام با صفحهکلید چتی (ChatKeypad).
ارسال پیام با دکمههای شیشهای (Inline).
ارسال استیکر در پاسخ به پیام.
ارسال فایل بر اساس File ID.
ویرایش متن پیام.
حذف پیام فعلی.
@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 بهصورت داخلی تنظیم میشود).
from rubka import Robot
from rubka.keypad import ChatKeypadBuilder
from rubka.button import InlineBuilder
from rubka.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 برای ساخت دکمههای اینلاین استفاده میشود که در پیامهای ربات قابل استفاده هستند.
from rubka.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)– لینک خارجی
keypad = builder.build()خروجی به صورت دیکشنری با کلید rows خواهد بود که میتوانید در متد send_message یا reply_* استفاده کنید.
کلاس ChatKeypadBuilder برای ساخت صفحهکلید چتی (chat keypad) استفاده میشود.
from rubka.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)– ساخت خروجی نهایی برای ارسال به کاربر
{
"rows": [
{"buttons": [
{"id": "btn_1", "type": "Simple", "button_text": "دکمه ۱"},
{"id": "btn_2", "type": "Simple", "button_text": "دکمه ۲"}
]}
],
"resize_keyboard": true,
"on_time_keyboard": false
}این پروژه یک ربات بر پایه کتابخانهی rubka است که به کاربر امکان میدهد با استفاده از کیپد، یک تایمر تنظیم کرده و پس از پایان تایمر، پیامی برای او ارسال شود. تمرکز اصلی این مستند، بر روی کلاس Job است که برای زمانبندی اجرای دستورات استفاده شده است.
- استفاده از کتابخانه
rubkaبرای ارتباط با Rubika Bot API - تعریف یک کیپد با گزینههای تاخیر زمانی مختلف (۱۰ الی ۱۵۰ ثانیه)
- استفاده از کلاس
Jobبرای مدیریت اجرای زمانبندیشده یک تابع - نمایش شمارش معکوس با بهروزرسانی مداوم پیام
کلاس Job در فایل rubka.jobs تعریف شده و هدف آن اجرای یک تابع خاص پس از گذشت یک بازه زمانی مشخص است.
from rubka.jobs import Job
job = Job(delay_in_seconds, callback_function)| پارامتر | نوع | توضیح |
|---|---|---|
delay_in_seconds |
int |
مدت زمانی که باید قبل از اجرای تابع منتظر بماند |
callback_function |
function |
تابعی که بعد از پایان زمان باید اجرا شود |
- اجرای غیرهمزمان (با استفاده از Thread داخلی)
- مناسب برای سناریوهایی مانند تایمرها، یادآورها و اعلانهای زمانبندی شده
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 ثانیه اجرا میکند.
این تابع تایمر فعال را به صورت زنده باقیمانده زمان را بهروزرسانی میکند:
def countdown_edit(chat_id, message_id, duration_sec):
# اجرای یک Thread برای بهروزرسانی پیام در هر ثانیهfrom rubka import Robot
from rubka.context import Message
from rubka.keypad import ChatKeypadBuilder
from rubka.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:
keypad.row(*row)
return keypad.build()
def countdown_edit(chat_id: str, message_id: str, duration_sec: int):
start_time = datetime.now()
end_time = start_time + timedelta(seconds=duration_sec)
def run():
while True:
now = datetime.now()
if now >= end_time:
try:
bot.edit_message_text(chat_id, message_id, "⏰ زمان تمام شد!")
except Exception as e:
print("خطا در ویرایش پیام:", e)
break
remaining = end_time - now
text = (
f"⏳ تایمر فعال است...\n"
f"🕰 شروع: {start_time.strftime('%H:%M:%S')}\n"
f"⏲ پایان: {end_time.strftime('%H:%M:%S')}\n"
f"⌛ باقیمانده: {str(remaining).split('.')[0]}"
)
try:
bot.edit_message_text(chat_id, message_id, text)
except Exception as e:
print("خطا در ویرایش پیام:", e)
time.sleep(1)
threading.Thread(target=run, daemon=True).start()
@bot.on_message(commands=["start"])
def start_handler(bot: Robot, message: Message):
keypad = build_delay_keypad()
message.reply_keypad(
"سلام 👋\n"
"یک زمان برای ارسال پیام انتخاب کنید:\n"
"📅 تاریخ و ساعت فعلی: " + datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
keypad
)
@bot.on_callback()
def callback_delay(bot: Robot, message: Message):
btn_id = message.aux_data.button_id
user_id = message.sender_id
if btn_id == "cancel":
if user_id in active_jobs:
active_jobs.pop(user_id)
message.reply("❌ همه ارسالهای زمانبندی شده لغو شدند.")
else:
message.reply("⚠️ شما هیچ ارسال زمانبندی شدهای ندارید.")
return
if not btn_id.startswith("delay_"):
message.reply("❌ دکمه نامعتبر است!")
return
seconds = int(btn_id.split("_")[1])
if user_id in active_jobs:
active_jobs.pop(user_id)
sent_msg = bot.send_message(
message.chat_id,
f"⏳ تایمر {seconds} ثانیهای شروع شد...\n🕰 زمان شروع: {datetime.now().strftime('%H:%M:%S')}"
)
countdown_edit(message.chat_id, sent_msg['data']['message_id'], 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
message.reply(
f"⏳ ثبت شد! پیام شما پس از {seconds} ثانیه ارسال خواهد شد.\n"
f"🕰 زمان شروع ثبت شده: {datetime.now().strftime('%H:%M:%S')}"
)
bot.run()##مثال ساده تر
from rubka import Robot
from rubka.context import Message
from rubka.jobs import Job
from datetime import datetime
bot = Robot("")
active_jobs = {}
@bot.on_message(commands=["timer"])
def timer_handler(bot: Robot, message: Message):
user_id = message.sender_id
chat_id = message.chat_id
parts = message.text.split()
if len(parts) != 2 or not parts[1].isdigit():
return message.reply("⚠️ لطفاً مدت زمان را به صورت صحیح وارد کنید. مثل: `/timer 30`", parse_mode="markdown")
seconds = int(parts[1])
if user_id in active_jobs:
active_jobs.pop(user_id)
message.reply(f"⏳ تایمر {seconds} ثانیهای شروع شد!\n🕰 زمان شروع: {datetime.now().strftime('%H:%M:%S')}")
def after_delay():
if user_id not in active_jobs:
return
bot.send_message(chat_id, f"✅ تایمر {seconds} ثانیهای تمام شد! ⏰")
active_jobs.pop(user_id, None)
job = Job(seconds, after_delay)
active_jobs[user_id] = job
bot.run()##نمونه کد ادیت تایم و کرون جاب با اینلاین کیبورد
from rubka import Robot
from rubka.context import Message
from rubka.keypad import ChatKeypadBuilder
from rubka.jobs import Job
from datetime import datetime, timedelta
import threading
import time
bot = Robot("token")
bot.edit_inline_keypad
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:
keypad.row(*row)
return keypad.build()
def countdown_edit(chat_id: str, message_id: str, duration_sec: int):
start_time = datetime.now()
end_time = start_time + timedelta(seconds=duration_sec)
def run():
while True:
now = datetime.now()
if now >= end_time:
try:
bot.edit_message_text(chat_id, message_id, "⏰ زمان تمام شد!")
except Exception as e:
print("خطا در ویرایش پیام:", e)
break
remaining = end_time - now
text = (
f"⏳ تایمر فعال است...\n"
f"🕰 شروع: {start_time.strftime('%H:%M:%S')}\n"
f"⏲ پایان: {end_time.strftime('%H:%M:%S')}\n"
f"⌛ باقیمانده: {str(remaining).split('.')[0]}"
)
try:
bot.edit_message_text(chat_id, message_id, text)
except Exception as e:
print("خطا در ویرایش پیام:", e)
time.sleep(1)
threading.Thread(target=run, daemon=True).start()
@bot.on_message(commands=["start"])
def start_handler(bot: Robot, message: Message):
keypad = build_delay_keypad()
message.reply_keypad(
"سلام 👋\n"
"یک زمان برای ارسال پیام انتخاب کنید:\n"
"📅 تاریخ و ساعت فعلی: " + datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
keypad
)
@bot.on_callback()
def callback_delay(bot: Robot, message: Message):
btn_id = message.aux_data.button_id
user_id = message.sender_id
if btn_id == "cancel":
if user_id in active_jobs:
active_jobs.pop(user_id)
message.reply("❌ همه ارسالهای زمانبندی شده لغو شدند.")
else:
message.reply("⚠️ شما هیچ ارسال زمانبندی شدهای ندارید.")
return
if not btn_id.startswith("delay_"):
message.reply("❌ دکمه نامعتبر است!")
return
seconds = int(btn_id.split("_")[1])
if user_id in active_jobs:
active_jobs.pop(user_id)
sent_msg = bot.edit_inline_keypad(
message.chat_id,
f"⏳ تایمر {seconds} ثانیهای شروع شد...\n🕰 زمان شروع: {datetime.now().strftime('%H:%M:%S')}"
)
print(sent_msg)
countdown_edit(message.chat_id, sent_msg['data']['message_id'], 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
message.reply(
f"⏳ ثبت شد! پیام شما پس از {seconds} ثانیه ارسال خواهد شد.\n"
f"🕰 زمان شروع ثبت شده: {datetime.now().strftime('%H:%M:%S')}"
)
bot.run()این مستند نحوه استفاده از قابلیت اجبار به عضویت در یک کانال (Force Join) در رباتهای ساختهشده با کتابخانه Rubka را توضیح میدهد.
اطمینان از اینکه کاربر عضو یک کانال خاص است، قبل از ادامه تعامل با ربات. اگر عضو نبود، به او اطلاع داده شود یا لینک عضویت ارسال گردد.
- نصب و راهاندازی کتابخانه
rubka - توکن معتبر ربات Rubika
- دسترسی به
channel_guid(شناسه عددی کانال) - ربات باید در کانال، ادمین باشد
from rubka import Robot
from rubka.context import Message
bot = Robot(token="your_token")
CHANNEL_GUID = "c0xABCDEF..." # GUID کانال هدف
@bot.on_message()
def handle_force_join(bot: Robot, message: Message):
name = bot.get_name(message.chat_id)
if bot.check_join(CHANNEL_GUID, message.chat_id):
message.reply(f"سلام {name} 👋\nشما عضو کانال هستید ✅")
else:
join_link = "https://rubika.ir/rubka_library"
message.reply(
f"سلام {name} 👋\nشما عضو کانال نیستید ❌\n\n"
f"لطفاً ابتدا عضو کانال شوید سپس دوباره تلاش کنید:\n{join_link}"
)
bot.run()| متد | کاربرد |
|---|---|
check_join(channel_guid, user_guid) |
بررسی عضویت کاربر در کانال مشخصشده |
get_name(user_guid) |
دریافت نام نمایشی کاربر از طریق GUID |
message.reply(text) |
پاسخ مستقیم به پیام دریافتشده |
- ربات باید حتماً ادمین کانال باشد.
- در صورت عدم عضویت، بهتر است لینک دعوت به کانال نمایش داده شود.
##Mahdi Ahmadi