mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-08-02 19:20:09 +03:00
Merge branch 'master' into asyncio
This commit is contained in:
commit
52042d4a1b
13
.github/ISSUE_TEMPLATE.md
vendored
13
.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,9 +1,10 @@
|
|||
<!--
|
||||
0. The library is Python 3.x, not Python 2.x.
|
||||
1. If you're posting an issue, make sure it's a bug in the library, not in your code.
|
||||
2. If you're posting a question, make sure you have read and tried enough things first.
|
||||
3. Show as much information as possible, including your failed attempts, and the full console output (to include the whole traceback with line numbers).
|
||||
4. Good looking issues are a lot more appealing. If you need help check out https://guides.github.com/features/mastering-markdown/.
|
||||
0. The library is Python >= 3.4, not Python 2.x.
|
||||
1. If you have a QUESTION, ask it on @TelethonChat (Telegram) or StackOverflow, not here. It will be closed immediatly with no explanation if you post it here.
|
||||
2. If you have an ISSUE or you are experiencing strange behaviour, make sure you're using the latest version (pip install -U telethon), and post as much information as possible here. Enhancement suggestions are welcome too.
|
||||
|
||||
You may also want to watch "How (not) to ask a technical question" over https://youtu.be/53zkBvL4ZB4
|
||||
If you paste code, please put it between three backticks (`):
|
||||
```python
|
||||
code here
|
||||
```
|
||||
-->
|
||||
|
|
|
@ -48,7 +48,7 @@ Basic Usage
|
|||
|
||||
# Retrieving messages from a chat
|
||||
from telethon import utils
|
||||
async for message in client.get_message_history('username', limit=10):
|
||||
async for message in client.iter_messages('username', limit=10):
|
||||
print(utils.get_display_name(message.sender), message.message)
|
||||
|
||||
# Listing all the dialogs (conversations you have open)
|
||||
|
@ -60,7 +60,7 @@ Basic Usage
|
|||
|
||||
# Once you have a message with .media (if message.media)
|
||||
# you can download it using client.download_media():
|
||||
messages = await client.get_message_history('username')
|
||||
messages = await client.get_messages('username')
|
||||
await client.download_media(messages[0])
|
||||
|
||||
**More details**: :ref:`telegram-client`
|
||||
|
|
|
@ -67,7 +67,7 @@ Many other common methods for quick scripts are also available:
|
|||
|
||||
# The utils package has some goodies, like .get_display_name()
|
||||
from telethon import utils
|
||||
async for message in client.get_message_history('username', limit=10):
|
||||
async for message in client.iter_messages('username', limit=10):
|
||||
print(utils.get_display_name(message.sender), message.message)
|
||||
|
||||
# Dialogs are the conversations you have open
|
||||
|
|
|
@ -288,7 +288,7 @@ use :tl:`GetMessagesViewsRequest`, setting ``increment=True``:
|
|||
|
||||
|
||||
# Obtain `channel' through dialogs or through client.get_entity() or anyhow.
|
||||
# Obtain `msg_ids' through `.get_message_history()` or anyhow. Must be a list.
|
||||
# Obtain `msg_ids' through `.get_messages()` or anyhow. Must be a list.
|
||||
|
||||
await client(GetMessagesViewsRequest(
|
||||
peer=channel,
|
||||
|
|
10
setup.py
10
setup.py
|
@ -10,14 +10,13 @@ Extra supported commands are:
|
|||
* pypi, to generate sdist, bdist_wheel, and push to PyPi
|
||||
"""
|
||||
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
# To use a consistent encoding
|
||||
import shutil
|
||||
from codecs import open
|
||||
from sys import argv, version_info
|
||||
|
||||
# Always prefer setuptools over distutils
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
|
||||
|
@ -44,7 +43,8 @@ ERRORS_IN_JSON = os.path.join(GENERATOR_DIR, 'data', 'errors.json')
|
|||
ERRORS_IN_DESC = os.path.join(GENERATOR_DIR, 'data', 'error_descriptions')
|
||||
ERRORS_OUT = os.path.join(LIBRARY_DIR, 'errors', 'rpc_error_list.py')
|
||||
|
||||
TLOBJECT_IN_TL = os.path.join(GENERATOR_DIR, 'data', 'scheme.tl')
|
||||
TLOBJECT_IN_CORE_TL = os.path.join(GENERATOR_DIR, 'data', 'mtproto_api.tl')
|
||||
TLOBJECT_IN_TL = os.path.join(GENERATOR_DIR, 'data', 'telegram_api.tl')
|
||||
TLOBJECT_OUT = os.path.join(LIBRARY_DIR, 'tl')
|
||||
IMPORT_DEPTH = 2
|
||||
|
||||
|
@ -57,7 +57,9 @@ def generate(which):
|
|||
from telethon_generator.generators import\
|
||||
generate_errors, generate_tlobjects, generate_docs, clean_tlobjects
|
||||
|
||||
tlobjects = list(parse_tl(TLOBJECT_IN_TL, ignore_core=True))
|
||||
tlobjects = list(itertools.chain(
|
||||
parse_tl(TLOBJECT_IN_CORE_TL), parse_tl(TLOBJECT_IN_TL)))
|
||||
|
||||
errors = list(parse_errors(ERRORS_IN_JSON, ERRORS_IN_DESC))
|
||||
layer = find_layer(TLOBJECT_IN_TL)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .common import Raw
|
||||
from .raw import Raw
|
||||
from .chataction import ChatAction
|
||||
from .messagedeleted import MessageDeleted
|
||||
from .messageedited import MessageEdited
|
||||
|
|
|
@ -95,7 +95,6 @@ class ChatAction(EventBuilder):
|
|||
photo (:tl:`Photo`, optional):
|
||||
The new photo (or ``None`` if it was removed).
|
||||
|
||||
|
||||
user_added (`bool`):
|
||||
``True`` if the user was added by some other.
|
||||
|
||||
|
@ -111,7 +110,7 @@ class ChatAction(EventBuilder):
|
|||
created (`bool`, optional):
|
||||
``True`` if this chat was just created.
|
||||
|
||||
new_title (`bool`, optional):
|
||||
new_title (`str`, optional):
|
||||
The new title string for the chat, if applicable.
|
||||
|
||||
unpin (`bool`):
|
||||
|
|
|
@ -97,6 +97,7 @@ class EventCommon(abc.ABC):
|
|||
self._chat = None
|
||||
|
||||
self.pattern_match = None
|
||||
self.original_update = None
|
||||
|
||||
self.is_private = isinstance(chat_peer, types.PeerUser)
|
||||
self.is_group = (
|
||||
|
@ -208,17 +209,6 @@ class EventCommon(abc.ABC):
|
|||
return d
|
||||
|
||||
|
||||
class Raw(EventBuilder):
|
||||
"""
|
||||
Represents a raw event. The event is the update itself.
|
||||
"""
|
||||
async def resolve(self, client):
|
||||
pass
|
||||
|
||||
def build(self, update):
|
||||
return update
|
||||
|
||||
|
||||
def name_inner_event(cls):
|
||||
"""Decorator to rename cls.Event 'Event' as 'cls.Event'"""
|
||||
if hasattr(cls, 'Event'):
|
||||
|
|
30
telethon/events/raw.py
Normal file
30
telethon/events/raw.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from .common import EventBuilder
|
||||
from .. import utils
|
||||
|
||||
|
||||
class Raw(EventBuilder):
|
||||
"""
|
||||
Represents a raw event. The event is the update itself.
|
||||
|
||||
Args:
|
||||
types (`list` | `tuple` | `type`, optional):
|
||||
The type or types that the :tl:`Update` instance must be.
|
||||
Equivalent to ``if not isinstance(update, types): return``.
|
||||
"""
|
||||
def __init__(self, types=None):
|
||||
super().__init__()
|
||||
if not types:
|
||||
self.types = None
|
||||
elif not utils.is_list_like(types):
|
||||
assert isinstance(types, type)
|
||||
self.types = types
|
||||
else:
|
||||
assert all(isinstance(x, type) for x in types)
|
||||
self.types = tuple(types)
|
||||
|
||||
async def resolve(self, client):
|
||||
pass
|
||||
|
||||
def build(self, update):
|
||||
if not self.types or isinstance(update, self.types):
|
||||
return update
|
|
@ -102,7 +102,9 @@ class TcpClient:
|
|||
# to none to recreate it on the next iteration
|
||||
self._socket = None
|
||||
await asyncio.sleep(timeout)
|
||||
timeout = min(timeout * 2, MAX_TIMEOUT)
|
||||
timeout *= 2
|
||||
if timeout > MAX_TIMEOUT:
|
||||
raise
|
||||
else:
|
||||
raise
|
||||
|
||||
|
|
|
@ -67,6 +67,25 @@ class Session(ABC):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def get_update_state(self, entity_id):
|
||||
"""
|
||||
Returns the ``UpdateState`` associated with the given `entity_id`.
|
||||
If the `entity_id` is 0, it should return the ``UpdateState`` for
|
||||
no specific channel (the "general" state). If no state is known
|
||||
it should ``return None``.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def set_update_state(self, entity_id, state):
|
||||
"""
|
||||
Sets the given ``UpdateState`` for the specified `entity_id`, which
|
||||
should be 0 if the ``UpdateState`` is the "general" state (and not
|
||||
for any specific channel).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def close(self):
|
||||
"""
|
||||
|
|
|
@ -35,6 +35,7 @@ class MemorySession(Session):
|
|||
|
||||
self._files = {}
|
||||
self._entities = set()
|
||||
self._update_states = {}
|
||||
|
||||
def set_dc(self, dc_id, server_address, port):
|
||||
self._dc_id = dc_id or 0
|
||||
|
@ -57,6 +58,12 @@ class MemorySession(Session):
|
|||
def auth_key(self, value):
|
||||
self._auth_key = value
|
||||
|
||||
def get_update_state(self, entity_id):
|
||||
return self._update_states.get(entity_id, None)
|
||||
|
||||
def set_update_state(self, entity_id, state):
|
||||
self._update_states[entity_id] = state
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sqlite3
|
||||
from base64 import b64decode
|
||||
from os.path import isfile as file_exists
|
||||
|
||||
from telethon.tl import types
|
||||
from .memory import MemorySession, _SentFileType
|
||||
from .. import utils
|
||||
from ..crypto import AuthKey
|
||||
|
@ -219,6 +221,25 @@ class SQLiteSession(MemorySession):
|
|||
))
|
||||
c.close()
|
||||
|
||||
def get_update_state(self, entity_id):
|
||||
c = self._cursor()
|
||||
row = c.execute('select pts, qts, date, seq from update_state '
|
||||
'where id = ?', (entity_id,)).fetchone()
|
||||
c.close()
|
||||
if row:
|
||||
pts, qts, date, seq = row
|
||||
date = datetime.datetime.utcfromtimestamp(date)
|
||||
return types.updates.State(pts, qts, date, seq, unread_count=0)
|
||||
|
||||
def set_update_state(self, entity_id, state):
|
||||
with self._db_lock:
|
||||
c = self._cursor()
|
||||
c.execute('insert or replace into update_state values (?,?,?,?,?)',
|
||||
(entity_id, state.pts, state.qts,
|
||||
state.date.timestamp(), state.seq))
|
||||
c.close()
|
||||
self.save()
|
||||
|
||||
def save(self):
|
||||
"""Saves the current session object as session_user_id.session"""
|
||||
self._conn.commit()
|
||||
|
|
|
@ -265,6 +265,7 @@ class TelegramBareClient:
|
|||
self._state_loop = None
|
||||
# TODO Shall we clear the _exported_sessions, or may be reused?
|
||||
self._first_request = True # On reconnect it will be first again
|
||||
self.session.set_update_state(0, self.updates.get_update_state(0))
|
||||
self.session.close()
|
||||
|
||||
async def _reconnect(self, new_dc=None):
|
||||
|
|
|
@ -1089,6 +1089,7 @@ class TelegramClient(TelegramBareClient):
|
|||
limit=1,
|
||||
max_id=max_id,
|
||||
min_id=min_id,
|
||||
hash=0,
|
||||
from_id=self.get_input_entity(from_user) if from_user else None
|
||||
)
|
||||
else:
|
||||
|
@ -1117,6 +1118,7 @@ class TelegramClient(TelegramBareClient):
|
|||
have = 0
|
||||
batch_size = min(max(batch_size, 1), 100)
|
||||
while have < limit:
|
||||
start = time.time()
|
||||
# Telegram has a hard limit of 100
|
||||
request.limit = min(limit - have, batch_size)
|
||||
r = await self(request)
|
||||
|
@ -1163,7 +1165,7 @@ class TelegramClient(TelegramBareClient):
|
|||
else:
|
||||
request.max_date = r.messages[-1].date
|
||||
|
||||
await asyncio.sleep(wait_time)
|
||||
await asyncio.sleep(max(wait_time - (time.time() - start), 0))
|
||||
|
||||
async def get_messages(self, *args, **kwargs):
|
||||
"""
|
||||
|
@ -2178,7 +2180,7 @@ class TelegramClient(TelegramBareClient):
|
|||
return result
|
||||
i += 1
|
||||
|
||||
async def download_file(self, input_location, file, part_size_kb=None,
|
||||
async def download_file(self, input_location, file=None, part_size_kb=None,
|
||||
file_size=None, progress_callback=None):
|
||||
"""
|
||||
Downloads the given input location to a file.
|
||||
|
@ -2187,10 +2189,13 @@ class TelegramClient(TelegramBareClient):
|
|||
input_location (:tl:`InputFileLocation`):
|
||||
The file location from which the file will be downloaded.
|
||||
|
||||
file (`str` | `file`):
|
||||
file (`str` | `file`, optional):
|
||||
The output file path, directory, or stream-like object.
|
||||
If the path exists and is a file, it will be overwritten.
|
||||
|
||||
If the file path is ``None``, then the result will be
|
||||
saved in memory and returned as `bytes`.
|
||||
|
||||
part_size_kb (`int`, optional):
|
||||
Chunk size when downloading files. The larger, the less
|
||||
requests will be made (up to 512KB maximum).
|
||||
|
@ -2221,7 +2226,10 @@ class TelegramClient(TelegramBareClient):
|
|||
raise ValueError(
|
||||
'The part size must be evenly divisible by 4096.')
|
||||
|
||||
if isinstance(file, str):
|
||||
in_memory = file is None
|
||||
if in_memory:
|
||||
f = io.BytesIO()
|
||||
elif isinstance(file, str):
|
||||
# Ensure that we'll be able to download the media
|
||||
helpers.ensure_parent_dir_exists(file)
|
||||
f = open(file, 'wb')
|
||||
|
@ -2231,6 +2239,7 @@ class TelegramClient(TelegramBareClient):
|
|||
# The used client will change if FileMigrateError occurs
|
||||
client = self
|
||||
cdn_decrypter = None
|
||||
input_location = utils.get_input_location(input_location)
|
||||
|
||||
__log__.info('Downloading file in chunks of %d bytes', part_size)
|
||||
try:
|
||||
|
@ -2264,7 +2273,11 @@ class TelegramClient(TelegramBareClient):
|
|||
# So there is nothing left to download and write
|
||||
if not result.bytes:
|
||||
# Return some extra information, unless it's a CDN file
|
||||
return getattr(result, 'type', '')
|
||||
if in_memory:
|
||||
f.flush()
|
||||
return f.getvalue()
|
||||
else:
|
||||
return getattr(result, 'type', '')
|
||||
|
||||
f.write(result.bytes)
|
||||
__log__.debug('Saved %d more bytes', len(result.bytes))
|
||||
|
@ -2279,7 +2292,7 @@ class TelegramClient(TelegramBareClient):
|
|||
cdn_decrypter.client.disconnect()
|
||||
except:
|
||||
pass
|
||||
if isinstance(file, str):
|
||||
if isinstance(file, str) or in_memory:
|
||||
f.close()
|
||||
|
||||
# endregion
|
||||
|
@ -2317,6 +2330,7 @@ class TelegramClient(TelegramBareClient):
|
|||
event = builder.build(update)
|
||||
if event:
|
||||
event._client = self
|
||||
event.original_update = update
|
||||
try:
|
||||
await callback(event)
|
||||
except events.StopPropagation:
|
||||
|
@ -2576,7 +2590,7 @@ class TelegramClient(TelegramBareClient):
|
|||
raise ValueError(
|
||||
'Could not find the input entity for "{}". Please read https://'
|
||||
'telethon.readthedocs.io/en/latest/extra/basic/entities.html to'
|
||||
'find out more details.'
|
||||
' find out more details.'
|
||||
.format(peer)
|
||||
)
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ class UpdateState:
|
|||
if self.handler:
|
||||
asyncio.ensure_future(self.handler(update), loop=self._loop)
|
||||
|
||||
def get_update_state(self, entity_id):
|
||||
"""Gets the updates.State corresponding to the given entity or 0."""
|
||||
return self._state
|
||||
|
||||
def process(self, update):
|
||||
"""Processes an update object. This method is normally called by
|
||||
the library itself.
|
||||
|
|
|
@ -25,7 +25,8 @@ from .tl.types import (
|
|||
InputPhotoEmpty, FileLocation, ChatPhotoEmpty, UserProfilePhotoEmpty,
|
||||
FileLocationUnavailable, InputMediaUploadedDocument, ChannelFull,
|
||||
InputMediaUploadedPhoto, DocumentAttributeFilename, photos,
|
||||
TopPeer, InputNotifyPeer, InputMessageID
|
||||
TopPeer, InputNotifyPeer, InputMessageID, InputFileLocation,
|
||||
InputDocumentFileLocation, PhotoSizeEmpty, InputDialogPeer
|
||||
)
|
||||
from .tl.types.contacts import ResolvedPeer
|
||||
|
||||
|
@ -181,6 +182,24 @@ def get_input_user(entity):
|
|||
_raise_cast_fail(entity, 'InputUser')
|
||||
|
||||
|
||||
def get_input_dialog(dialog):
|
||||
"""Similar to :meth:`get_input_peer`, but for dialogs"""
|
||||
try:
|
||||
if dialog.SUBCLASS_OF_ID == 0xa21c9795: # crc32(b'InputDialogPeer')
|
||||
return dialog
|
||||
if dialog.SUBCLASS_OF_ID == 0xc91c90b6: # crc32(b'InputPeer')
|
||||
return InputDialogPeer(dialog)
|
||||
except AttributeError:
|
||||
_raise_cast_fail(dialog, 'InputDialogPeer')
|
||||
|
||||
try:
|
||||
return InputDialogPeer(get_input_peer(dialog))
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
_raise_cast_fail(dialog, 'InputDialogPeer')
|
||||
|
||||
|
||||
def get_input_document(document):
|
||||
"""Similar to :meth:`get_input_peer`, but for documents"""
|
||||
try:
|
||||
|
@ -352,6 +371,39 @@ def get_input_message(message):
|
|||
_raise_cast_fail(message, 'InputMedia')
|
||||
|
||||
|
||||
def get_input_location(location):
|
||||
"""Similar to :meth:`get_input_peer`, but for input messages."""
|
||||
try:
|
||||
if location.SUBCLASS_OF_ID == 0x1523d462:
|
||||
return location # crc32(b'InputFileLocation'):
|
||||
except AttributeError:
|
||||
_raise_cast_fail(location, 'InputFileLocation')
|
||||
|
||||
if isinstance(location, Message):
|
||||
location = location.media
|
||||
|
||||
if isinstance(location, MessageMediaDocument):
|
||||
location = location.document
|
||||
elif isinstance(location, MessageMediaPhoto):
|
||||
location = location.photo
|
||||
|
||||
if isinstance(location, Document):
|
||||
return InputDocumentFileLocation(
|
||||
location.id, location.access_hash, location.version)
|
||||
elif isinstance(location, Photo):
|
||||
try:
|
||||
location = next(x for x in reversed(location.sizes)
|
||||
if not isinstance(x, PhotoSizeEmpty)).location
|
||||
except StopIteration:
|
||||
pass
|
||||
|
||||
if isinstance(location, (FileLocation, FileLocationUnavailable)):
|
||||
return InputFileLocation(
|
||||
location.volume_id, location.local_id, location.secret)
|
||||
|
||||
_raise_cast_fail(location, 'InputFileLocation')
|
||||
|
||||
|
||||
def is_image(file):
|
||||
"""
|
||||
Returns ``True`` if the file extension looks like an image file to Telegram.
|
||||
|
|
|
@ -207,7 +207,7 @@ class InteractiveTelegramClient(TelegramClient):
|
|||
# History
|
||||
elif msg == '!h':
|
||||
# First retrieve the messages and some information
|
||||
messages = self.get_message_history(entity, limit=10)
|
||||
messages = self.get_messages(entity, limit=10)
|
||||
|
||||
# Iterate over all (in reverse order so the latest appear
|
||||
# the last in the console) and print them with format:
|
||||
|
@ -216,7 +216,7 @@ class InteractiveTelegramClient(TelegramClient):
|
|||
# Note that the .sender attribute is only there for
|
||||
# convenience, the API returns it differently. But
|
||||
# this shouldn't concern us. See the documentation
|
||||
# for .get_message_history() for more information.
|
||||
# for .iter_messages() for more information.
|
||||
name = get_display_name(msg.sender)
|
||||
|
||||
# Format the message content
|
||||
|
|
90
telethon_generator/data/mtproto_api.tl
Normal file
90
telethon_generator/data/mtproto_api.tl
Normal file
|
@ -0,0 +1,90 @@
|
|||
//int ? = Int;
|
||||
//long ? = Long;
|
||||
//double ? = Double;
|
||||
//string ? = String;
|
||||
|
||||
dummyHttpWait = HttpWait;
|
||||
|
||||
//vector {t:Type} # [ t ] = Vector t;
|
||||
|
||||
//int128 4*[ int ] = Int128;
|
||||
//int256 8*[ int ] = Int256;
|
||||
|
||||
resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<long> = ResPQ;
|
||||
|
||||
p_q_inner_data#83c95aec pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data;
|
||||
p_q_inner_data_temp#3c6a84d4 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 expires_in:int = P_Q_inner_data;
|
||||
|
||||
server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
|
||||
server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
|
||||
|
||||
server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;
|
||||
|
||||
client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:string = Client_DH_Inner_Data;
|
||||
|
||||
dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;
|
||||
dh_gen_retry#46dc1fb9 nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer;
|
||||
dh_gen_fail#a69dae02 nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer;
|
||||
|
||||
bind_auth_key_inner#75a3f765 nonce:long temp_auth_key_id:long perm_auth_key_id:long temp_session_id:long expires_at:int = BindAuthKeyInner;
|
||||
|
||||
//rpc_result#f35c6d01 req_msg_id:long result:string = RpcResult;
|
||||
rpc_error#2144ca19 error_code:int error_message:string = RpcError;
|
||||
|
||||
rpc_answer_unknown#5e2ad36e = RpcDropAnswer;
|
||||
rpc_answer_dropped_running#cd78e586 = RpcDropAnswer;
|
||||
rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer;
|
||||
|
||||
future_salt#0949d9dc valid_since:int valid_until:int salt:long = FutureSalt;
|
||||
future_salts#ae500895 req_msg_id:long now:int salts:vector<future_salt> = FutureSalts;
|
||||
|
||||
pong#347773c5 msg_id:long ping_id:long = Pong;
|
||||
|
||||
destroy_session_ok#e22045fc session_id:long = DestroySessionRes;
|
||||
destroy_session_none#62d350c9 session_id:long = DestroySessionRes;
|
||||
|
||||
new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long = NewSession;
|
||||
|
||||
//msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;
|
||||
//message msg_id:long seqno:int bytes:int body:string = Message;
|
||||
//msg_copy#e06046b2 orig_message:Message = MessageCopy;
|
||||
|
||||
gzip_packed#3072cfa1 packed_data:string = Object;
|
||||
|
||||
msgs_ack#62d6b459 msg_ids:Vector<long> = MsgsAck;
|
||||
|
||||
bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
|
||||
bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;
|
||||
|
||||
msg_resend_req#7d861a08 msg_ids:Vector<long> = MsgResendReq;
|
||||
msgs_state_req#da69fb52 msg_ids:Vector<long> = MsgsStateReq;
|
||||
msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
|
||||
msgs_all_info#8cc0d131 msg_ids:Vector<long> info:string = MsgsAllInfo;
|
||||
msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
|
||||
msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
|
||||
|
||||
rsa_public_key n:string e:string = RSAPublicKey;
|
||||
|
||||
---functions---
|
||||
|
||||
req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
|
||||
|
||||
req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;
|
||||
|
||||
set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:string = Set_client_DH_params_answer;
|
||||
|
||||
rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;
|
||||
get_future_salts#b921bd04 num:int = FutureSalts;
|
||||
ping#7abe77ec ping_id:long = Pong;
|
||||
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
|
||||
destroy_session#e7512126 session_id:long = DestroySessionRes;
|
||||
|
||||
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
|
||||
|
||||
//test.useGzipPacked = GzipPacked;
|
||||
//test.useServerDhInnerData = Server_DH_inner_data;
|
||||
//test.useNewSessionCreated = NewSession;
|
||||
//test.useMsgsAck = MsgsAck;
|
||||
//test.useBadMsgNotification = BadMsgNotification;
|
||||
|
||||
//test.useOther key:rsa_public_key p_q_data:P_Q_inner_data dh_data:client_DH_inner_data = RpcError;
|
|
@ -1,147 +1,29 @@
|
|||
// Core types (no need to gen)
|
||||
//int ? = Int;
|
||||
//long ? = Long;
|
||||
//double ? = Double;
|
||||
//string ? = String;
|
||||
|
||||
//bytes = Bytes;
|
||||
|
||||
//true#3fedd339 = True;
|
||||
|
||||
//boolFalse#bc799737 = Bool;
|
||||
//boolTrue#997275b5 = Bool;
|
||||
|
||||
//vector#1cb5c415 {t:Type} # [ t ] = Vector t;
|
||||
|
||||
///////////////////////////////
|
||||
/////////////////// Layer cons
|
||||
///////////////////////////////
|
||||
|
||||
//invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
|
||||
//invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;
|
||||
//invokeWithLayer1#53835315 query:!X = X;
|
||||
//invokeWithLayer2#289dd1f6 query:!X = X;
|
||||
//invokeWithLayer3#b7475268 query:!X = X;
|
||||
//invokeWithLayer4#dea0d430 query:!X = X;
|
||||
//invokeWithLayer5#417a57ae query:!X = X;
|
||||
//invokeWithLayer6#3a64d54d query:!X = X;
|
||||
//invokeWithLayer7#a5be56d3 query:!X = X;
|
||||
//invokeWithLayer8#e9abd9fd query:!X = X;
|
||||
//invokeWithLayer9#76715a63 query:!X = X;
|
||||
//invokeWithLayer10#39620c41 query:!X = X;
|
||||
//invokeWithLayer11#a6b88fdf query:!X = X;
|
||||
//invokeWithLayer12#dda60d3c query:!X = X;
|
||||
//invokeWithLayer13#427c8ea2 query:!X = X;
|
||||
//invokeWithLayer14#2b9b08fa query:!X = X;
|
||||
//invokeWithLayer15#b4418b64 query:!X = X;
|
||||
//invokeWithLayer16#cf5f0987 query:!X = X;
|
||||
//invokeWithLayer17#50858a19 query:!X = X;
|
||||
//invokeWithLayer18#1c900537 query:!X = X;
|
||||
//invokeWithLayer#da9b0d0d layer:int query:!X = X; // after 18 layer
|
||||
|
||||
///////////////////////////////
|
||||
/// Authorization key creation
|
||||
///////////////////////////////
|
||||
|
||||
resPQ#05162463 nonce:int128 server_nonce:int128 pq:bytes server_public_key_fingerprints:Vector<long> = ResPQ;
|
||||
|
||||
p_q_inner_data#83c95aec pq:bytes p:bytes q:bytes nonce:int128 server_nonce:int128 new_nonce:int256 = P_Q_inner_data;
|
||||
|
||||
server_DH_params_fail#79cb045d nonce:int128 server_nonce:int128 new_nonce_hash:int128 = Server_DH_Params;
|
||||
server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:bytes = Server_DH_Params;
|
||||
|
||||
server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:bytes g_a:bytes server_time:int = Server_DH_inner_data;
|
||||
|
||||
client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:bytes = Client_DH_Inner_Data;
|
||||
|
||||
dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;
|
||||
dh_gen_retry#46dc1fb9 nonce:int128 server_nonce:int128 new_nonce_hash2:int128 = Set_client_DH_params_answer;
|
||||
dh_gen_fail#a69dae02 nonce:int128 server_nonce:int128 new_nonce_hash3:int128 = Set_client_DH_params_answer;
|
||||
|
||||
destroy_auth_key_ok#f660e1d4 = DestroyAuthKeyRes;
|
||||
destroy_auth_key_none#0a9f2259 = DestroyAuthKeyRes;
|
||||
destroy_auth_key_fail#ea109b13 = DestroyAuthKeyRes;
|
||||
|
||||
---functions---
|
||||
|
||||
// Deprecated since somewhere around February of 2018
|
||||
// See https://core.telegram.org/mtproto/auth_key
|
||||
req_pq#60469778 nonce:int128 = ResPQ;
|
||||
req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;
|
||||
|
||||
req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:bytes q:bytes public_key_fingerprint:long encrypted_data:bytes = Server_DH_Params;
|
||||
|
||||
set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:bytes = Set_client_DH_params_answer;
|
||||
|
||||
destroy_auth_key#d1435160 = DestroyAuthKeyRes;
|
||||
|
||||
///////////////////////////////
|
||||
////////////// System messages
|
||||
///////////////////////////////
|
||||
|
||||
---types---
|
||||
|
||||
msgs_ack#62d6b459 msg_ids:Vector<long> = MsgsAck;
|
||||
|
||||
bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
|
||||
bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;
|
||||
|
||||
msgs_state_req#da69fb52 msg_ids:Vector<long> = MsgsStateReq;
|
||||
msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
|
||||
msgs_all_info#8cc0d131 msg_ids:Vector<long> info:string = MsgsAllInfo;
|
||||
|
||||
msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
|
||||
msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
|
||||
|
||||
msg_resend_req#7d861a08 msg_ids:Vector<long> = MsgResendReq;
|
||||
|
||||
//rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult; // parsed manually
|
||||
|
||||
rpc_error#2144ca19 error_code:int error_message:string = RpcError;
|
||||
|
||||
rpc_answer_unknown#5e2ad36e = RpcDropAnswer;
|
||||
rpc_answer_dropped_running#cd78e586 = RpcDropAnswer;
|
||||
rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer;
|
||||
|
||||
future_salt#0949d9dc valid_since:int valid_until:int salt:long = FutureSalt;
|
||||
future_salts#ae500895 req_msg_id:long now:int salts:vector<future_salt> = FutureSalts;
|
||||
|
||||
pong#347773c5 msg_id:long ping_id:long = Pong;
|
||||
|
||||
destroy_session_ok#e22045fc session_id:long = DestroySessionRes;
|
||||
destroy_session_none#62d350c9 session_id:long = DestroySessionRes;
|
||||
|
||||
new_session_created#9ec20908 first_msg_id:long unique_id:long server_salt:long = NewSession;
|
||||
|
||||
//message msg_id:long seqno:int bytes:int body:Object = Message; // parsed manually
|
||||
//msg_container#73f1f8dc messages:vector<message> = MessageContainer; // parsed manually
|
||||
//msg_copy#e06046b2 orig_message:Message = MessageCopy; // parsed manually, not used - use msg_container
|
||||
//gzip_packed#3072cfa1 packed_data:string = Object; // parsed manually
|
||||
|
||||
http_wait#9299359f max_delay:int wait_after:int max_wait:int = HttpWait;
|
||||
error#c4b9f9bb code:int text:string = Error;
|
||||
|
||||
ipPort ipv4:int port:int = IpPort;
|
||||
help.configSimple#d997c3c5 date:int expires:int dc_id:int ip_port_list:Vector<ipPort> = help.ConfigSimple;
|
||||
|
||||
---functions---
|
||||
|
||||
rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;
|
||||
|
||||
get_future_salts#b921bd04 num:int = FutureSalts;
|
||||
|
||||
ping#7abe77ec ping_id:long = Pong;
|
||||
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;
|
||||
|
||||
destroy_session#e7512126 session_id:long = DestroySessionRes;
|
||||
|
||||
contest.saveDeveloperInfo#9a5f6e95 vk_id:int name:string phone_number:string age:int city:string = Bool;
|
||||
|
||||
///////////////////////////////
|
||||
///////// Main application API
|
||||
///////////////////////////////
|
||||
test.useError = Error;
|
||||
test.useConfigSimple = help.ConfigSimple;
|
||||
|
||||
---types---
|
||||
|
||||
boolFalse#bc799737 = Bool;
|
||||
boolTrue#997275b5 = Bool;
|
||||
|
||||
true#3fedd339 = True;
|
||||
|
||||
vector#1cb5c415 {t:Type} # [ t ] = Vector t;
|
||||
|
||||
error#c4b9f9bb code:int text:string = Error;
|
||||
|
||||
null#56730bcc = Null;
|
||||
|
||||
inputPeerEmpty#7f3b18ea = InputPeer;
|
||||
inputPeerSelf#7da07ec9 = InputPeer;
|
||||
inputPeerChat#179be863 chat_id:int = InputPeer;
|
||||
|
@ -273,6 +155,7 @@ messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAct
|
|||
messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||
messageActionScreenshotTaken#4792929b = MessageAction;
|
||||
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
|
||||
|
||||
|
@ -425,8 +308,8 @@ updateRecentStickers#9a422c20 = Update;
|
|||
updateConfig#a229dd06 = Update;
|
||||
updatePtsChanged#3354678f = Update;
|
||||
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
|
||||
updateDialogPinned#d711a2cc flags:# pinned:flags.0?true peer:Peer = Update;
|
||||
updatePinnedDialogs#d8caf68d flags:# order:flags.0?Vector<Peer> = Update;
|
||||
updateDialogPinned#19d27f3c flags:# pinned:flags.0?true peer:DialogPeer = Update;
|
||||
updatePinnedDialogs#ea4cb65b flags:# order:flags.0?Vector<DialogPeer> = Update;
|
||||
updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
|
||||
updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
|
@ -460,11 +343,11 @@ photos.photosSlice#15051f54 count:int photos:Vector<Photo> users:Vector<User> =
|
|||
photos.photo#20212ca8 photo:Photo users:Vector<User> = photos.Photo;
|
||||
|
||||
upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
|
||||
upload.fileCdnRedirect#ea52fe5a dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes cdn_file_hashes:Vector<CdnFileHash> = upload.File;
|
||||
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
|
||||
|
||||
dcOption#5d8c6cc flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int = DcOption;
|
||||
|
||||
config#9c840964 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int disabled_features:Vector<DisabledFeature> = Config;
|
||||
config#86b5778e flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string suggested_lang_code:flags.2?string lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
|
@ -569,8 +452,6 @@ stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
|
|||
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
|
||||
messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
|
||||
|
||||
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
|
||||
|
||||
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
|
||||
|
||||
contactLinkUnknown#5f4f9247 = ContactLink;
|
||||
|
@ -608,7 +489,7 @@ inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
|||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#cd303b41 flags:# installed:flags.0?true archived:flags.1?true official:flags.2?true masks:flags.3?true id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
stickerSet#5585a139 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
|
@ -645,6 +526,8 @@ messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
|
|||
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
|
||||
messageEntityMentionName#352dca58 offset:int length:int user_id:int = MessageEntity;
|
||||
inputMessageEntityMentionName#208e68c9 offset:int length:int user_id:InputUser = MessageEntity;
|
||||
messageEntityPhone#9b69e34b offset:int length:int = MessageEntity;
|
||||
messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#afeb712e channel_id:int access_hash:long = InputChannel;
|
||||
|
@ -695,7 +578,7 @@ inputBotInlineMessageMediaVenue#aaafadc8 flags:# geo_point:InputGeoPoint title:s
|
|||
inputBotInlineMessageMediaContact#2daf01a7 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage;
|
||||
|
||||
inputBotInlineResult#2cbbe15a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResult#88bf9319 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?InputWebDocument content:flags.5?InputWebDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
|
||||
|
@ -706,7 +589,7 @@ botInlineMessageMediaGeo#b722de65 flags:# geo:GeoPoint period:int reply_markup:f
|
|||
botInlineMessageMediaVenue#4366232e flags:# geo:GeoPoint title:string address:string provider:string venue_id:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
botInlineMessageMediaContact#35edb4d4 flags:# phone_number:string first_name:string last_name:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
|
||||
|
||||
botInlineResult#9bebaeb9 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb_url:flags.4?string content_url:flags.5?string content_type:flags.5?string w:flags.6?int h:flags.6?int duration:flags.7?int send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineResult#11965f3a flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?WebDocument content:flags.5?WebDocument send_message:BotInlineMessage = BotInlineResult;
|
||||
botInlineMediaResult#17db940b flags:# id:string type:string photo:flags.0?Photo document:flags.1?Document title:flags.2?string description:flags.3?string send_message:BotInlineMessage = BotInlineResult;
|
||||
|
||||
messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM results:Vector<BotInlineResult> cache_time:int users:Vector<User> = messages.BotResults;
|
||||
|
@ -755,7 +638,7 @@ messages.featuredStickersNotModified#4ede3cf = messages.FeaturedStickers;
|
|||
messages.featuredStickers#f89d88e5 hash:int sets:Vector<StickerSetCovered> unread:Vector<long> = messages.FeaturedStickers;
|
||||
|
||||
messages.recentStickersNotModified#b17f890 = messages.RecentStickers;
|
||||
messages.recentStickers#5ce20970 hash:int stickers:Vector<Document> = messages.RecentStickers;
|
||||
messages.recentStickers#22f3afb3 hash:int packs:Vector<StickerPack> stickers:Vector<Document> dates:Vector<int> = messages.RecentStickers;
|
||||
|
||||
messages.archivedStickers#4fcba9c8 count:int sets:Vector<StickerSetCovered> = messages.ArchivedStickers;
|
||||
|
||||
|
@ -837,6 +720,7 @@ paymentRequestedInfo#909c3f94 flags:# name:flags.0?string phone:flags.1?string e
|
|||
paymentSavedCredentialsCard#cdc27a1f id:string title:string = PaymentSavedCredentials;
|
||||
|
||||
webDocument#c61acbd8 url:string access_hash:long size:int mime_type:string attributes:Vector<DocumentAttribute> dc_id:int = WebDocument;
|
||||
webDocumentNoProxy#f9c8bcc6 url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = WebDocument;
|
||||
|
||||
inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
|
||||
|
||||
|
@ -925,8 +809,6 @@ channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?tru
|
|||
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
|
||||
cdnFileHash#77eec38f offset:int limit:int hash:bytes = CdnFileHash;
|
||||
|
||||
messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
|
||||
messages.favedStickers#f37f2f16 hash:int packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
|
||||
|
||||
|
@ -948,6 +830,15 @@ inputMessageID#a676a322 id:int = InputMessage;
|
|||
inputMessageReplyTo#bad88395 id:int = InputMessage;
|
||||
inputMessagePinned#86872538 = InputMessage;
|
||||
|
||||
inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
|
||||
|
||||
dialogPeer#e56dbf05 peer:Peer = DialogPeer;
|
||||
|
||||
messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
|
||||
messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
|
||||
|
||||
fileHash#6242c773 offset:int limit:int hash:bytes = FileHash;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
|
@ -974,7 +865,7 @@ auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentC
|
|||
auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
||||
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||
|
||||
account.registerDevice#1389cc token_type:int token:string app_sandbox:Bool other_uids:Vector<int> = Bool;
|
||||
account.registerDevice#5cbea590 token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
|
||||
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||
account.updateNotifySettings#84be5b93 peer:InputNotifyPeer settings:InputPeerNotifySettings = Bool;
|
||||
account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
|
||||
|
@ -1027,7 +918,7 @@ contacts.resetSaved#879537f1 = Bool;
|
|||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#39e9ea0 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
|
@ -1039,6 +930,7 @@ messages.forwardMessages#708e0195 flags:# silent:flags.5?true background:flags.6
|
|||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.hideReportSpam#a8f1709b peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
|
||||
messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
|
||||
messages.editChatTitle#dc452855 chat_id:int title:string = Updates;
|
||||
|
@ -1058,7 +950,7 @@ messages.sendEncryptedService#32d439a4 peer:InputEncryptedChat random_id:long da
|
|||
messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
|
||||
messages.reportEncryptedSpam#4b0c8c0f peer:InputEncryptedChat = Bool;
|
||||
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
|
||||
messages.getStickers#85cb5182 flags:# exclude_featured:flags.0?true emoticon:string hash:string = messages.Stickers;
|
||||
messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#7d885289 chat_id:int = ExportedChatInvite;
|
||||
|
@ -1086,7 +978,7 @@ messages.editMessage#5d1b8dd flags:# no_webpage:flags.1?true stop_geo_live:flags
|
|||
messages.editInlineBotMessage#b0e08243 flags:# no_webpage:flags.1?true stop_geo_live:flags.12?true id:InputBotInlineMessageID message:flags.11?string reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> geo_point:flags.13?InputGeoPoint = Bool;
|
||||
messages.getBotCallbackAnswer#810a9fec flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes = messages.BotCallbackAnswer;
|
||||
messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool;
|
||||
messages.getPeerDialogs#2d9776b9 peers:Vector<InputPeer> = messages.PeerDialogs;
|
||||
messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
|
||||
messages.saveDraft#bc39e14b flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int peer:InputPeer message:string entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
messages.getAllDrafts#6a3f8d65 = Updates;
|
||||
messages.getFeaturedStickers#2dacca4f hash:int = messages.FeaturedStickers;
|
||||
|
@ -1104,8 +996,8 @@ messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:Inpu
|
|||
messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = messages.Chats;
|
||||
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
|
||||
messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
|
||||
messages.toggleDialogPin#3289be6a flags:# pinned:flags.0?true peer:InputPeer = Bool;
|
||||
messages.reorderPinnedDialogs#959ff644 flags:# force:flags.0?true order:Vector<InputPeer> = Bool;
|
||||
messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.reorderPinnedDialogs#5b51d63f flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
||||
messages.getPinnedDialogs#e254d64e = messages.PeerDialogs;
|
||||
messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
|
||||
messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
|
||||
|
@ -1115,9 +1007,10 @@ messages.getFavedStickers#21ce0b0e hash:int = messages.FavedStickers;
|
|||
messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.getRecentLocations#249431e2 peer:InputPeer limit:int = messages.Messages;
|
||||
messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = messages.Messages;
|
||||
messages.sendMultiMedia#2095512f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
|
@ -1133,8 +1026,9 @@ upload.getFile#e3a6cfb5 location:InputFileLocation offset:int limit:int = upload
|
|||
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
|
||||
upload.getWebFile#24e6818d location:InputWebFileLocation offset:int limit:int = upload.WebFile;
|
||||
upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
|
||||
upload.reuploadCdnFile#1af91c09 file_token:bytes request_token:bytes = Vector<CdnFileHash>;
|
||||
upload.getCdnFileHashes#f715c87b file_token:bytes offset:int = Vector<CdnFileHash>;
|
||||
upload.reuploadCdnFile#9b2754a8 file_token:bytes request_token:bytes = Vector<FileHash>;
|
||||
upload.getCdnFileHashes#4da54231 file_token:bytes offset:int = Vector<FileHash>;
|
||||
upload.getFileHashes#c7025931 location:InputFileLocation offset:int = Vector<FileHash>;
|
||||
|
||||
help.getConfig#c4f9186b = Config;
|
||||
help.getNearestDc#1fb33026 = NearestDc;
|
||||
|
@ -1210,4 +1104,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
|
|||
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
|
||||
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
|
||||
|
||||
// LAYER 75
|
||||
// LAYER 76
|
|
@ -1,13 +1,15 @@
|
|||
from telethon_generator.parsers import parse_errors, parse_tl, find_layer
|
||||
from telethon_generator.generators import\
|
||||
generate_errors, generate_tlobjects, generate_docs
|
||||
import itertools
|
||||
|
||||
|
||||
ERRORS_INPUT_JSON = 'data/errors.json'
|
||||
ERRORS_INPUT_DESC = 'data/error_descriptions'
|
||||
ERRORS_OUTPUT = '../telethon/errors/rpc_error_list.py'
|
||||
|
||||
TLOBJECT_INPUT_TL = 'data/scheme.tl'
|
||||
TLOBJECT_INPUT_CORE_TL = 'data/mtproto_api.tl'
|
||||
TLOBJECT_INPUT_TL = 'data/telegram_api.tl'
|
||||
TLOBJECT_OUTPUT = '../telethon/tl'
|
||||
|
||||
DOCS_INPUT_RES = 'data/html'
|
||||
|
@ -15,7 +17,9 @@ DOCS_OUTPUT = '../docs'
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
tlobjects = list(parse_tl(TLOBJECT_INPUT_TL, ignore_core=True))
|
||||
tlobjects = list(itertools.chain(
|
||||
parse_tl(TLOBJECT_INPUT_CORE_TL), parse_tl(TLOBJECT_INPUT_TL)))
|
||||
|
||||
errors = list(parse_errors(ERRORS_INPUT_JSON, ERRORS_INPUT_DESC))
|
||||
layer = find_layer(TLOBJECT_INPUT_TL)
|
||||
|
||||
|
|
|
@ -439,9 +439,9 @@ def _write_html_pages(tlobjects, errors, layer, input_res, output_dir):
|
|||
# List all the methods which take this type as input
|
||||
docs.write_title('Methods accepting this type as input', level=3)
|
||||
other_methods = sorted(
|
||||
(t for t in tlobjects
|
||||
if any(t == a.type for a in t.args) and t.is_function),
|
||||
key=lambda t: t.name
|
||||
(u for u in tlobjects
|
||||
if any(a.type == t for a in u.args) and u.is_function),
|
||||
key=lambda u: u.name
|
||||
)
|
||||
if not other_methods:
|
||||
docs.write_text(
|
||||
|
@ -464,10 +464,9 @@ def _write_html_pages(tlobjects, errors, layer, input_res, output_dir):
|
|||
# List every other type which has this type as a member
|
||||
docs.write_title('Other types containing this type', level=3)
|
||||
other_types = sorted(
|
||||
(t for t in tlobjects
|
||||
if any(t == a.type for a in t.args)
|
||||
and not t.is_function
|
||||
), key=lambda t: t.name
|
||||
(u for u in tlobjects
|
||||
if any(a.type == t for a in u.args) and not u.is_function),
|
||||
key=lambda u: u.name
|
||||
)
|
||||
|
||||
if not other_types:
|
||||
|
|
|
@ -17,6 +17,7 @@ AUTO_CASTS = {
|
|||
'InputPeer': 'utils.get_input_peer(await client.get_input_entity({}))',
|
||||
'InputChannel': 'utils.get_input_channel(await client.get_input_entity({}))',
|
||||
'InputUser': 'utils.get_input_user(await client.get_input_entity({}))',
|
||||
'InputDialogPeer': 'utils.get_input_dialog(await client.get_input_entity({}))',
|
||||
'InputMedia': 'utils.get_input_media({})',
|
||||
'InputPhoto': 'utils.get_input_photo({})',
|
||||
'InputMessage': 'utils.get_input_message({})'
|
||||
|
|
|
@ -34,7 +34,7 @@ class HigherLevelTests(unittest.TestCase):
|
|||
progress_callback=lambda c, t:
|
||||
print('test_cdn_download:uploading {:.2%}...'.format(c/t))
|
||||
)
|
||||
msg = (await client.get_message_history(me))[1][0]
|
||||
msg = (await client.get_messages(me))[0]
|
||||
|
||||
out = BytesIO()
|
||||
await client.download_media(msg, out)
|
||||
|
|
Loading…
Reference in New Issue
Block a user