RubigramClient 1.6.4__tar.gz → 1.6.5__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.

Potentially problematic release.


This version of RubigramClient might be problematic. Click here for more details.

@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RubigramClient
3
- Version: 1.6.4
3
+ Version: 1.6.5
4
4
  Summary: A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters.
5
- Author-email: Javad RZ <Javad.Py1385@gmail.com>
5
+ Author-email: Javad RZ <MrJavad.Email@gmail.com>
6
6
  Classifier: Programming Language :: Python :: 3
7
7
  Classifier: License :: OSI Approved :: MIT License
8
8
  Classifier: Operating System :: OS Independent
@@ -11,7 +11,6 @@ Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: aiohttp
13
13
  Requires-Dist: aiofiles
14
- Requires-Dist: aiosqlite
15
14
  Dynamic: license-file
16
15
 
17
16
  # Rubigram
@@ -25,12 +24,12 @@ pip install RubigramClient
25
24
  ## Send Message
26
25
  ```python
27
26
  from rubigram import Client, filters
28
- from rubigram.models import Update
27
+ from rubigram.types import Update
29
28
 
30
- bot = Client("your_bot_token")
29
+ bot = Client(token="YOUR_TOKEN_BOT")
31
30
 
32
- @bot.on_message(filters.command("start") & filters.private)
33
- async def start_handler(client, message: Update):
31
+ @bot.on_message(filters.private)
32
+ async def welcome_message(client, message: Update):
34
33
  await message.reply("Hi, WELCOME TO RUBIGRAM")
35
34
 
36
35
  bot.run()
@@ -39,10 +38,10 @@ bot.run()
39
38
  ## Send Message & Get receiveInlineMessage
40
39
  ```python
41
40
  from rubigram import Client, filters
42
- from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
41
+ from rubigram.types import Update, Button, Keypad, KeypadRow, InlineMessage
43
42
 
44
43
 
45
- bot = Client(token="bot_token", endpoint="endpoint_url")
44
+ bot = Client(token="BOT_TOKEN", endpoint="ENDPOINT_URL")
46
45
 
47
46
 
48
47
  @bot.on_message(filters.command("start"))
@@ -75,7 +74,7 @@ bot.run()
75
74
  from rubigram import Client
76
75
  import asyncio
77
76
 
78
- bot = Client("bot_token")
77
+ bot = Client("YOUR_BOT_TOKEN")
79
78
 
80
79
  async def main():
81
80
  async with bot:
@@ -9,12 +9,12 @@ pip install RubigramClient
9
9
  ## Send Message
10
10
  ```python
11
11
  from rubigram import Client, filters
12
- from rubigram.models import Update
12
+ from rubigram.types import Update
13
13
 
14
- bot = Client("your_bot_token")
14
+ bot = Client(token="YOUR_TOKEN_BOT")
15
15
 
16
- @bot.on_message(filters.command("start") & filters.private)
17
- async def start_handler(client, message: Update):
16
+ @bot.on_message(filters.private)
17
+ async def welcome_message(client, message: Update):
18
18
  await message.reply("Hi, WELCOME TO RUBIGRAM")
19
19
 
20
20
  bot.run()
@@ -23,10 +23,10 @@ bot.run()
23
23
  ## Send Message & Get receiveInlineMessage
24
24
  ```python
25
25
  from rubigram import Client, filters
26
- from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
26
+ from rubigram.types import Update, Button, Keypad, KeypadRow, InlineMessage
27
27
 
28
28
 
29
- bot = Client(token="bot_token", endpoint="endpoint_url")
29
+ bot = Client(token="BOT_TOKEN", endpoint="ENDPOINT_URL")
30
30
 
31
31
 
32
32
  @bot.on_message(filters.command("start"))
@@ -59,7 +59,7 @@ bot.run()
59
59
  from rubigram import Client
60
60
  import asyncio
61
61
 
62
- bot = Client("bot_token")
62
+ bot = Client("YOUR_BOT_TOKEN")
63
63
 
64
64
  async def main():
65
65
  async with bot:
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RubigramClient
3
- Version: 1.6.4
3
+ Version: 1.6.5
4
4
  Summary: A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters.
5
- Author-email: Javad RZ <Javad.Py1385@gmail.com>
5
+ Author-email: Javad RZ <MrJavad.Email@gmail.com>
6
6
  Classifier: Programming Language :: Python :: 3
7
7
  Classifier: License :: OSI Approved :: MIT License
8
8
  Classifier: Operating System :: OS Independent
@@ -11,7 +11,6 @@ Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: aiohttp
13
13
  Requires-Dist: aiofiles
14
- Requires-Dist: aiosqlite
15
14
  Dynamic: license-file
16
15
 
17
16
  # Rubigram
@@ -25,12 +24,12 @@ pip install RubigramClient
25
24
  ## Send Message
26
25
  ```python
27
26
  from rubigram import Client, filters
28
- from rubigram.models import Update
27
+ from rubigram.types import Update
29
28
 
30
- bot = Client("your_bot_token")
29
+ bot = Client(token="YOUR_TOKEN_BOT")
31
30
 
32
- @bot.on_message(filters.command("start") & filters.private)
33
- async def start_handler(client, message: Update):
31
+ @bot.on_message(filters.private)
32
+ async def welcome_message(client, message: Update):
34
33
  await message.reply("Hi, WELCOME TO RUBIGRAM")
35
34
 
36
35
  bot.run()
@@ -39,10 +38,10 @@ bot.run()
39
38
  ## Send Message & Get receiveInlineMessage
40
39
  ```python
41
40
  from rubigram import Client, filters
42
- from rubigram.models import Update, Button, Keypad, KeypadRow, InlineMessage
41
+ from rubigram.types import Update, Button, Keypad, KeypadRow, InlineMessage
43
42
 
44
43
 
45
- bot = Client(token="bot_token", endpoint="endpoint_url")
44
+ bot = Client(token="BOT_TOKEN", endpoint="ENDPOINT_URL")
46
45
 
47
46
 
48
47
  @bot.on_message(filters.command("start"))
@@ -75,7 +74,7 @@ bot.run()
75
74
  from rubigram import Client
76
75
  import asyncio
77
76
 
78
- bot = Client("bot_token")
77
+ bot = Client("YOUR_BOT_TOKEN")
79
78
 
80
79
  async def main():
81
80
  async with bot:
@@ -8,8 +8,9 @@ RubigramClient.egg-info/requires.txt
8
8
  RubigramClient.egg-info/top_level.txt
9
9
  rubigram/__init__.py
10
10
  rubigram/client.py
11
+ rubigram/enums.py
11
12
  rubigram/filters.py
12
13
  rubigram/method.py
13
- rubigram/models.py
14
14
  rubigram/network.py
15
- rubigram/state.py
15
+ rubigram/state.py
16
+ rubigram/types.py
@@ -1,3 +1,2 @@
1
1
  aiohttp
2
2
  aiofiles
3
- aiosqlite
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "RubigramClient"
3
- version = "1.6.4"
3
+ version = "1.6.5"
4
4
  description = "A simple and flexible Python library for building advanced Rubika bots with powerful message handling, inline buttons, and custom filters."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.7"
7
7
  license = {file = "LICENSE"}
8
8
  authors = [
9
- { name="Javad RZ", email="Javad.Py1385@gmail.com" }
9
+ { name="Javad RZ", email="MrJavad.Email@gmail.com" }
10
10
  ]
11
11
  classifiers = [
12
12
  "Programming Language :: Python :: 3",
@@ -15,7 +15,5 @@ classifiers = [
15
15
  ]
16
16
  dependencies = [
17
17
  "aiohttp",
18
- "aiofiles",
19
- "aiosqlite",
20
-
18
+ "aiofiles",
21
19
  ]
@@ -2,5 +2,6 @@ from .network import Network
2
2
  from .method import Method
3
3
  from .client import Client
4
4
  from .state import StateManager
5
- from . import models
6
- from . import filters
5
+ from . import enums
6
+ from . import filters
7
+ from . import types
@@ -1,13 +1,16 @@
1
1
  from typing import Optional, Callable, Literal, Union
2
- from rubigram.models import Update, InlineMessage
2
+ from rubigram.types import Update, InlineMessage
3
3
  from rubigram.method import Method
4
4
  from rubigram.filters import Filter
5
5
  from rubigram.state import StateManager
6
6
  from datetime import datetime
7
7
  from aiohttp import web
8
8
  import asyncio
9
+ import logging
9
10
 
10
11
 
12
+ logging.basicConfig(format=("%(levelname)s | %(message)s"))
13
+
11
14
 
12
15
  class Client(Method):
13
16
  def __init__(
@@ -96,7 +99,7 @@ class Client(Method):
96
99
  await self.dispatch(update, "message")
97
100
  self.offset_id = get_updates.next_offset_id
98
101
  except Exception as error:
99
- print(f"ERROR : {error}")
102
+ logging.error(error)
100
103
  finally:
101
104
  await self.stop()
102
105
 
@@ -122,5 +125,6 @@ class Client(Method):
122
125
  else:
123
126
  try:
124
127
  asyncio.run(self.runner())
128
+ except KeyboardInterrupt:pass
125
129
  except Exception as error:
126
- print(f"ERROR : {error}")
130
+ logging.error(error)
@@ -0,0 +1,129 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ChatType(str, Enum):
5
+ User = "User"
6
+ Bot = "Bot"
7
+ Group = "Group"
8
+ Channel = "Channel"
9
+
10
+
11
+ class ForwardedFrom(str, Enum):
12
+ User = "User"
13
+ Bot = "Bot"
14
+ Channel = "Channel"
15
+
16
+
17
+ class PaymentStatus(str, Enum):
18
+ Paid = "Paid"
19
+ NotPaid = "NotPaid"
20
+
21
+
22
+ class PollStatus(str, Enum):
23
+ Open = "Open"
24
+ Closed = "Closed"
25
+
26
+
27
+ class LiveLocationStatus(str, Enum):
28
+ Stopped = "Stopped"
29
+ Live = "Live"
30
+
31
+
32
+ class ButtonSelectionType(str, Enum):
33
+ TextOnly = "TextOnly"
34
+ TextImgThu = "TextImgThu"
35
+ TextImgBig = "TextImgBig"
36
+
37
+
38
+ class ButtonSelectionSearch(str, Enum):
39
+ Local = "Local"
40
+ Api = "Api"
41
+
42
+
43
+ class ButtonSelectionGet(str, Enum):
44
+ Local = "Local"
45
+ Api = "Api"
46
+
47
+
48
+ class ButtonCalendarType(str, Enum):
49
+ DatePersian = "DatePersian"
50
+ DateGregorian = "DateGregorian"
51
+
52
+
53
+ class ButtonTextboxTypeKeypad(str, Enum):
54
+ String = "String"
55
+ Number = "Number"
56
+
57
+
58
+ class ButtonTextboxTypeLine(str, Enum):
59
+ SingleLine = "SingleLine"
60
+ MultiLine = "MultiLine"
61
+
62
+
63
+ class ButtonLocationType(str, Enum):
64
+ Picker = "Picker"
65
+ View = "View"
66
+
67
+
68
+ class ButtonLinkType(str, Enum):
69
+ joinchannel = "joinchannel"
70
+ url = "url"
71
+
72
+ class MessageSender(str, Enum):
73
+ User = "User"
74
+ Bot = "Bot"
75
+
76
+
77
+ class UpdateType(str, Enum):
78
+ UpdatedMessage = "UpdatedMessage"
79
+ NewMessage = "NewMessage"
80
+ RemovedMessage = "RemovedMessage"
81
+ StartedBot = "StartedBot"
82
+ StoppedBot = "StoppedBot"
83
+ UpdatedPayment = "UpdatedPayment"
84
+
85
+
86
+ class ChatKeypadType(str, Enum):
87
+ New = "New"
88
+ Remove = "Remove"
89
+
90
+
91
+ class UpdateEndpointType(str, Enum):
92
+ ReceiveUpdate = "ReceiveUpdate"
93
+ ReceiveInlineMessage = "ReceiveInlineMessage"
94
+ ReceiveQuery = "ReceiveQuery"
95
+ GetSelectionItem = "GetSelectionItem"
96
+ SearchSelectionItems = "SearchSelectionItems"
97
+
98
+
99
+ class ButtonType(str, Enum):
100
+ Simple = "Simple"
101
+ Selection = "Selection"
102
+ Calendar = "Calendar"
103
+ NumberPicker = "NumberPicker"
104
+ StringPicker = "StringPicker"
105
+ Location = "Location"
106
+ Payment = "Payment"
107
+ CameraImage = "CameraImage"
108
+ CameraVideo = "CameraVideo"
109
+ GalleryImage = "GalleryImage"
110
+ GalleryVideo = "GalleryVideo"
111
+ File = "File"
112
+ Audio = "Audio"
113
+ RecordAudio = "RecordAudio"
114
+ MyPhoneNumber = "MyPhoneNumber"
115
+ MyLocation = "MyLocation"
116
+ Textbox = "Textbox"
117
+ Link = "Link"
118
+ AskMyPhoneNumber = "AskMyPhoneNumber"
119
+ AskLocation = "AskLocation"
120
+ Barcode = "Barcode"
121
+
122
+
123
+ class FileType(str, Enum):
124
+ File = "File"
125
+ Image = "Image"
126
+ Video = "Video"
127
+ Gif = "Gif"
128
+ Music = "Music"
129
+ Voice = "Voice"
@@ -1,4 +1,4 @@
1
- from rubigram.models import Update, InlineMessage
1
+ from rubigram.types import Update, InlineMessage
2
2
  from typing import Union
3
3
  import re
4
4
 
@@ -108,36 +108,45 @@ forward_channel = Filter(FORWARD_CHANNEL)
108
108
 
109
109
 
110
110
  class state(Filter):
111
- def __init__(self, states: Union[str, list[str]]):
112
- self.states = states
111
+ def __init__(self, state: Union[str, list[str]]):
112
+ self.states = state if isinstance(state, list) else [state]
113
113
  super().__init__(self.filter)
114
114
 
115
115
  async def filter(self, update: Union[Update, InlineMessage]):
116
- states = self.states if isinstance(self.states, list) else [self.states]
117
- user = await update.client.state.get_state(update.chat_id)
118
- return user.lower() in states if user else False
116
+ user_state = await update.client.state.get_state(update.chat_id)
117
+ return user_state in self.states
119
118
 
120
119
 
121
120
  class command(Filter):
122
- def __init__(self, cmd: Union[str, list[str]], prefix: str = "/"):
123
- self.cmd = cmd
124
- self.prefix = prefix
121
+ def __init__(self, command: Union[str, list[str]], prefix: Union[str, list[str]] = "/", case_sensitive: bool = False):
122
+ self.commands = [c if case_sensitive else c.lower() for c in (command if isinstance(command, list) else [command])]
123
+ self.prefixs = prefix if isinstance(prefix, list) else [prefix]
124
+ self.cmds = [p + c for p in self.prefixs for c in self.commands]
125
+ self.case_sensitive = case_sensitive
125
126
  super().__init__(self.filter)
126
127
 
127
128
  async def filter(self, update: Update):
128
- commands = self.cmd if isinstance(self.cmd, list) else [self.cmd]
129
- text = ""
130
- if isinstance(update, Update):
131
- if update.type == "NewMessage":
132
- text = update.new_message.text
133
- elif update.type == "UpdatedMessage":
134
- text = update.updated_message.text
135
- if text:
136
- for cmd in commands:
137
- if text.lower().startswith(self.prefix + cmd.lower()):
138
- return True
139
- return False
129
+ if isinstance(update, Update) and update.type == "NewMessage":
130
+ text = update.new_message.text or ""
131
+ text = text if self.case_sensitive else text.lower()
132
+ return any(text.startswith(cmd) for cmd in self.cmds)
133
+ return False
134
+
140
135
 
136
+ class button(Filter):
137
+ def __init__(self, button_id: Union[str, list[str]], prefix: Union[str, list[str]] = "", case_sensitive: bool = False):
138
+ self.button_ids = [btn_id if case_sensitive else btn_id.lower() for btn_id in (button_id if isinstance(button_id, list) else [button_id])]
139
+ self.prefixs = prefix if isinstance(prefix, list) else [prefix]
140
+ self.btn_ids = [p + b for p in self.prefixs for b in self.button_ids]
141
+ self.case_sensitive = case_sensitive
142
+ super().__init__(self.filter)
143
+
144
+ async def filter(self, update: InlineMessage):
145
+ if isinstance(update, InlineMessage):
146
+ text = update.text or ""
147
+ text = text if self.case_sensitive else text.lower()
148
+ return any(text.startswith(btn) for btn in self.btn_ids)
149
+ return False
141
150
 
142
151
  class regex(Filter):
143
152
  def __init__(self, pattern: str):
@@ -166,19 +175,4 @@ class chat(Filter):
166
175
 
167
176
  async def filter(self, update: Union[Update, InlineMessage]):
168
177
  chat_ids = self.chat_id if isinstance(self.chat_id, list) else [self.chat_id]
169
- return update.chat_id in chat_ids
170
-
171
-
172
- class button(Filter):
173
- def __init__(self, button_id: Union[str, list[str]], prefix: str = ""):
174
- self.button_id = button_id
175
- self.prefix = prefix
176
- super().__init__(self.filter)
177
-
178
- async def filter(self, update: InlineMessage):
179
- if isinstance(update, InlineMessage):
180
- button_ids = self.button_id if isinstance(self.button_id, list) else [self.button_id]
181
- for btn_id in button_ids:
182
- if update.aux_data.button_id.startswith(self.prefix + btn_id):
183
- return True
184
- return False
178
+ return update.chat_id in chat_ids
@@ -1,12 +1,16 @@
1
1
  from .network import Network
2
- from typing import Literal, Optional
3
- from rubigram.models import Bot, Chat, Keypad, MessageId, Updates
2
+ from . import enums
3
+ from typing import Optional
4
+ from rubigram.types import Bot, Chat, Keypad, MessageId, Updates, BotCommand
4
5
 
5
6
 
6
7
  class Method(Network):
7
8
  def __init__(self, token: str):
8
9
  super().__init__(token)
9
-
10
+
11
+ def clean_data(self, data: dict):
12
+ return {key: value for key, value in data.items() if value is not None}
13
+
10
14
  async def get_me(self) -> "Bot":
11
15
  response = await self.request("getMe", {})
12
16
  return Bot.from_dict(response["bot"])
@@ -23,11 +27,11 @@ class Method(Network):
23
27
  response = await self.request("getFile", {"file_id": file_id})
24
28
  return response["download_url"]
25
29
 
26
- async def set_command(self, command: list):
27
- response = await self.request("setCommands", {"bot_commands": command})
30
+ async def set_command(self, commands: list[BotCommand]):
31
+ response = await self.request("setCommands", {"bot_commands": [command.to_dict() for command in commands]})
28
32
  return response
29
33
 
30
- async def update_bot_endpoint(self, url: str, type: Literal["ReceiveUpdate", "ReceiveInlineMessage", "ReceiveQuery", "GetSelectionItem", "SearchSelectionItems"]):
34
+ async def update_bot_endpoint(self, url: str, type: enums.UpdateEndpointType):
31
35
  response = await self.request("updateBotEndpoints", {"url": url, "type": type})
32
36
  return response
33
37
 
@@ -49,7 +53,10 @@ class Method(Network):
49
53
  async def forward_message(self, from_chat_id: str, message_id: str, to_chat_id: str, disable_notification: bool = False) -> "MessageId":
50
54
  data = {"from_chat_id": from_chat_id, "message_id": message_id, "to_chat_id": to_chat_id, "disable_notification": disable_notification}
51
55
  response = await self.request("forwardMessage", data)
52
- return MessageId.from_dict(response)
56
+ message = MessageId.from_dict(response)
57
+ message.chat_id = to_chat_id
58
+ message.client = self
59
+ return message
53
60
 
54
61
  async def send_message(
55
62
  self,
@@ -57,7 +64,7 @@ class Method(Network):
57
64
  text: str,
58
65
  chat_keypad: Keypad = None,
59
66
  inline_keypad: Keypad = None,
60
- chat_keypad_type: Literal["New", "Remove"] = None,
67
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
61
68
  disable_notification: bool = None,
62
69
  reply_to_message_id=None
63
70
  ) -> "MessageId":
@@ -70,9 +77,11 @@ class Method(Network):
70
77
  "disable_notification": disable_notification,
71
78
  "reply_to_message_id": reply_to_message_id
72
79
  }
73
- data = {key: value for key, value in data.items() if value is not None}
74
- response = await self.request("sendMessage", data)
75
- return MessageId.from_dict(response)
80
+ response = await self.request("sendMessage", self.clean_data(data))
81
+ message = MessageId.from_dict(response)
82
+ message.chat_id = chat_id
83
+ message.client = self
84
+ return message
76
85
 
77
86
  async def send_poll(
78
87
  self,
@@ -81,9 +90,9 @@ class Method(Network):
81
90
  options: list[str],
82
91
  chat_keypad: Keypad = None,
83
92
  inline_keypad: Keypad = None,
93
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
84
94
  disable_notification: bool = False,
85
95
  reply_to_message_id: str = None,
86
- chat_keypad_type: Literal["New", "Remove"] = None
87
96
  ) -> "MessageId":
88
97
  data = {
89
98
  "chat_id": chat_id,
@@ -95,9 +104,11 @@ class Method(Network):
95
104
  "reply_to_message_id": reply_to_message_id,
96
105
  "chat_keypad_type": chat_keypad_type
97
106
  }
98
- data = {key: value for key, value in data.items() if value is not None}
99
- response = await self.request("sendPoll", data)
100
- return MessageId.from_dict(response)
107
+ response = await self.request("sendPoll", self.clean_data(data))
108
+ message = MessageId.from_dict(response)
109
+ message.chat_id = chat_id
110
+ message.client = self
111
+ return message
101
112
 
102
113
  async def send_location(
103
114
  self,
@@ -106,9 +117,9 @@ class Method(Network):
106
117
  longitude: str,
107
118
  chat_keypad: Keypad = None,
108
119
  inline_keypad: Keypad = None,
120
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
109
121
  disable_notification: bool = False,
110
122
  reply_to_message_id: str = None,
111
- chat_keypad_type: Literal["New", "Remove"] = None
112
123
  ) -> "MessageId":
113
124
  data = {
114
125
  "chat_id": chat_id,
@@ -120,9 +131,11 @@ class Method(Network):
120
131
  "reply_to_message_id": reply_to_message_id,
121
132
  "chat_keypad_type": chat_keypad_type
122
133
  }
123
- data = {key: value for key, value in data.items() if value is not None}
124
- response = await self.request("sendLocation", data)
125
- return MessageId.from_dict(response)
134
+ response = await self.request("sendLocation", self.clean_data(data))
135
+ message = MessageId.from_dict(response)
136
+ message.chat_id = chat_id
137
+ message.client = self
138
+ return message
126
139
 
127
140
  async def send_contact(
128
141
  self,
@@ -132,9 +145,9 @@ class Method(Network):
132
145
  phone_number: str,
133
146
  chat_keypad: Keypad = None,
134
147
  inline_keypad: Keypad = None,
148
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
135
149
  disable_notification: bool = False,
136
150
  reply_to_message_id: str = None,
137
- chat_keypad_type: Literal["New", "Remove"] = None
138
151
  ) -> "MessageId":
139
152
  data = {
140
153
  "chat_id": chat_id,
@@ -147,9 +160,11 @@ class Method(Network):
147
160
  "reply_to_message_id": reply_to_message_id,
148
161
  "chat_keypad_type": chat_keypad_type
149
162
  }
150
- data = {key: value for key, value in data.items() if value is not None}
151
- response = await self.request("sendContact", data)
152
- return MessageId.from_dict(response)
163
+ response = await self.request("sendContact", self.clean_data(data))
164
+ message = MessageId.from_dict(response)
165
+ message.chat_id = chat_id
166
+ message.client = self
167
+ return message
153
168
 
154
169
  async def send_sticker(
155
170
  self,
@@ -157,9 +172,9 @@ class Method(Network):
157
172
  sticker_id: str,
158
173
  chat_keypad: Keypad = None,
159
174
  inline_keypad: Keypad = None,
175
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
160
176
  disable_notification: bool = False,
161
177
  reply_to_message_id: str = None,
162
- chat_keypad_type: Literal["New", "Remove"] = None,
163
178
  ) -> "MessageId":
164
179
  data = {
165
180
  "chat_id": chat_id,
@@ -170,9 +185,11 @@ class Method(Network):
170
185
  "reply_to_message_id": reply_to_message_id,
171
186
  "chat_keypad_type": chat_keypad_type
172
187
  }
173
- data = {key: value for key, value in data.items() if value is not None}
174
- response = await self.request("sendSticker", data)
175
- return MessageId.from_dict(response)
188
+ response = await self.request("sendSticker", self.clean_data(data))
189
+ message = MessageId.from_dict(response)
190
+ message.chat_id = chat_id
191
+ message.client = self
192
+ return message
176
193
 
177
194
  async def request_send_file(self, type: str):
178
195
  response = await self.request("requestSendFile", {"type": type})
@@ -194,10 +211,10 @@ class Method(Network):
194
211
  file: str,
195
212
  file_name: str,
196
213
  caption: str = None,
197
- type: Literal["File", "Image", "Voice", "Music", "Gif", "Video"] = "File",
214
+ type: enums.FileType = enums.FileType.File,
198
215
  chat_keypad: Keypad = None,
199
216
  inline_keypad: Keypad = None,
200
- chat_keypad_type: Literal["New", "Remove"] = None,
217
+ chat_keypad_type: Optional[enums.ChatKeypadType] = None,
201
218
  disable_notification: bool = False,
202
219
  reply_to_message_id: str = None,
203
220
  ) -> "MessageId":
@@ -212,9 +229,12 @@ class Method(Network):
212
229
  "reply_to_message_id": reply_to_message_id,
213
230
  "chat_keypad_type": chat_keypad_type,
214
231
  }
215
- data = {key: value for key, value in data.items() if value is not None}
216
- response = await self.request("sendFile", data)
217
- return MessageId.from_dict(response)
232
+ response = await self.request("sendFile", self.clean_data(data))
233
+ message = MessageId.from_dict(response)
234
+ message.chat_id = chat_id
235
+ message.file_id = file_id
236
+ message.client = self
237
+ return message
218
238
 
219
239
  async def send_document(self, chat_id: str, document: str, name: str, caption: str = None, **kwargs):
220
240
  return await self.send_file(chat_id, document, name, caption, "File", **kwargs)