Pytdbot 0.9.5.dev0__tar.gz → 0.9.6.dev1__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.
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/PKG-INFO +2 -2
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/Pytdbot.egg-info/PKG-INFO +2 -2
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/README.md +1 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/__init__.py +1 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/client.py +125 -53
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/methods/methods.py +6 -1
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/methods/td_functions.py +296 -4
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/__init__.py +33 -3
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/types.py +4484 -23
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/tdserver/schedule.py +11 -11
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/LICENSE +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/MANIFEST.in +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/Pytdbot.egg-info/SOURCES.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/Pytdbot.egg-info/dependency_links.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/Pytdbot.egg-info/requires.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/Pytdbot.egg-info/top_level.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/client_manager.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/exception/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/filters.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/handlers/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/handlers/decorators.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/handlers/handler.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/handlers/td_updates.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/methods/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/tdjson/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/tdjson/tdjson.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/plugins/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/bound_methods/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/bound_methods/callback_query.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/bound_methods/chatActions.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/bound_methods/file.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/td_types/bound_methods/message.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/tdserver/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/types/tdserver/stats.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/__init__.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/asyncio_utils.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/escape.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/json_utils.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/obj_encoder.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/strings.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/text_format.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/pytdbot/utils/webapps.py +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/requirements.txt +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/setup.cfg +0 -0
- {pytdbot-0.9.5.dev0 → pytdbot-0.9.6.dev1}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6.dev1
|
|
4
4
|
Summary: Easy-to-use asynchronous TDLib wrapper for Python.
|
|
5
5
|
Home-page: https://github.com/pytdbot/client
|
|
6
6
|
Author: AYMEN Mohammed
|
|
@@ -30,7 +30,7 @@ Dynamic: requires-dist
|
|
|
30
30
|
Dynamic: requires-python
|
|
31
31
|
Dynamic: summary
|
|
32
32
|
|
|
33
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
34
34
|
|
|
35
35
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
36
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: Pytdbot
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.6.dev1
|
|
4
4
|
Summary: Easy-to-use asynchronous TDLib wrapper for Python.
|
|
5
5
|
Home-page: https://github.com/pytdbot/client
|
|
6
6
|
Author: AYMEN Mohammed
|
|
@@ -30,7 +30,7 @@ Dynamic: requires-dist
|
|
|
30
30
|
Dynamic: requires-python
|
|
31
31
|
Dynamic: summary
|
|
32
32
|
|
|
33
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
34
34
|
|
|
35
35
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
36
36
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Pytdbot [](https://pypi.org/project/Pytdbot) [](https://pypi.org/project/Pytdbot) [](https://github.com/tdlib/td) [](https://pepy.tech/project/pytdbot) [](https://t.me/pytdbotchat)
|
|
2
2
|
|
|
3
3
|
Pytdbot (Python TDLib) is an asynchronous [**TDLib**](https://github.com/tdlib/td) wrapper for **Telegram** users/bots written in **Python**.
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ from os.path import join as join_path
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from platform import python_implementation, python_version
|
|
9
9
|
from threading import current_thread, main_thread
|
|
10
|
-
from typing import Callable, Dict, Union
|
|
10
|
+
from typing import Callable, Dict, Type, Union
|
|
11
11
|
|
|
12
12
|
import aio_pika
|
|
13
13
|
from deepdiff import DeepDiff
|
|
@@ -94,6 +94,9 @@ class Client(Decorators, Methods):
|
|
|
94
94
|
workers (``int``, *optional*):
|
|
95
95
|
Number of workers to handle updates. Default is ``5``. If set to ``None``, updates will be immediately handled instead of being queued, which can impact performance.
|
|
96
96
|
|
|
97
|
+
handlers_timeout (``float``, *optional*):
|
|
98
|
+
Timeout for handlers. If set, each handler will be awaited with this timeout. Default is ``None`` (no timeout)
|
|
99
|
+
|
|
97
100
|
no_updates (``bool``, *optional*):
|
|
98
101
|
Whether the client should handle updates or not. Applicable only when using [TDLib Server](https://github.com/pytdbot/tdlib-server). Default is ``False``
|
|
99
102
|
|
|
@@ -128,7 +131,9 @@ class Client(Decorators, Methods):
|
|
|
128
131
|
loop: asyncio.AbstractEventLoop = None,
|
|
129
132
|
options: dict = None,
|
|
130
133
|
workers: int = 5,
|
|
134
|
+
handlers_timeout: float = None,
|
|
131
135
|
no_updates: bool = False,
|
|
136
|
+
load_messages_before_reply: bool = False,
|
|
132
137
|
td_verbosity: int = 2,
|
|
133
138
|
td_log: LogStream = None,
|
|
134
139
|
user_bot: bool = False,
|
|
@@ -158,7 +163,9 @@ class Client(Decorators, Methods):
|
|
|
158
163
|
self.use_message_database = use_message_database
|
|
159
164
|
self.td_options = options
|
|
160
165
|
self.workers = workers
|
|
166
|
+
self.handlers_timeout = handlers_timeout
|
|
161
167
|
self.no_updates = no_updates
|
|
168
|
+
self.load_messages_before_reply = load_messages_before_reply
|
|
162
169
|
self.queue = asyncio.Queue()
|
|
163
170
|
self.user_bot = user_bot
|
|
164
171
|
self.my_id = (
|
|
@@ -179,6 +186,12 @@ class Client(Decorators, Methods):
|
|
|
179
186
|
self.is_rabbitmq = True if rabbitmq_url else False
|
|
180
187
|
self.options = {}
|
|
181
188
|
self.allow_outgoing_message_types: tuple = (types.MessagePaymentRefunded,)
|
|
189
|
+
self.get_message_methods = {
|
|
190
|
+
"getmessage",
|
|
191
|
+
"getmessagelocally",
|
|
192
|
+
"getrepliedmessage",
|
|
193
|
+
"getcallbackquerymessage",
|
|
194
|
+
} # TODO: improve this
|
|
182
195
|
|
|
183
196
|
self._check_init_args()
|
|
184
197
|
|
|
@@ -240,13 +253,13 @@ class Client(Decorators, Methods):
|
|
|
240
253
|
return await self.invoke({"@type": "getServerStats"})
|
|
241
254
|
|
|
242
255
|
async def scheduleEvent(
|
|
243
|
-
self,
|
|
256
|
+
self, payload: str, send_at: int
|
|
244
257
|
) -> Union["pytdbot.types.ScheduledEvent", "pytdbot.types.Error"]:
|
|
245
258
|
"""Schedule an event
|
|
246
259
|
|
|
247
260
|
Parameters:
|
|
248
|
-
|
|
249
|
-
The event
|
|
261
|
+
payload (:class:`str`):
|
|
262
|
+
The event payload to be scheduled
|
|
250
263
|
|
|
251
264
|
send_at (:class:`int`):
|
|
252
265
|
Unix timestamp when the event should be sent
|
|
@@ -254,13 +267,13 @@ class Client(Decorators, Methods):
|
|
|
254
267
|
|
|
255
268
|
self._check_rabbitmq()
|
|
256
269
|
|
|
257
|
-
if not isinstance(
|
|
258
|
-
raise ValueError("
|
|
270
|
+
if not isinstance(payload, str):
|
|
271
|
+
raise ValueError("payload must be str")
|
|
259
272
|
if not isinstance(send_at, (int, float)):
|
|
260
273
|
raise ValueError("send_at must be int")
|
|
261
274
|
|
|
262
275
|
return await self.invoke(
|
|
263
|
-
{"@type": "scheduleEvent", "
|
|
276
|
+
{"@type": "scheduleEvent", "payload": payload, "send_at": send_at}
|
|
264
277
|
)
|
|
265
278
|
|
|
266
279
|
async def cancelScheduledEvent(
|
|
@@ -326,7 +339,7 @@ class Client(Decorators, Methods):
|
|
|
326
339
|
|
|
327
340
|
def add_handler(
|
|
328
341
|
self,
|
|
329
|
-
update_type: str,
|
|
342
|
+
update_type: Union[Type["pytdbot.types.Update"], str],
|
|
330
343
|
func: Callable,
|
|
331
344
|
filters: pytdbot.filters.Filter = None,
|
|
332
345
|
position: int = None,
|
|
@@ -336,7 +349,7 @@ class Client(Decorators, Methods):
|
|
|
336
349
|
r"""Add an update handler
|
|
337
350
|
|
|
338
351
|
Parameters:
|
|
339
|
-
update_type (``str``):
|
|
352
|
+
update_type (``str`` || :class:`~pytdbot.types.Update`):
|
|
340
353
|
An update type
|
|
341
354
|
|
|
342
355
|
func (``Callable``):
|
|
@@ -359,23 +372,28 @@ class Client(Decorators, Methods):
|
|
|
359
372
|
"""
|
|
360
373
|
|
|
361
374
|
if not isinstance(update_type, str):
|
|
362
|
-
|
|
363
|
-
|
|
375
|
+
if issubclass(update_type, types.Update):
|
|
376
|
+
update_type = update_type.getType()
|
|
377
|
+
else:
|
|
378
|
+
raise TypeError(
|
|
379
|
+
"update_type must be str or subclass of pytdbot.types.Update"
|
|
380
|
+
)
|
|
381
|
+
if not isinstance(func, Callable):
|
|
364
382
|
raise TypeError("func must be callable")
|
|
365
|
-
|
|
383
|
+
if filters is not None and not isinstance(filters, Filter):
|
|
366
384
|
raise TypeError("filters must be instance of pytdbot.filters.Filter")
|
|
367
|
-
else:
|
|
368
|
-
handler = Handler(
|
|
369
|
-
func, update_type, filters, position, inner_object, is_from_plugin
|
|
370
|
-
)
|
|
371
385
|
|
|
372
|
-
|
|
373
|
-
|
|
386
|
+
handler = Handler(
|
|
387
|
+
func, update_type, filters, position, inner_object, is_from_plugin
|
|
388
|
+
)
|
|
374
389
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
390
|
+
if update_type not in self._handlers:
|
|
391
|
+
self._handlers[update_type] = []
|
|
392
|
+
|
|
393
|
+
if isinstance(position, int):
|
|
394
|
+
self._handlers[update_type].insert(position, handler)
|
|
395
|
+
else:
|
|
396
|
+
self._handlers[update_type].append(handler)
|
|
379
397
|
|
|
380
398
|
self._update_handlers()
|
|
381
399
|
|
|
@@ -451,56 +469,78 @@ class Client(Decorators, Methods):
|
|
|
451
469
|
"""
|
|
452
470
|
|
|
453
471
|
request = obj_to_dict(request)
|
|
454
|
-
|
|
455
472
|
request["@extra"] = {"id": create_extra_id()}
|
|
456
|
-
|
|
457
|
-
future = self._create_request_future(request)
|
|
473
|
+
request_method = request["@type"].lower()
|
|
458
474
|
|
|
459
475
|
if (
|
|
460
476
|
self.logger.root.level >= DEBUG or self.logger.level >= DEBUG
|
|
461
477
|
): # dumping all requests may create performance issues
|
|
462
478
|
self.logger.debug(f"Sending: {dumps(request, indent=4)}")
|
|
463
479
|
|
|
464
|
-
is_chat_attempted_load =
|
|
480
|
+
is_chat_attempted_load = request_method == "getchat"
|
|
481
|
+
is_message_attempted_load = request_method in self.get_message_methods
|
|
465
482
|
|
|
466
483
|
while True:
|
|
467
484
|
future = self._create_request_future(request)
|
|
468
485
|
await self.__send(request)
|
|
469
486
|
result = await future
|
|
470
487
|
|
|
471
|
-
if isinstance(result, types.Error):
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
488
|
+
if not isinstance(result, types.Error):
|
|
489
|
+
break
|
|
490
|
+
|
|
491
|
+
error_code = result.code
|
|
492
|
+
error_message = result.message
|
|
493
|
+
|
|
494
|
+
if error_message.startswith(
|
|
495
|
+
"Failed to parse JSON object as TDLib request:"
|
|
496
|
+
):
|
|
497
|
+
raise ValueError(error_message)
|
|
498
|
+
|
|
499
|
+
if error_code != 400:
|
|
500
|
+
break
|
|
477
501
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
):
|
|
481
|
-
is_chat_attempted_load = True
|
|
502
|
+
chat_id = request.get("chat_id")
|
|
503
|
+
message_id = request.get("message_id")
|
|
482
504
|
|
|
483
|
-
|
|
505
|
+
if not is_message_attempted_load and (
|
|
506
|
+
error_message == "Message not found" and (chat_id and message_id)
|
|
507
|
+
):
|
|
508
|
+
is_message_attempted_load = True
|
|
484
509
|
|
|
485
|
-
|
|
510
|
+
self.logger.debug(f"Attempt to load message {message_id} in {chat_id}")
|
|
486
511
|
|
|
487
|
-
|
|
512
|
+
message = await self.getMessage(chat_id=chat_id, message_id=message_id)
|
|
513
|
+
if message:
|
|
514
|
+
self.logger.debug(f"Message {message_id} in {chat_id} is loaded")
|
|
515
|
+
continue
|
|
516
|
+
else:
|
|
517
|
+
self.logger.debug(
|
|
518
|
+
f"Failed to load message {message_id} in {chat_id}"
|
|
519
|
+
)
|
|
488
520
|
|
|
489
|
-
|
|
490
|
-
|
|
521
|
+
if not is_chat_attempted_load and (
|
|
522
|
+
error_message == "Chat not found" and chat_id
|
|
523
|
+
):
|
|
524
|
+
is_chat_attempted_load = True
|
|
491
525
|
|
|
492
|
-
|
|
493
|
-
"message_id", 0
|
|
494
|
-
)
|
|
526
|
+
self.logger.debug(f"Attempt to load chat {chat_id}")
|
|
495
527
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
await self.getMessage(chat_id, reply_to_message_id)
|
|
528
|
+
chat = await self.getChat(chat_id)
|
|
529
|
+
if not isinstance(chat, types.Error):
|
|
530
|
+
self.logger.debug(f"Chat {chat_id} is loaded")
|
|
500
531
|
|
|
501
|
-
|
|
532
|
+
reply_to_message_id = (request.get("reply_to") or {}).get(
|
|
533
|
+
"message_id", 0
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
# if the request is a reply to another message
|
|
537
|
+
# load the replied message to avoid "Message not found"
|
|
538
|
+
if reply_to_message_id > 0:
|
|
539
|
+
await self.getMessage(chat_id, reply_to_message_id)
|
|
502
540
|
|
|
503
|
-
|
|
541
|
+
continue
|
|
542
|
+
else:
|
|
543
|
+
self.logger.error(f"Couldn't load chat {chat_id}")
|
|
504
544
|
|
|
505
545
|
break
|
|
506
546
|
|
|
@@ -785,7 +825,18 @@ class Client(Decorators, Methods):
|
|
|
785
825
|
elif not filter_function(self, handler_value):
|
|
786
826
|
continue
|
|
787
827
|
|
|
788
|
-
|
|
828
|
+
if self.handlers_timeout is None:
|
|
829
|
+
await initializer(self, handler_value)
|
|
830
|
+
else:
|
|
831
|
+
try:
|
|
832
|
+
await asyncio.wait_for(
|
|
833
|
+
initializer(self, handler_value),
|
|
834
|
+
timeout=self.handlers_timeout,
|
|
835
|
+
)
|
|
836
|
+
except asyncio.TimeoutError:
|
|
837
|
+
self.logger.warning(
|
|
838
|
+
f"Initializer {initializer} timed out after {self.handlers_timeout} seconds"
|
|
839
|
+
)
|
|
789
840
|
except StopHandlers as e:
|
|
790
841
|
raise e
|
|
791
842
|
except Exception:
|
|
@@ -806,7 +857,17 @@ class Client(Decorators, Methods):
|
|
|
806
857
|
elif not filter_function(self, handler_value):
|
|
807
858
|
continue
|
|
808
859
|
|
|
809
|
-
|
|
860
|
+
if self.handlers_timeout is None:
|
|
861
|
+
await handler(self, handler_value)
|
|
862
|
+
else:
|
|
863
|
+
try:
|
|
864
|
+
await asyncio.wait_for(
|
|
865
|
+
handler(self, handler_value), timeout=self.handlers_timeout
|
|
866
|
+
)
|
|
867
|
+
except asyncio.TimeoutError:
|
|
868
|
+
self.logger.warning(
|
|
869
|
+
f"Handler {handler} timed out after {self.handlers_timeout} seconds"
|
|
870
|
+
)
|
|
810
871
|
except StopHandlers as e:
|
|
811
872
|
raise e
|
|
812
873
|
except Exception:
|
|
@@ -828,7 +889,18 @@ class Client(Decorators, Methods):
|
|
|
828
889
|
elif not filter_function(self, handler_value):
|
|
829
890
|
continue
|
|
830
891
|
|
|
831
|
-
|
|
892
|
+
if self.handlers_timeout is None:
|
|
893
|
+
await finalizer(self, handler_value)
|
|
894
|
+
else:
|
|
895
|
+
try:
|
|
896
|
+
await asyncio.wait_for(
|
|
897
|
+
finalizer(self, handler_value),
|
|
898
|
+
timeout=self.handlers_timeout,
|
|
899
|
+
)
|
|
900
|
+
except asyncio.TimeoutError:
|
|
901
|
+
self.logger.warning(
|
|
902
|
+
f"Finalizer {finalizer} timed out after {self.handlers_timeout} seconds"
|
|
903
|
+
)
|
|
832
904
|
except StopHandlers as e:
|
|
833
905
|
raise e
|
|
834
906
|
except Exception:
|
|
@@ -1027,7 +1027,7 @@ class Methods(TDLibFunctions):
|
|
|
1027
1027
|
return await self.sendMessageWithContent(
|
|
1028
1028
|
chat_id=chat_id,
|
|
1029
1029
|
content=InputMessageVoiceNote(
|
|
1030
|
-
|
|
1030
|
+
voice_note=voice,
|
|
1031
1031
|
waveform=waveform,
|
|
1032
1032
|
duration=duration,
|
|
1033
1033
|
caption=caption,
|
|
@@ -1389,6 +1389,11 @@ class Methods(TDLibFunctions):
|
|
|
1389
1389
|
message_id=reply_to_message_id, quote=quote
|
|
1390
1390
|
)
|
|
1391
1391
|
|
|
1392
|
+
if self.load_messages_before_reply and isinstance(
|
|
1393
|
+
reply_to, InputMessageReplyToMessage
|
|
1394
|
+
):
|
|
1395
|
+
await self.getMessage(chat_id=chat_id, message_id=reply_to.message_id)
|
|
1396
|
+
|
|
1392
1397
|
res = await self.sendMessage(
|
|
1393
1398
|
chat_id=chat_id,
|
|
1394
1399
|
message_thread_id=message_thread_id,
|