RubigramClient 1.7.17__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. rubigram/__init__.py +15 -0
  2. rubigram/client.py +294 -0
  3. rubigram/enums/__init__.py +52 -0
  4. rubigram/enums/buttons/__init__.py +13 -0
  5. rubigram/enums/buttons/button_calendar_type.py +20 -0
  6. rubigram/enums/buttons/button_location_type.py +20 -0
  7. rubigram/enums/buttons/button_selection_get_type.py +20 -0
  8. rubigram/enums/buttons/button_selection_search_type.py +20 -0
  9. rubigram/enums/buttons/button_selection_type.py +22 -0
  10. rubigram/enums/buttons/button_textbox_type_keypad.py +20 -0
  11. rubigram/enums/buttons/button_textbox_type_line.py +20 -0
  12. rubigram/enums/buttons/button_type.py +58 -0
  13. rubigram/enums/chat_action_type.py +22 -0
  14. rubigram/enums/chat_keypad_type.py +20 -0
  15. rubigram/enums/chat_type.py +24 -0
  16. rubigram/enums/enum.py +6 -0
  17. rubigram/enums/file_type.py +28 -0
  18. rubigram/enums/forwarded_from_type.py +22 -0
  19. rubigram/enums/live_location_status.py +20 -0
  20. rubigram/enums/message_sender_type.py +20 -0
  21. rubigram/enums/metadata_type.py +18 -0
  22. rubigram/enums/parse_mode.py +20 -0
  23. rubigram/enums/payment_status_type.py +20 -0
  24. rubigram/enums/poll_status_type.py +20 -0
  25. rubigram/enums/update_endpoint_type.py +26 -0
  26. rubigram/enums/update_type.py +28 -0
  27. rubigram/errors.py +16 -0
  28. rubigram/filters.py +865 -0
  29. rubigram/http_session.py +96 -0
  30. rubigram/methods/__init__.py +26 -0
  31. rubigram/methods/chats/__init__.py +10 -0
  32. rubigram/methods/chats/get_chat.py +53 -0
  33. rubigram/methods/decorators/__init__.py +25 -0
  34. rubigram/methods/decorators/on_inline_message.py +70 -0
  35. rubigram/methods/decorators/on_message.py +62 -0
  36. rubigram/methods/decorators/on_remove_message.py +65 -0
  37. rubigram/methods/decorators/on_start.py +65 -0
  38. rubigram/methods/decorators/on_started_bot.py +70 -0
  39. rubigram/methods/decorators/on_stop.py +65 -0
  40. rubigram/methods/decorators/on_stopped_bot.py +70 -0
  41. rubigram/methods/decorators/on_update_message.py +70 -0
  42. rubigram/methods/files/__init__.py +32 -0
  43. rubigram/methods/files/download_file.py +118 -0
  44. rubigram/methods/files/get_file.py +41 -0
  45. rubigram/methods/files/get_file_name.py +41 -0
  46. rubigram/methods/files/request_send_file.py +49 -0
  47. rubigram/methods/files/send_file.py +133 -0
  48. rubigram/methods/files/send_gif.py +51 -0
  49. rubigram/methods/files/send_music.py +97 -0
  50. rubigram/methods/files/send_photo.py +95 -0
  51. rubigram/methods/files/send_video.py +96 -0
  52. rubigram/methods/files/send_voice.py +96 -0
  53. rubigram/methods/files/upload_file.py +114 -0
  54. rubigram/methods/messages/__init__.py +34 -0
  55. rubigram/methods/messages/delete_messages.py +84 -0
  56. rubigram/methods/messages/edit_chat_keypad.py +68 -0
  57. rubigram/methods/messages/edit_message.py +82 -0
  58. rubigram/methods/messages/edit_message_keypad.py +72 -0
  59. rubigram/methods/messages/edit_message_text.py +68 -0
  60. rubigram/methods/messages/forward_message.py +78 -0
  61. rubigram/methods/messages/remove_chat_keypad.py +46 -0
  62. rubigram/methods/messages/send_contact.py +114 -0
  63. rubigram/methods/messages/send_location.py +108 -0
  64. rubigram/methods/messages/send_message.py +115 -0
  65. rubigram/methods/messages/send_poll.py +104 -0
  66. rubigram/methods/messages/send_sticker.py +98 -0
  67. rubigram/methods/network/__init__.py +12 -0
  68. rubigram/methods/network/request.py +129 -0
  69. rubigram/methods/settings/__init__.py +16 -0
  70. rubigram/methods/settings/set_command.py +50 -0
  71. rubigram/methods/settings/setup_endpoints.py +48 -0
  72. rubigram/methods/settings/update_bot_endpoint.py +62 -0
  73. rubigram/methods/updates/__init__.py +14 -0
  74. rubigram/methods/updates/get_me.py +35 -0
  75. rubigram/methods/updates/get_update.py +62 -0
  76. rubigram/methods/utilities/__init__.py +14 -0
  77. rubigram/methods/utilities/dispatcher.py +66 -0
  78. rubigram/methods/utilities/run.py +118 -0
  79. rubigram/rubino/__init__.py +6 -0
  80. rubigram/rubino/client.py +374 -0
  81. rubigram/rubino/network.py +129 -0
  82. rubigram/server/__init__.py +6 -0
  83. rubigram/server/server.py +245 -0
  84. rubigram/state/__init__.py +7 -0
  85. rubigram/state/state.py +121 -0
  86. rubigram/state/storage.py +131 -0
  87. rubigram/types/__init__.py +66 -0
  88. rubigram/types/aux_data.py +28 -0
  89. rubigram/types/bot.py +51 -0
  90. rubigram/types/bot_command.py +26 -0
  91. rubigram/types/buttons/__init__.py +13 -0
  92. rubigram/types/buttons/button.py +59 -0
  93. rubigram/types/buttons/button_calendar.py +40 -0
  94. rubigram/types/buttons/button_location.py +40 -0
  95. rubigram/types/buttons/button_number_picker.py +34 -0
  96. rubigram/types/buttons/button_selection.py +48 -0
  97. rubigram/types/buttons/button_selection_item.py +32 -0
  98. rubigram/types/buttons/button_string_picker.py +29 -0
  99. rubigram/types/buttons/button_text_box.py +40 -0
  100. rubigram/types/chat.py +86 -0
  101. rubigram/types/config/__init__.py +6 -0
  102. rubigram/types/config/object.py +442 -0
  103. rubigram/types/contact_message.py +29 -0
  104. rubigram/types/file.py +78 -0
  105. rubigram/types/forwarded_from.py +39 -0
  106. rubigram/types/keypads/__init__.py +7 -0
  107. rubigram/types/keypads/keypad.py +31 -0
  108. rubigram/types/keypads/keypad_row.py +23 -0
  109. rubigram/types/live_location.py +44 -0
  110. rubigram/types/location.py +24 -0
  111. rubigram/types/messages/__init__.py +8 -0
  112. rubigram/types/messages/inline_message.py +78 -0
  113. rubigram/types/messages/message.py +117 -0
  114. rubigram/types/messages/update_message.py +341 -0
  115. rubigram/types/metadata/__init__.py +7 -0
  116. rubigram/types/metadata/metadata.py +43 -0
  117. rubigram/types/metadata/metadata_parts.py +42 -0
  118. rubigram/types/payment_status.py +30 -0
  119. rubigram/types/poll.py +32 -0
  120. rubigram/types/poll_status.py +40 -0
  121. rubigram/types/sticker.py +33 -0
  122. rubigram/types/updates/__init__.py +7 -0
  123. rubigram/types/updates/update.py +917 -0
  124. rubigram/types/updates/updates.py +56 -0
  125. rubigram/utils/__init__.py +14 -0
  126. rubigram/utils/auto_delete.py +93 -0
  127. rubigram/utils/parser.py +99 -0
  128. rubigramclient-1.7.17.dist-info/METADATA +215 -0
  129. rubigramclient-1.7.17.dist-info/RECORD +132 -0
  130. rubigramclient-1.7.17.dist-info/WHEEL +5 -0
  131. rubigramclient-1.7.17.dist-info/licenses/LICENSE +21 -0
  132. rubigramclient-1.7.17.dist-info/top_level.txt +1 -0
@@ -0,0 +1,96 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from aiohttp import ClientSession, TCPConnector, ClientTimeout
7
+ from typing import Optional
8
+ import logging
9
+
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class HttpSession:
15
+ """
16
+ Asynchronous HTTP session manager based on aiohttp.
17
+
18
+ This class manages the lifecycle of a shared aiohttp ClientSession,
19
+ providing configurable timeouts and connection pooling. It is intended
20
+ to be used as the low-level HTTP transport layer for Rubigram.
21
+
22
+ Parameters:
23
+ timeout (float):
24
+ Total timeout (in seconds) for a single HTTP request, including
25
+ connection, redirects, and response reading.
26
+
27
+ connect_timeout (float):
28
+ Maximum time (in seconds) allowed to establish a connection
29
+ to the remote server.
30
+
31
+ read_timeout (float):
32
+ Maximum time (in seconds) to wait for data to be read from
33
+ the socket after the connection is established.
34
+
35
+ max_connections (int):
36
+ Maximum number of simultaneous connections allowed in the
37
+ connection pool.
38
+
39
+ Example:
40
+ .. code-block:: python
41
+ async with HttpSession(timeout=30, max_connections=100) as http:
42
+ session = http.get_session()
43
+ await session.get("https://example.com")
44
+ """
45
+
46
+ def __init__(
47
+ self,
48
+ timeout: float = 30.0,
49
+ connect_timeout: float = 10.0,
50
+ read_timeout: float = 20.0,
51
+ max_connections: int = 100
52
+ ):
53
+ self.timeout = ClientTimeout(
54
+ total=timeout,
55
+ connect=connect_timeout,
56
+ sock_read=read_timeout
57
+ )
58
+ self.max_connections = max_connections
59
+ self.session: Optional[ClientSession] = None
60
+
61
+ async def connect(self) -> None:
62
+ if not self.is_connected:
63
+ connector = TCPConnector(
64
+ limit=self.max_connections, enable_cleanup_closed=True
65
+ )
66
+ self.session = ClientSession(
67
+ connector=connector, timeout=self.timeout
68
+ )
69
+ logger.info(
70
+ "Connect to HTTP session, timeout=%s, connections=%s",
71
+ self.timeout.total, self.max_connections
72
+ )
73
+ else:
74
+ logger.debug("HTTP session already connected")
75
+
76
+ async def disconnect(self) -> None:
77
+ if self.is_connected:
78
+ await self.session.close()
79
+ logger.info("HTTP session closed")
80
+ self.session = None
81
+
82
+ @property
83
+ def is_connected(self) -> bool:
84
+ return self.session is not None and not self.session.closed
85
+
86
+ def get_session(self) -> "ClientSession":
87
+ if not self.is_connected:
88
+ raise RuntimeError("HTTP session is not connected")
89
+ return self.session
90
+
91
+ async def __aenter__(self) -> "HttpSession":
92
+ await self.connect()
93
+ return self
94
+
95
+ async def __aexit__(self, *args) -> None:
96
+ await self.disconnect()
@@ -0,0 +1,26 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from .decorators import Decorators
7
+ from .utilities import Utilities
8
+ from .messages import Messages
9
+ from .settings import Settings
10
+ from .updates import Updates
11
+ from .network import Network
12
+ from .chats import Chats
13
+ from .files import Files
14
+
15
+
16
+ class Methods(
17
+ Decorators,
18
+ Utilities,
19
+ Messages,
20
+ Network,
21
+ Settings,
22
+ Updates,
23
+ Chats,
24
+ Files
25
+ ):
26
+ pass
@@ -0,0 +1,10 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from .get_chat import GetChat
7
+
8
+
9
+ class Chats(GetChat):
10
+ pass
@@ -0,0 +1,53 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ import rubigram
7
+
8
+
9
+ class GetChat:
10
+ async def get_chat(
11
+ self: "rubigram.Client",
12
+ chat_id: str
13
+ ) -> "rubigram.types.Chat":
14
+ """
15
+ **Get information about a specific chat.**
16
+ `await client.get_chat(chat_id)`
17
+
18
+ This method retrieves detailed information about a chat, including
19
+ its type, title, user information (for private chats), and other
20
+ metadata.
21
+
22
+ Args:
23
+ chat_id (`str`):
24
+ The unique identifier of the chat to retrieve information for.
25
+
26
+ Returns:
27
+ rubigram.types.Chat: A Chat object containing the chat information.
28
+
29
+ Example:
30
+ .. code-block:: python
31
+
32
+ # Get information about a chat
33
+ chat = await client.get_chat(chat_id=chat_id)
34
+ print(f"Chat title: {chat.title}")
35
+ print(f"Chat type: {chat.chat_type}")
36
+ print(f"Username: {chat.username}")
37
+
38
+ # For private chats, access user information
39
+ if chat.chat_type == rubigram.enums.ChatType.USER:
40
+ print(f"User full name: {chat.full_name}")
41
+
42
+ Note:
43
+ - Works for all chat types (private, group, supergroup, channel)
44
+ - For private chats, returns user information
45
+ - For groups/channels, returns group metadata and settings
46
+ """
47
+ response = await self.request(
48
+ "getChat",
49
+ {
50
+ "chat_id": chat_id
51
+ }
52
+ )
53
+ return rubigram.types.Chat.parse(response["chat"])
@@ -0,0 +1,25 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from .on_stop import OnStop
7
+ from .on_start import OnStart
8
+ from .on_message import OnMessage
9
+ from .on_stopped_bot import OnStoppedBot
10
+ from .on_started_bot import OnStartedBot
11
+ from .on_inline_message import OnInlineMessage
12
+ from .on_remove_message import OnRemoveMessage
13
+ from .on_update_message import OnUpdateMessage
14
+
15
+ class Decorators(
16
+ OnStop,
17
+ OnStart,
18
+ OnMessage,
19
+ OnStoppedBot,
20
+ OnStartedBot,
21
+ OnInlineMessage,
22
+ OnRemoveMessage,
23
+ OnUpdateMessage
24
+ ):
25
+ pass
@@ -0,0 +1,70 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Optional, Callable
7
+ from rubigram.filters import Filter
8
+ import rubigram
9
+
10
+
11
+ class OnInlineMessage:
12
+ def on_inline_message(
13
+ self: "rubigram.Client",
14
+ filters: Optional["Filter"] = None
15
+ ):
16
+ """
17
+ **Decorator for handling inline messages.**
18
+ `@client.on_inline_message(filters.button("my_button"))`
19
+
20
+ This decorator registers a function to handle inline message events
21
+ that match the specified filters. If no filters are provided,
22
+ all inline messages will be handled.
23
+
24
+ Args:
25
+ filters (`Optional[Filter]`):
26
+ Filter to determine which inline messages should be handled.
27
+ If None, all inline messages will be processed.
28
+
29
+ Returns:
30
+ Callable: The decorator function.
31
+
32
+ Example:
33
+ .. code-block:: python
34
+
35
+ # Handle specific button clicks
36
+ @client.on_inline_message(filters.button("start_btn"))
37
+ async def handle_start_button(client, update):
38
+ await client.send_message(
39
+ update.chat_id,
40
+ "Start button was clicked!"
41
+ )
42
+
43
+ # Handle inline messages with text
44
+ @client.on_inline_message(filters.text)
45
+ async def handle_inline_text(client, update):
46
+ print(f"Inline message text: {update.text}")
47
+
48
+ # Handle all inline messages (no filter)
49
+ @client.on_inline_message()
50
+ async def handle_all_inline(client, update):
51
+ print(f"Inline message received from: {update.sender_id}")
52
+
53
+ Note:
54
+ Inline messages are typically generated by button clicks in
55
+ inline keyboards or other interactive elements. The button ID
56
+ can be accessed via `update.aux_data.button_id`.
57
+ """
58
+ def decorator(func: Callable) -> Callable:
59
+ async def wrapper(
60
+ client: "rubigram.Client",
61
+ update: "rubigram.types.InlineMessage"
62
+ ):
63
+ if filters is None or await filters(client, update):
64
+ await func(client, update)
65
+ return True
66
+ return False
67
+
68
+ self.inline_message_handlers.append(wrapper)
69
+ return func
70
+ return decorator
@@ -0,0 +1,62 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Optional, Callable
7
+ from rubigram.filters import Filter
8
+ import rubigram
9
+
10
+
11
+ class OnMessage:
12
+ def on_message(
13
+ self: "rubigram.Client",
14
+ filters: Optional["Filter"] = None
15
+ ):
16
+ """
17
+ **Decorator for handling incoming messages.**
18
+ `@client.on_message(filters.text)`
19
+
20
+ This decorator registers a function to handle incoming messages
21
+ that match the specified filters. If no filters are provided,
22
+ all messages will be handled.
23
+
24
+ Args:
25
+ filters (`Optional[Filter]`):
26
+ Filter to determine which messages should be handled.
27
+ If None, all messages will be processed.
28
+
29
+ Returns:
30
+ Callable: The decorator function.
31
+
32
+ Example:
33
+ .. code-block:: python
34
+
35
+ # Handle all text messages
36
+ @client.on_message(filters.text)
37
+ async def handle_text(client, update):
38
+ await client.send_message(update.chat_id, "Text message received!")
39
+
40
+ # Handle commands
41
+ @client.on_message(filters.command("start"))
42
+ async def handle_start(client, update):
43
+ await client.send_message(update.chat_id, "Bot started!")
44
+
45
+ # Handle all messages (no filter)
46
+ @client.on_message()
47
+ async def handle_all(client, update):
48
+ print(f"Received message: {update.new_message.text}")
49
+ """
50
+ def decorator(func: Callable) -> Callable:
51
+ async def wrapper(
52
+ client: "rubigram.Client",
53
+ update: "rubigram.types.Update"
54
+ ):
55
+ if filters is None or await filters(client, update):
56
+ await func(client, update)
57
+ return True
58
+ return False
59
+
60
+ self.new_message_handlers.append(wrapper)
61
+ return func
62
+ return decorator
@@ -0,0 +1,65 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Optional, Callable
7
+ from rubigram.filters import Filter
8
+ import rubigram
9
+
10
+
11
+ class OnRemoveMessage:
12
+ def on_remove_message(
13
+ self: "rubigram.Client",
14
+ filters: Optional["Filter"] = None
15
+ ):
16
+ """
17
+ **Decorator for handling deleted messages.**
18
+ `@client.on_delete_message(filters.private)`
19
+
20
+ This decorator registers a function to handle message deletion events
21
+ that match the specified filters. If no filters are provided,
22
+ all message deletions will be handled.
23
+
24
+ Args:
25
+ filters (`Optional[Filter]`):
26
+ Filter to determine which message deletions should be handled.
27
+ If None, all message deletions will be processed.
28
+
29
+ Returns:
30
+ Callable: The decorator function.
31
+
32
+ Example:
33
+ .. code-block:: python
34
+
35
+ # Handle all message deletions in private chats
36
+ @client.on_delete_message(filters.private)
37
+ async def handle_private_deletion(client, update):
38
+ await client.send_message(
39
+ update.chat_id,
40
+ "A message was deleted in this private chat!"
41
+ )
42
+
43
+ # Handle message deletions in specific chats
44
+ @client.on_delete_message(filters.chat(["g0123456789", "g0987654321"]))
45
+ async def handle_group_deletions(client, update):
46
+ print(f"Message deleted in group: {update.chat_id}")
47
+
48
+ # Handle all message deletions (no filter)
49
+ @client.on_delete_message()
50
+ async def handle_all_deletions(client, update):
51
+ print(f"Message {update.removed_message_id} was deleted in {update.chat_id}")
52
+ """
53
+ def decorator(func: Callable) -> Callable:
54
+ async def wrapper(
55
+ client: "rubigram.Client",
56
+ update: "rubigram.types.Update"
57
+ ):
58
+ if filters is None or await filters(client, update):
59
+ await func(client, update)
60
+ return True
61
+ return False
62
+
63
+ self.remove_message_handlers.append(wrapper)
64
+ return func
65
+ return decorator
@@ -0,0 +1,65 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Callable
7
+ import rubigram
8
+
9
+
10
+ class OnStart:
11
+ def on_start(self: "rubigram.Client"):
12
+ """
13
+ **Decorator for handling application startup events.**
14
+ `@client.on_start()`
15
+
16
+ This decorator registers a function to be executed when the
17
+ Rubigram client starts up and connects to the server. This is
18
+ useful for initialization tasks, setting up webhooks, or
19
+ performing any setup required before the bot starts processing updates.
20
+
21
+ Returns:
22
+ Callable: The decorator function.
23
+
24
+ Example:
25
+ .. code-block:: python
26
+
27
+ # Initialize bot on startup
28
+ @client.on_start()
29
+ async def initialize_bot(client):
30
+ await client.set_commands([
31
+ rubigram.types.BotCommand(command="start", description="Start the bot"),
32
+ rubigram.types.BotCommand(command="help", description="Get help")
33
+ ])
34
+ print("Bot started and commands registered!")
35
+
36
+ # Set up webhook on startup
37
+ @client.on_start()
38
+ async def setup_webhook(client):
39
+ await client.update_bot_endpoints(
40
+ url="https://api.example.com/webhook",
41
+ type="ReceiveUpdate"
42
+ )
43
+ print("Webhook configured successfully!")
44
+
45
+ # Perform database initialization
46
+ @client.on_start()
47
+ async def init_database(client):
48
+ # Initialize database connections
49
+ # Create necessary tables
50
+ # Load initial data
51
+ print("Database initialized!")
52
+
53
+ Note:
54
+ - This handler runs only once when the client starts
55
+ - Multiple startup handlers can be registered
56
+ - All startup handlers run before the client begins processing updates
57
+ - The client parameter provides access to all bot methods
58
+ """
59
+ def decorator(func: Callable) -> Callable:
60
+ async def wrapper(client):
61
+ return await func(client)
62
+
63
+ self.start_handlers.append(wrapper)
64
+ return func
65
+ return decorator
@@ -0,0 +1,70 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Optional, Callable
7
+ from rubigram.filters import Filter
8
+ import rubigram
9
+
10
+
11
+ class OnStartedBot:
12
+ def on_started_bot(
13
+ self: "rubigram.Client",
14
+ filters: Optional["Filter"] = None
15
+ ):
16
+ """
17
+ **Decorator for handling bot start events.**
18
+ `@client.on_start_bot(filters.private)`
19
+
20
+ This decorator registers a function to handle bot start events
21
+ that match the specified filters. If no filters are provided,
22
+ all bot start events will be handled.
23
+
24
+ Args:
25
+ filters (`Optional[Filter]`):
26
+ Filter to determine which bot start events should be handled.
27
+ If None, all bot start events will be processed.
28
+
29
+ Returns:
30
+ Callable: The decorator function.
31
+
32
+ Example:
33
+ .. code-block:: python
34
+
35
+ # Handle bot starts in private chats only
36
+ @client.on_start_bot(filters.private)
37
+ async def handle_private_start(client, update):
38
+ await client.send_message(
39
+ update.chat_id,
40
+ "Welcome to the bot! Use /help for commands."
41
+ )
42
+
43
+ # Handle bot starts from specific users
44
+ @client.on_start_bot(filters.chat(["b0123456789", "b0987654321"]))
45
+ async def handle_specific_users(client, update):
46
+ print(f"Bot started by user: {update.chat_id}")
47
+
48
+ # Handle all bot start events (no filter)
49
+ @client.on_start_bot()
50
+ async def handle_all_starts(client, update):
51
+ print(f"Bot started in chat: {update.chat_id}")
52
+
53
+ Note:
54
+ This handler triggers when the bot is started by a user,
55
+ typically when they first interact with the bot or use a /start command.
56
+ The chat ID is available in `update.chat_id`.
57
+ """
58
+ def decorator(func: Callable) -> Callable:
59
+ async def wrapper(
60
+ client: "rubigram.Client",
61
+ update: "rubigram.types.Update"
62
+ ):
63
+ if filters is None or await filters(client, update):
64
+ await func(client, update)
65
+ return True
66
+ return False
67
+
68
+ self.started_bot_handlers.append(wrapper)
69
+ return func
70
+ return decorator
@@ -0,0 +1,65 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Callable
7
+ import rubigram
8
+
9
+
10
+ class OnStop:
11
+ def on_stop(self: "rubigram.Client"):
12
+ """
13
+ **Decorator for handling application shutdown events.**
14
+ `@client.on_stop()`
15
+
16
+ This decorator registers a function to be executed when the
17
+ Rubigram client is shutting down. This is useful for cleanup tasks,
18
+ closing database connections, saving state, or performing any
19
+ cleanup required before the bot stops completely.
20
+
21
+ Returns:
22
+ Callable: The decorator function.
23
+
24
+ Example:
25
+ .. code-block:: python
26
+
27
+ # Cleanup resources on shutdown
28
+ @client.on_stop()
29
+ async def cleanup_resources(client):
30
+ # Close database connections
31
+ # Save bot state
32
+ # Clean up temporary files
33
+ print("Resources cleaned up successfully!")
34
+
35
+ # Send shutdown notification
36
+ @client.on_stop()
37
+ async def send_shutdown_notification(client):
38
+ await client.send_message(
39
+ "b0ADMIN_USER_ID",
40
+ "Bot is shutting down for maintenance."
41
+ )
42
+ print("Shutdown notification sent!")
43
+
44
+ # Backup data before shutdown
45
+ @client.on_stop()
46
+ async def backup_data(client):
47
+ # Backup user data
48
+ # Save logs
49
+ # Export statistics
50
+ print("Data backup completed!")
51
+
52
+ Note:
53
+ - This handler runs only once when the client is shutting down
54
+ - Multiple shutdown handlers can be registered
55
+ - All shutdown handlers run before the client completely stops
56
+ - The client parameter provides access to all bot methods until shutdown completes
57
+ - Useful for graceful shutdown and resource cleanup
58
+ """
59
+ def decorator(func: Callable) -> Callable:
60
+ async def wrapper(client):
61
+ return await func(client)
62
+
63
+ self.stop_handlers.append(wrapper)
64
+ return func
65
+ return decorator
@@ -0,0 +1,70 @@
1
+ # RubigramClient - Rubika API library for python
2
+ # Copyright (C) 2025-present Javad <https://github.com/DevJavad>
3
+ # Github - https://github.com/DevJavad/rubigram
4
+
5
+
6
+ from typing import Optional, Callable
7
+ from rubigram.filters import Filter
8
+ import rubigram
9
+
10
+
11
+ class OnStoppedBot:
12
+ def on_stopped_bot(
13
+ self: "rubigram.Client",
14
+ filters: Optional["Filter"] = None
15
+ ):
16
+ """
17
+ **Decorator for handling bot stop events.**
18
+ `@client.on_stop_bot(filters.private)`
19
+
20
+ This decorator registers a function to handle bot stop events
21
+ that match the specified filters. If no filters are provided,
22
+ all bot stop events will be handled.
23
+
24
+ Args:
25
+ filters (`Optional[Filter]`):
26
+ Filter to determine which bot stop events should be handled.
27
+ If None, all bot stop events will be processed.
28
+
29
+ Returns:
30
+ Callable: The decorator function.
31
+
32
+ Example:
33
+ .. code-block:: python
34
+
35
+ # Handle bot stops in private chats only
36
+ @client.on_stop_bot(filters.private)
37
+ async def handle_private_stop(client, update):
38
+ await client.send_message(
39
+ update.chat_id,
40
+ "Sorry to see you go! You can always start me again with /start."
41
+ )
42
+
43
+ # Handle bot stops from specific users
44
+ @client.on_stop_bot(filters.chat(["b0123456789", "b0987654321"]))
45
+ async def handle_specific_users_stop(client, update):
46
+ print(f"Bot stopped by user: {update.chat_id}")
47
+
48
+ # Handle all bot stop events (no filter)
49
+ @client.on_stop_bot()
50
+ async def handle_all_stops(client, update):
51
+ print(f"Bot stopped in chat: {update.chat_id}")
52
+
53
+ Note:
54
+ This handler triggers when the bot is stopped by a user,
55
+ typically when they block the bot or use a /stop command.
56
+ The chat ID is available in `update.chat_id`.
57
+ """
58
+ def decorator(func: Callable) -> Callable:
59
+ async def wrapper(
60
+ client: "rubigram.Client",
61
+ update: "rubigram.types.Update"
62
+ ):
63
+ if filters is None or await filters(client, update):
64
+ await func(client, update)
65
+ return True
66
+ return False
67
+
68
+ self.stopped_bot_handlers.append(wrapper)
69
+ return func
70
+ return decorator