tlgr-cli 2.0.1__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.
Files changed (192) hide show
  1. tlgr/__init__.py +3 -0
  2. tlgr/__main__.py +6 -0
  3. tlgr/actions/__init__.py +45 -0
  4. tlgr/actions/forward.py +74 -0
  5. tlgr/actions/reply.py +32 -0
  6. tlgr/cli/__init__.py +259 -0
  7. tlgr/cli/confirm.py +55 -0
  8. tlgr/cli/errors.py +84 -0
  9. tlgr/cli/gen.py +690 -0
  10. tlgr/cli/globals.py +273 -0
  11. tlgr/cli/introspect.py +170 -0
  12. tlgr/cli/params.py +189 -0
  13. tlgr/cli/render.py +418 -0
  14. tlgr/core/__init__.py +0 -0
  15. tlgr/core/accounts.py +384 -0
  16. tlgr/core/config.py +358 -0
  17. tlgr/core/custom_tl.py +170 -0
  18. tlgr/core/errors.py +687 -0
  19. tlgr/core/eventtypes.py +1170 -0
  20. tlgr/core/identity.py +127 -0
  21. tlgr/core/launchd.py +122 -0
  22. tlgr/core/logging.py +194 -0
  23. tlgr/core/media.py +134 -0
  24. tlgr/core/output.py +251 -0
  25. tlgr/core/pagination.py +227 -0
  26. tlgr/core/paths.py +360 -0
  27. tlgr/core/peers.py +427 -0
  28. tlgr/core/process.py +138 -0
  29. tlgr/core/signing.py +38 -0
  30. tlgr/core/systemd.py +96 -0
  31. tlgr/core/telethon_compat.py +295 -0
  32. tlgr/core/text.py +211 -0
  33. tlgr/core/timefmt.py +199 -0
  34. tlgr/core/tl.py +98 -0
  35. tlgr/daemon/__init__.py +0 -0
  36. tlgr/daemon/app.py +869 -0
  37. tlgr/daemon/dispatch.py +446 -0
  38. tlgr/daemon/events.py +723 -0
  39. tlgr/daemon/files.py +431 -0
  40. tlgr/daemon/idle.py +119 -0
  41. tlgr/daemon/jobs.py +68 -0
  42. tlgr/daemon/main.py +161 -0
  43. tlgr/daemon/peercred.py +75 -0
  44. tlgr/daemon/policy.py +113 -0
  45. tlgr/daemon/preauth.py +366 -0
  46. tlgr/daemon/ratelimit.py +391 -0
  47. tlgr/daemon/server.py +24 -0
  48. tlgr/daemon/session.py +648 -0
  49. tlgr/daemon/sessions.py +274 -0
  50. tlgr/daemon/singleton.py +114 -0
  51. tlgr/daemon/stream.py +193 -0
  52. tlgr/daemon/transfers.py +219 -0
  53. tlgr/daemon/webhook.py +390 -0
  54. tlgr/data/catalog_index.json +1 -0
  55. tlgr/data/parity_waivers.toml +90 -0
  56. tlgr/filters/__init__.py +42 -0
  57. tlgr/filters/compose.py +121 -0
  58. tlgr/filters/content.py +85 -0
  59. tlgr/filters/context.py +114 -0
  60. tlgr/filters/message.py +161 -0
  61. tlgr/filters/temporal.py +87 -0
  62. tlgr/filters/user.py +36 -0
  63. tlgr/gateway/__init__.py +1 -0
  64. tlgr/gateway/config.py +161 -0
  65. tlgr/gateway/engine.py +215 -0
  66. tlgr/gateway/event.py +22 -0
  67. tlgr/jobs/__init__.py +0 -0
  68. tlgr/jobs/base.py +81 -0
  69. tlgr/jobs/client.py +37 -0
  70. tlgr/models/__init__.py +1220 -0
  71. tlgr/models/admin.py +744 -0
  72. tlgr/models/auth.py +510 -0
  73. tlgr/models/base.py +81 -0
  74. tlgr/models/bot.py +576 -0
  75. tlgr/models/business.py +265 -0
  76. tlgr/models/call.py +586 -0
  77. tlgr/models/config.py +101 -0
  78. tlgr/models/contact.py +481 -0
  79. tlgr/models/daemon.py +336 -0
  80. tlgr/models/dialog.py +626 -0
  81. tlgr/models/envelope.py +68 -0
  82. tlgr/models/error.py +30 -0
  83. tlgr/models/event.py +79 -0
  84. tlgr/models/export.py +66 -0
  85. tlgr/models/gift.py +275 -0
  86. tlgr/models/inline.py +84 -0
  87. tlgr/models/location.py +115 -0
  88. tlgr/models/media.py +507 -0
  89. tlgr/models/message.py +584 -0
  90. tlgr/models/net.py +232 -0
  91. tlgr/models/notify.py +105 -0
  92. tlgr/models/page.py +32 -0
  93. tlgr/models/payment.py +172 -0
  94. tlgr/models/peer.py +400 -0
  95. tlgr/models/poll.py +119 -0
  96. tlgr/models/premium.py +161 -0
  97. tlgr/models/privacy.py +93 -0
  98. tlgr/models/profile.py +217 -0
  99. tlgr/models/reaction.py +160 -0
  100. tlgr/models/resolve.py +175 -0
  101. tlgr/models/settings.py +103 -0
  102. tlgr/models/stars.py +101 -0
  103. tlgr/models/sticker.py +243 -0
  104. tlgr/models/story.py +467 -0
  105. tlgr/models/sync.py +105 -0
  106. tlgr/models/todo.py +36 -0
  107. tlgr/models/webapp.py +89 -0
  108. tlgr/ops/__init__.py +63 -0
  109. tlgr/ops/_admin.py +313 -0
  110. tlgr/ops/_auth.py +599 -0
  111. tlgr/ops/_bots.py +586 -0
  112. tlgr/ops/_calls.py +535 -0
  113. tlgr/ops/_common.py +160 -0
  114. tlgr/ops/_layer.py +46 -0
  115. tlgr/ops/_media.py +592 -0
  116. tlgr/ops/_params.py +212 -0
  117. tlgr/ops/_rights.py +402 -0
  118. tlgr/ops/_send.py +593 -0
  119. tlgr/ops/_serialize.py +667 -0
  120. tlgr/ops/_settings.py +306 -0
  121. tlgr/ops/_spec.py +167 -0
  122. tlgr/ops/_story.py +743 -0
  123. tlgr/ops/account.py +2604 -0
  124. tlgr/ops/agent.py +937 -0
  125. tlgr/ops/auth.py +1282 -0
  126. tlgr/ops/bot.py +4880 -0
  127. tlgr/ops/business.py +1520 -0
  128. tlgr/ops/call.py +1610 -0
  129. tlgr/ops/chat.py +4025 -0
  130. tlgr/ops/chat_admin.py +929 -0
  131. tlgr/ops/chat_extra.py +1061 -0
  132. tlgr/ops/chat_invite.py +716 -0
  133. tlgr/ops/chat_manage.py +1691 -0
  134. tlgr/ops/chat_member.py +1357 -0
  135. tlgr/ops/chat_stats.py +902 -0
  136. tlgr/ops/chat_topic.py +905 -0
  137. tlgr/ops/conference.py +791 -0
  138. tlgr/ops/config.py +1698 -0
  139. tlgr/ops/contact.py +2330 -0
  140. tlgr/ops/daemon.py +1397 -0
  141. tlgr/ops/draft.py +299 -0
  142. tlgr/ops/emoji.py +343 -0
  143. tlgr/ops/events.py +1327 -0
  144. tlgr/ops/export.py +596 -0
  145. tlgr/ops/folder.py +1322 -0
  146. tlgr/ops/gif.py +522 -0
  147. tlgr/ops/gift.py +1546 -0
  148. tlgr/ops/giveaway.py +541 -0
  149. tlgr/ops/inline.py +773 -0
  150. tlgr/ops/job.py +799 -0
  151. tlgr/ops/location.py +917 -0
  152. tlgr/ops/media.py +4495 -0
  153. tlgr/ops/message.py +3769 -0
  154. tlgr/ops/net.py +536 -0
  155. tlgr/ops/notify.py +840 -0
  156. tlgr/ops/passport.py +464 -0
  157. tlgr/ops/payment.py +907 -0
  158. tlgr/ops/poll.py +1078 -0
  159. tlgr/ops/premium.py +488 -0
  160. tlgr/ops/privacy.py +794 -0
  161. tlgr/ops/profile.py +1481 -0
  162. tlgr/ops/proxy.py +750 -0
  163. tlgr/ops/reaction.py +1475 -0
  164. tlgr/ops/resolve.py +1140 -0
  165. tlgr/ops/search.py +521 -0
  166. tlgr/ops/settings.py +1066 -0
  167. tlgr/ops/stars.py +594 -0
  168. tlgr/ops/sticker.py +1602 -0
  169. tlgr/ops/story.py +3216 -0
  170. tlgr/ops/sync.py +788 -0
  171. tlgr/ops/todo.py +514 -0
  172. tlgr/ops/user.py +1406 -0
  173. tlgr/ops/vc.py +2351 -0
  174. tlgr/ops/webapp.py +717 -0
  175. tlgr/ops/webhook.py +418 -0
  176. tlgr/parity.py +386 -0
  177. tlgr/processors/__init__.py +125 -0
  178. tlgr/processors/regex.py +26 -0
  179. tlgr/processors/text.py +56 -0
  180. tlgr/registry.py +519 -0
  181. tlgr/schema.py +173 -0
  182. tlgr/transport/__init__.py +30 -0
  183. tlgr/transport/autostart.py +293 -0
  184. tlgr/transport/client.py +805 -0
  185. tlgr/transport/ndjson.py +44 -0
  186. tlgr/version.py +31 -0
  187. tlgr_cli-2.0.1.dist-info/METADATA +957 -0
  188. tlgr_cli-2.0.1.dist-info/RECORD +192 -0
  189. tlgr_cli-2.0.1.dist-info/WHEEL +5 -0
  190. tlgr_cli-2.0.1.dist-info/entry_points.txt +2 -0
  191. tlgr_cli-2.0.1.dist-info/licenses/LICENSE +21 -0
  192. tlgr_cli-2.0.1.dist-info/top_level.txt +1 -0
tlgr/models/bot.py ADDED
@@ -0,0 +1,576 @@
1
+ """The bot surface's wire shapes: profile cards, buttons, queries and games.
2
+
3
+ Two of these shapes carry more weight than the rest.
4
+
5
+ `Keyboard`/`KeyboardButton` are the **write** side of the reply-markup schema
6
+ whose read side is `models.message.ReplyMarkup`. One JSON document therefore
7
+ round-trips: `message get --json` prints a keyboard, `bot press --button` can
8
+ address a button in it by the `n` that listing printed, and `bot welcome set
9
+ --keyboard` can send the same document back. Two schemas for one object is how
10
+ a button that can be read stops being a button that can be pressed.
11
+
12
+ `Pressed` is deliberately one model for every button kind rather than a union.
13
+ A caller pressing a button does not know in advance whether the answer is a
14
+ toast, a URL, a mini-app session or a list of inline results — that is what
15
+ the bot decides — so `kind` names what came back and the rest of the fields
16
+ are the ones that kind fills in.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from typing import Any
22
+
23
+ from tlgr.models.base import Model
24
+
25
+ __all__ = [
26
+ "AttachMenuBot",
27
+ "BotAccess",
28
+ "BotAnswer",
29
+ "BotApiResult",
30
+ "BotCommand",
31
+ "BotCommandSet",
32
+ "BotCreated",
33
+ "BotEdited",
34
+ "BotIds",
35
+ "BotInfo",
36
+ "BotPermission",
37
+ "BotQuery",
38
+ "BotRef",
39
+ "BotStarted",
40
+ "BotStopped",
41
+ "BotToken",
42
+ "BotUsernameCheck",
43
+ "BotUsernames",
44
+ "BotVerification",
45
+ "BotVerified",
46
+ "BotWelcomeMessage",
47
+ "BusinessConnection",
48
+ "CommandSent",
49
+ "DefaultRights",
50
+ "EmojiGame",
51
+ "EphemeralDeleted",
52
+ "EphemeralSent",
53
+ "GameSent",
54
+ "HighScore",
55
+ "Keyboard",
56
+ "KeyboardButton",
57
+ "MenuButton",
58
+ "Pressed",
59
+ "PreviewChange",
60
+ "PreviewMedia",
61
+ "RecentBots",
62
+ "ReportOutcome",
63
+ "ScoreSet",
64
+ "SponsoredRead",
65
+ "StarRefProgram",
66
+ "StreamProgress",
67
+ "ToggledAttachMenu",
68
+ "UrlAuth",
69
+ "WelcomeDeleted",
70
+ "WelcomeSet",
71
+ ]
72
+
73
+
74
+ # ---------------------------------------------------------------------------
75
+ # The reply-markup write side
76
+ # ---------------------------------------------------------------------------
77
+
78
+
79
+ class KeyboardButton(Model):
80
+ """One button, in the schema `--keyboard`/`--buttons` files use.
81
+
82
+ `type` is the same vocabulary `models.message.Button.type` prints, so a
83
+ button that was read back can be written out again unchanged.
84
+ """
85
+
86
+ text: str
87
+ type: str = "text"
88
+ #: callback payload; UTF-8 text, or `hex:…` for bytes that are not text.
89
+ data: str | None = None
90
+ url: str | None = None
91
+ query: str | None = None
92
+ user_id: int | None = None
93
+ requires_password: bool = False
94
+ same_peer: bool = False
95
+ copy_text: str | None = None
96
+ button_id: int | None = None
97
+ fwd_text: str | None = None
98
+ request_write_access: bool = False
99
+
100
+
101
+ class Keyboard(Model):
102
+ """A whole reply markup: rows of buttons plus the keyboard's own flags."""
103
+
104
+ kind: str = "inline"
105
+ rows: list[list[KeyboardButton]] = []
106
+ resize: bool = False
107
+ single_use: bool = False
108
+ selective: bool = False
109
+ persistent: bool = False
110
+ placeholder: str | None = None
111
+
112
+
113
+ # ---------------------------------------------------------------------------
114
+ # Profile
115
+ # ---------------------------------------------------------------------------
116
+
117
+
118
+ class BotCommand(Model):
119
+ """One slash command a bot declares."""
120
+
121
+ bot_id: int = 0
122
+ command: str = ""
123
+ description: str = ""
124
+ ephemeral: bool = False
125
+ scope: str | None = None
126
+ lang: str | None = None
127
+ #: The GUI's "Bot Help" / "Bot Settings" entries exist only when the bot
128
+ #: declares `/help` and `/settings`; reporting them as always-true would
129
+ #: put two dead menu items in front of the user.
130
+ has_help: bool = False
131
+ has_settings: bool = False
132
+
133
+
134
+ class MenuButton(Model):
135
+ """The button left of the message input: commands, a mini app, or default.
136
+
137
+ `kind` has no default: "commands" is a real answer the server gives, and a
138
+ field omitted because it happened to equal a default would make "the bot
139
+ shows its commands" indistinguishable from "tlgr did not look".
140
+ """
141
+
142
+ kind: str = ""
143
+ text: str | None = None
144
+ url: str | None = None
145
+ user_id: int | None = None
146
+
147
+
148
+ class BotVerification(Model):
149
+ """A third-party verification badge, next to Telegram's own `verified`."""
150
+
151
+ verified_by_bot: int | None = None
152
+ description: str | None = None
153
+ icon: int | None = None
154
+ telegram_verified: bool = False
155
+
156
+
157
+ class StarRefProgram(Model):
158
+ """A bot's affiliate (star-ref) program, or my connection to one."""
159
+
160
+ bot_id: int = 0
161
+ url: str | None = None
162
+ commission_permille: int = 0
163
+ duration_months: int | None = None
164
+ end_date: str | None = None
165
+ end_date_unix: int | None = None
166
+ participants: int | None = None
167
+ revenue: int | None = None
168
+ date: str | None = None
169
+ date_unix: int | None = None
170
+ revoked: bool = False
171
+
172
+
173
+ class BotAccess(Model):
174
+ """Who may use a managed bot.
175
+
176
+ `restricted` is a tri-state on the wire on purpose: `omit_defaults` would
177
+ drop a plain `False`, and "anyone may use this bot" is an answer, not the
178
+ absence of one.
179
+ """
180
+
181
+ restricted: bool | None = None
182
+ allowed_users: list[int] = []
183
+ allowed_chats: list[int] = []
184
+
185
+
186
+ class BotInfo(Model):
187
+ """A bot's profile card, as `userFull.bot_info` and the user flags carry it."""
188
+
189
+ id: int = 0
190
+ username: str | None = None
191
+ usernames: list[str] = []
192
+ first_name: str | None = None
193
+ about: str | None = None
194
+ description: str | None = None
195
+ description_photo: int | None = None
196
+ description_document: int | None = None
197
+ privacy_policy_url: str | None = None
198
+ commands: list[BotCommand] = []
199
+ menu_button: MenuButton | None = None
200
+ app_settings: dict[str, Any] | None = None
201
+ verifier_settings: dict[str, Any] | None = None
202
+ bot_verification: BotVerification | None = None
203
+ bot_info_version: int | None = None
204
+ bot_active_users: int | None = None
205
+ bot_can_edit: bool = False
206
+ bot_has_main_app: bool = False
207
+ bot_nochats: bool = False
208
+ bot_business: bool = False
209
+ bot_attach_menu: bool = False
210
+ bot_inline_geo: bool = False
211
+ inline_placeholder: str | None = None
212
+ bot_group_admin_rights: list[str] = []
213
+ bot_broadcast_admin_rights: list[str] = []
214
+ has_preview_medias: bool = False
215
+ starref_program: StarRefProgram | None = None
216
+ blocked: bool = False
217
+ access: BotAccess | None = None
218
+ lang: str | None = None
219
+
220
+
221
+ class BotRef(Model):
222
+ """A row in any of the four bot listings."""
223
+
224
+ id: int = 0
225
+ username: str | None = None
226
+ title: str | None = None
227
+ kind: str = "bot"
228
+ active_users: int | None = None
229
+ #: Non-Premium accounts get a shortened similar-bots list plus a count.
230
+ truncated_count: int | None = None
231
+ rating: float | None = None
232
+
233
+
234
+ class BotIds(Model):
235
+ """The same peer in both id dialects."""
236
+
237
+ mtproto_id: int = 0
238
+ bot_api_id: int = 0
239
+ kind: str = ""
240
+ has_access_hash: bool = False
241
+ username: str | None = None
242
+
243
+
244
+ class BotUsernameCheck(Model):
245
+ username: str = ""
246
+ #: None only if nothing was checked; a real answer is always emitted.
247
+ available: bool | None = None
248
+ reason: str | None = None
249
+
250
+
251
+ class BotUsernames(Model):
252
+ bot_id: int = 0
253
+ usernames: list[str] = []
254
+
255
+
256
+ class BotCreated(Model):
257
+ bot_id: int = 0
258
+ username: str = ""
259
+ manager: int | None = None
260
+ token_available: bool = False
261
+
262
+
263
+ class BotEdited(Model):
264
+ bot_id: int = 0
265
+ name: str | None = None
266
+ about: str | None = None
267
+ description: str | None = None
268
+ lang: str | None = None
269
+ photo_id: int | None = None
270
+
271
+
272
+ class BotToken(Model):
273
+ """A managed bot's credential. Redacted unless the caller asked to see it."""
274
+
275
+ bot_id: int = 0
276
+ token: str | None = None
277
+ revoked: bool = False
278
+ path: str | None = None
279
+
280
+
281
+ class DefaultRights(Model):
282
+ group_rights: list[str] = []
283
+ channel_rights: list[str] = []
284
+
285
+
286
+ class BotPermission(Model):
287
+ bot_id: int = 0
288
+ can_send_messages: bool | None = None
289
+ emoji_status_allowed: bool | None = None
290
+ key: str | None = None
291
+ state: str | None = None
292
+ already: bool = False
293
+
294
+
295
+ class BotVerified(Model):
296
+ peer_id: int = 0
297
+ verified: bool | None = None
298
+ description: str | None = None
299
+
300
+
301
+ class PreviewMedia(Model):
302
+ index: int = 0
303
+ kind: str = "photo"
304
+ date: str | None = None
305
+ date_unix: int | None = None
306
+ lang: str | None = None
307
+ file_id: int | None = None
308
+ size: int | None = None
309
+
310
+
311
+ class PreviewChange(Model):
312
+ index: int | None = None
313
+ kind: str | None = None
314
+ lang: str | None = None
315
+ order: list[int] = []
316
+ deleted: int = 0
317
+ remaining: int = 0
318
+
319
+
320
+ # ---------------------------------------------------------------------------
321
+ # Lifecycle
322
+ # ---------------------------------------------------------------------------
323
+
324
+
325
+ class BotStarted(Model):
326
+ bot_id: int = 0
327
+ chat_id: int = 0
328
+ msg_id: int = 0
329
+ start_param: str | None = None
330
+ admin_rights: list[str] = []
331
+ unblocked: bool = False
332
+
333
+
334
+ class BotStopped(Model):
335
+ bot_id: int = 0
336
+ blocked: bool = False
337
+ history_deleted: int = 0
338
+
339
+
340
+ class CommandSent(Model):
341
+ chat_id: int = 0
342
+ msg_id: int = 0
343
+ text: str = ""
344
+ via_bot: str | None = None
345
+
346
+
347
+ class BotCommandSet(Model):
348
+ scope: str = "default"
349
+ lang: str = ""
350
+ commands: list[BotCommand] = []
351
+ cleared: bool = False
352
+
353
+
354
+ # ---------------------------------------------------------------------------
355
+ # Buttons
356
+ # ---------------------------------------------------------------------------
357
+
358
+
359
+ class Pressed(Model):
360
+ """What pressing a button produced. `kind` says which fields are filled."""
361
+
362
+ kind: str = ""
363
+ row: int | None = None
364
+ col: int | None = None
365
+ n: int | None = None
366
+ text: str | None = None
367
+ message: str | None = None
368
+ alert: bool = False
369
+ url: str | None = None
370
+ native_ui: bool = False
371
+ cache_time: int | None = None
372
+ query_id: str | None = None
373
+ copy_text: str | None = None
374
+ user: dict[str, Any] | None = None
375
+ peers: list[int] = []
376
+ results: list[dict[str, Any]] = []
377
+ sent_message_id: int | None = None
378
+ auth: dict[str, Any] | None = None
379
+
380
+
381
+ class UrlAuth(Model):
382
+ """A seamless-login request, inspected or completed."""
383
+
384
+ result: str = ""
385
+ bot: str | None = None
386
+ domain: str | None = None
387
+ verified_app_name: str | None = None
388
+ is_app: bool = False
389
+ browser: str | None = None
390
+ platform: str | None = None
391
+ ip: str | None = None
392
+ region: str | None = None
393
+ request_write_access: bool = False
394
+ request_phone_number: bool = False
395
+ match_codes: bool = False
396
+ match_codes_first: bool = False
397
+ user_id_hint: int | None = None
398
+ url: str | None = None
399
+ code_valid: bool | None = None
400
+ write_allowed: bool = False
401
+ phone_shared: bool = False
402
+ declined: bool = False
403
+
404
+
405
+ # ---------------------------------------------------------------------------
406
+ # Bot-side plumbing
407
+ # ---------------------------------------------------------------------------
408
+
409
+
410
+ class BotQuery(Model):
411
+ """One pending query out of the daemon's bot-update buffer."""
412
+
413
+ query_id: str = ""
414
+ kind: str = ""
415
+ user_id: int | None = None
416
+ peer_id: int | None = None
417
+ msg_id: int | None = None
418
+ inline_msg_id: str | None = None
419
+ data: str | None = None
420
+ query: str | None = None
421
+ payload: str | None = None
422
+ answered: bool = False
423
+ expires_at: str | None = None
424
+ message: dict[str, Any] | None = None
425
+
426
+
427
+ class BotAnswer(Model):
428
+ query_id: str = ""
429
+ kind: str = ""
430
+ answered: bool = False
431
+
432
+
433
+ class BotApiResult(Model):
434
+ """An opaque `DataJSON` reply, passed through verbatim."""
435
+
436
+ method: str = ""
437
+ result: Any = None
438
+
439
+
440
+ class BusinessConnection(Model):
441
+ connection_id: str = ""
442
+ user_id: int | None = None
443
+ dc_id: int | None = None
444
+ date: str | None = None
445
+ date_unix: int | None = None
446
+ rights: list[str] = []
447
+ disabled: bool = False
448
+ result: Any = None
449
+
450
+
451
+ class StreamProgress(Model):
452
+ chat_id: int = 0
453
+ draft_id: int = 0
454
+ chunks_sent: int = 0
455
+ stopped: bool = False
456
+
457
+
458
+ # ---------------------------------------------------------------------------
459
+ # Attachment menu, ads, games
460
+ # ---------------------------------------------------------------------------
461
+
462
+
463
+ class AttachMenuBot(Model):
464
+ bot_id: int = 0
465
+ username: str | None = None
466
+ short_name: str | None = None
467
+ peer_types: list[str] = []
468
+ inactive: bool = False
469
+ request_write_access: bool = False
470
+ show_in_attach_menu: bool = False
471
+ show_in_side_menu: bool = False
472
+ side_menu_disclaimer_needed: bool = False
473
+
474
+
475
+ class ToggledAttachMenu(Model):
476
+ bot_id: int = 0
477
+ installed: bool | None = None
478
+ write_allowed: bool | None = None
479
+
480
+
481
+ class RecentBots(Model):
482
+ enabled: bool = True
483
+ kind: str = "pm"
484
+ forgotten: list[int] = []
485
+
486
+
487
+ class SponsoredRead(Model):
488
+ random_id: str = ""
489
+ viewed: bool | None = None
490
+ clicked: bool | None = None
491
+
492
+
493
+ class ReportOutcome(Model):
494
+ """One step of the report option tree, or its end."""
495
+
496
+ result: str = ""
497
+ title: str | None = None
498
+ options: list[dict[str, str]] = []
499
+ reported: bool = False
500
+
501
+
502
+ class EmojiGame(Model):
503
+ """`messages.getEmojiGameInfo`, as the method actually answers.
504
+
505
+ The parameters the work list called "stakes and payouts" arrive as one
506
+ opaque `params` vector plus the caller's own streak; reporting invented
507
+ field names over them would be a schema nobody could check against the
508
+ server. `ton_enabled` is false whenever the server says the game is
509
+ unavailable — and staking TON is a financial action tlgr does not perform
510
+ either way.
511
+ """
512
+
513
+ emoticon: str = ""
514
+ available: bool = False
515
+ game_hash: str | None = None
516
+ prev_stake: int | None = None
517
+ current_streak: int | None = None
518
+ params: list[int] = []
519
+ plays_left: int | None = None
520
+ ton_enabled: bool = False
521
+
522
+
523
+ class GameSent(Model):
524
+ chat_id: int = 0
525
+ msg_id: int = 0
526
+ game_id: int | None = None
527
+ short_name: str = ""
528
+
529
+
530
+ class HighScore(Model):
531
+ position: int = 0
532
+ user_id: int = 0
533
+ score: int = 0
534
+
535
+
536
+ class ScoreSet(Model):
537
+ user_id: int = 0
538
+ score: int = 0
539
+ position: int | None = None
540
+
541
+
542
+ # ---------------------------------------------------------------------------
543
+ # Layer-229 shapes tlgr models but cannot yet call
544
+ # ---------------------------------------------------------------------------
545
+
546
+
547
+ class EphemeralSent(Model):
548
+ chat_id: int = 0
549
+ ephemeral_id: int = 0
550
+ receiver_id: int | None = None
551
+ anchor: bool = False
552
+
553
+
554
+ class EphemeralDeleted(Model):
555
+ chat_id: int = 0
556
+ deleted: int = 0
557
+ dismissed: bool = False
558
+
559
+
560
+ class BotWelcomeMessage(Model):
561
+ id: int = 0
562
+ text: str = ""
563
+ entities: list[dict[str, Any]] = []
564
+ reply_markup: Keyboard | None = None
565
+ media: dict[str, Any] | None = None
566
+
567
+
568
+ class WelcomeSet(Model):
569
+ chat_id: int = 0
570
+ id: int = 0
571
+ text: str = ""
572
+
573
+
574
+ class WelcomeDeleted(Model):
575
+ chat_id: int = 0
576
+ deleted: int = 0