rubkey 1.0.2__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.
rubkey/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from .bot import Bot as Rubkey
2
+ from .types import Message
3
+ from .keyboards import Keypad, KeyButton
4
+
5
+ __version__ = "1.0.2"
6
+ __author__ = "taha ansarianpour"
7
+ __all__ = ["Rubkey", "Message", "Keypad", "KeyButton"]
rubkey/bot.py ADDED
@@ -0,0 +1,221 @@
1
+ import requests
2
+ import json
3
+ import time
4
+ import threading
5
+ import os
6
+ from .types import Message
7
+
8
+ class Bot:
9
+ def __init__(self, token, session_file=None):
10
+ self.token = token
11
+ self.api_url = f"https://botapi.rubika.ir/v3/{token}"
12
+ self.handlers = {}
13
+ self.button_handlers = {}
14
+ self.default_handler = None
15
+ self._running = False
16
+ self.session_file = session_file
17
+ self.offset = None
18
+ self.ADMIN_ID = None
19
+ self.ADMIN_PASSWORD = None
20
+ self.admin_handlers = {}
21
+ self.admin_button_handlers = {}
22
+ self.admin_default_handler = None
23
+ self.admin_verified = set()
24
+ if session_file:
25
+ self.session_file = session_file if session_file.endswith('.rubkey') else f"{session_file}.rubkey"
26
+ self._load_offset()
27
+ def _api(self, method, data=None):
28
+ if data is None:
29
+ data = {}
30
+ try:
31
+ r = requests.post(f"{self.api_url}/{method}", json=data, timeout=30)
32
+ if r.status_code == 200 and r.text.strip():
33
+ return r.json()
34
+ except Exception as e:
35
+ print(f"API Error: {e}")
36
+ return {}
37
+ def _load_offset(self):
38
+ if self.session_file and os.path.exists(self.session_file):
39
+ try:
40
+ with open(self.session_file, "r") as f:
41
+ data = f.read().strip()
42
+ self.offset = data if data else None
43
+ except:
44
+ pass
45
+ def _save_offset(self):
46
+ if self.session_file and self.offset:
47
+ try:
48
+ with open(self.session_file, "w") as f:
49
+ f.write(str(self.offset))
50
+ except:
51
+ pass
52
+ def _is_admin(self, msg):
53
+ if self.ADMIN_ID:
54
+ if msg.sender_id == self.ADMIN_ID or msg.chat_id == self.ADMIN_ID:
55
+ return True
56
+ if self.ADMIN_PASSWORD:
57
+ if msg.sender_id in self.admin_verified:
58
+ return True
59
+ return False
60
+ def get_updates(self, limit=10):
61
+ body = {"limit": limit}
62
+ if self.offset:
63
+ body["offset_id"] = self.offset
64
+ result = self._api("getUpdates", body)
65
+ data = result.get("data", result)
66
+ if data.get("next_offset_id"):
67
+ self.offset = data["next_offset_id"]
68
+ self._save_offset()
69
+ updates = []
70
+ for update in data.get("updates", []):
71
+ msg_data = update.get("new_message") or update.get("updated_message")
72
+ if msg_data:
73
+ msg_data["chat_id"] = update.get("chat_id", "")
74
+ updates.append(Message(msg_data, bot=self))
75
+ return updates
76
+ def poll_updates(self, limit=10, sleep=1):
77
+ print("Please wait...")
78
+ if self.offset:
79
+ while True:
80
+ result = self._api("getUpdates", {"limit": 50, "offset_id": self.offset})
81
+ data = result.get("data", result)
82
+ updates = data.get("updates", [])
83
+ if not updates:
84
+ break
85
+ if data.get("next_offset_id"):
86
+ self.offset = data["next_offset_id"]
87
+ else:
88
+ break
89
+ else:
90
+ result = self._api("getUpdates", {"limit": 1})
91
+ data = result.get("data", result)
92
+ if data.get("next_offset_id"):
93
+ self.offset = data["next_offset_id"]
94
+ while True:
95
+ result = self._api("getUpdates", {"limit": 50, "offset_id": self.offset})
96
+ data = result.get("data", result)
97
+ updates = data.get("updates", [])
98
+ if not updates:
99
+ break
100
+ if data.get("next_offset_id"):
101
+ self.offset = data["next_offset_id"]
102
+ else:
103
+ break
104
+ self._save_offset()
105
+ print("Rubkey bot run...")
106
+ self._running = True
107
+ while self._running:
108
+ try:
109
+ updates = self.get_updates(limit=limit)
110
+ for update in updates:
111
+ threading.Thread(target=self._process_message, args=(update._data,), daemon=True).start()
112
+ time.sleep(sleep)
113
+ except KeyboardInterrupt:
114
+ print("\nBot stopped.")
115
+ break
116
+ except Exception as e:
117
+ print(f"Error: {e}")
118
+ time.sleep(2)
119
+ def send_message(self, chat_id, text, keypad=None, reply_to=None):
120
+ data = {"chat_id": chat_id, "text": text}
121
+ if keypad:
122
+ data["chat_keypad_type"] = "New"
123
+ data["chat_keypad"] = keypad.to_dict()
124
+ if reply_to:
125
+ data["reply_to_message_id"] = reply_to
126
+ result = self._api("sendMessage", data)
127
+ return result.get("data", result)
128
+ def edit_message(self, chat_id, message_id, text):
129
+ result = self._api("editMessageText", {"chat_id": chat_id, "message_id": message_id, "text": text})
130
+ return result.get("data", result)
131
+ def delete_message(self, chat_id, message_id):
132
+ result = self._api("deleteMessage", {"chat_id": chat_id, "message_id": message_id})
133
+ return result.get("data", result)
134
+ def send_poll(self, chat_id, question, options):
135
+ result = self._api("sendPoll", {"chat_id": chat_id, "question": question, "options": options})
136
+ return result.get("data", result)
137
+ def get_chat(self, chat_id):
138
+ result = self._api("getChat", {"chat_id": chat_id})
139
+ return result.get("data", result)
140
+ def get_me(self):
141
+ result = self._api("getMe", {})
142
+ return result.get("data", result)
143
+ def remove_keypad(self, chat_id):
144
+ result = self._api("editChatKeypad", {"chat_id": chat_id, "chat_keypad_type": "Remove"})
145
+ return result.get("data", result)
146
+ def edit_chat_keypad(self, chat_id, keypad):
147
+ result = self._api("editChatKeypad", {"chat_id": chat_id, "chat_keypad_type": "New", "chat_keypad": keypad.to_dict()})
148
+ return result.get("data", result)
149
+ def set_commands(self, commands):
150
+ result = self._api("setCommands", {"bot_commands": commands})
151
+ return result.get("data", result)
152
+ def delete_commands(self):
153
+ result = self._api("setCommands", {"bot_commands": []})
154
+ return result.get("data", result)
155
+ def command(self, name):
156
+ def decorator(func):
157
+ self.handlers[name] = func
158
+ return func
159
+ return decorator
160
+ def on_message(self):
161
+ def decorator(func):
162
+ self.default_handler = func
163
+ return func
164
+ return decorator
165
+ def on_button(self, button_id):
166
+ def decorator(func):
167
+ self.button_handlers[button_id] = func
168
+ return func
169
+ return decorator
170
+ def admin_command(self, name):
171
+ def decorator(func):
172
+ self.admin_handlers[name] = func
173
+ return func
174
+ return decorator
175
+ def admin_on_message(self):
176
+ def decorator(func):
177
+ self.admin_default_handler = func
178
+ return func
179
+ return decorator
180
+ def admin_on_button(self, button_id):
181
+ def decorator(func):
182
+ self.admin_button_handlers[button_id] = func
183
+ return func
184
+ return decorator
185
+ def _process_message(self, msg_data):
186
+ msg = Message(msg_data, bot=self)
187
+ text = (msg.text or "").strip()
188
+ button_id = msg.button_id
189
+ if self.ADMIN_PASSWORD and text == self.ADMIN_PASSWORD:
190
+ self.admin_verified.add(msg.sender_id)
191
+ return
192
+ if self._is_admin(msg):
193
+ if button_id and button_id in self.admin_button_handlers:
194
+ self.admin_button_handlers[button_id](msg)
195
+ return
196
+ if text.startswith("/"):
197
+ cmd = text[1:].split()[0]
198
+ if cmd in self.admin_handlers:
199
+ self.admin_handlers[cmd](msg)
200
+ return
201
+ if text in self.admin_handlers:
202
+ self.admin_handlers[text](msg)
203
+ return
204
+ if self.admin_default_handler:
205
+ self.admin_default_handler(msg)
206
+ return
207
+ if button_id and button_id in self.button_handlers:
208
+ self.button_handlers[button_id](msg)
209
+ return
210
+ if text.startswith("/"):
211
+ cmd = text[1:].split()[0]
212
+ if cmd in self.handlers:
213
+ self.handlers[cmd](msg)
214
+ return
215
+ if text in self.handlers:
216
+ self.handlers[text](msg)
217
+ return
218
+ if self.default_handler:
219
+ self.default_handler(msg)
220
+ def run(self):
221
+ self.poll_updates()
rubkey/keyboards.py ADDED
@@ -0,0 +1,26 @@
1
+ class KeyButton:
2
+ def __init__(self, button_id, text, button_type="Simple"):
3
+ self.id = button_id
4
+ self.text = text
5
+ self.type = button_type
6
+
7
+ def to_dict(self):
8
+ return {"id": self.id, "type": self.type, "button_text": self.text}
9
+
10
+
11
+ class Keypad:
12
+ def __init__(self, resize=True, one_time=False):
13
+ self.rows = []
14
+ self.resize = resize
15
+ self.one_time = one_time
16
+
17
+ def add_row(self, *buttons):
18
+ self.rows.append(list(buttons))
19
+ return self
20
+
21
+ def to_dict(self):
22
+ return {
23
+ "rows": [{"buttons": [btn.to_dict() for btn in row]} for row in self.rows],
24
+ "resize_keyboard": self.resize,
25
+ "one_time_keyboard": self.one_time
26
+ }
rubkey/types.py ADDED
@@ -0,0 +1,31 @@
1
+ class Message:
2
+ def __init__(self, data, bot=None):
3
+ self._data = data
4
+ self._bot = bot
5
+ self.chat_id = data.get("chat_id", "")
6
+ self.text = data.get("text", "")
7
+ self.message_id = data.get("message_id", "")
8
+ self.sender_id = data.get("sender_id", "")
9
+ self.time = data.get("time", 0)
10
+ self.is_edited = data.get("is_edited", False)
11
+ self.poll = data.get("poll")
12
+ self.location = data.get("location")
13
+ self.contact = data.get("contact_message")
14
+ self.aux_data = data.get("aux_data", {})
15
+ self.reply_to_message_id = data.get("reply_to_message_id", "")
16
+ @property
17
+ def button_id(self):
18
+ return self.aux_data.get("button_id", "") if self.aux_data else ""
19
+ def reply(self, text, keypad=None):
20
+ if self._bot:
21
+ result = self._bot.send_message(self.chat_id, text, keypad=keypad, reply_to=self.message_id)
22
+ result["chat_id"] = self.chat_id
23
+ return Message(result, bot=self._bot)
24
+ def edit(self, text):
25
+ if self._bot:
26
+ return self._bot.edit_message(self.chat_id, self.message_id, text)
27
+ def delete(self):
28
+ if self._bot:
29
+ return self._bot.delete_message(self.chat_id, self.message_id)
30
+ def __repr__(self):
31
+ return f"<Message id={self.message_id} text='{str(self.text)[:30]}'>"
@@ -0,0 +1,400 @@
1
+ Metadata-Version: 2.4
2
+ Name: rubkey
3
+ Version: 1.0.2
4
+ Summary: Rubika Bot API library - Simple and powerful bot framework for Rubika messenger
5
+ Author: taha ansarianpour
6
+ Author-email: codetansarian@gmail.com
7
+ License: MIT
8
+ Keywords: rubika bot rubkey messenger api
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: requests>=2.20.0
24
+ Dynamic: author
25
+ Dynamic: author-email
26
+ Dynamic: classifier
27
+ Dynamic: description
28
+ Dynamic: description-content-type
29
+ Dynamic: keywords
30
+ Dynamic: license
31
+ Dynamic: license-file
32
+ Dynamic: requires-dist
33
+ Dynamic: requires-python
34
+ Dynamic: summary
35
+
36
+ Rubika Bot API Libraryary for Rubika Bot API with all features.
37
+
38
+
39
+ Quick Start
40
+
41
+ ```python
42
+ from rubkey import Rubkey
43
+
44
+ bot = Rubkey("YOUR_BOT_TOKEN")
45
+
46
+ for update in bot.poll_updates():
47
+ if update.new_message and update.new_message.text == "/start":
48
+ bot.send_message(update.chat_id, "Hello!")
49
+ ```
50
+
51
+ Features
52
+
53
+ · Send text, poll, location, contact, file
54
+ · Inline and chat keypad with all button types (Selection, Calendar, NumberPicker, StringPicker, Textbox, Location, Camera, Gallery, File, Audio, Link, AskMyPhoneNumber, AskMyLocation, Barcode)
55
+ · Metadata for text formatting (Bold, Italic, Mono, Underline, Strike, Spoiler, Link, Mention, Pre, Quote)
56
+ · Group management (ban, unban, delete messages)
57
+ · Polling updates with auto offset management
58
+ · Edit messages and keypads
59
+ · Forward messages
60
+ · Get chat information
61
+ · Upload and send files
62
+ · Webhook support
63
+ · Auto skip old messages on start
64
+
65
+ Examples
66
+
67
+ Send simple message
68
+
69
+ ```python
70
+ from rubkey import Rubkey
71
+
72
+ bot = Rubkey("YOUR_BOT_TOKEN")
73
+ bot.send_message("chat_id", "Hello World")
74
+ ```
75
+
76
+ Send message with inline keypad
77
+
78
+ ```python
79
+ from rubkey import Rubkey, Button, InlineKeypad
80
+ from rubkey.enums import ButtonType
81
+
82
+ bot = Rubkey("YOUR_BOT_TOKEN")
83
+
84
+ button1 = Button("btn1", "Click Me", ButtonType.SIMPLE)
85
+ button2 = Button("btn2", "Cancel", ButtonType.SIMPLE)
86
+
87
+ keypad = InlineKeypad().add_row(button1, button2)
88
+
89
+ bot.send_message("chat_id", "Choose an option:", inline_keypad=keypad)
90
+ ```
91
+
92
+ Send message with metadata formatting
93
+
94
+ ```python
95
+ from rubkey import Rubkey, Metadata, MetadataPart
96
+ from rubkey.enums import MetadataType
97
+
98
+ bot = Rubkey("YOUR_BOT_TOKEN")
99
+
100
+ metadata = Metadata()
101
+ metadata.add_part(MetadataPart(MetadataType.BOLD, 0, 5))
102
+ metadata.add_part(MetadataPart(MetadataType.ITALIC, 6, 4))
103
+
104
+ bot.send_message("chat_id", "Hello Dear User", metadata=metadata)
105
+ ```
106
+
107
+ Send poll
108
+
109
+ ```python
110
+ from rubkey import Rubkey
111
+
112
+ bot = Rubkey("YOUR_BOT_TOKEN")
113
+ bot.send_poll("chat_id", "Do you like Rubkey?", ["Yes", "No", "Maybe"])
114
+ ```
115
+
116
+ Send location
117
+
118
+ ```python
119
+ from rubkey import Rubkey
120
+
121
+ bot = Rubkey("YOUR_BOT_TOKEN")
122
+ bot.send_location("chat_id", "35.6892", "51.3890")
123
+ ```
124
+
125
+ Send contact
126
+
127
+ ```python
128
+ from rubkey import Rubkey
129
+
130
+ bot = Rubkey("YOUR_BOT_TOKEN")
131
+ bot.send_contact("chat_id", "John", "09123456789", "Doe")
132
+ ```
133
+
134
+ Send file
135
+
136
+ ```python
137
+ from rubkey import Rubkey
138
+ from rubkey.enums import FileType
139
+
140
+ bot = Rubkey("YOUR_BOT_TOKEN")
141
+
142
+ result = bot.request_send_file(FileType.IMAGE)
143
+ upload_url = result.get("upload_url")
144
+
145
+ with open("photo.jpg", "rb") as f:
146
+ files = {"file": f}
147
+ response = requests.post(upload_url, files=files)
148
+ file_data = response.json().get("data", {})
149
+ file_id = file_data.get("file_id")
150
+
151
+ bot.send_file("chat_id", file_id, "Check this photo!")
152
+ ```
153
+
154
+ Group management
155
+
156
+ ```python
157
+ from rubkey import Rubkey
158
+
159
+ bot = Rubkey("YOUR_BOT_TOKEN")
160
+
161
+ bot.ban_chat_member("group_id", "user_id")
162
+ bot.unban_chat_member("group_id", "user_id")
163
+ bot.delete_message("group_id", "message_id")
164
+ ```
165
+
166
+ Edit message
167
+
168
+ ```python
169
+ from rubkey import Rubkey
170
+
171
+ bot = Rubkey("YOUR_BOT_TOKEN")
172
+ bot.edit_message_text("chat_id", "message_id", "New text content")
173
+ ```
174
+
175
+ Forward message
176
+
177
+ ```python
178
+ from rubkey import Rubkey
179
+
180
+ bot = Rubkey("YOUR_BOT_TOKEN")
181
+ bot.forward_message("from_chat_id", "to_chat_id", "message_id")
182
+ ```
183
+
184
+ Set bot commands
185
+
186
+ ```python
187
+ from rubkey import Rubkey, BotCommand
188
+
189
+ bot = Rubkey("YOUR_BOT_TOKEN")
190
+
191
+ commands = [
192
+ BotCommand("start", "Start the bot"),
193
+ BotCommand("help", "Get help"),
194
+ BotCommand("about", "About this bot")
195
+ ]
196
+
197
+ bot.set_commands(commands)
198
+ ```
199
+
200
+ Get updates manually
201
+
202
+ ```python
203
+ from rubkey import Rubkey
204
+
205
+ bot = Rubkey("YOUR_BOT_TOKEN")
206
+
207
+ updates = bot.get_updates(limit=10)
208
+ for update in updates:
209
+ if update.new_message:
210
+ print(update.new_message.text)
211
+ ```
212
+
213
+ Poll updates continuously
214
+
215
+ ```python
216
+ from rubkey import Rubkey
217
+
218
+ bot = Rubkey("YOUR_BOT_TOKEN")
219
+
220
+ for update in bot.poll_updates(limit=10, sleep=1):
221
+ if update.new_message:
222
+ msg = update.new_message
223
+ if msg.text == "/start":
224
+ bot.send_message(update.chat_id, "Welcome!")
225
+ ```
226
+
227
+ Advanced Examples
228
+
229
+ Button with selection list
230
+
231
+ ```python
232
+ from rubkey import Rubkey, Button, InlineKeypad
233
+ from rubkey.enums import ButtonType, SelectionType, SelectionSearch, SelectionGet
234
+ from rubkey.keypad import ButtonSelectionItem
235
+
236
+ bot = Rubkey("YOUR_BOT_TOKEN")
237
+
238
+ items = [
239
+ ButtonSelectionItem("Option 1"),
240
+ ButtonSelectionItem("Option 2"),
241
+ ButtonSelectionItem("Option 3")
242
+ ]
243
+
244
+ button = Button("select_btn", "Choose Option", ButtonType.SELECTION)
245
+ button.set_selection(
246
+ selection_id="menu_1",
247
+ items=[item.to_dict() for item in items],
248
+ search_type=SelectionSearch.LOCAL,
249
+ get_type=SelectionGet.LOCAL,
250
+ is_multi_selection=False,
251
+ columns_count="1",
252
+ title="Select an option"
253
+ )
254
+
255
+ keypad = InlineKeypad().add_row(button)
256
+ bot.send_message("chat_id", "Please select:", inline_keypad=keypad)
257
+ ```
258
+
259
+ Button with calendar
260
+
261
+ ```python
262
+ from rubkey import Rubkey, Button, InlineKeypad
263
+ from rubkey.enums import ButtonType, CalendarType
264
+
265
+ bot = Rubkey("YOUR_BOT_TOKEN")
266
+
267
+ button = Button("date_btn", "Select Date", ButtonType.CALENDAR)
268
+ button.set_calendar(
269
+ title="Choose a date",
270
+ default_value="1400-01-01",
271
+ calendar_type=CalendarType.PERSIAN,
272
+ min_year="1390",
273
+ max_year="1410"
274
+ )
275
+
276
+ keypad = InlineKeypad().add_row(button)
277
+ bot.send_message("chat_id", "Select your birth date:", inline_keypad=keypad)
278
+ ```
279
+
280
+ Button with number picker
281
+
282
+ ```python
283
+ from rubkey import Rubkey, Button, InlineKeypad
284
+ from rubkey.enums import ButtonType
285
+
286
+ bot = Rubkey("YOUR_BOT_TOKEN")
287
+
288
+ button = Button("num_btn", "Select Quantity", ButtonType.NUMBER_PICKER)
289
+ button.set_number_picker(
290
+ title="Choose quantity",
291
+ min_value=1,
292
+ max_value=100,
293
+ default_value=10
294
+ )
295
+
296
+ keypad = InlineKeypad().add_row(button)
297
+ bot.send_message("chat_id", "How many items?", inline_keypad=keypad)
298
+ ```
299
+
300
+ Button with textbox
301
+
302
+ ```python
303
+ from rubkey import Rubkey, Button, InlineKeypad
304
+ from rubkey.enums import ButtonType, TextboxLineType, TextboxKeypadType
305
+
306
+ bot = Rubkey("YOUR_BOT_TOKEN")
307
+
308
+ button = Button("text_btn", "Write Message", ButtonType.TEXTBOX)
309
+ button.set_textbox(
310
+ title="Enter your message",
311
+ place_holder="Type here...",
312
+ default_value="Hello",
313
+ type_line=TextboxLineType.MULTI_LINE,
314
+ type_keypad=TextboxKeypadType.STRING
315
+ )
316
+
317
+ keypad = InlineKeypad().add_row(button)
318
+ bot.send_message("chat_id", "Please write your message:", inline_keypad=keypad)
319
+ ```
320
+
321
+ Button with location picker
322
+
323
+ ```python
324
+ from rubkey import Rubkey, Button, InlineKeypad, Location
325
+ from rubkey.enums import ButtonType, LocationType
326
+
327
+ bot = Rubkey("YOUR_BOT_TOKEN")
328
+
329
+ default_location = Location({"latitude": "35.6892", "longitude": "51.3890"})
330
+
331
+ button = Button("loc_btn", "Select Location", ButtonType.LOCATION)
332
+ button.set_location(
333
+ title="Pick a location",
334
+ default_pointer_location=default_location,
335
+ default_map_location=default_location,
336
+ location_type=LocationType.PICKER
337
+ )
338
+
339
+ keypad = InlineKeypad().add_row(button)
340
+ bot.send_message("chat_id", "Please select your location:", inline_keypad=keypad)
341
+ ```
342
+
343
+ Chat keypad (keyboard at bottom)
344
+
345
+ ```python
346
+ from rubkey import Rubkey, Button, ChatKeypad
347
+ from rubkey.enums import ButtonType
348
+
349
+ bot = Rubkey("YOUR_BOT_TOKEN")
350
+
351
+ button1 = Button("btn1", "Option A", ButtonType.SIMPLE)
352
+ button2 = Button("btn2", "Option B", ButtonType.SIMPLE)
353
+ button3 = Button("btn3", "Option C", ButtonType.SIMPLE)
354
+
355
+ keypad = ChatKeypad(resize_keyboard=True, one_time_keyboard=False)
356
+ keypad.add_row(button1, button2).add_row(button3)
357
+
358
+ bot.send_message("chat_id", "Choose an option:", chat_keypad=keypad, chat_keypad_type="New")
359
+ ```
360
+
361
+ Remove chat keypad
362
+
363
+ ```python
364
+ from rubkey import Rubkey
365
+
366
+ bot = Rubkey("YOUR_BOT_TOKEN")
367
+ bot.remove_chat_keypad("chat_id")
368
+ ```
369
+
370
+ API Reference
371
+
372
+ Rubkey Class
373
+
374
+ Method Description
375
+ get_me() Get bot information
376
+ get_updates(limit=10) Get new updates
377
+ poll_updates(limit=10, sleep=1) Generator for continuous polling
378
+ send_message() Send text message with optional keypad and metadata
379
+ send_poll() Send poll
380
+ send_location() Send location
381
+ send_contact() Send contact
382
+ send_file() Send file
383
+ request_send_file(file_type) Get upload URL for file
384
+ upload_file(upload_url, file_path) Upload file to server
385
+ get_file(file_id) Get file download URL
386
+ get_chat(chat_id) Get chat information
387
+ delete_message(chat_id, message_id) Delete message
388
+ edit_message_text(chat_id, message_id, text) Edit message text
389
+ edit_message_keypad(chat_id, message_id, inline_keypad) Edit message keypad
390
+ forward_message(from_chat_id, to_chat_id, message_id) Forward message
391
+ ban_chat_member(chat_id, user_id) Ban user from group
392
+ unban_chat_member(chat_id, user_id) Unban user from group
393
+ set_commands(commands) Set bot commands
394
+ edit_chat_keypad(chat_id, chat_keypad, chat_keypad_type) Edit chat keypad
395
+ remove_chat_keypad(chat_id) Remove chat keypad
396
+ update_bot_endpoints(url, endpoint_type) Update webhook endpoints
397
+
398
+ License
399
+
400
+ MIT License (c) 2026 taha ansarianpour
@@ -0,0 +1,9 @@
1
+ rubkey/__init__.py,sha256=zjSWohDUvoWdBuSqg5YAeGtEVpXAhYVaSN6cJ0wQO5M,209
2
+ rubkey/bot.py,sha256=Bv41kmwgNEwVEJK3FDHUkTEimFPtG87pbijEAIRB5Ww,8738
3
+ rubkey/keyboards.py,sha256=S86YkTwpkkA040dmOVI9-cuGM5EpMS78Fa4vDQf8r7U,754
4
+ rubkey/types.py,sha256=y4044kKhnazhYmVHjAHmLEpjUZsm-ShHA8w92ZwBB1k,1367
5
+ rubkey-1.0.2.dist-info/licenses/LICENSE,sha256=TCZw423S9jZcqyB0Xwq1zYae0-S9XOSRHLYFutHuORk,1073
6
+ rubkey-1.0.2.dist-info/METADATA,sha256=gtLU-7KmdbC6amSDW9D1nqOMfhBphYSmfLdvwHFrKdM,10101
7
+ rubkey-1.0.2.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
8
+ rubkey-1.0.2.dist-info/top_level.txt,sha256=I4H5GVjU4LRf8wxUkeUqZB2zt2yd1gJ1SqXzxMNv9zw,7
9
+ rubkey-1.0.2.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 taha ansarianpour
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ rubkey