RubigramClient 1.3.2__py3-none-any.whl → 1.3.4__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.
Potentially problematic release.
This version of RubigramClient might be problematic. Click here for more details.
- rubigram/__init__.py +3 -1
- rubigram/client.py +8 -291
- rubigram/filters.py +49 -46
- rubigram/method.py +208 -0
- rubigram/network.py +30 -0
- rubigram/types.py +8 -4
- {rubigramclient-1.3.2.dist-info → rubigramclient-1.3.4.dist-info}/METADATA +1 -1
- rubigramclient-1.3.4.dist-info/RECORD +11 -0
- rubigramclient-1.3.2.dist-info/RECORD +0 -9
- {rubigramclient-1.3.2.dist-info → rubigramclient-1.3.4.dist-info}/WHEEL +0 -0
- {rubigramclient-1.3.2.dist-info → rubigramclient-1.3.4.dist-info}/licenses/LICENSE +0 -0
- {rubigramclient-1.3.2.dist-info → rubigramclient-1.3.4.dist-info}/top_level.txt +0 -0
rubigram/__init__.py
CHANGED
rubigram/client.py
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
from rubigram.types import Update,
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
import aiofiles
|
|
1
|
+
from rubigram.types import Update, InlineMessage
|
|
2
|
+
from rubigram.method import Method
|
|
3
|
+
from aiohttp import web
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
class Client:
|
|
5
|
+
class Client(Method):
|
|
8
6
|
def __init__(self, token: str):
|
|
9
|
-
self.token = token
|
|
10
7
|
self.messages_handler = []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
async def request(self, method: str, data: dict):
|
|
14
|
-
async with ClientSession() as session:
|
|
15
|
-
async with session.post(f"{self.api}/{method}", json=data) as response:
|
|
16
|
-
response.raise_for_status()
|
|
17
|
-
return await response.json()
|
|
18
|
-
|
|
8
|
+
super().__init__(token)
|
|
9
|
+
|
|
19
10
|
def on_message(self, *filters):
|
|
20
11
|
def decorator(func):
|
|
21
12
|
async def wrapped(client, update):
|
|
@@ -26,283 +17,9 @@ class Client:
|
|
|
26
17
|
return decorator
|
|
27
18
|
|
|
28
19
|
async def update(self, data: dict):
|
|
29
|
-
event = Update.read(data["update"]
|
|
20
|
+
event = Update.read(data["update"]) if data.get("update") else InlineMessage.read(data["inline_message"])
|
|
30
21
|
for handler in self.messages_handler:
|
|
31
22
|
await handler(self, event)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
async def get_me(self) -> "Bot":
|
|
35
|
-
response = await self.request("getMe", {})
|
|
36
|
-
return Bot.read(response["data"]["bot"])
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
async def get_chat(self, chat_id: str) -> "Chat":
|
|
40
|
-
response = await self.request("getChat", {"chat_id": chat_id})
|
|
41
|
-
return Chat.read(response["data"]["chat"])
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
async def get_updates(self, limit: int = 1, offset_id: str = None) -> list["Update"]:
|
|
45
|
-
response = await self.request("getUpdates", {"limit": limit, "offset_id": offset_id})
|
|
46
|
-
updates = [update for update in response["data"]["updates"]]
|
|
47
|
-
return [Update.read(update) for update in updates]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
async def set_command(self, commands: list):
|
|
51
|
-
response = await self.request("setCommands", {"bot_commands": commands})
|
|
52
|
-
return response
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
async def update_bot_endpoint(
|
|
56
|
-
self,
|
|
57
|
-
url: str,
|
|
58
|
-
type: Literal["ReceiveUpdate", "ReceiveInlineMessage", "ReceiveQuery", "GetSelectionItem", "SearchSelectionItems"]
|
|
59
|
-
):
|
|
60
|
-
response = await self.request("updateBotEndpoints", {"url": url, "type": type})
|
|
61
|
-
return response
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
async def send_message(
|
|
65
|
-
self,
|
|
66
|
-
chat_id: str,
|
|
67
|
-
text: str,
|
|
68
|
-
chat_keypad : Optional[Keypad] = None,
|
|
69
|
-
inline_keypad: Optional[Keypad] = None,
|
|
70
|
-
chat_keypad_type: Literal["New", "Remove"] = None,
|
|
71
|
-
disable_notification: bool = None,
|
|
72
|
-
reply_to_message_id = None
|
|
73
|
-
) -> "MessageId":
|
|
74
|
-
data = {
|
|
75
|
-
"chat_id": chat_id,
|
|
76
|
-
"text": text,
|
|
77
|
-
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
78
|
-
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
79
|
-
"chat_keypad_type": chat_keypad_type,
|
|
80
|
-
"disable_notification": disable_notification,
|
|
81
|
-
"reply_to_message_id": reply_to_message_id
|
|
82
|
-
}
|
|
83
|
-
response = await self.request("sendMessage", data)
|
|
84
|
-
return MessageId.read(response["data"])
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
async def send_poll(
|
|
88
|
-
self,
|
|
89
|
-
chat_id: str,
|
|
90
|
-
question: str,
|
|
91
|
-
options: list[str],
|
|
92
|
-
chat_keypad: Keypad = None,
|
|
93
|
-
inline_keypad: Keypad = None,
|
|
94
|
-
disable_notification: bool = False,
|
|
95
|
-
reply_to_message_id: str = None,
|
|
96
|
-
chat_keypad_type: Literal[None, "New", "Remove"] = None
|
|
97
|
-
) -> "MessageId":
|
|
98
|
-
data = {
|
|
99
|
-
"chat_id": chat_id,
|
|
100
|
-
"question": question,
|
|
101
|
-
"options": options,
|
|
102
|
-
"chat_keypad": chat_keypad,
|
|
103
|
-
"inline_keypad": inline_keypad,
|
|
104
|
-
"disable_notification": disable_notification,
|
|
105
|
-
"reply_to_message_id": reply_to_message_id,
|
|
106
|
-
"chat_keypad_type": chat_keypad_type
|
|
107
|
-
}
|
|
108
|
-
response = await self.request("sendPoll", data)
|
|
109
|
-
return MessageId.read(response["data"])
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
async def send_location(
|
|
113
|
-
self,
|
|
114
|
-
chat_id: str,
|
|
115
|
-
latitude: str,
|
|
116
|
-
longitude: str,
|
|
117
|
-
chat_keypad: Keypad = None,
|
|
118
|
-
inline_keypad: Keypad = None,
|
|
119
|
-
disable_notification: bool = False,
|
|
120
|
-
reply_to_message_id: str = None,
|
|
121
|
-
chat_keypad_type: Literal[None, "New", "Remove"] = None
|
|
122
|
-
) -> "MessageId":
|
|
123
|
-
data = {
|
|
124
|
-
"chat_id": chat_id,
|
|
125
|
-
"latitude": latitude,
|
|
126
|
-
"longitude": longitude,
|
|
127
|
-
"chat_keypad": chat_keypad,
|
|
128
|
-
"inline_keypad": inline_keypad,
|
|
129
|
-
"disable_notification": disable_notification,
|
|
130
|
-
"reply_to_message_id": reply_to_message_id,
|
|
131
|
-
"chat_keypad_type": chat_keypad_type
|
|
132
|
-
}
|
|
133
|
-
response = await self.request("sendLocation", data)
|
|
134
|
-
return MessageId.read(response["data"])
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
async def send_contact(
|
|
138
|
-
self,
|
|
139
|
-
chat_id: str,
|
|
140
|
-
first_name: str,
|
|
141
|
-
last_name: str,
|
|
142
|
-
phone_number: str,
|
|
143
|
-
chat_keypad: Keypad = None,
|
|
144
|
-
inline_keypad: Keypad = None,
|
|
145
|
-
disable_notification: bool = False,
|
|
146
|
-
reply_to_message_id: str = None,
|
|
147
|
-
chat_keypad_type: Literal[None, "New", "Remove"] = None
|
|
148
|
-
) -> "MessageId":
|
|
149
|
-
data = {
|
|
150
|
-
"chat_id": chat_id,
|
|
151
|
-
"first_name": first_name,
|
|
152
|
-
"last_name": last_name,
|
|
153
|
-
"phone_number": phone_number,
|
|
154
|
-
"chat_keypad": chat_keypad,
|
|
155
|
-
"inline_keypad": inline_keypad,
|
|
156
|
-
"disable_notification": disable_notification,
|
|
157
|
-
"reply_to_message_id": reply_to_message_id,
|
|
158
|
-
"chat_keypad_type": chat_keypad_type
|
|
159
|
-
}
|
|
160
|
-
response = await self.request("sendContact", data)
|
|
161
|
-
return MessageId.read(response["data"])
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
async def send_sticker(
|
|
165
|
-
self,
|
|
166
|
-
chat_id: str,
|
|
167
|
-
sticker_id: str,
|
|
168
|
-
chat_keypad: Keypad = None,
|
|
169
|
-
inline_keypad: Keypad = None,
|
|
170
|
-
disable_notification: bool = False,
|
|
171
|
-
reply_to_message_id: str = None,
|
|
172
|
-
chat_keypad_type: Literal[None, "New", "Remove"] = None,
|
|
173
|
-
) -> "MessageId":
|
|
174
|
-
data = {
|
|
175
|
-
"chat_id": chat_id,
|
|
176
|
-
"sticker_id": sticker_id,
|
|
177
|
-
"chat_keypad": chat_keypad,
|
|
178
|
-
"disable_notification": disable_notification,
|
|
179
|
-
"inline_keypad": inline_keypad,
|
|
180
|
-
"reply_to_message_id": reply_to_message_id,
|
|
181
|
-
"chat_keypad_type": chat_keypad_type
|
|
182
|
-
}
|
|
183
|
-
response = await self.request("sendSticker", data)
|
|
184
|
-
return MessageId.read(response["data"])
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
async def forward_message(
|
|
188
|
-
self,
|
|
189
|
-
from_chat_id: str,
|
|
190
|
-
message_id: str,
|
|
191
|
-
to_chat_id: str,
|
|
192
|
-
disable_notification: bool = False
|
|
193
|
-
) -> "MessageId":
|
|
194
|
-
data = {
|
|
195
|
-
"from_chat_id": from_chat_id,
|
|
196
|
-
"message_id": message_id,
|
|
197
|
-
"to_chat_id": to_chat_id,
|
|
198
|
-
"disable_notification": disable_notification
|
|
199
|
-
}
|
|
200
|
-
response = await self.request("forwardMessage", data)
|
|
201
|
-
return MessageId.read(response["data"])
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
async def edit_message_text(
|
|
205
|
-
self,
|
|
206
|
-
chat_id: str,
|
|
207
|
-
message_id: str,
|
|
208
|
-
text: str
|
|
209
|
-
) -> None:
|
|
210
|
-
data = {"chat_id": chat_id, "message_id": message_id, "text": text}
|
|
211
|
-
await self.request("editMessageText", data)
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
async def edit_message_keypad(
|
|
215
|
-
self,
|
|
216
|
-
chat_id: str,
|
|
217
|
-
message_id: str,
|
|
218
|
-
inline_keypad: Keypad
|
|
219
|
-
) -> None:
|
|
220
|
-
data = {"chat_id": chat_id, "message_id": message_id, "inline_keypad": inline_keypad}
|
|
221
|
-
await self.request("editMessageKeypad", data)
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
async def edit_chat_keypad(
|
|
225
|
-
self,
|
|
226
|
-
chat_id: str,
|
|
227
|
-
chat_keypad: Keypad
|
|
228
|
-
) -> None:
|
|
229
|
-
data = {"chat_id": chat_id, "chat_keypad_type": "New", "chat_keypad": chat_keypad}
|
|
230
|
-
await self.request("editChatKeypad", data)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
async def remove_chat_keypad(
|
|
234
|
-
self,
|
|
235
|
-
chat_id: str
|
|
236
|
-
) -> None:
|
|
237
|
-
data = {"chat_id": chat_id, "chat_keypad_type": "Remove"}
|
|
238
|
-
await self.request("editChatKeypad", data)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
async def delete_message(
|
|
242
|
-
self,
|
|
243
|
-
chat_id: str,
|
|
244
|
-
message_id: str
|
|
245
|
-
) -> None:
|
|
246
|
-
data = {"chat_id": chat_id, "message_id": message_id}
|
|
247
|
-
await self.request("deleteMessage", data)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
async def get_file(self, file_id: str) -> str:
|
|
251
|
-
response = await self.request("getFile", {"file_id": file_id})
|
|
252
|
-
return response["data"]["download_url"]
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
async def request_send_file(self, type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"]) -> str:
|
|
256
|
-
response = await self.request("requestSendFile", {"type": type})
|
|
257
|
-
return response["data"]["upload_url"]
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
async def upload_file(self, path: str, file_name: str, type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"]) -> str:
|
|
261
|
-
upload_url = await self.request_send_file(type)
|
|
262
|
-
form = FormData()
|
|
263
|
-
form.add_field("file", open(path, "rb"), filename=file_name, content_type="application/octet-stream")
|
|
264
|
-
async with ClientSession() as session:
|
|
265
|
-
async with session.post(upload_url, data=form) as response:
|
|
266
|
-
result = await response.json()
|
|
267
|
-
return result["data"]["file_id"]
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
async def send_file(
|
|
271
|
-
self,
|
|
272
|
-
chat_id: str,
|
|
273
|
-
path: str,
|
|
274
|
-
file_name: str,
|
|
275
|
-
type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"] = "File",
|
|
276
|
-
chat_keypad = None,
|
|
277
|
-
inline_keypad = None,
|
|
278
|
-
disable_notification: bool = False,
|
|
279
|
-
reply_to_message_id: str = None,
|
|
280
|
-
chat_keypad_type: Literal["New", "Remove"] = None,
|
|
281
|
-
) -> str:
|
|
282
|
-
file_id = await self.upload_file(path, file_name, type)
|
|
283
|
-
data = {
|
|
284
|
-
"chat_id": chat_id,
|
|
285
|
-
"file_id": file_id,
|
|
286
|
-
"chat_keypad": chat_keypad,
|
|
287
|
-
"disable_notification": disable_notification,
|
|
288
|
-
"inline_keypad": inline_keypad,
|
|
289
|
-
"reply_to_message_id": reply_to_message_id,
|
|
290
|
-
"chat_keypad_type": chat_keypad_type,
|
|
291
|
-
}
|
|
292
|
-
response = await self.request("sendFile", data)
|
|
293
|
-
return MessageId.read(response["data"])
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
async def download_file(self, file_id: str, file_name: str):
|
|
297
|
-
download_url = await self.get_file(file_id)
|
|
298
|
-
async with ClientSession() as session:
|
|
299
|
-
async with session.get(download_url) as response:
|
|
300
|
-
if response.status == 200:
|
|
301
|
-
async with aiofiles.open(file_name, "wb") as file:
|
|
302
|
-
await file.write(await response.read())
|
|
303
|
-
return {"status": "OK", "file": file_name}
|
|
304
|
-
raise Exception(f"Download Error | status_code : {response.status}")
|
|
305
|
-
|
|
306
23
|
|
|
307
24
|
def run(self):
|
|
308
25
|
routes = web.RouteTableDef()
|
|
@@ -314,4 +31,4 @@ class Client:
|
|
|
314
31
|
return web.json_response({"status": "ok"})
|
|
315
32
|
app = web.Application()
|
|
316
33
|
app.add_routes(routes)
|
|
317
|
-
web.run_app(app, host="0.0.0.0", port=
|
|
34
|
+
web.run_app(app, host="0.0.0.0", port=5000)
|
rubigram/filters.py
CHANGED
|
@@ -1,50 +1,53 @@
|
|
|
1
|
-
from rubigram.types import Update
|
|
1
|
+
from rubigram.types import Update, InlineMessage
|
|
2
2
|
from typing import Union
|
|
3
3
|
|
|
4
|
+
def command(commands: Union[str, list[str]], prefixe: str = "/"):
|
|
5
|
+
def filter(message: Update):
|
|
6
|
+
if isinstance(message, Update) and message.type == "NewMessage" and message.new_message.text:
|
|
7
|
+
text = message.new_message.text
|
|
8
|
+
COMMANDS = commands if isinstance(commands, list) else [commands]
|
|
9
|
+
for cmd in COMMANDS:
|
|
10
|
+
if text.lower().startswith(prefixe + cmd):
|
|
11
|
+
return True
|
|
12
|
+
return False
|
|
13
|
+
return filter
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
15
|
+
def button(id: Union[str, list[str]]):
|
|
16
|
+
def filter(message: InlineMessage):
|
|
17
|
+
if isinstance(message, InlineMessage):
|
|
18
|
+
button_id = message.aux_data.button_id
|
|
19
|
+
ID = id if isinstance(id, list) else [id]
|
|
20
|
+
for i in ID:
|
|
21
|
+
if button_id == i:
|
|
22
|
+
return True
|
|
23
|
+
return False
|
|
24
|
+
return filter
|
|
11
25
|
|
|
12
|
-
|
|
13
|
-
def
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
return
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
@staticmethod
|
|
41
|
-
def file():
|
|
42
|
-
def inner(update: Update):
|
|
43
|
-
return update.new_message.file
|
|
44
|
-
return inner
|
|
45
|
-
|
|
46
|
-
@staticmethod
|
|
47
|
-
def button(id: str):
|
|
48
|
-
def inner(update: Update):
|
|
49
|
-
return update.new_message.aux_data.button_id == id if update.new_message.aux_data else False
|
|
50
|
-
return inner
|
|
26
|
+
def chat(chat_id: Union[str, list[str]]):
|
|
27
|
+
def filter(message: Union[Update, InlineMessage]):
|
|
28
|
+
chat_ids = chat_id if isinstance(chat_id, list) else [chat_id]
|
|
29
|
+
if isinstance(message, Update) or isinstance(message, InlineMessage):
|
|
30
|
+
return message.chat_id in chat_ids
|
|
31
|
+
return False
|
|
32
|
+
return filter
|
|
33
|
+
|
|
34
|
+
def text():
|
|
35
|
+
def filter(message: Update):
|
|
36
|
+
if isinstance(message, Update) and message.type == "NewMessage":
|
|
37
|
+
return bool(message.new_message.text)
|
|
38
|
+
return False
|
|
39
|
+
return filter
|
|
40
|
+
|
|
41
|
+
def file():
|
|
42
|
+
def filter(message: Update):
|
|
43
|
+
if isinstance(message, Update) and message.type == "NewMessage":
|
|
44
|
+
return bool(message.new_message.file)
|
|
45
|
+
return False
|
|
46
|
+
return filter
|
|
47
|
+
|
|
48
|
+
def private():
|
|
49
|
+
def filter(message: Update):
|
|
50
|
+
if isinstance(message, Update) and message.type == "NewMessage":
|
|
51
|
+
return message.new_message.sender_type in ["User", "Bot"]
|
|
52
|
+
return False
|
|
53
|
+
return filter
|
rubigram/method.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
from rubigram.network import NetWork
|
|
2
|
+
from typing import Literal, Optional
|
|
3
|
+
from rubigram.types import Bot, Chat, Update, Keypad, MessageId
|
|
4
|
+
|
|
5
|
+
class Method(NetWork):
|
|
6
|
+
def __init__(self, token: str):
|
|
7
|
+
super().__init__(token)
|
|
8
|
+
|
|
9
|
+
async def get_me(self) -> "Bot":
|
|
10
|
+
response = await self.request("getMe", {})
|
|
11
|
+
return Bot.read(response["data"]["bot"])
|
|
12
|
+
|
|
13
|
+
async def get_chat(self, chat_id: str) -> "Chat":
|
|
14
|
+
response = await self.request("getChat", {"chat_id": chat_id})
|
|
15
|
+
return Chat.read(response["data"]["chat"])
|
|
16
|
+
|
|
17
|
+
async def get_update(self, limit: int = 1, offset_id: Optional[int] = None) -> list[Update]:
|
|
18
|
+
response = await self.request("getUpdates", {"limit": limit, "offset_id": offset_id})
|
|
19
|
+
return [Update.read(update) for update in response["data"]["updates"]]
|
|
20
|
+
|
|
21
|
+
async def get_file(self, file_id: str) -> str:
|
|
22
|
+
response = await self.request("getFile", {"file_id": file_id})
|
|
23
|
+
return response["data"]["download_url"]
|
|
24
|
+
|
|
25
|
+
async def set_command(self, command: list):
|
|
26
|
+
response = await self.request("setCommands", {"bot_commands": command})
|
|
27
|
+
return response
|
|
28
|
+
|
|
29
|
+
async def update_bot_endpoint(self, url: str, type: Literal["ReceiveUpdate", "ReceiveInlineMessage", "ReceiveQuery", "GetSelectionItem", "SearchSelectionItems"]):
|
|
30
|
+
response = await self.request("updateBotEndpoints", {"url": url, "type": type})
|
|
31
|
+
return response
|
|
32
|
+
|
|
33
|
+
async def request_send_file(self, type: str):
|
|
34
|
+
response = await self.request("requestSendFile", {"type": type})
|
|
35
|
+
return response["data"]["upload_url"]
|
|
36
|
+
|
|
37
|
+
async def upload_file(self, path: str, name: str, type: str):
|
|
38
|
+
upload_url = await self.request_send_file(type)
|
|
39
|
+
response = await self.request_upload_file(upload_url, path, name)
|
|
40
|
+
return response
|
|
41
|
+
|
|
42
|
+
async def forward_message(self, from_chat_id: str, message_id: str, to_chat_id: str, disable_notification: bool = False) -> "MessageId":
|
|
43
|
+
data = {"from_chat_id": from_chat_id, "message_id": message_id, "to_chat_id": to_chat_id, "disable_notification": disable_notification}
|
|
44
|
+
response = await self.request("forwardMessage", data)
|
|
45
|
+
return MessageId.read(response["data"])
|
|
46
|
+
|
|
47
|
+
async def delete_message(self, chat_id: str, message_id: str):
|
|
48
|
+
await self.request("deleteMessage", {"chat_id": chat_id, "message_id": message_id})
|
|
49
|
+
|
|
50
|
+
async def remove_chat_keypad(self, chat_id: str):
|
|
51
|
+
await self.request("editChatKeypad", {"chat_id": chat_id, "chat_keypad_type": "Remove"})
|
|
52
|
+
|
|
53
|
+
async def edit_chat_keypad(self, chat_id: str, chat_keypad):
|
|
54
|
+
await self.request("editChatKeypad", {"chat_id": chat_id, "chat_keypad_type": "New", "chat_keypad": chat_keypad})
|
|
55
|
+
|
|
56
|
+
async def edit_message_keypad(self, chat_id: str, message_id: str, inline_keypad):
|
|
57
|
+
await self.request("editMessageKeypad", {"chat_id": chat_id, "message_id": message_id, "inline_keypad": inline_keypad})
|
|
58
|
+
|
|
59
|
+
async def edit_message_text(self, chat_id: str, message_id: str, text: str):
|
|
60
|
+
await self.request("editMessageText", {"chat_id": chat_id, "message_id": message_id, "text": text})
|
|
61
|
+
|
|
62
|
+
async def send_message(
|
|
63
|
+
self,
|
|
64
|
+
chat_id: str,
|
|
65
|
+
text: str,
|
|
66
|
+
chat_keypad: Keypad = None,
|
|
67
|
+
inline_keypad: Keypad= None,
|
|
68
|
+
chat_keypad_type: Literal["New", "Remove"] = None,
|
|
69
|
+
disable_notification: bool = None,
|
|
70
|
+
reply_to_message_id = None
|
|
71
|
+
) -> "MessageId":
|
|
72
|
+
data = {
|
|
73
|
+
"chat_id": chat_id,
|
|
74
|
+
"text": text,
|
|
75
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
76
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
77
|
+
"chat_keypad_type": chat_keypad_type,
|
|
78
|
+
"disable_notification": disable_notification,
|
|
79
|
+
"reply_to_message_id": reply_to_message_id
|
|
80
|
+
}
|
|
81
|
+
response = await self.request("sendMessage", data)
|
|
82
|
+
return MessageId.read(response["data"])
|
|
83
|
+
|
|
84
|
+
async def send_poll(
|
|
85
|
+
self,
|
|
86
|
+
chat_id: str,
|
|
87
|
+
question: str,
|
|
88
|
+
options: list[str],
|
|
89
|
+
chat_keypad: Keypad = None,
|
|
90
|
+
inline_keypad: Keypad = None,
|
|
91
|
+
disable_notification: bool = False,
|
|
92
|
+
reply_to_message_id: str = None,
|
|
93
|
+
chat_keypad_type: Literal["New", "Remove"] = None
|
|
94
|
+
) -> "MessageId":
|
|
95
|
+
data = {
|
|
96
|
+
"chat_id": chat_id,
|
|
97
|
+
"question": question,
|
|
98
|
+
"options": options,
|
|
99
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
100
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
101
|
+
"disable_notification": disable_notification,
|
|
102
|
+
"reply_to_message_id": reply_to_message_id,
|
|
103
|
+
"chat_keypad_type": chat_keypad_type
|
|
104
|
+
}
|
|
105
|
+
response = await self.request("sendPoll", data)
|
|
106
|
+
return MessageId.read(response["data"])
|
|
107
|
+
|
|
108
|
+
async def send_location(
|
|
109
|
+
self,
|
|
110
|
+
chat_id: str,
|
|
111
|
+
latitude: str,
|
|
112
|
+
longitude: str,
|
|
113
|
+
chat_keypad: Keypad = None,
|
|
114
|
+
inline_keypad: Keypad = None,
|
|
115
|
+
disable_notification: bool = False,
|
|
116
|
+
reply_to_message_id: str = None,
|
|
117
|
+
chat_keypad_type: Literal["New", "Remove"] = None
|
|
118
|
+
) -> "MessageId":
|
|
119
|
+
data = {
|
|
120
|
+
"chat_id": chat_id,
|
|
121
|
+
"latitude": latitude,
|
|
122
|
+
"longitude": longitude,
|
|
123
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
124
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
125
|
+
"disable_notification": disable_notification,
|
|
126
|
+
"reply_to_message_id": reply_to_message_id,
|
|
127
|
+
"chat_keypad_type": chat_keypad_type
|
|
128
|
+
}
|
|
129
|
+
response = await self.request("sendLocation", data)
|
|
130
|
+
return MessageId.read(response["data"])
|
|
131
|
+
|
|
132
|
+
async def send_contact(
|
|
133
|
+
self,
|
|
134
|
+
chat_id: str,
|
|
135
|
+
first_name: str,
|
|
136
|
+
last_name: str,
|
|
137
|
+
phone_number: str,
|
|
138
|
+
chat_keypad: Keypad = None,
|
|
139
|
+
inline_keypad: Keypad = None,
|
|
140
|
+
disable_notification: bool = False,
|
|
141
|
+
reply_to_message_id: str = None,
|
|
142
|
+
chat_keypad_type: Literal["New", "Remove"] = None
|
|
143
|
+
) -> "MessageId":
|
|
144
|
+
data = {
|
|
145
|
+
"chat_id": chat_id,
|
|
146
|
+
"first_name": first_name,
|
|
147
|
+
"last_name": last_name,
|
|
148
|
+
"phone_number": phone_number,
|
|
149
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
150
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
151
|
+
"disable_notification": disable_notification,
|
|
152
|
+
"reply_to_message_id": reply_to_message_id,
|
|
153
|
+
"chat_keypad_type": chat_keypad_type
|
|
154
|
+
}
|
|
155
|
+
response = await self.request("sendContact", data)
|
|
156
|
+
return MessageId.read(response["data"])
|
|
157
|
+
|
|
158
|
+
async def send_sticker(
|
|
159
|
+
self,
|
|
160
|
+
chat_id: str,
|
|
161
|
+
sticker_id: str,
|
|
162
|
+
chat_keypad: Keypad = None,
|
|
163
|
+
inline_keypad: Keypad = None,
|
|
164
|
+
disable_notification: bool = False,
|
|
165
|
+
reply_to_message_id: str = None,
|
|
166
|
+
chat_keypad_type: Literal["New", "Remove"] = None,
|
|
167
|
+
) -> "MessageId":
|
|
168
|
+
data = {
|
|
169
|
+
"chat_id": chat_id,
|
|
170
|
+
"sticker_id": sticker_id,
|
|
171
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
172
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
173
|
+
"disable_notification": disable_notification,
|
|
174
|
+
"reply_to_message_id": reply_to_message_id,
|
|
175
|
+
"chat_keypad_type": chat_keypad_type
|
|
176
|
+
}
|
|
177
|
+
response = await self.request("sendSticker", data)
|
|
178
|
+
return MessageId.read(response["data"])
|
|
179
|
+
|
|
180
|
+
async def send_file(
|
|
181
|
+
self,
|
|
182
|
+
chat_id: str,
|
|
183
|
+
path: str,
|
|
184
|
+
file_name: str,
|
|
185
|
+
type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"] = "File",
|
|
186
|
+
chat_keypad: Keypad = None,
|
|
187
|
+
inline_keypad: Keypad = None,
|
|
188
|
+
disable_notification: bool = False,
|
|
189
|
+
reply_to_message_id: str = None,
|
|
190
|
+
chat_keypad_type: Literal["New", "Remove"] = None,
|
|
191
|
+
) -> "MessageId":
|
|
192
|
+
file_id = await self.upload_file(path, file_name, type)
|
|
193
|
+
data = {
|
|
194
|
+
"chat_id": chat_id,
|
|
195
|
+
"file_id": file_id,
|
|
196
|
+
"chat_keypad": chat_keypad._dict() if chat_keypad else None,
|
|
197
|
+
"inline_keypad": inline_keypad._dict() if inline_keypad else None,
|
|
198
|
+
"disable_notification": disable_notification,
|
|
199
|
+
"reply_to_message_id": reply_to_message_id,
|
|
200
|
+
"chat_keypad_type": chat_keypad_type,
|
|
201
|
+
}
|
|
202
|
+
response = await self.request("sendFile", data)
|
|
203
|
+
return MessageId.read(response["data"])
|
|
204
|
+
|
|
205
|
+
async def download_file(self, file_id: str, file_name: str):
|
|
206
|
+
download_url = await self.get_file(file_id)
|
|
207
|
+
response = await self.request_download_file(download_url, file_name)
|
|
208
|
+
return response
|
rubigram/network.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from aiohttp import ClientSession, FormData
|
|
2
|
+
import aiofiles
|
|
3
|
+
|
|
4
|
+
class NetWork:
|
|
5
|
+
def __init__(self, token: str):
|
|
6
|
+
self.token = token
|
|
7
|
+
self.api = f"https://botapi.rubika.ir/v3/{self.token}/"
|
|
8
|
+
|
|
9
|
+
async def request(self, method: str, json: dict) -> dict:
|
|
10
|
+
async with ClientSession() as session:
|
|
11
|
+
async with session.post(self.api + method, json=json) as response:
|
|
12
|
+
response.raise_for_status()
|
|
13
|
+
return await response.json()
|
|
14
|
+
|
|
15
|
+
async def request_upload_file(self, url: str, path: str, name: str) -> str:
|
|
16
|
+
form = FormData()
|
|
17
|
+
form.add_field("file", open(path, "rb"), filename=name, content_type="application/octet-stream")
|
|
18
|
+
async with ClientSession() as session:
|
|
19
|
+
async with session.post(url, data=form) as response:
|
|
20
|
+
response.raise_for_status()
|
|
21
|
+
result = await response.json()
|
|
22
|
+
return result["data"]["file_id"]
|
|
23
|
+
|
|
24
|
+
async def request_download_file(self, url: str, name: str):
|
|
25
|
+
async with ClientSession() as session:
|
|
26
|
+
async with session.get(url) as response:
|
|
27
|
+
response.raise_for_status()
|
|
28
|
+
async with aiofiles.open(name, mode="wb") as file:
|
|
29
|
+
await file.write(await response.read())
|
|
30
|
+
return {"status": True, "file": name}
|
rubigram/types.py
CHANGED
|
@@ -200,6 +200,7 @@ class MessageId:
|
|
|
200
200
|
message_id = data.get("message_id"),
|
|
201
201
|
file_id = data.get("file_id")
|
|
202
202
|
)
|
|
203
|
+
|
|
203
204
|
|
|
204
205
|
@dataclass
|
|
205
206
|
class PollStatus:
|
|
@@ -270,14 +271,14 @@ class Poll:
|
|
|
270
271
|
@dataclass
|
|
271
272
|
class ContactMessage:
|
|
272
273
|
phone_number: Optional[str] = None
|
|
273
|
-
first_name: Optional[
|
|
274
|
+
first_name: Optional[str] = None
|
|
274
275
|
last_name: Optional[str] = None
|
|
275
276
|
|
|
276
277
|
@classmethod
|
|
277
278
|
def read(cls, data: dict[str, Any]) -> "ContactMessage":
|
|
278
279
|
return cls(
|
|
279
280
|
phone_number = data.get("phone_number"),
|
|
280
|
-
first_name =
|
|
281
|
+
first_name = data.get("first_name"),
|
|
281
282
|
last_name = data.get("last_name")
|
|
282
283
|
)
|
|
283
284
|
|
|
@@ -458,7 +459,7 @@ class Update:
|
|
|
458
459
|
type = data["type"],
|
|
459
460
|
chat_id = data["chat_id"],
|
|
460
461
|
removed_message_id = data.get("removed_message_id"),
|
|
461
|
-
new_message = Message.read(data["new_message"]),
|
|
462
|
+
new_message = Message.read(data["new_message"]) if "new_message" in data else None,
|
|
462
463
|
updated_message = Message.read(data["updated_message"]) if "updated_message" in data else None,
|
|
463
464
|
updated_payment = PaymentStatus.read(data["updated_payment"]) if "updated_payment" in data else None
|
|
464
465
|
)
|
|
@@ -467,4 +468,7 @@ class Update:
|
|
|
467
468
|
return await self.client.send_message(self.chat_id, text, reply_to_message_id=self.new_message.message_id)
|
|
468
469
|
|
|
469
470
|
async def reply_file(self, path: str, file_name: str, type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"] = "File") -> "MessageId":
|
|
470
|
-
return await self.client.send_file(self.chat_id, path, file_name, type, reply_to_message_id=self.new_message.message_id)
|
|
471
|
+
return await self.client.send_file(self.chat_id, path, file_name, type, reply_to_message_id=self.new_message.message_id)
|
|
472
|
+
|
|
473
|
+
async def download(self, file_name: str):
|
|
474
|
+
return await self.client.download_file(self.new_message.file.file_id, file_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: RubigramClient
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters.
|
|
5
5
|
Author-email: Javad RZ <Javad.Py1385@gmail.com>
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
rubigram/__init__.py,sha256=4JZ6q8ukflz_izRmJNYcndcKZFCsyJdYoYVoAPwN5V0,107
|
|
2
|
+
rubigram/client.py,sha256=wjSFIoE5s2vniZuNUPpa80TvyYC6dvxbwCfKpJDcLnI,1257
|
|
3
|
+
rubigram/filters.py,sha256=VU9Nd5ALWQAXafH1mXi19hm-E5H20JgTswTS4usK3ro,1955
|
|
4
|
+
rubigram/method.py,sha256=nm2qfzkanpzDo3yusIXmjYgCYmLzV6nVOyaxPDDqqz4,9074
|
|
5
|
+
rubigram/network.py,sha256=K7vvGikXStvUBqHX2gogy3hJ1eQjLAJ7kdwLbfFuZIg,1399
|
|
6
|
+
rubigram/types.py,sha256=TidelegJkJ-UT8b9JTmhL_qKBmm-A-nu04pyPYk-ApI,16955
|
|
7
|
+
rubigramclient-1.3.4.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
rubigramclient-1.3.4.dist-info/METADATA,sha256=uKmdhwhbiJcdPSGpq3LEUjFUV1U-bRjwZ41kFZs37fo,984
|
|
9
|
+
rubigramclient-1.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
10
|
+
rubigramclient-1.3.4.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
|
|
11
|
+
rubigramclient-1.3.4.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
rubigram/__init__.py,sha256=K1WXGcBx9-1cLmImtnruqFk91nb_6XuhY_Ud0KS_IUk,55
|
|
2
|
-
rubigram/client.py,sha256=5xaA_HOMQIU5HyEadUdT-WpD9CxGE0wxbwImqQg29Zw,11506
|
|
3
|
-
rubigram/filters.py,sha256=HuW_Rscb02TK3Qm7jKVyvy-83FP-plIjTLTccypVniw,1468
|
|
4
|
-
rubigram/types.py,sha256=GIGvTGdDURuwJ3oHPvRR7B8oJ3V1f8MDaMAqjvOOO-0,16813
|
|
5
|
-
rubigramclient-1.3.2.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
rubigramclient-1.3.2.dist-info/METADATA,sha256=eFXLcEp55Hxf_A9WYnrvn1RxBHx3olq-wR6iODLpxkQ,984
|
|
7
|
-
rubigramclient-1.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
8
|
-
rubigramclient-1.3.2.dist-info/top_level.txt,sha256=Mhg5HfkL6rLec5sI4ClGmwoqYUANAZUz8sVa1sT_cas,9
|
|
9
|
-
rubigramclient-1.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|