RubigramClient 1.7.0__py3-none-any.whl → 1.7.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.

Potentially problematic release.


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

Files changed (74) hide show
  1. rubigram/__init__.py +1 -5
  2. rubigram/client.py +102 -154
  3. rubigram/enums.py +4 -3
  4. rubigram/filters.py +600 -139
  5. rubigram/handler.py +24 -0
  6. rubigram/http.py +32 -0
  7. rubigram/logger.py +20 -0
  8. rubigram/method/__init__.py +18 -0
  9. rubigram/method/chat/__init__.py +10 -0
  10. rubigram/method/chat/get_chat.py +26 -0
  11. rubigram/method/chat/get_me.py +22 -0
  12. rubigram/method/chat/get_update.py +32 -0
  13. rubigram/method/decorator/__init__.py +8 -0
  14. rubigram/method/decorator/on_delete_message.py +37 -0
  15. rubigram/method/decorator/on_edit_message.py +37 -0
  16. rubigram/method/decorator/on_inline_message.py +40 -0
  17. rubigram/method/decorator/on_message.py +38 -0
  18. rubigram/method/decorator/on_start.py +30 -0
  19. rubigram/method/decorator/on_stop.py +29 -0
  20. rubigram/method/decorator/register.py +43 -0
  21. rubigram/method/file/__init__.py +32 -0
  22. rubigram/method/file/download_file.py +34 -0
  23. rubigram/method/file/get_bytes.py +25 -0
  24. rubigram/method/file/get_file.py +27 -0
  25. rubigram/method/file/get_file_name.py +29 -0
  26. rubigram/method/file/request_download_file.py +35 -0
  27. rubigram/method/file/request_send_file.py +28 -0
  28. rubigram/method/file/request_upload_file.py +62 -0
  29. rubigram/method/file/send_document.py +58 -0
  30. rubigram/method/file/send_file.py +78 -0
  31. rubigram/method/file/send_gif.py +58 -0
  32. rubigram/method/file/send_music.py +58 -0
  33. rubigram/method/file/send_photo.py +58 -0
  34. rubigram/method/file/send_video.py +58 -0
  35. rubigram/method/file/send_voice.py +55 -0
  36. rubigram/method/messages/__init__.py +29 -0
  37. rubigram/method/messages/delete_message.py +50 -0
  38. rubigram/method/messages/edit_chat_keypad.py +34 -0
  39. rubigram/method/messages/edit_message.py +41 -0
  40. rubigram/method/messages/edit_message_keypad.py +38 -0
  41. rubigram/method/messages/edit_message_text.py +34 -0
  42. rubigram/method/messages/forward_message.py +43 -0
  43. rubigram/method/messages/remove_chat_keypad.py +28 -0
  44. rubigram/method/messages/send_contact.py +74 -0
  45. rubigram/method/messages/send_location.py +70 -0
  46. rubigram/method/messages/send_message.py +67 -0
  47. rubigram/method/messages/send_poll.py +71 -0
  48. rubigram/method/messages/send_sticker.py +66 -0
  49. rubigram/method/network/__init__.py +7 -0
  50. rubigram/method/network/request.py +20 -0
  51. rubigram/method/setting/__init__.py +9 -0
  52. rubigram/method/setting/set_command.py +32 -0
  53. rubigram/method/setting/update_bot_endpoint.py +31 -0
  54. rubigram/method/utilities/__init__.py +11 -0
  55. rubigram/method/utilities/dispatch.py +25 -0
  56. rubigram/method/utilities/setup_endpoint.py +16 -0
  57. rubigram/method/utilities/updater.py +17 -0
  58. rubigram/state.py +14 -19
  59. rubigram/types/__init__.py +3 -0
  60. rubigram/types/messages.py +175 -0
  61. rubigram/types/object.py +112 -0
  62. rubigram/types/types.py +211 -0
  63. rubigram/types/updates.py +572 -0
  64. {rubigramclient-1.7.0.dist-info → rubigramclient-1.7.2.dist-info}/METADATA +12 -8
  65. rubigramclient-1.7.2.dist-info/RECORD +68 -0
  66. rubigram/method.py +0 -354
  67. rubigram/network.py +0 -80
  68. rubigram/rubino/__init__.py +0 -1
  69. rubigram/rubino/client.py +0 -480
  70. rubigram/types.py +0 -538
  71. rubigramclient-1.7.0.dist-info/RECORD +0 -15
  72. {rubigramclient-1.7.0.dist-info → rubigramclient-1.7.2.dist-info}/WHEEL +0 -0
  73. {rubigramclient-1.7.0.dist-info → rubigramclient-1.7.2.dist-info}/licenses/LICENSE +0 -0
  74. {rubigramclient-1.7.0.dist-info → rubigramclient-1.7.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,25 @@
1
+ from typing import Union
2
+ import rubigram
3
+
4
+
5
+ class Dispatch:
6
+ async def dispatch(
7
+ self: "rubigram.Client",
8
+ update: Union[
9
+ "rubigram.types.Update",
10
+ "rubigram.types.InlineMessage"
11
+ ]
12
+ ):
13
+ if isinstance(update, rubigram.types.InlineMessage):
14
+ event_type = "inline"
15
+ else:
16
+ match update.type:
17
+ case "NewMessage": event_type = "message"
18
+ case "UpdatedMessage": event_type = "edit"
19
+ case "RemovedMessage": event_type = "delete"
20
+ case other:
21
+ return
22
+
23
+ for handler in self.handlers[event_type]:
24
+ if handler.filters is None or await handler.filters(update):
25
+ await handler.func(self, update)
@@ -0,0 +1,16 @@
1
+ import rubigram
2
+ from ...logger import logger
3
+
4
+
5
+ class SetupEndpoints:
6
+ async def setup_endpoints(self: "rubigram.Client"):
7
+ endpoint_types = [
8
+ "ReceiveUpdate",
9
+ "ReceiveInlineMessage"
10
+ ]
11
+ for endpoint_type in endpoint_types:
12
+ setup = await self.update_bot_endpoints(
13
+ "{}/{}".format(self.endpoint, endpoint_type),
14
+ endpoint_type
15
+ )
16
+ logger.info("[<] set endpoint for {} : {}".format(endpoint_type, setup["status"]))
@@ -0,0 +1,17 @@
1
+ import rubigram
2
+
3
+
4
+ class Updater:
5
+ async def updater(
6
+ self: "rubigram.Client",
7
+ data: dict
8
+ ):
9
+ if "inline_message" in data:
10
+ event = rubigram.types.InlineMessage.parse(data["inline_message"])
11
+ elif "update" in data:
12
+ event = rubigram.types.Update.parse(data["update"])
13
+ else:
14
+ return
15
+
16
+ event.client = self
17
+ await self.dispatch(event)
rubigram/state.py CHANGED
@@ -1,35 +1,30 @@
1
1
  from typing import Any
2
2
 
3
- class StateManager:
3
+
4
+ class state:
4
5
  def __init__(self):
5
- self.DATA: dict[str, dict[str, Any]] = {}
6
- self.STATE: dict[str, str] = {}
6
+ self.data: dict[str, dict[str, Any]] = {}
7
+ self.state: dict[str, str] = {}
7
8
 
8
-
9
9
  async def set_state(self, user_id: str, state: str):
10
- self.STATE[user_id] = state
11
-
12
-
10
+ self.state[user_id] = state
11
+
13
12
  async def get_state(self, user_id: str):
14
- return self.STATE.get(user_id)
13
+ return self.state.get(user_id)
15
14
 
16
-
17
15
  async def remove_state(self, user_id: str):
18
- self.STATE.pop(user_id, None)
16
+ self.state.pop(user_id, None)
19
17
 
20
-
21
18
  async def set_data(self, user_id: str, **data):
22
- if user_id not in self.DATA:
23
- self.DATA[user_id] = {}
24
- self.DATA[user_id].update(data)
19
+ if user_id not in self.data:
20
+ self.data[user_id] = {}
21
+ self.data[user_id].update(data)
25
22
 
26
-
27
23
  async def get_data(self, user_id: str, key: str = None):
28
- data = self.DATA.get(user_id, {})
24
+ data = self.data.get(user_id, {})
29
25
  return data.get(key) if key else data
30
26
 
31
-
32
27
  async def remove_data(self, user_id: str, key: str = None):
33
28
  if key:
34
- return self.DATA.get(user_id, {}).pop(key, None)
35
- return self.DATA.pop(user_id, None)
29
+ return self.data.get(user_id, {}).pop(key, None)
30
+ return self.data.pop(user_id, None)
@@ -0,0 +1,3 @@
1
+ from .types import *
2
+ from .messages import *
3
+ from .updates import *
@@ -0,0 +1,175 @@
1
+ from typing import Optional
2
+ from dataclasses import dataclass
3
+ from .object import Object
4
+ from .types import *
5
+ import rubigram
6
+
7
+
8
+ @dataclass
9
+ class Message(Object):
10
+ message_id: Optional[str] = None
11
+ text: Optional[str] = None
12
+ time: Optional[str] = None
13
+ is_edited: Optional[bool] = None
14
+ sender_type: Optional[enums.MessageSender] = None
15
+ sender_id: Optional[str] = None
16
+ aux_data: Optional[AuxData] = None
17
+ file: Optional[File] = None
18
+ reply_to_message_id: Optional[str] = None
19
+ forwarded_from: Optional[ForwardedFrom] = None
20
+ forwarded_no_link: Optional[str] = None
21
+ location: Optional[Location] = None
22
+ sticker: Optional[Sticker] = None
23
+ contact_message: Optional[ContactMessage] = None
24
+ poll: Optional[Poll] = None
25
+ live_location: Optional[LiveLocation] = None
26
+ client: Optional["rubigram.Client"] = None
27
+
28
+
29
+ @dataclass
30
+ class InlineMessage(Object):
31
+ sender_id: Optional[str] = None
32
+ text: Optional[str] = None
33
+ message_id: Optional[str] = None
34
+ chat_id: Optional[str] = None
35
+ file: Optional[File] = None
36
+ location: Optional[Location] = None
37
+ aux_data: Optional[AuxData] = None
38
+ client: Optional["rubigram.Client"] = None
39
+
40
+
41
+ @dataclass
42
+ class UMessage(Object):
43
+ message_id: Optional[str] = None
44
+ file_id: Optional[str] = None
45
+ chat_id: Optional[str] = None
46
+ client: Optional["rubigram.Client"] = None
47
+
48
+ async def delete(self):
49
+ """Delete this message from the chat.
50
+
51
+ Sends a request to Rubigram to remove the message identified
52
+ by this object's `message_id` from its chat.
53
+
54
+ Args:
55
+ self (UMessage): The message instance to be deleted.
56
+
57
+ Returns:
58
+ bool: True if the message was successfully deleted, False otherwise.
59
+
60
+ Example:
61
+ >>> message = await client.send_message(chat_id="b0X123", text="Hello!")
62
+ >>> await message.delete()
63
+ """
64
+ return await self.client.delete_message(
65
+ self.chat_id, self.message_id
66
+ )
67
+
68
+ async def edit(
69
+ self,
70
+ text: Optional[str] = None,
71
+ inline: Optional[Keypad] = None,
72
+ keypad: Optional[Keypad] = None
73
+ ):
74
+ """Edit this message's content, inline keyboard, or chat keypad.
75
+
76
+ This method allows modifying the text, inline keyboard, or chat keypad
77
+ of the current message. You can use any combination of parameters to
78
+ update different parts of the message.
79
+
80
+ Args:
81
+ self (UMessage): The message instance to edit.
82
+ text (Optional[str], optional): New text content for the message. Defaults to None.
83
+ inline (Optional[Keypad], optional): Inline keyboard to attach to the message. Defaults to None.
84
+ keypad (Optional[Keypad], optional): Chat keypad to attach to the message. Defaults to None.
85
+
86
+ Returns:
87
+ None
88
+
89
+ Example:
90
+ >>> message = await client.send_message(chat_id="b0X123", text="Hello!")
91
+ >>> await message.edit(text="Updated text")
92
+ >>> await message.edit(inline=my_inline_keypad)
93
+ >>> await message.edit(keypad=my_chat_keypad)
94
+ """
95
+ if text:
96
+ await self.edit_text(text)
97
+ if inline:
98
+ await self.edit_inline(inline)
99
+ if keypad:
100
+ await self.edit_keypad(keypad)
101
+
102
+ async def edit_text(self, text: str):
103
+ """Edit the text content of this message.
104
+
105
+ Args:
106
+ self (UMessage): The message instance to edit.
107
+ text (str): New text to replace the current message content.
108
+
109
+ Returns:
110
+ UMessage: The updated message object returned by the client.
111
+
112
+ Example:
113
+ >>> await message.edit_text("Updated text content")
114
+ """
115
+ return await self.client.edit_message_text(
116
+ self.chat_id,
117
+ self.message_id,
118
+ text
119
+ )
120
+
121
+ async def edit_inline(self, inline: Keypad):
122
+ """Edit the inline keyboard of this message.
123
+
124
+ Args:
125
+ self (UMessage): The message instance to edit.
126
+ inline (Keypad): New inline keyboard to attach to the message.
127
+
128
+ Returns:
129
+ UMessage: The updated message object returned by the client.
130
+
131
+ Example:
132
+ >>> await message.edit_inline(my_inline_keypad)
133
+ """
134
+ return await self.client.edit_message_keypad(
135
+ self.chat_id,
136
+ self.message_id,
137
+ inline
138
+ )
139
+
140
+ async def edit_keypad(self, keypad: Keypad):
141
+ """Edit the chat keypad for this message's chat.
142
+
143
+ Args:
144
+ self (UMessage): The message instance whose chat keypad will be edited.
145
+ keypad (Keypad): New chat keypad to attach.
146
+
147
+ Returns:
148
+ UMessage: The updated message object returned by the client.
149
+
150
+ Example:
151
+ >>> await message.edit_keypad(my_chat_keypad)
152
+ """
153
+ return await self.client.edit_chat_keypad(
154
+ self.chat_id,
155
+ keypad
156
+ )
157
+
158
+ async def forward(self, chat_id: str):
159
+ """Forward this message to another chat.
160
+
161
+ Args:
162
+ self (UMessage): The message instance to forward.
163
+ chat_id (str): ID of the chat to forward the message to.
164
+
165
+ Returns:
166
+ UMessage: The forwarded message object returned by the client.
167
+
168
+ Example:
169
+ >>> await message.forward("b0AnotherChat")
170
+ """
171
+ return await self.client.forward_message(
172
+ self.chat_id,
173
+ self.message_id,
174
+ chat_id
175
+ )
@@ -0,0 +1,112 @@
1
+ import sys
2
+ from typing import Union, TypeVar, Type, get_origin, get_args, get_type_hints
3
+ from dataclasses import dataclass, fields
4
+ from json import dumps
5
+
6
+ T = TypeVar("T", bound="Object")
7
+
8
+
9
+ @dataclass
10
+ class Object:
11
+
12
+ def asdict(self):
13
+ data = {}
14
+ for f in fields(self):
15
+ value = getattr(self, f.name)
16
+ if isinstance(value, Object):
17
+ inner = value.asdict()
18
+ data[f.name] = {"_": value.__class__.__name__, **inner}
19
+ elif isinstance(value, list):
20
+ data[f.name] = [
21
+ {"_": v.__class__.__name__, **v.asdict()} if isinstance(v, Object) else v for v in value
22
+ ]
23
+ else:
24
+ data[f.name] = value
25
+ return data
26
+
27
+ def jsonify(self, exclude_none: bool = False) -> str:
28
+ def clear(obj):
29
+ if isinstance(obj, dict):
30
+ return {k: clear(v) for k, v in obj.items() if v is not None}
31
+ elif isinstance(obj, list):
32
+ return [clear(i) for i in obj if i is not None]
33
+ else:
34
+ return obj
35
+
36
+ data = self.asdict()
37
+ data.pop("client", None)
38
+ if exclude_none:
39
+ data = clear(data)
40
+ return dumps(
41
+ {"_": self.__class__.__name__, **data},
42
+ ensure_ascii=False,
43
+ indent=4
44
+ )
45
+
46
+ @classmethod
47
+ def parse(cls: Type[T], data: dict) -> T:
48
+ data = data or {}
49
+ init_data = {}
50
+
51
+ try:
52
+ module = sys.modules[cls.__module__]
53
+ type_hints = get_type_hints(
54
+ cls, globalns=module.__dict__, localns=None)
55
+ except Exception:
56
+ type_hints = {}
57
+
58
+ for field in fields(cls):
59
+ raw_value = data.get(field.name)
60
+ if isinstance(raw_value, dict) and "_" in raw_value:
61
+ raw_value = {k: v for k, v in raw_value.items() if k != "_"}
62
+
63
+ field_type = type_hints.get(field.name, field.type)
64
+ origin = get_origin(field_type)
65
+
66
+ if origin is Union:
67
+ args = get_args(field_type)
68
+ non_none_args = [arg for arg in args if arg is not type(None)]
69
+ if len(non_none_args) == 1:
70
+ field_type = non_none_args[0]
71
+ origin = get_origin(field_type)
72
+ else:
73
+ pass
74
+
75
+ if isinstance(raw_value, dict) and isinstance(field_type, type) and issubclass(field_type, Object):
76
+ init_data[field.name] = field_type.parse(raw_value)
77
+
78
+ elif origin == list:
79
+ inner_type = get_args(field_type)[0]
80
+ inner_origin = get_origin(inner_type)
81
+ if inner_origin is Union:
82
+ inner_args = [a for a in get_args(
83
+ inner_type) if a is not type(None)]
84
+ inner_type = inner_args[0] if inner_args else inner_type
85
+
86
+ if isinstance(raw_value, list):
87
+ if isinstance(inner_type, type) and issubclass(inner_type, Object):
88
+ init_data[field.name] = [
89
+ inner_type.parse(v) if isinstance(v, dict) else v for v in raw_value
90
+ ]
91
+ else:
92
+ init_data[field.name] = raw_value
93
+ else:
94
+ init_data[field.name] = [
95
+ ] if raw_value is None else raw_value
96
+
97
+ elif origin is Union:
98
+ args = get_args(field_type)
99
+ obj_arg = next((arg for arg in args if isinstance(
100
+ arg, type) and issubclass(arg, Object)), None)
101
+ if obj_arg and isinstance(raw_value, dict):
102
+ init_data[field.name] = obj_arg.parse(raw_value)
103
+ else:
104
+ init_data[field.name] = raw_value
105
+
106
+ else:
107
+ init_data[field.name] = raw_value
108
+
109
+ return cls(**init_data)
110
+
111
+ def __str__(self):
112
+ return self.jsonify(True)
@@ -0,0 +1,211 @@
1
+ from typing import Optional, Union
2
+ from dataclasses import dataclass, field
3
+ from .. import enums
4
+ from .object import Object
5
+
6
+
7
+ @dataclass
8
+ class Chat(Object):
9
+ chat_id: Optional[str] = None
10
+ chat_type: Optional[enums.ChatType] = None
11
+ user_id: Optional[str] = None
12
+ first_name: Optional[str] = None
13
+ last_name: Optional[str] = None
14
+ title: Optional[str] = None
15
+ username: Optional[str] = None
16
+
17
+
18
+ @dataclass
19
+ class File(Object):
20
+ file_id: Optional[str] = None
21
+ file_name: Optional[str] = None
22
+ size: Optional[int] = None
23
+
24
+
25
+ @dataclass
26
+ class ForwardedFrom(Object):
27
+ type_from: Optional[enums.ForwardedFrom] = None
28
+ message_id: Optional[str] = None
29
+ from_chat_id: Optional[str] = None
30
+ from_sender_id: Optional[str] = None
31
+
32
+
33
+ @dataclass
34
+ class PaymentStatus(Object):
35
+ payment_id: Optional[str] = None
36
+ status: Optional[Union[str, enums.PaymentStatus]] = None
37
+
38
+
39
+ @dataclass
40
+ class Bot(Object):
41
+ bot_id: Optional[str] = None
42
+ bot_title: Optional[str] = None
43
+ avatar: Optional[File] = None
44
+ description: Optional[str] = None
45
+ username: Optional[str] = None
46
+ start_message: Optional[str] = None
47
+ share_url: Optional[str] = None
48
+
49
+
50
+ @dataclass
51
+ class BotCommand(Object):
52
+ command: Optional[str] = None
53
+ description: Optional[str] = None
54
+
55
+
56
+ @dataclass
57
+ class Sticker(Object):
58
+ sticker_id: Optional[str] = None
59
+ file: Optional[File] = None
60
+ emoji_character: Optional[str] = None
61
+
62
+
63
+ @dataclass
64
+ class ContactMessage(Object):
65
+ phone_number: Optional[str] = None
66
+ first_name: Optional[str] = None
67
+ last_name: Optional[str] = None
68
+
69
+
70
+ @dataclass
71
+ class PollStatus(Object):
72
+ state: Optional[Union[str, enums.PollStatus]] = None
73
+ selection_index: Optional[int] = None
74
+ percent_vote_options: Optional[list[int]] = None
75
+ total_vote: Optional[int] = None
76
+ show_total_votes: Optional[bool] = None
77
+
78
+
79
+ @dataclass
80
+ class Poll(Object):
81
+ question: Optional[str] = None
82
+ options: Optional[list[str]] = None
83
+ poll_status: Optional[PollStatus] = None
84
+
85
+
86
+ @dataclass
87
+ class Location(Object):
88
+ longitude: Optional[str] = None
89
+ latitude: Optional[str] = None
90
+
91
+
92
+ @dataclass
93
+ class LiveLocation(Object):
94
+ start_time: Optional[str] = None
95
+ live_period: Optional[int] = None
96
+ current_location: Optional[Location] = None
97
+ user_id: Optional[str] = None
98
+ status: Optional[Union[str, enums.LiveLocationStatus]] = None
99
+ last_update_time: Optional[str] = None
100
+
101
+
102
+ @dataclass
103
+ class ButtonSelectionItem(Object):
104
+ text: Optional[str] = None
105
+ image_url: Optional[str] = None
106
+ type: Optional[Union[str, enums.ButtonSelectionType]] = None
107
+
108
+
109
+ @dataclass
110
+ class ButtonSelection(Object):
111
+ selection_id: Optional[str] = None
112
+ search_type: Optional[str] = None
113
+ get_type: Optional[str] = None
114
+ items: Optional[list[ButtonSelectionItem]] = None
115
+ is_multi_selection: Optional[bool] = None
116
+ columns_count: Optional[str] = None
117
+ title: Optional[str] = None
118
+
119
+
120
+ @dataclass
121
+ class ButtonCalendar(Object):
122
+ default_value: Optional[str] = None
123
+ type: Optional[Union[str, enums.ButtonCalendarType]] = None
124
+ min_year: Optional[str] = None
125
+ max_year: Optional[str] = None
126
+ title: Optional[str] = None
127
+
128
+
129
+ @dataclass
130
+ class ButtonNumberPicker(Object):
131
+ min_value: Optional[str] = None
132
+ max_value: Optional[str] = None
133
+ default_value: Optional[str] = None
134
+ title: Optional[str] = None
135
+
136
+
137
+ @dataclass
138
+ class ButtonStringPicker(Object):
139
+ items: Optional[list[str]] = None
140
+ default_value: Optional[str] = None
141
+ title: Optional[str] = None
142
+
143
+
144
+ @dataclass
145
+ class ButtonTextbox(Object):
146
+ type_line: Optional[Union[str, enums.ButtonTextboxTypeLine]] = None
147
+ type_keypad: Optional[Union[str, enums.ButtonTextboxTypeKeypad]] = None
148
+ place_holder: Optional[str] = None
149
+ title: Optional[str] = None
150
+ default_value: Optional[str] = None
151
+
152
+
153
+ @dataclass
154
+ class ButtonLocation(Object):
155
+ default_pointer_location: Optional[Location] = None
156
+ default_map_location: Optional[Location] = None
157
+ type: Optional[Union[str, enums.ButtonLocationType]] = None
158
+ title: Optional[str] = None
159
+ location_image_url: Optional[str] = None
160
+
161
+
162
+ @dataclass
163
+ class OpenChatData(Object):
164
+ Object_guid: Optional[str] = None
165
+ Object_type: Optional[Union[str, enums.ChatType]] = None
166
+
167
+
168
+ @dataclass
169
+ class JoinChannelData(Object):
170
+ username: Optional[str] = None
171
+ ask_join: bool = False
172
+
173
+
174
+ @dataclass
175
+ class ButtonLink(Object):
176
+ type: Optional[Union[str, enums.ButtonLinkType]] = None
177
+ link_url: Optional[str] = None
178
+ joinchannel_data: Optional[JoinChannelData] = None
179
+ open_chat_data: Optional[OpenChatData] = None
180
+
181
+
182
+ @dataclass
183
+ class AuxData(Object):
184
+ start_id: Optional[str] = None
185
+ button_id: Optional[str] = None
186
+
187
+
188
+ @dataclass
189
+ class Button(Object):
190
+ id: Optional[str] = None
191
+ button_text: Optional[str] = None
192
+ type: Optional[Union[str, enums.ButtonType]] = enums.ButtonType.Simple
193
+ button_selection: Optional[ButtonSelection] = None
194
+ button_calendar: Optional[ButtonCalendar] = None
195
+ button_number_picker: Optional[ButtonNumberPicker] = None
196
+ button_string_picker: Optional[ButtonStringPicker] = None
197
+ button_location: Optional[ButtonLocation] = None
198
+ button_textbox: Optional[ButtonTextbox] = None
199
+ button_link: Optional[ButtonLink] = None
200
+
201
+
202
+ @dataclass
203
+ class KeypadRow(Object):
204
+ buttons: list[Button] = field(default_factory=list)
205
+
206
+
207
+ @dataclass
208
+ class Keypad(Object):
209
+ rows: list[KeypadRow] = field(default_factory=list)
210
+ resize_keyboard: bool = True
211
+ on_time_keyboard: bool = False