PyRubikaBotAPI 1.0.0__tar.gz → 1.0.1__tar.gz
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.
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PKG-INFO +5 -14
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PyRubikaBotAPI.egg-info/PKG-INFO +5 -14
- pyrubikabotapi-1.0.1/README.md +31 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/__init__.py +92 -26
- pyrubikabotapi-1.0.1/rubibot/exceptions.py +14 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/rubika_api.py +0 -1
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/types.py +7 -14
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/updates.py +17 -6
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/setup.py +2 -2
- pyrubikabotapi-1.0.0/README.md +0 -40
- pyrubikabotapi-1.0.0/rubibot/exceptions.py +0 -14
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/LICENCE +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PyRubikaBotAPI.egg-info/SOURCES.txt +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PyRubikaBotAPI.egg-info/dependency_links.txt +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PyRubikaBotAPI.egg-info/requires.txt +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/PyRubikaBotAPI.egg-info/top_level.txt +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/pyproject.toml +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/metadata.py +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/rubibot/parse.py +0 -0
- {pyrubikabotapi-1.0.0 → pyrubikabotapi-1.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyRubikaBotAPI
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: A Python library with a simple and familiar interface for working with the official Rubika bot API
|
|
5
5
|
Home-page: https://github.com/alireza-sadeghian/PyRubikaBotAPI
|
|
6
6
|
Author: Alireza Sadeghian
|
|
@@ -9,14 +9,14 @@ License: MIT
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENCE
|
|
15
15
|
Requires-Dist: requests
|
|
16
16
|
|
|
17
17
|
# PyRubikaBotAPI
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
کتابخانه قدرتمند و آشنا برای ساخت ربات های تخصصی روبیکا
|
|
20
20
|
|
|
21
21
|
## نصب
|
|
22
22
|
```bash
|
|
@@ -38,17 +38,8 @@ def start(message):
|
|
|
38
38
|
bot.polling()
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@bot.message_handler(content_types=['file'])
|
|
44
|
-
def handle(msg):
|
|
45
|
-
file_id = msg.file.id
|
|
46
|
-
file_url = bot.get_file(file_id)
|
|
47
|
-
file = bot.download_file(file_url)
|
|
48
|
-
with open('file.format', 'wb') as f
|
|
49
|
-
f.write(file)
|
|
50
|
-
# استفاده از فایل ارسالی
|
|
51
|
-
```
|
|
41
|
+
برای استفاده دقیقتر حتما مستندات رو مطالعه بفرمایید و یا برای دریافت سورس کد ها
|
|
42
|
+
و مثال ها به کانال روبیکای ما سر بزنید
|
|
52
43
|
|
|
53
44
|
## مستندات:
|
|
54
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyRubikaBotAPI
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: A Python library with a simple and familiar interface for working with the official Rubika bot API
|
|
5
5
|
Home-page: https://github.com/alireza-sadeghian/PyRubikaBotAPI
|
|
6
6
|
Author: Alireza Sadeghian
|
|
@@ -9,14 +9,14 @@ License: MIT
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENCE
|
|
15
15
|
Requires-Dist: requests
|
|
16
16
|
|
|
17
17
|
# PyRubikaBotAPI
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
کتابخانه قدرتمند و آشنا برای ساخت ربات های تخصصی روبیکا
|
|
20
20
|
|
|
21
21
|
## نصب
|
|
22
22
|
```bash
|
|
@@ -38,17 +38,8 @@ def start(message):
|
|
|
38
38
|
bot.polling()
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@bot.message_handler(content_types=['file'])
|
|
44
|
-
def handle(msg):
|
|
45
|
-
file_id = msg.file.id
|
|
46
|
-
file_url = bot.get_file(file_id)
|
|
47
|
-
file = bot.download_file(file_url)
|
|
48
|
-
with open('file.format', 'wb') as f
|
|
49
|
-
f.write(file)
|
|
50
|
-
# استفاده از فایل ارسالی
|
|
51
|
-
```
|
|
41
|
+
برای استفاده دقیقتر حتما مستندات رو مطالعه بفرمایید و یا برای دریافت سورس کد ها
|
|
42
|
+
و مثال ها به کانال روبیکای ما سر بزنید
|
|
52
43
|
|
|
53
44
|
## مستندات:
|
|
54
45
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# PyRubikaBotAPI
|
|
2
|
+
|
|
3
|
+
کتابخانه قدرتمند و آشنا برای ساخت ربات های تخصصی روبیکا
|
|
4
|
+
|
|
5
|
+
## نصب
|
|
6
|
+
```bash
|
|
7
|
+
pip install PyRubikaBotAPI
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## مثال ساده
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from rubibot import RubiBot
|
|
15
|
+
|
|
16
|
+
bot = RubiBot("YOUR_TOKEN")
|
|
17
|
+
|
|
18
|
+
@bot.message_handler(commands=["start"])
|
|
19
|
+
def start(message):
|
|
20
|
+
bot.send_message(message.chat_id, "سلام! خوش آمدید!")
|
|
21
|
+
|
|
22
|
+
bot.polling()
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
برای استفاده دقیقتر حتما مستندات رو مطالعه بفرمایید و یا برای دریافت سورس کد ها
|
|
26
|
+
و مثال ها به کانال روبیکای ما سر بزنید
|
|
27
|
+
|
|
28
|
+
## مستندات:
|
|
29
|
+
|
|
30
|
+
Rubika: https://rubika.ir/pyrubikabotapi
|
|
31
|
+
GitHub: https://github.com/alireza-sadeghian/PyRubikaBotAPI
|
|
@@ -47,8 +47,8 @@ class RubiBot:
|
|
|
47
47
|
commands: Optional[List[str]]=None,
|
|
48
48
|
content_types: Optional[List[str]]=None,
|
|
49
49
|
func=None,
|
|
50
|
-
update_types: Optional[List[str]]=None
|
|
51
|
-
|
|
50
|
+
update_types: Optional[List[str]]=None,
|
|
51
|
+
):
|
|
52
52
|
"""
|
|
53
53
|
It is responsible for managing messages received from the user.
|
|
54
54
|
It handles all types of messages such as text, video, Voice, Poll, etc.
|
|
@@ -134,7 +134,7 @@ class RubiBot:
|
|
|
134
134
|
"commands": commands,
|
|
135
135
|
"content_types": content_types,
|
|
136
136
|
"func": func,
|
|
137
|
-
"update_types": update_types
|
|
137
|
+
"update_types": update_types,
|
|
138
138
|
}
|
|
139
139
|
})
|
|
140
140
|
return handler
|
|
@@ -151,12 +151,15 @@ class RubiBot:
|
|
|
151
151
|
return decorator
|
|
152
152
|
|
|
153
153
|
def register_message_handler(self, handler: Callable, **filters):
|
|
154
|
+
for filter in ['commands', 'content_types', 'func', 'update_types']:
|
|
155
|
+
filters.setdefault(filter, None)
|
|
156
|
+
|
|
154
157
|
self._message_handlers.append({
|
|
155
158
|
'handler': handler,
|
|
156
159
|
'filters': filters
|
|
157
160
|
})
|
|
158
161
|
|
|
159
|
-
def register_next_step_message_handler_by_chat_id(self, chat_id: str, handler:
|
|
162
|
+
def register_next_step_message_handler_by_chat_id(self, chat_id: str, handler: Callable):
|
|
160
163
|
""" To register a handler for the next message in a specific chat """
|
|
161
164
|
|
|
162
165
|
if chat_id in self._next_step_message_handlers_by_chat_id:
|
|
@@ -214,8 +217,16 @@ class RubiBot:
|
|
|
214
217
|
res = requests.post(f"{self.BASE_URL}/getUpdates", json=params, timeout=15)
|
|
215
218
|
except Exception as e:
|
|
216
219
|
raise Exception("Error: {}".format(e))
|
|
217
|
-
data = res.json()
|
|
218
|
-
|
|
220
|
+
data: dict = res.json()
|
|
221
|
+
if data.get('status') != 'OK':
|
|
222
|
+
if data["status"] == "INVALID_INPUT":
|
|
223
|
+
raise exceptions.RubiBotInputError(
|
|
224
|
+
"invalid inputs {}".format(data.get('dev_message', ''))
|
|
225
|
+
)
|
|
226
|
+
if data["status"] == "INVALID_ACCESS":
|
|
227
|
+
raise exceptions.RubiBotAccessError("not Access")
|
|
228
|
+
raise exceptions.RubiBotError(data["status"])
|
|
229
|
+
|
|
219
230
|
if not res or res.status_code !=200:
|
|
220
231
|
raise Exception("Error in receiving updates: {}".format(data.get("status")))
|
|
221
232
|
|
|
@@ -228,13 +239,13 @@ class RubiBot:
|
|
|
228
239
|
def __load_offset(self) -> dict:
|
|
229
240
|
if not os.path.exists(self.OFFSET_FILE):
|
|
230
241
|
with open(self.OFFSET_FILE, 'w', encoding="utf-8") as f:
|
|
231
|
-
json.dump({}, f, ensure_ascii=False, indent=4)
|
|
242
|
+
json.dump({self.token: None}, f, ensure_ascii=False, indent=4)
|
|
232
243
|
|
|
233
244
|
with open(self.OFFSET_FILE, "r", encoding="utf-8") as f:
|
|
234
245
|
return json.load(f)
|
|
235
246
|
|
|
236
|
-
def __get_offset(self) -> str:
|
|
237
|
-
return self.__load_offset()
|
|
247
|
+
def __get_offset(self) -> Optional[str]:
|
|
248
|
+
return self.__load_offset().get(self.token)
|
|
238
249
|
|
|
239
250
|
def __save_offset(self, offset_id):
|
|
240
251
|
next_offset_ids = self.__load_offset()
|
|
@@ -286,10 +297,10 @@ class RubiBot:
|
|
|
286
297
|
self.polling(*args, **kwargs)
|
|
287
298
|
except requests.exceptions.JSONDecodeError:
|
|
288
299
|
print('Json Decode Error')
|
|
289
|
-
|
|
300
|
+
time.sleep(1)
|
|
290
301
|
except Exception as e:
|
|
291
302
|
print(f"{e.__class__.__name__}: {e}")
|
|
292
|
-
|
|
303
|
+
time.sleep(1)
|
|
293
304
|
|
|
294
305
|
|
|
295
306
|
def send_message(
|
|
@@ -350,6 +361,10 @@ class RubiBot:
|
|
|
350
361
|
if parse_mode:
|
|
351
362
|
parser = parse_mode()
|
|
352
363
|
text, metadata_list = parser(text)
|
|
364
|
+
|
|
365
|
+
if not metadata_list:
|
|
366
|
+
metadata_list = []
|
|
367
|
+
|
|
353
368
|
text = self._process_metadata(text, *metadata_list)
|
|
354
369
|
|
|
355
370
|
return rubika_api.send_message(self.token, chat_id, text, chat_keypad, inline_keypad,
|
|
@@ -807,6 +822,7 @@ class RubiBot:
|
|
|
807
822
|
if filters["content_types"]:
|
|
808
823
|
if message.get_content_type() not in filters["content_types"]:
|
|
809
824
|
return False
|
|
825
|
+
|
|
810
826
|
|
|
811
827
|
if filters["func"]:
|
|
812
828
|
return filters["func"](message)
|
|
@@ -850,22 +866,25 @@ class RubiBot:
|
|
|
850
866
|
|
|
851
867
|
if isinstance(upd, rubibot.updates.Update):
|
|
852
868
|
message = upd.to_message()
|
|
853
|
-
message
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
869
|
+
if isinstance(message, rubibot.updates.InlineMessage):
|
|
870
|
+
upd = rubibot.updates.InlineUpdate(upd.dict)
|
|
871
|
+
else:
|
|
872
|
+
message.token = self.token
|
|
873
|
+
|
|
874
|
+
if message.type == "NewMessage":
|
|
875
|
+
if message.chat_id in self._next_step_message_handlers_by_chat_id:
|
|
876
|
+
self._next_step_message_handlers_by_chat_id.pop(message.chat_id)(message)
|
|
877
|
+
return
|
|
878
|
+
elif message.sender_id in self._next_step_message_handlers_by_sender_id:
|
|
879
|
+
self._next_step_message_handlers_by_sender_id.pop(message.sender_id)(message)
|
|
880
|
+
return
|
|
881
|
+
|
|
882
|
+
for handler in self._message_handlers:
|
|
883
|
+
if self._test_message_handler(handler, message):
|
|
884
|
+
handler["handler"](message)
|
|
885
|
+
break
|
|
867
886
|
|
|
868
|
-
|
|
887
|
+
if isinstance(upd, rubibot.updates.InlineUpdate):
|
|
869
888
|
message = upd.to_inline_message()
|
|
870
889
|
message.token = self.token
|
|
871
890
|
for handler in self._inline_message_handlers:
|
|
@@ -875,5 +894,52 @@ class RubiBot:
|
|
|
875
894
|
else: raise exceptions.RubiBotValueError("Invalid type for update")
|
|
876
895
|
|
|
877
896
|
|
|
897
|
+
|
|
898
|
+
class GroupBot(RubiBot):
|
|
899
|
+
def __init__(self, token, set_token_env=True):
|
|
900
|
+
super().__init__(token, set_token_env)
|
|
901
|
+
|
|
902
|
+
def command_handler(self, command: str):
|
|
903
|
+
def decorator(handler):
|
|
904
|
+
self.register_message_handler(handler, commands=[command])
|
|
905
|
+
return handler
|
|
906
|
+
return decorator
|
|
907
|
+
|
|
908
|
+
def in_text_handler(self, text: str):
|
|
909
|
+
def decorator(handler):
|
|
910
|
+
self.register_message_handler(
|
|
911
|
+
handler,
|
|
912
|
+
func= lambda m: text in m.text
|
|
913
|
+
)
|
|
914
|
+
return handler
|
|
915
|
+
return decorator
|
|
916
|
+
|
|
917
|
+
def text_equal_handler(self, text: str):
|
|
918
|
+
def decorator(handler):
|
|
919
|
+
self.register_message_handler(
|
|
920
|
+
handler,
|
|
921
|
+
func= lambda m: m.text==text
|
|
922
|
+
)
|
|
923
|
+
return handler
|
|
924
|
+
return decorator
|
|
925
|
+
|
|
926
|
+
def text_startswith_handler(self, text: str):
|
|
927
|
+
def decorator(handler):
|
|
928
|
+
self.register_message_handler(
|
|
929
|
+
handler,
|
|
930
|
+
func= lambda m: m.text.startswith(text)
|
|
931
|
+
)
|
|
932
|
+
return handler
|
|
933
|
+
return decorator
|
|
934
|
+
|
|
935
|
+
def text_endswith_handler(self, text: str):
|
|
936
|
+
def decorator(handler):
|
|
937
|
+
self.register_message_handler(
|
|
938
|
+
handler,
|
|
939
|
+
func= lambda m: m.text.endswith(text)
|
|
940
|
+
)
|
|
941
|
+
return handler
|
|
942
|
+
return decorator
|
|
943
|
+
|
|
878
944
|
# soon...
|
|
879
945
|
# This is not the end of our work... 😎
|
|
@@ -281,7 +281,7 @@ class KeypadTextboxButton(BaseKeypadButton):
|
|
|
281
281
|
dic['button_textbox']['default_value'] = self.default_value
|
|
282
282
|
if self.title:
|
|
283
283
|
dic['button_textbox']['title'] = self.title
|
|
284
|
-
|
|
284
|
+
|
|
285
285
|
return dic
|
|
286
286
|
|
|
287
287
|
class KeypadRow:
|
|
@@ -293,16 +293,12 @@ class KeypadRow:
|
|
|
293
293
|
self.btns.append(btn.to_dict())
|
|
294
294
|
return self
|
|
295
295
|
|
|
296
|
-
def remove(self,
|
|
297
|
-
if isinstance(
|
|
298
|
-
for btn in self.btns:
|
|
299
|
-
if btn.id ==
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return buttton
|
|
303
|
-
if isinstance(btn_or_btn_id, KeypadSimpleButton):
|
|
304
|
-
return self.btns.pop(btn_or_btn_id)
|
|
305
|
-
|
|
296
|
+
def remove(self, btn_id):
|
|
297
|
+
if isinstance(btn_id, str):
|
|
298
|
+
for i, btn in enumerate(self.btns):
|
|
299
|
+
if btn.get('id') == btn_id:
|
|
300
|
+
return self.btns.pop(i)
|
|
301
|
+
return None
|
|
306
302
|
|
|
307
303
|
def to_dict(self):
|
|
308
304
|
return {"buttons": self.btns}
|
|
@@ -319,9 +315,6 @@ class BaseKeypad:
|
|
|
319
315
|
for row in rows:
|
|
320
316
|
self.rows.append(row.to_dict())
|
|
321
317
|
return self
|
|
322
|
-
|
|
323
|
-
def remove(self, row):
|
|
324
|
-
return self.rows.pop(row)
|
|
325
318
|
|
|
326
319
|
def clear(self):
|
|
327
320
|
self.rows = []
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
from typing import Optional
|
|
1
2
|
from rubibot import types
|
|
2
3
|
from rubibot import rubika_api
|
|
3
4
|
import json, os
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class BaseUpdate:
|
|
7
|
-
def __init__(self, type: str, chat_id: str, update_time: str):
|
|
8
|
+
def __init__(self, type: str, chat_id: str, update_time: Optional[str]):
|
|
8
9
|
self.type = type
|
|
9
10
|
self.chat_id = chat_id
|
|
10
11
|
self.update_time = update_time
|
|
@@ -18,7 +19,15 @@ class BaseUpdate:
|
|
|
18
19
|
token = os.getenv('RUBIKA_BOT_API_TOKEN')
|
|
19
20
|
return rubika_api.get_chat(token, self.chat_id)
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
@property
|
|
23
|
+
def chat_type(self):
|
|
24
|
+
if self.chat_id.startswith('b'):
|
|
25
|
+
return 'Private'
|
|
26
|
+
if self.chat_id.startswith('g'):
|
|
27
|
+
return 'Group'
|
|
28
|
+
if self.chat_id.startswith('c'):
|
|
29
|
+
return 'Channel'
|
|
30
|
+
return 'NotFound'
|
|
22
31
|
|
|
23
32
|
class Message(BaseUpdate):
|
|
24
33
|
def __init__(
|
|
@@ -78,17 +87,18 @@ class Message(BaseUpdate):
|
|
|
78
87
|
return f"Message: from {self.chat.get_full_name()}"
|
|
79
88
|
|
|
80
89
|
|
|
81
|
-
class InlineMessage:
|
|
90
|
+
class InlineMessage(BaseUpdate):
|
|
82
91
|
def __init__(self, chat_id: str, sender_id: str, message_id: str, text: str, aux_data: types.AuxData,
|
|
83
92
|
file: types.File, location: types.Location):
|
|
84
|
-
|
|
93
|
+
super().__init__('InlineMessage', chat_id, None)
|
|
85
94
|
self.sender_id = sender_id
|
|
86
95
|
self.message_id = message_id
|
|
87
96
|
self.text = text
|
|
88
97
|
self.aux = aux_data
|
|
89
98
|
self.file = file
|
|
90
99
|
self.location = location
|
|
91
|
-
|
|
100
|
+
self.token = None
|
|
101
|
+
|
|
92
102
|
def has_file(self):
|
|
93
103
|
return self.file is not None
|
|
94
104
|
|
|
@@ -107,6 +117,7 @@ class InlineMessage:
|
|
|
107
117
|
if self.has_location(): return "location"
|
|
108
118
|
|
|
109
119
|
|
|
120
|
+
|
|
110
121
|
class RemovedMessage(BaseUpdate):
|
|
111
122
|
def __init__(self, type, chat_id, update_time, removed_message_id):
|
|
112
123
|
super().__init__(type, chat_id, update_time)
|
|
@@ -221,7 +232,7 @@ class Update:
|
|
|
221
232
|
update_time=update_time,
|
|
222
233
|
removed_message_id=update.get('removed_message_id')
|
|
223
234
|
)
|
|
224
|
-
elif type_ == "NewMessage":
|
|
235
|
+
elif type_ == "NewMessage" or type_ == "UpdatedMessage":
|
|
225
236
|
|
|
226
237
|
new_message: dict = update.get("new_message")
|
|
227
238
|
message_id = new_message.get("message_id")
|
|
@@ -2,10 +2,10 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="PyRubikaBotAPI",
|
|
5
|
-
version="1.0.
|
|
5
|
+
version="1.0.1",
|
|
6
6
|
packages=find_packages(),
|
|
7
7
|
install_requires=["requests"],
|
|
8
|
-
python_requires=">=3.
|
|
8
|
+
python_requires=">=3.10",
|
|
9
9
|
description="A Python library with a simple and familiar interface for working with the official Rubika bot API",
|
|
10
10
|
long_description=open("README.md", encoding="utf-8").read(),
|
|
11
11
|
long_description_content_type="text/markdown",
|
pyrubikabotapi-1.0.0/README.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# PyRubikaBotAPI
|
|
2
|
-
|
|
3
|
-
یک کتابخانه برای ساخت رباتهای روبیکا با پایتون
|
|
4
|
-
|
|
5
|
-
## نصب
|
|
6
|
-
```bash
|
|
7
|
-
pip install PyRubikaBotAPI
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## مثال ساده
|
|
12
|
-
|
|
13
|
-
```python
|
|
14
|
-
from rubibot import RubiBot
|
|
15
|
-
|
|
16
|
-
bot = RubiBot("YOUR_TOKEN")
|
|
17
|
-
|
|
18
|
-
@bot.message_handler(commands=["start"])
|
|
19
|
-
def start(message):
|
|
20
|
-
bot.send_message(message.chat_id, "سلام! خوش آمدید!")
|
|
21
|
-
|
|
22
|
-
bot.polling()
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
## مثال پیشرفته تر
|
|
26
|
-
```py
|
|
27
|
-
@bot.message_handler(content_types=['file'])
|
|
28
|
-
def handle(msg):
|
|
29
|
-
file_id = msg.file.id
|
|
30
|
-
file_url = bot.get_file(file_id)
|
|
31
|
-
file = bot.download_file(file_url)
|
|
32
|
-
with open('file.format', 'wb') as f
|
|
33
|
-
f.write(file)
|
|
34
|
-
# استفاده از فایل ارسالی
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## مستندات:
|
|
38
|
-
|
|
39
|
-
Rubika: https://rubika.ir/pyrubikabotapi
|
|
40
|
-
GitHub: https://github.com/alireza-sadeghian/PyRubikaBotAPI
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|