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/net.py ADDED
@@ -0,0 +1,232 @@
1
+ """Network, data-centre, proxy and server-configuration shapes.
2
+
3
+ The distinction these encode is the one v1 never made: **the server's
4
+ configuration** (`help.getConfig`, `help.getAppConfig`) is not the same thing
5
+ as **the connection** (which DC, which transport, how far the clock is off),
6
+ and neither is **the proxy** (a client-side list with credentials in a 0600
7
+ file). Three nouns, three shapes.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import Any
13
+
14
+ from tlgr.models.base import Model
15
+
16
+ __all__ = [
17
+ "AppConfigDoc",
18
+ "Country",
19
+ "CountryCode",
20
+ "DcOption",
21
+ "InfoTopic",
22
+ "NearestDc",
23
+ "NetStatus",
24
+ "NetUsage",
25
+ "PingResult",
26
+ "PromoData",
27
+ "Proxy",
28
+ "ProxyLink",
29
+ "ProxyProbe",
30
+ "ProxySelection",
31
+ "ServerConfig",
32
+ "SyncCursors",
33
+ ]
34
+
35
+
36
+ class DcOption(Model):
37
+ id: int
38
+ ip_address: str = ""
39
+ port: int = 0
40
+ ipv6: bool = False
41
+ media_only: bool = False
42
+ tcpo_only: bool = False
43
+ cdn: bool = False
44
+ static: bool = False
45
+ this_port_only: bool = False
46
+ secret: str | None = None
47
+ current: bool = False
48
+
49
+
50
+ class NearestDc(Model):
51
+ country: str = ""
52
+ this_dc: int = 0
53
+ nearest_dc: int = 0
54
+ current_dc: int | None = None
55
+
56
+
57
+ class PingResult(Model):
58
+ account: str = ""
59
+ dc_id: int | None = None
60
+ proxy: str | None = None
61
+ probes: int = 0
62
+ min_ms: float | None = None
63
+ avg_ms: float | None = None
64
+ max_ms: float | None = None
65
+ loss: float = 0.0
66
+
67
+
68
+ class SyncCursors(Model):
69
+ """pts/qts/seq/date, the four numbers the update transport turns on."""
70
+
71
+ pts: int | None = None
72
+ qts: int | None = None
73
+ seq: int | None = None
74
+ date: str | None = None
75
+ date_unix: int | None = None
76
+
77
+
78
+ class NetStatus(Model):
79
+ account: str = ""
80
+ authorized: bool = False
81
+ connected: bool = False
82
+ phase: str = "disconnected"
83
+ dc_id: int | None = None
84
+ dc_address: str | None = None
85
+ ipv6: bool = False
86
+ transport: str = ""
87
+ proxy: str | None = None
88
+ ping_ms: float | None = None
89
+ layer: int = 0
90
+ #: |offset| > 30 s is reported as a warning: it pushes msg_ids outside the
91
+ #: server's window, and requests are then dropped with no error at all.
92
+ time_offset_seconds: int = 0
93
+ exported_senders: int = 0
94
+ reconnects: int = 0
95
+ last_error: str | None = None
96
+ state: SyncCursors | None = None
97
+ behind_seconds: int | None = None
98
+ frozen: bool = False
99
+
100
+
101
+ class NetUsage(Model):
102
+ account: str = ""
103
+ since: str = ""
104
+ rpc_bytes_sent: int = 0
105
+ rpc_bytes_received: int = 0
106
+ download_bytes: int = 0
107
+ upload_bytes: int = 0
108
+ requests: int = 0
109
+ updates_received: int = 0
110
+ reconnects: int = 0
111
+
112
+
113
+ class Proxy(Model):
114
+ """A saved proxy. Credentials live in a 0600 file and are never printed."""
115
+
116
+ id: str
117
+ name: str = ""
118
+ type: str = "socks5"
119
+ host: str = ""
120
+ port: int = 0
121
+ user: str | None = None
122
+ rdns: bool = True
123
+ active: bool = False
124
+ order: int = 0
125
+ last_ping_ms: float | None = None
126
+ last_ok_at: str | None = None
127
+ failures: int = 0
128
+ has_password: bool = False
129
+ has_secret: bool = False
130
+
131
+
132
+ class ProxyProbe(Model):
133
+ id: str = ""
134
+ name: str = ""
135
+ ok: bool = False
136
+ ping_ms: float | None = None
137
+ dc_id: int | None = None
138
+ error: str | None = None
139
+
140
+
141
+ class ProxyLink(Model):
142
+ id: str
143
+ link: str
144
+ type: str = ""
145
+ host: str = ""
146
+ port: int = 0
147
+ qr: str | None = None
148
+
149
+
150
+ class ProxySelection(Model):
151
+ active: str | None = None
152
+ type: str = ""
153
+ host: str = ""
154
+ port: int = 0
155
+ reconnected: bool = False
156
+ accounts: list[str] = []
157
+ removed: bool = False
158
+ was_active: bool = False
159
+
160
+
161
+ class ServerConfig(Model):
162
+ """`help.getConfig`, the fields a client actually acts on."""
163
+
164
+ expires: str | None = None
165
+ test_mode: bool = False
166
+ this_dc: int = 0
167
+ date: str | None = None
168
+ date_unix: int | None = None
169
+ chat_size_max: int = 0
170
+ megagroup_size_max: int = 0
171
+ message_length_max: int = 0
172
+ caption_length_max: int = 0
173
+ online_update_period_ms: int = 0
174
+ offline_blur_timeout_ms: int = 0
175
+ offline_idle_timeout_ms: int = 0
176
+ edit_time_limit: int = 0
177
+ revoke_time_limit: int = 0
178
+ rating_e_decay: int = 0
179
+ forwarded_count_max: int = 0
180
+ push_chat_period_ms: int = 0
181
+ dc_options: list[DcOption] = []
182
+ values: dict[str, Any] = {}
183
+
184
+
185
+ class AppConfigDoc(Model):
186
+ """`help.getAppConfig`, hash-cached, with the freeze fields lifted out."""
187
+
188
+ hash: int = 0
189
+ not_modified: bool = False
190
+ freeze_since_date: str | None = None
191
+ freeze_until_date: str | None = None
192
+ freeze_appeal_url: str | None = None
193
+ values: dict[str, Any] = {}
194
+ config: ServerConfig | None = None
195
+
196
+
197
+ class CountryCode(Model):
198
+ country_code: str = ""
199
+ prefixes: list[str] = []
200
+ patterns: list[str] = []
201
+
202
+
203
+ class Country(Model):
204
+ iso2: str
205
+ name: str = ""
206
+ default_name: str = ""
207
+ hidden: bool = False
208
+ flag_emoji: str = ""
209
+ preferred_language: str = ""
210
+ codes: list[CountryCode] = []
211
+ #: Filled only by `--phone`: what the number was classified as.
212
+ matched_prefix: str | None = None
213
+ valid: bool | None = None
214
+
215
+
216
+ class InfoTopic(Model):
217
+ """One of the flat `help.*` / `langpack.*` read-only endpoints."""
218
+
219
+ topic: str
220
+ items: list[dict[str, Any]] = []
221
+ raw: dict[str, Any] = {}
222
+
223
+
224
+ class PromoData(Model):
225
+ kind: str = "none"
226
+ chat_id: int | None = None
227
+ psa_type: str | None = None
228
+ psa_message: str | None = None
229
+ proxy: bool = False
230
+ expires: str | None = None
231
+ hidden: bool = False
232
+ pending_suggestions: list[str] = []
tlgr/models/notify.py ADDED
@@ -0,0 +1,105 @@
1
+ """The Notifications screen: scopes, per-chat exceptions, reactions, sounds.
2
+
3
+ Telegram spreads one screen over three unrelated APIs — `getNotifySettings`
4
+ for the scopes and the chats, `getReactionsNotifySettings` for the reaction
5
+ alerts, `getContactSignUpNotification` for "X joined Telegram" — so the
6
+ model, like the command, is one shape with a `target` naming which of them
7
+ answered.
8
+
9
+ `mute_until` is an **absolute UNIX timestamp**, and the second field exists
10
+ to say so. v1 computed it from the asyncio event loop's clock, which is an
11
+ arbitrary monotonic origin: "mute for an hour" produced a timestamp somewhere
12
+ in 1970 and the chat was never muted at all.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from tlgr.models.base import Model
18
+ from tlgr.models.dialog import NotifySettings
19
+ from tlgr.models.peer import Peer
20
+
21
+ __all__ = [
22
+ "ExceptionsCleared",
23
+ "NotifyException",
24
+ "NotifyReset",
25
+ "NotifyTarget",
26
+ "Ringtone",
27
+ "RingtoneSaved",
28
+ ]
29
+
30
+
31
+ class NotifyTarget(Model):
32
+ """Notification settings for one target, whatever kind of target it is.
33
+
34
+ `target` is the word the caller typed (`private`, `groups`, `channels`,
35
+ `stories`, `reactions`, `contact-joined`, or a chat reference), so the
36
+ answer can be piped straight back into `notify set`.
37
+ """
38
+
39
+ target: str
40
+ kind: str = "scope"
41
+ chat_id: int | None = None
42
+ chat: Peer | None = None
43
+ topic: int | None = None
44
+ settings: NotifySettings | None = None
45
+ muted: bool | None = None
46
+ mute_until: str | None = None
47
+ mute_until_unix: int | None = None
48
+ show_previews: bool | None = None
49
+ sound: str | None = None
50
+ stories_muted: bool | None = None
51
+ stories_hide_sender: bool | None = None
52
+ stories_sound: str | None = None
53
+ #: `reactions` target: contacts | all | off, one per alert kind.
54
+ messages_from: str | None = None
55
+ stories_from: str | None = None
56
+ poll_votes_from: str | None = None
57
+ #: `contact-joined` target. Stored inverted on the wire (`silent=true`).
58
+ contact_joined: bool | None = None
59
+ changed: list[str] = []
60
+ already: bool = False
61
+
62
+
63
+ class NotifyException(Model):
64
+ """A chat whose settings differ from its scope default."""
65
+
66
+ chat_id: int
67
+ chat: Peer | None = None
68
+ title: str = ""
69
+ muted: bool = False
70
+ mute_until: str | None = None
71
+ mute_until_unix: int | None = None
72
+ show_previews: bool | None = None
73
+ sound: str | None = None
74
+ stories_muted: bool | None = None
75
+ scope: str = ""
76
+
77
+
78
+ class ExceptionsCleared(Model):
79
+ cleared: int = 0
80
+ chat_ids: list[int] = []
81
+ scope: str | None = None
82
+ already: bool = False
83
+
84
+
85
+ class NotifyReset(Model):
86
+ ok: bool
87
+
88
+
89
+ class Ringtone(Model):
90
+ id: int
91
+ access_hash: int | None = None
92
+ file_name: str = ""
93
+ mime_type: str = ""
94
+ size: int = 0
95
+ duration: int | None = None
96
+
97
+
98
+ class RingtoneSaved(Model):
99
+ id: int | None = None
100
+ file_name: str | None = None
101
+ #: The server may hand back a *new* document id when an existing voice
102
+ #: message is saved as a ringtone; using the old one afterwards fails.
103
+ converted: bool = False
104
+ removed: bool = False
105
+ already: bool = False
tlgr/models/page.py ADDED
@@ -0,0 +1,32 @@
1
+ """The one paginated shape: `Page[T]`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Generic, TypeVar
6
+
7
+ from tlgr.models.base import Model
8
+
9
+ __all__ = ["Page", "PageInfo"]
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ class Page(Model, Generic[T]):
15
+ """A slice of a longer list.
16
+
17
+ `total` is the server's own count where it gives one and `null` otherwise;
18
+ it is never estimated, because a wrong total is worse than no total.
19
+ """
20
+
21
+ items: list[T] = []
22
+ has_more: bool = False
23
+ next_cursor: str | None = None
24
+ total: int | None = None
25
+
26
+
27
+ class PageInfo(Model):
28
+ """The pagination half of a response envelope, without the items."""
29
+
30
+ has_more: bool = False
31
+ next_cursor: str | None = None
32
+ total: int | None = None
tlgr/models/payment.py ADDED
@@ -0,0 +1,172 @@
1
+ """Payments, read-only by design.
2
+
3
+ tlgr models the whole checkout surface — the invoice, the form, the receipt,
4
+ the subscription — and implements every verb that does *not* move money.
5
+ `PaymentForm.payable_here` is therefore always false and carries the reason:
6
+ the shape a caller needs in order to decide is here, the button that would
7
+ charge is deliberately not, and saying so in the payload is better than
8
+ leaving a caller to discover it from an exit code.
9
+
10
+ Amounts are integers in the smallest unit of `currency`, exactly as Telegram
11
+ sends them (`XTR` means Telegram Stars, whose smallest unit is one Star).
12
+ Rounding them into a float here would lose money in the last decimal on every
13
+ currency that has three of them.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any
19
+
20
+ from tlgr.models.base import Model
21
+
22
+ __all__ = [
23
+ "BankCard",
24
+ "Invoice",
25
+ "InvoiceLink",
26
+ "InvoiceSent",
27
+ "PaymentForm",
28
+ "PaymentInfo",
29
+ "PaymentInfoCleared",
30
+ "PriceLine",
31
+ "Receipt",
32
+ "StarSubscription",
33
+ "SubscriptionChange",
34
+ ]
35
+
36
+
37
+ class PriceLine(Model):
38
+ label: str = ""
39
+ amount: int = 0
40
+
41
+
42
+ class Invoice(Model):
43
+ """The invoice itself: what is being charged for, and what it needs."""
44
+
45
+ currency: str = ""
46
+ total_amount: int = 0
47
+ prices: list[PriceLine] = []
48
+ test: bool = False
49
+ name_requested: bool = False
50
+ phone_requested: bool = False
51
+ email_requested: bool = False
52
+ shipping_address_requested: bool = False
53
+ flexible: bool = False
54
+ recurring: bool = False
55
+ terms_url: str | None = None
56
+ subscription_period: int | None = None
57
+ max_tip_amount: int | None = None
58
+ suggested_tip_amounts: list[int] = []
59
+
60
+
61
+ class PaymentForm(Model):
62
+ """A checkout form, read without paying for it."""
63
+
64
+ form_kind: str = "form"
65
+ form_id: int = 0
66
+ bot_id: int | None = None
67
+ provider_id: int | None = None
68
+ title: str | None = None
69
+ description: str | None = None
70
+ photo: str | None = None
71
+ invoice: Invoice | None = None
72
+ currency: str = ""
73
+ total_amount: int = 0
74
+ prices: list[PriceLine] = []
75
+ tip_amounts: list[int] = []
76
+ recurring: bool = False
77
+ terms_url: str | None = None
78
+ subscription_period: int | None = None
79
+ url: str | None = None
80
+ native_provider: str | None = None
81
+ native_params: Any = None
82
+ additional_methods: list[dict[str, Any]] = []
83
+ saved_info: dict[str, Any] | None = None
84
+ saved_credentials: list[dict[str, Any]] = []
85
+ can_save_credentials: bool = False
86
+ password_missing: bool = False
87
+ expires_at: str | None = None
88
+ #: Always false, and always *emitted*: an omitted flag would leave a
89
+ #: caller to infer the policy, and `reason` says which one it is.
90
+ payable_here: bool | None = None
91
+ reason: str = ""
92
+
93
+
94
+ class Receipt(Model):
95
+ date: str | None = None
96
+ date_unix: int | None = None
97
+ bot_id: int | None = None
98
+ provider_id: int | None = None
99
+ title: str | None = None
100
+ description: str | None = None
101
+ invoice: Invoice | None = None
102
+ currency: str = ""
103
+ total_amount: int = 0
104
+ tip_amount: int | None = None
105
+ credentials_title: str | None = None
106
+ shipping: dict[str, Any] | None = None
107
+ info: dict[str, Any] | None = None
108
+ transaction_id: str | None = None
109
+ recurring: bool = False
110
+ refunded: bool = False
111
+
112
+
113
+ class PaymentInfo(Model):
114
+ """My saved order information and saved cards. Never a card number."""
115
+
116
+ has_saved_credentials: bool | None = None
117
+ credentials: list[dict[str, Any]] = []
118
+ saved_info: dict[str, Any] | None = None
119
+ name: str | None = None
120
+ phone: str | None = None
121
+ email: str | None = None
122
+ shipping: dict[str, Any] | None = None
123
+ has_saved_info: bool | None = None
124
+ cleared: bool = False
125
+
126
+
127
+ class PaymentInfoCleared(Model):
128
+ credentials_cleared: bool | None = None
129
+ info_cleared: bool | None = None
130
+
131
+
132
+ class InvoiceLink(Model):
133
+ url: str = ""
134
+ slug: str = ""
135
+
136
+
137
+ class InvoiceSent(Model):
138
+ chat_id: int = 0
139
+ msg_id: int = 0
140
+ slug: str | None = None
141
+ currency: str = ""
142
+ total_amount: int = 0
143
+
144
+
145
+ class BankCard(Model):
146
+ title: str = ""
147
+ open_urls: list[dict[str, str]] = []
148
+
149
+
150
+ class StarSubscription(Model):
151
+ id: str = ""
152
+ peer: int | None = None
153
+ until_date: str | None = None
154
+ until_date_unix: int | None = None
155
+ pricing: dict[str, int] | None = None
156
+ cancelled: bool | None = None
157
+ #: Re-joining a lapsed subscription debits Stars, so tlgr reports that the
158
+ #: server would allow it and still refuses to do it.
159
+ can_refulfill: bool | None = None
160
+ missing_balance: bool | None = None
161
+ invoice_slug: str | None = None
162
+ chat_invite_hash: str | None = None
163
+ title: str | None = None
164
+ photo: str | None = None
165
+
166
+
167
+ class SubscriptionChange(Model):
168
+ subscription_id: str | None = None
169
+ user_id: int | None = None
170
+ charge_id: str | None = None
171
+ cancelled: bool | None = None
172
+ until_date: str | None = None