### BotClient Plugin Example Source: https://context7.com/shayanheidari01/rubika/llms.txt Demonstrates how to create and register a custom plugin for BotClient, including setup, teardown, and handler registration. ```python from rubpy.bot import BotClient from rubpy.bot import filters from rubpy.plugins import Plugin, PluginMeta class GreetPlugin(Plugin): meta = PluginMeta( name="greet", version="1.0.0", description="Greets new users", default_config={"greeting": "Hello!"}, ) async def setup(self): msg = self.get_config("greeting") @self.bot.on_update(filters.commands("hi")) async def greet(client, update): await update.reply(msg) async def teardown(self): print("GreetPlugin unloaded") async def main(): bot = BotClient( "your_bot_token", plugins=["greet"], # enable by name after registration auto_enable_plugins=True, plugin_configs={"greet": {"greeting": "Hey there! 👋"}}, ) bot.register_plugin(GreetPlugin) async with bot: await bot.enable_plugins(["greet"]) await bot.run() import asyncio asyncio.run(main()) ``` -------------------------------- ### Test Plugin Locally with Editable Install Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Instructions for installing a plugin in editable mode (`pip install -e .`) within a virtual environment to test it locally before publishing. The bot should be run with `auto_enable_plugins=True`. ```bash pip install -e . ``` -------------------------------- ### Run Example Plugin from Command Line Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Command to execute an inline plugin example script. Ensure the `RUBPY_BOT_TOKEN` environment variable is set before running. ```bash export RUBPY_BOT_TOKEN="توکن_ربات" python examples/plugin_echo.py ``` -------------------------------- ### Install Rubpy and Optional Extras Source: https://context7.com/shayanheidari01/rubika/llms.txt Install the Rubpy framework using pip. Optional extras can be installed for specific functionalities like image processing, thumbnails, video generation, or voice chat streaming. ```bash pip install -U rubpy # Optional extras pip install rubpy[cv] # OpenCV for image/video processing pip install rubpy[pil] # Pillow for thumbnails pip install rubpy[movie] # moviepy for video generation pip install rubpy[rtc] # aiortc for voice-chat streaming ``` -------------------------------- ### User Client Plugin Example Source: https://context7.com/shayanheidari01/rubika/llms.txt Shows how to implement a plugin for a user-account Client using the PluginManager, including message handling. ```python from rubpy import Client from rubpy.plugins import Plugin, PluginMeta class EchoPlugin(Plugin): meta = PluginMeta(name="echo", version="1.0.0") def setup(self): from rubpy import filters @self.bot.on_message_updates(filters.text) async def echo(update): await update.reply(update.text) async def main(): async with Client("mybot") as client: client.plugin_manager.register_plugin(EchoPlugin) await client.plugin_manager.enable("echo") await client.run() import asyncio asyncio.run(main()) ``` -------------------------------- ### Minimal Sync Rubpy Client Example Source: https://github.com/shayanheidari01/rubika/blob/master/README.md A minimal example of sending a message synchronously using Rubpy's Client. It uses a context manager for client initialization. ```python from rubpy import Client with Client(name='rubpy') as client: result = client.send_message('me', '`hello` __from__ **rubpy**') print(result) ``` -------------------------------- ### Define Plugin Entry Point in setup.py Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Shows the equivalent way to define a Rubpy plugin's entry point using `setup.py` for packaging, utilizing the `entry_points` argument in the `setup` function. ```python setup( ..., entry_points={ "rubpy.plugins": [ "rubpy_echo = my_echo_plugin.plugin:EchoPlugin", ] } ) ``` -------------------------------- ### Minimal Async Rubpy Client Example Source: https://github.com/shayanheidari01/rubika/blob/master/README.md A concise example of sending a message asynchronously using Rubpy's Client. It utilizes an async context manager for the client. ```python from rubpy import Client import asyncio async def main(): async with Client(name='rubpy') as bot: result = await bot.send_message('me', '`hello` __from__ **rubpy**') print(result) asyncio.run(main()) ``` -------------------------------- ### Register and Enable Plugin at Runtime Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Illustrates how to register a plugin class directly with the bot client and then enable it programmatically after the bot has started. ```python bot.register_plugin(EchoPlugin, name="rubpy_echo") await bot.enable_plugins(["rubpy_echo"]) ``` -------------------------------- ### Implement Middleware in Plugin Setup Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Illustrates how to add custom middleware to the bot's pipeline by defining a method decorated with `@bot.middleware()` within the plugin's `setup` method. This can be used for logging or modifying the update pipeline. ```python @self.bot.middleware() async def my_middleware(client, update, next_middleware): # Process update or modify pipeline return await next_middleware(client, update) ``` -------------------------------- ### Rubika Client Channel Operations Source: https://context7.com/shayanheidari01/rubika/llms.txt Provides examples for managing channels, including retrieving channel information, joining channels by GUID or invite link, listing members, banning users, editing channel details, and managing voice chats. Requires an authenticated client instance. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Get channel info by GUID info = await client.get_channel_info("c0_channel_guid") print(info.channel_title, info.member_count) # Join a public channel by username await client.join_channel_action("c0_channel_guid", "Join") # Join via invite link await client.join_channel_by_link("https://rubika.ir/joinc/ABCDEF") # Get all members (paginated) async for member in client.get_channel_all_members("c0_channel_guid"): print(member.member_guid, member.member_type) # Ban a member await client.ban_channel_member("c0_channel_guid", "u0_user_guid", "Set") # Edit channel info await client.edit_channel_info("c0_channel_guid", channel_title="New Title") # Create/discard voice chat await client.create_channel_voice_chat("c0_channel_guid") await client.discard_channel_voice_chat("c0_channel_guid", "vc_id") import asyncio asyncio.run(main()) ``` -------------------------------- ### Rubpy Client Message Updates Example Source: https://github.com/shayanheidari01/rubika/blob/master/README.md This example demonstrates how to handle incoming text messages using the Rubpy Client. It prints the update and replies with formatted text. ```python from rubpy import Client, filters from rubpy.types import Update bot = Client(name='rubpy') @bot.on_message_updates(filters.text) async def updates(update: Update): print(update) await update.reply('`hello` __from__ **rubpy**') bot.run() ``` -------------------------------- ### BotClient.run Source: https://context7.com/shayanheidari01/rubika/llms.txt Starts the bot's event loop for either long polling or webhook mode. ```APIDOC ## BotClient.run — Long Polling and Webhook Modes ### Description This is the main method to run the bot. It can operate in long-polling mode by default or switch to webhook mode if `webhook_url` is provided. It also serves as a base for registering update handlers. ### Method `run(webhook_url, path, host, port)` ### Parameters - **webhook_url** (string) - Optional - The URL to use for webhook mode. If provided, the bot will run in webhook mode. - **path** (string) - Optional - The endpoint path for the webhook server (e.g., "/wk"). - **host** (string) - Optional - The host address for the webhook server (e.g., "0.0.0.0"). - **port** (integer) - Optional - The port for the webhook server (e.g., 8080). ### Handlers This method is used in conjunction with decorators like `@bot.on_update` to register functions that will be called when specific updates are received. ``` -------------------------------- ### Install Rubpy Package Source: https://github.com/shayanheidari01/rubika/blob/master/README.md Install or upgrade the Rubpy package using pip. This command ensures you have the latest version. ```bash pip install -U rubpy ``` -------------------------------- ### Rubpy Bot Client Example Source: https://github.com/shayanheidari01/rubika/blob/master/README.md Use this snippet to create a Rubpy bot that responds to private messages. It requires the 'bot_token' for authentication. ```python from rubpy.bot import BotClient, filters app = BotClient("bot_token") @app.on_update(filters.private) async def hello(client, message): await message.reply("Hello from Rubpy!") app.run() ``` -------------------------------- ### Sync Rubpy Client Message Updates Example Source: https://github.com/shayanheidari01/rubika/blob/master/README.md This snippet shows how to handle incoming messages synchronously using the Rubpy Client. It replies to messages with formatted text. ```python from rubpy import Client bot = Client('rubpy') @bot.on_message_updates() def updates(message): message.reply('`hello` __from__ **rubpy**') bot.run() ``` -------------------------------- ### Run Bot in Long Polling or Webhook Mode Source: https://context7.com/shayanheidari01/rubika/llms.txt Start the bot's main event loop using run(). By default, it uses long polling. To use webhook mode, provide a webhook_url and other optional parameters. ```python import asyncio from rubpy.bot import BotClient, filters bot = BotClient("your_bot_token") @bot.on_update(filters.commands("start")) async def start(client, update): await update.reply("Welcome!") @bot.on_update(filters.text) async def echo(client, update): await update.reply(update.new_message.text) # Long-polling mode asyncio.run(bot.run()) # Webhook mode — Rubpy starts an aiohttp server and registers all endpoints # asyncio.run(bot.run(webhook_url="https://example.com", path="/wk", host="0.0.0.0", port=8080)) ``` -------------------------------- ### Handle button clicks Source: https://context7.com/shayanheidari01/rubika/llms.txt Use filters.button to trigger actions when an inline button with a specific ID is clicked. This example edits the message text upon confirmation. ```python from rubpy.bot import BotClient, filters bot = BotClient("your_bot_token") @bot.on_update(filters.button("btn_ok")) async def ok_clicked(client: BotClient, update: InlineMessage): await update.edit_text("✅ Confirmed!") ``` -------------------------------- ### Account-Level Filters with Rubika Client Source: https://context7.com/shayanheidari01/rubika/llms.txt Illustrates using `rubpy.filters` for advanced filtering of messages based on chat type, author, object GUIDs, commands, regex patterns, and message IDs. Filters can be combined using logical operators. ```python from rubpy import Client, filters bot = Client("mybot") # Match only group messages @bot.on_message_updates(filters.is_group) def group_only(update): pass # Match private chats @bot.on_message_updates(filters.is_private) def private_only(update): pass # Match by specific author GUIDs @bot.on_message_updates(filters.author_guids("u0_friend_guid", "u0_other_guid")) def from_friends(update): pass # Match by specific chat GUIDs @bot.on_message_updates(filters.object_guids("g0_group_guid")) def in_group(update): pass # Match /command prefix @bot.on_message_updates(filters.commands("/start")) def start(update): await update.reply("Started!") # Regex match on message text @bot.on_message_updates(filters.regex(r"order #(\d+)")) def order_handler(update): match = update.pattern_match print("Order:", match.group(1)) # Filter by message_id using operators @bot.on_message_updates(filters.message_id > 1000) def recent_only(update): pass # Combine @bot.on_message_updates(filters.is_private & filters.text) def private_text(update): await update.reply(update.text) bot.run() ``` -------------------------------- ### Configure Plugins with Custom Settings Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Demonstrates how to provide custom configuration values to plugins via the `BotClient` constructor using the `plugin_configs` argument. Plugin-specific configuration can be accessed using `self.get_config` within the plugin. ```python BotClient(..., plugin_configs={"plugin_id": {...}}) ``` -------------------------------- ### Handle /start or /help commands Source: https://context7.com/shayanheidari01/rubika/llms.txt Use filters.commands to match specific commands. This snippet shows how to reply to /start or /help. ```python from rubpy.bot import BotClient, filters bot = BotClient("your_bot_token") @bot.on_update(filters.commands(["start", "help"])) async def help_cmd(client: BotClient, update: Update): await update.reply("Use /start to begin") ``` -------------------------------- ### Initialize BotClient for Rubika Bots Source: https://context7.com/shayanheidari01/rubika/llms.txt Initialize BotClient for bot-token based development. Configure parameters like parse mode, rate limits, timeouts, and polling intervals. Use an async context manager for automatic start/stop. ```python from rubpy.bot import BotClient from rubpy.enums import ParseMode bot = BotClient( token="your_bot_token", parse_mode=ParseMode.MARKDOWN, # default parse mode for outgoing messages rate_limit=0.5, # minimum seconds between API calls timeout=10.0, # HTTP request timeout poll_interval=0.5, # seconds between long-poll iterations long_poll_timeout=30.0, # server-side long-poll wait window max_retries=3, # retries on network/5xx errors backoff_factor=0.5, # exponential back-off base (seconds) persist_offset=True, # survive restarts by caching offset on disk ) # Async context manager — handles start/stop automatically async def main(): async with bot: me = await bot.get_me() print(me.bot_title, me.username) import asyncio asyncio.run(main()) ``` -------------------------------- ### Initialize Client for Rubika User Accounts (SQLite Session) Source: https://context7.com/shayanheidari01/rubika/llms.txt Initialize a Client for user account authentication using a SQLite session file. Configure parameters like phone number, parse mode, timeouts, proxy, platform, and language code. ```python from rubpy import Client, StringSession # SQLite session (file: mybot.session) async def main(): async with Client( name="mybot", phone_number="+989123456789", # used for first-time login parse_mode="markdown", timeout=20, proxy="http://127.0.0.1:8080", # optional SOCKS/HTTP proxy platform="PWA", # or "Android" max_retries=5, lang_code="fa", ) as client: result = await client.send_message("me", "Hello from Rubpy!") print(result) # StringSession — portable, no file on disk session = StringSession() async def main_ss(): async with Client(name=session, phone_number="+989123456789") as client: print(await client.get_me()) import asyncio asyncio.run(main()) ``` -------------------------------- ### Activate Plugins in Rubpy Bot Client Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Demonstrates how to activate plugins when initializing the `BotClient`. Setting `auto_enable_plugins=True` automatically loads discovered plugins, and the `plugins` list can specify which ones to enable. ```python from rubpy.bot import BotClient bot = BotClient( token="...", auto_enable_plugins=True, plugins=["rubpy_echo"], # اختیاری: فهرست شناسه‌هایی که باید فعال شوند ) bot.run() ``` -------------------------------- ### Define Plugin Entry Point in pyproject.toml Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Specifies how to define a Rubpy plugin's entry point within the `pyproject.toml` file for packaging and distribution via PyPI. The `rubpy.plugins` group is used, mapping a readable ID to the plugin class path. ```toml [project] name = "rubpy-echo-plugin" version = "1.0.0" dependencies = ["rubpy>=7.2.7"] [project.entry-points."rubpy.plugins"] rubpy_echo = "my_echo_plugin.plugin:EchoPlugin" ``` -------------------------------- ### BotClient Lifecycle Hooks Source: https://context7.com/shayanheidari01/rubika/llms.txt Register startup and shutdown callbacks using @bot.on_start() and @bot.on_shutdown(). Middleware can be added with @bot.middleware() to wrap every incoming update. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") @bot.on_start() async def startup(client: BotClient): print("Bot is online") await client.set_commands([{"command": "start", "description": "Start"}]) @bot.on_shutdown() async def shutdown(client: BotClient): print("Bot is shutting down") @bot.middleware() async def logger_middleware(client, update, call_next): import time t = time.time() print(f"[{update.type if hasattr(update, 'type') else 'InlineMessage'}] incoming") await call_next() print(f" processed in {time.time()-t:.3f}s") import asyncio asyncio.run(bot.run()) ``` -------------------------------- ### StringSession Serialization and Restoration Source: https://context7.com/shayanheidari01/rubika/llms.txt Illustrates how to serialize an authentication session to a string and restore it for subsequent client runs. ```python from rubpy import Client, StringSession # First run: save session string async def save_session(): session = StringSession() async with Client(name=session, phone_number="+989123456789") as client: saved = str(session) # serialize print("Save this:", saved) # store securely (env var, secrets manager) # Subsequent runs: restore from string SESSION_STRING = "your_saved_string_here" async def run_bot(): async with Client(name=StringSession(SESSION_STRING)) as client: await client.send_message("me", "Session restored!") import asyncio asyncio.run(run_bot()) ``` -------------------------------- ### Define Plugin Dependencies Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Shows how to specify dependencies on other plugins using the `PluginMeta.dependencies` field. These dependencies will be automatically enabled before the main plugin. ```python class MyPlugin(Plugin): meta = PluginMeta( ..., dependencies=["other_plugin_id"], ) ``` -------------------------------- ### Query Bot and Chat Info with BotClient Source: https://context7.com/shayanheidari01/rubika/llms.txt Use get_me, get_chat, and get_chat_member to retrieve information about the bot, chats, and individual members. Ensure the bot token is correctly set. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: # Bot profile me = await bot.get_me() print(me.bot_title, me.username, me.description) # Chat info chat = await bot.get_chat("g0_group_id") print(chat.title, chat.chat_type) # Member count count = await bot.get_chat_member_count("g0_group_id") print("Members:", count) # Individual member member = await bot.get_chat_member("g0_group_id", "b0_user_id") print(member) import asyncio asyncio.run(main()) ``` -------------------------------- ### Send Files (Image, Video, Voice, Music, GIF) Source: https://context7.com/shayanheidari01/rubika/llms.txt Uploads local files or sends existing file IDs. Supports various media types like Image, Video, Voice (auto-converted to OGG), and Music. Text can be added to media messages. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: chat = "b0_user_chat_id" # Upload and send an image from disk msg = await bot.send_file( chat_id=chat, file="/path/to/photo.jpg", type="Image", text="Here is your photo 📸", ) # Re-use file_id for a second send (no re-upload) await bot.send_file(chat_id=chat, file_id=msg.file_id, type="Image") # Send a video await bot.send_file(chat_id=chat, file="/path/to/clip.mp4", type="Video") # Send voice (auto-converted to OGG) await bot.send_voice(chat_id=chat, file="/path/to/message.ogg") # Send music await bot.send_music(chat_id=chat, file="/path/to/song.mp3", text="🎵 Enjoy!") import asyncio asyncio.run(main()) ``` -------------------------------- ### Client Extras — Search, Join, Info Source: https://context7.com/shayanheidari01/rubika/llms.txt High-level utility methods available on user accounts for searching, joining chats, and retrieving information. ```APIDOC ## Client Extras — Search, Join, Info High-level utility methods available on user accounts. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Resolve any username to object info info = await client.get_object_by_username("rubikapy") print(info.type, info.object_guid) # General get_info (works for user, group, channel, bot) obj = await client.get_info("u0_user_guid") # Global text search results = await client.search_global_objects("Python") # Join group or channel by link await client.join("https://rubika.ir/joing/ABCDEF") # Leave a chat await client.leave_chat("g0_group_guid") # Get server time ts = await client.get_time() print("Server timestamp:", ts) # Transcribe voice message transcript = await client.transcribe_voice("u0_friend", message_id="voice_msg_id") print(transcript) import asyncio asyncio.run(main()) ``` ``` -------------------------------- ### BotClient.download_file Source: https://context7.com/shayanheidari01/rubika/llms.txt Download files from Rubika servers, with options for saving to disk or retrieving raw bytes, and progress tracking. ```APIDOC ## BotClient.download_file — Download Files ### Description Downloads a file using its `file_id`. Supports saving the file to a specified path or retrieving its content as bytes, with an optional progress callback. ### Method `download_file(file_id, save_as, progress, chunk_size, as_bytes)` ### Parameters - **file_id** (string) - Required - The unique identifier of the file to download. - **save_as** (string) - Optional - The path where the file should be saved. If not provided and `as_bytes` is False, the behavior might be undefined or raise an error. - **progress** (callable) - Optional - A callback function that is called during download with `downloaded` and `total` bytes. - **chunk_size** (integer) - Optional - The size of chunks to download in bytes. Defaults to 65536. - **as_bytes** (boolean) - Optional - If True, the file content is returned as bytes instead of saving to disk. ### Response - If `save_as` is provided, returns the path where the file was saved (string). - If `as_bytes` is True, returns the raw file content as bytes. ``` -------------------------------- ### Send Messages with Rubika Client Source: https://context7.com/shayanheidari01/rubika/llms.txt Demonstrates sending plain text, markdown, images from URLs, and local videos with auto-delete functionality using the Rubika Client. Ensure the Client is properly initialized with authentication details. ```python from rubpy import Client async def main(): async with Client("mybot", phone_number="+989123456789") as client: # Plain text await client.send_message("me", "Hello from Rubpy!") # Markdown text await client.send_message( "me", "`code` **bold** __italic__", parse_mode="markdown", ) # Send image from URL await client.send_message( object_guid="u0_friend_guid", text="Check this out!", file_inline="https://example.com/image.jpg", type="Image", ) # Send local video with auto-delete after 60 s await client.send_message( object_guid="u0_friend_guid", file_inline="/path/to/video.mp4", type="Video", auto_delete=60, ) import asyncio asyncio.run(main()) ``` -------------------------------- ### Client Channel Methods Source: https://context7.com/shayanheidari01/rubika/llms.txt Provides methods for user-account channel operations including creation, joining, editing, member management, and retrieving channel information. ```APIDOC ## Client Channel Methods User-account channel operations: create, join, edit, manage members, and retrieve info. ### Methods - **`get_channel_info(channel_guid)`**: Retrieves information about a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. - **Returns**: Channel information object (e.g., `channel_title`, `member_count`). - **`join_channel_action(channel_guid, action)`**: Joins or leaves a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. `action` (string) - "Join" or "Leave". - **`join_channel_by_link(invite_link)`**: Joins a channel using an invite link. - **Parameters**: `invite_link` (string) - The full invite link to the channel. - **`get_channel_all_members(channel_guid)`**: Retrieves all members of a channel (paginated). - **Parameters**: `channel_guid` (string) - The GUID of the channel. - **Returns**: An async iterator yielding member objects. - **`ban_channel_member(channel_guid, member_guid, action)`**: Bans a member from a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. `member_guid` (string) - The GUID of the member to ban. `action` (string) - Typically "Set" to ban. - **`edit_channel_info(channel_guid, **kwargs)`**: Edits the information of a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. `**kwargs` - Key-value pairs for channel attributes to edit (e.g., `channel_title`). - **`create_channel_voice_chat(channel_guid)`**: Creates a voice chat in a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. - **`discard_channel_voice_chat(channel_guid, voice_chat_id)`**: Discards an ongoing voice chat in a channel. - **Parameters**: `channel_guid` (string) - The GUID of the channel. `voice_chat_id` (string) - The ID of the voice chat to discard. ### Example (Get channel info) ```python info = await client.get_channel_info("c0_channel_guid") print(info.channel_title, info.member_count) ``` ### Example (Join channel) ```python await client.join_channel_action("c0_channel_guid", "Join") ``` ### Example (Join by link) ```python await client.join_channel_by_link("https://rubika.ir/joinc/ABCDEF") ``` ### Example (Get all members) ```python async for member in client.get_channel_all_members("c0_channel_guid"): print(member.member_guid, member.member_type) ``` ### Example (Ban member) ```python await client.ban_channel_member("c0_channel_guid", "u0_user_guid", "Set") ``` ### Example (Edit channel info) ```python await client.edit_channel_info("c0_channel_guid", channel_title="New Title") ``` ### Example (Voice chat operations) ```python await client.create_channel_voice_chat("c0_channel_guid") await client.discard_channel_voice_chat("c0_channel_guid", "vc_id") ``` ``` -------------------------------- ### Create a Simple Echo Plugin Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Defines a basic plugin that echoes incoming private messages. It inherits from `rubpy.plugins.Plugin` and uses `self.bot.on_update` with a text filter to process messages. ```python from rubpy.plugins import Plugin, PluginMeta from rubpy.bot.filters import text class EchoPlugin(Plugin): meta = PluginMeta( name="rubpy-echo", version="1.0.0", description="Echo incoming private messages", author="Rubpy Dev", homepage="https://github.com/...", ) def setup(self): @self.bot.on_update(text) async def echo(client, update): await client.send_message(update.chat_id, update.new_message.text) ``` -------------------------------- ### Register Bot Commands with BotClient Source: https://context7.com/shayanheidari01/rubika/llms.txt Register commands that will appear in the Rubika bot command menu using set_commands. The commands should be provided as a list of dictionaries, each with a 'command' and 'description'. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: ok = await bot.set_commands([ {"command": "start", "description": "Start the bot"}, {"command": "help", "description": "Show help"}, {"command": "status", "description": "Check status"}, ]) print("Commands set:", ok) import asyncio asyncio.run(main()) ``` -------------------------------- ### Manage Rubika Groups Source: https://context7.com/shayanheidari01/rubika/llms.txt Perform group creation, management, and member administration tasks. Requires a Client instance. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Get group info info = await client.get_group_info("g0_group_guid") print(info.group_title, info.member_count) # Add members await client.add_group_members("g0_group_guid", ["u0_user1", "u0_user2"]) # Remove a member await client.remove_group_members("g0_group_guid", ["u0_user1"]) # Ban and unban await client.ban_group_member("g0_group_guid", "u0_user2") # Get admin list admins = await client.get_group_admin_members("g0_group_guid") for a in admins.admin_list: print(a.member_guid, a.access_list) # Set a new admin await client.set_group_admin("g0_group_guid", "u0_user3", access_list=["SendMessages"]) # Edit group info await client.edit_group_info("g0_group_guid", group_title="Renamed Group") import asyncio asyncio.run(main()) ``` -------------------------------- ### Rubika Utility Functions Source: https://context7.com/shayanheidari01/rubika/llms.txt Utilize high-level utility methods for searching, joining/leaving chats, and retrieving server information. Requires a Client instance. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Resolve any username to object info info = await client.get_object_by_username("rubikapy") print(info.type, info.object_guid) # General get_info (works for user, group, channel, bot) obj = await client.get_info("u0_user_guid") # Global text search results = await client.search_global_objects("Python") # Join group or channel by link await client.join("https://rubika.ir/joing/ABCDEF") # Leave a chat await client.leave_chat("g0_group_guid") # Get server time ts = await client.get_time() print("Server timestamp:", ts) # Transcribe voice message transcript = await client.transcribe_voice("u0_friend", message_id="voice_msg_id") print(transcript) import asyncio asyncio.run(main()) ``` -------------------------------- ### BotClient.set_commands Source: https://context7.com/shayanheidari01/rubika/llms.txt Register commands that will be visible in the Rubika bot command menu. ```APIDOC ## BotClient.set_commands — Register Bot Commands ### Description Allows you to define and register a list of commands that will appear in the bot's command menu within Rubika. ### Method `set_commands(commands)` ### Parameters - **commands** (list of dict) - Required - A list where each dictionary contains: - **command** (string) - The command name (e.g., "start"). - **description** (string) - A brief description of the command. ### Response - Returns a boolean (`ok`) indicating whether the commands were set successfully. ``` -------------------------------- ### Download Files with BotClient Source: https://context7.com/shayanheidari01/rubika/llms.txt Download files from Rubika servers by file_id. You can save the file to disk or retrieve its raw bytes. A progress callback can be provided for large files. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def on_progress(downloaded: int, total: int): if total: print(f"{downloaded}/{total} bytes ({100*downloaded//total}%)") async def main(): async with bot: # Save to disk path = await bot.download_file( file_id="file_abc123", save_as="/tmp/download.jpg", progress=on_progress, chunk_size=65536, ) print("Saved to:", path) # Get raw bytes data: bytes = await bot.download_file( file_id="file_abc123", as_bytes=True, ) print("Bytes received:", len(data)) import asyncio asyncio.run(main()) ``` -------------------------------- ### Decorator-Based Event Handlers with Rubika Client Source: https://context7.com/shayanheidari01/rubika/llms.txt Shows how to register event handlers using decorators like `@bot.on_message_updates()` and `filters` from `rubpy.filters`. This approach is suitable for building interactive bots that respond to different types of updates. ```python from rubpy import Client, filters from rubpy.types import Update bot = Client("mybot") @bot.on_message_updates(filters.text) async def on_text(update: Update): print(update.text) await update.reply("`echo:` " + update.text) @bot.on_message_updates(filters.photo) async def on_photo(update: Update): await update.reply("Got a photo!") @bot.on_message_updates(filters.commands("/start")) async def on_start(update: Update): await update.reply("**Welcome!** Use `/help` for commands.") @bot.on_chat_updates() async def on_chat(update: Update): print("Chat updated:", update.object_guid) bot.run() ``` -------------------------------- ### Dynamically add and remove handlers Source: https://context7.com/shayanheidari01/rubika/llms.txt Handlers can be added and removed at runtime using bot.add_handler and bot.remove_handler. The add_handler method returns a key to identify the handler for later removal. ```python from rubpy.bot import BotClient, filters bot = BotClient("your_bot_token") # Add/remove handlers dynamically key = bot.add_handler(private_text, filters.private) bot.remove_handler(key) ``` -------------------------------- ### Client Group Methods Source: https://context7.com/shayanheidari01/rubika/llms.txt Methods for creating, managing, and administering group memberships within Rubika. ```APIDOC ## Client Group Methods Group creation, management, and member administration. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Get group info info = await client.get_group_info("g0_group_guid") print(info.group_title, info.member_count) # Add members await client.add_group_members("g0_group_guid", ["u0_user1", "u0_user2"]) # Remove a member await client.remove_group_members("g0_group_guid", ["u0_user1"]) # Ban and unban await client.ban_group_member("g0_group_guid", "u0_user2") # Get admin list admins = await client.get_group_admin_members("g0_group_guid") for a in admins.admin_list: print(a.member_guid, a.access_list) # Set a new admin await client.set_group_admin("g0_group_guid", "u0_user3", access_list=["SendMessages"]) # Edit group info await client.edit_group_info("g0_group_guid", group_title="Renamed Group") import asyncio asyncio.run(main()) ``` ``` -------------------------------- ### Send Location and Contact Cards Source: https://context7.com/shayanheidari01/rubika/llms.txt Sends a user's location using latitude and longitude, or a contact card with first name, last name, and phone number. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: chat = "b0_user_chat_id" # Location await bot.send_location( chat_id=chat, latitude=35.6892, longitude=51.3890, ) # Contact card await bot.send_contact( chat_id=chat, first_name="Ali", last_name="Rezaei", phone_number="+989123456789", ) import asyncio asyncio.run(main()) ``` -------------------------------- ### Client Message Methods Source: https://context7.com/shayanheidari01/rubika/llms.txt Provides a rich set of message operations for user accounts, including retrieval, editing, deletion, forwarding, and reactions. ```APIDOC ## Client Message Methods Rich set of message operations for user accounts. ```python from rubpy import Client async def main(): async with Client("mybot") as client: guid = "u0_friend_guid" # Get messages by ID msgs = await client.get_messages_by_id(guid, ["msg_id_1", "msg_id_2"]) # Edit a message await client.edit_message(guid, message_id="msg_id_1", text="Edited text") # Delete messages await client.delete_messages(guid, message_ids=["msg_id_1"]) # Forward await client.forward_messages( from_object_guid=guid, message_ids=["msg_id_2"], to_object_guid="g0_group_guid", ) # Pin a message await client.set_pin_message(guid, message_id="msg_id_2") # React to a message await client.reaction(guid, message_id="msg_id_2", reaction_id="👍") await client.remove_reaction(guid, message_id="msg_id_2") # Vote in a poll await client.vote_poll(guid, message_id="poll_msg_id", selection_index=0) # Get messages in a range interval = await client.get_messages_interval(guid, middle_message_id="msg_id_2") # Get shareable URL for a message url = await client.get_message_share_url(guid, message_id="msg_id_2") print(url) import asyncio asyncio.run(main()) ``` ``` -------------------------------- ### Disable Plugin at Runtime Source: https://github.com/shayanheidari01/rubika/blob/master/docs/docs/plugins.md Shows the method for disabling a previously enabled plugin programmatically during the bot's runtime. ```python await bot.disable_plugins(["rubpy_echo"]) ``` -------------------------------- ### FSM Filter for Conversational Flows Source: https://context7.com/shayanheidari01/rubika/llms.txt Implement multi-step conversations using the filters.states FSM filter. States are stored per-user or per-chat and can have an optional Time-To-Live (TTL). ```python from rubpy.bot import BotClient, filters from rubpy.bot.filters import states as States bot = BotClient("your_bot_token") # Create a reusable states filter instance waiting_name = States("waiting_name", scope="user") waiting_email = States("waiting_email", scope="user") @bot.on_update(filters.commands("register")) async def start_registration(client, update): await waiting_name.set_state_for(update, "waiting_name", expire=300) await update.reply("Please enter your name:") @bot.on_update(waiting_name, filters.text) async def got_name(client, update): name = update.new_message.text await waiting_name.clear_state_for(update) await waiting_email.set_state_for(update, "waiting_email", expire=300) await update.reply(f"Hi {name}! Now enter your email:") @bot.on_update(waiting_email, filters.text) async def got_email(client, update): email = update.new_message.text await waiting_email.clear_state_for(update) await update.reply(f"Registered with email: {email} ✅") import asyncio asyncio.run(bot.run()) ``` -------------------------------- ### Client Contacts Methods Source: https://context7.com/shayanheidari01/rubika/llms.txt Methods for managing the Rubika address book, including adding, retrieving, and deleting contacts. ```APIDOC ## Client Contacts Methods Manage the Rubika address book. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Add a contact await client.add_address_book( phone="+989123456789", first_name="Ali", last_name="Rezaei", ) # Get all contacts contacts = await client.get_contacts() for c in contacts.contacts: print(c.first_name, c.phone) # Delete a contact await client.delete_contact("u0_contact_guid") # Reset all contacts await client.reset_contacts() import asyncio asyncio.run(main()) ``` ``` -------------------------------- ### BotClient.send_file Source: https://context7.com/shayanheidari01/rubika/llms.txt Uploads a local file or sends an already-uploaded `file_id`. The `type` parameter selects how Rubika renders the attachment. ```APIDOC ## BotClient.send_file — Send Files (Image, Video, Voice, Music, GIF) ### Description Uploads a local file or sends an already-uploaded `file_id`. The `type` parameter selects how Rubika renders the attachment. ### Method `send_file` ### Parameters - **chat_id** (string) - Required - The ID of the chat to send the file to. - **file** (string) - Optional - The path to the local file to upload. - **file_id** (string) - Optional - The ID of an already uploaded file to send. - **type** (string) - Required - The type of file to send (e.g., "Image", "Video", "Voice", "Music", "GIF"). - **text** (string) - Optional - A caption for the file. ### Request Example ```python # Upload and send an image from disk msg = await bot.send_file( chat_id=chat, file="/path/to/photo.jpg", type="Image", text="Here is your photo 📸", ) # Re-use file_id for a second send (no re-upload) await bot.send_file(chat_id=chat, file_id=msg.file_id, type="Image") # Send a video await bot.send_file(chat_id=chat, file="/path/to/clip.mp4", type="Video") # Send voice (auto-converted to OGG) await bot.send_voice(chat_id=chat, file="/path/to/message.ogg") # Send music await bot.send_music(chat_id=chat, file="/path/to/song.mp3", text="🎵 Enjoy!") ``` ### Response #### Success Response - **message_id** (integer) - The ID of the sent message. - **file_id** (string) - The ID of the uploaded file. ``` -------------------------------- ### BotClient.on_update Source: https://context7.com/shayanheidari01/rubika/llms.txt Decorator to register asynchronous handler functions that are triggered when specified filters match incoming updates. ```APIDOC ## BotClient.on_update — Decorator-Based Handler Registration ### Description Registers an asynchronous handler function that will be executed when all the provided filter conditions are met for an incoming update. ### Decorator `@bot.on_update(*filters)` ### Parameters - **filters** (Filter objects) - Variable number of filter objects that must all match for the handler to be called. Examples include `filters.private`, `filters.text`, `filters.commands('command_name')`. ### Handler Function Signature `async def handler_function(client: BotClient, update: Update):` - **client**: The BotClient instance. - **update**: An Update object containing details about the incoming event. ``` -------------------------------- ### Manage Rubika Contacts Source: https://context7.com/shayanheidari01/rubika/llms.txt Manage the Rubika address book by adding, retrieving, deleting, and resetting contacts. Requires a Client instance. ```python from rubpy import Client async def main(): async with Client("mybot") as client: # Add a contact await client.add_address_book( phone="+989123456789", first_name="Ali", last_name="Rezaei", ) # Get all contacts contacts = await client.get_contacts() for c in contacts.contacts: print(c.first_name, c.phone) # Delete a contact await client.delete_contact("u0_contact_guid") # Reset all contacts await client.reset_contacts() import asyncio asyncio.run(main()) ``` -------------------------------- ### Manage Chat Members with BotClient Source: https://context7.com/shayanheidari01/rubika/llms.txt Moderate chat members using ban_chat_member and unban_chat_member. Retrieve a list of administrators using get_chat_administrators. Ensure correct chat and user IDs are used. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: await bot.ban_chat_member(chat_id="g0_group_id", user_id="b0_offender_id") await bot.unban_chat_member(chat_id="g0_group_id", user_id="b0_offender_id") admins = await bot.get_chat_administrators("g0_group_id") print(admins) import asyncio asyncio.run(main()) ``` -------------------------------- ### Pin and Unpin Messages with BotClient Source: https://context7.com/shayanheidari01/rubika/llms.txt Manage pinned messages in a chat using pin_chat_message, unpin_chat_message, and unpin_all_chat_messages. Ensure the correct chat ID and message ID are provided. ```python from rubpy.bot import BotClient bot = BotClient("your_bot_token") async def main(): async with bot: await bot.pin_chat_message( chat_id="g0_group_id", message_id="99999", disable_notification=True, ) # Unpin a specific message await bot.unpin_chat_message(chat_id="g0_group_id", message_id="99999") # Unpin all await bot.unpin_all_chat_messages(chat_id="g0_group_id", message_id="99999") import asyncio asyncio.run(main()) ``` -------------------------------- ### BotClient.send_location / send_contact Source: https://context7.com/shayanheidari01/rubika/llms.txt Sends a user's location or a contact card to a chat. ```APIDOC ## BotClient.send_location / send_contact — Send Location and Contact Cards ### Description Sends a user's location or a contact card to a chat. ### Method `send_location`, `send_contact` ### Parameters for `send_location` - **chat_id** (string) - Required - The ID of the chat to send the location to. - **latitude** (float) - Required - The latitude of the location. - **longitude** (float) - Required - The longitude of the location. ### Parameters for `send_contact` - **chat_id** (string) - Required - The ID of the chat to send the contact to. - **first_name** (string) - Required - The first name of the contact. - **last_name** (string) - Optional - The last name of the contact. - **phone_number** (string) - Required - The phone number of the contact. ### Request Example ```python # Location await bot.send_location( chat_id=chat, latitude=35.6892, longitude=51.3890, ) # Contact card await bot.send_contact( chat_id=chat, first_name="Ali", last_name="Rezaei", phone_number="+989123456789", ) ``` ### Response #### Success Response - **message_id** (integer) - The ID of the sent message. ```