diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md deleted file mode 100644 index 9420f6d8f..000000000 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Bug Report -about: Create a report about a bug inside the library or issues with the documentation -title: '' -labels: '' -assignees: '' - ---- - -**Checklist** - - -* [ ] The error is in the library's code, and not in my own. -* [ ] I have searched for this issue before posting it and there isn't a duplicate. -* [ ] I ran `pip install -U https://github.com/LonamiWebs/Telethon/archive/v1.zip` and triggered the bug in the latest version. - -**Code that causes the issue** -```python -from telethon.sync import TelegramClient -... - -``` - -**Traceback** -``` -Traceback (most recent call last): - File "code.py", line 1, in - -``` diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 000000000..9ca5d9167 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,96 @@ +name: Bug Report +description: Create a report about a bug inside the library. +body: + + - type: textarea + id: reproducing-example + attributes: + label: Code that causes the issue + description: Provide a code example that reproduces the problem. Try to keep it short without other dependencies. + placeholder: | + ```python + from telethon.sync import TelegramClient + ... + + ``` + validations: + required: true + + - type: textarea + id: expected-behavior + attributes: + label: Expected behavior + description: Explain what you should expect to happen. Include reproduction steps. + placeholder: | + "I was doing... I was expecting the following to happen..." + validations: + required: true + + - type: textarea + id: actual-behavior + attributes: + label: Actual behavior + description: Explain what actually happens. + placeholder: | + "This happened instead..." + validations: + required: true + + - type: textarea + id: traceback + attributes: + label: Traceback + description: | + The traceback, if the problem is a crash. + placeholder: | + ``` + Traceback (most recent call last): + File "code.py", line 1, in + + ``` + + - type: input + id: telethon-version + attributes: + label: Telethon version + description: The output of `python -c "import telethon; print(telethon.__version__)"`. + placeholder: "1.x" + validations: + required: true + + - type: input + id: python-version + attributes: + label: Python version + description: The output of `python --version`. + placeholder: "3.x" + validations: + required: true + + - type: input + id: os + attributes: + label: Operating system (including distribution name and version) + placeholder: Windows 11, macOS 13.4, Ubuntu 23.04... + validations: + required: true + + - type: textarea + id: other-details + attributes: + label: Other details + placeholder: | + Additional details and attachments. Is it a server? Network condition? + + - type: checkboxes + id: checklist + attributes: + label: Checklist + description: Read this carefully, we will close and ignore your issue if you skimmed through this. + options: + - label: The error is in the library's code, and not in my own. + required: true + - label: I have searched for this issue before posting it and there isn't an open duplicate. + required: true + - label: I ran `pip install -U https://github.com/LonamiWebs/Telethon/archive/v1.zip` and triggered the bug in the latest version. + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3428bb104..762435093 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,3 +1,4 @@ +blank_issues_enabled: false contact_links: - name: Ask questions in StackOverflow url: https://stackoverflow.com/questions/ask?tags=telethon diff --git a/.github/ISSUE_TEMPLATE/documentation-issue.yml b/.github/ISSUE_TEMPLATE/documentation-issue.yml new file mode 100644 index 000000000..24fa7d441 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation-issue.yml @@ -0,0 +1,22 @@ +name: Documentation Issue +description: Report a problem with the documentation. +labels: [documentation] +body: + + - type: textarea + id: description + attributes: + label: Description + description: Describe the problem in detail. + placeholder: This part is unclear... + + - type: checkboxes + id: checklist + attributes: + label: Checklist + description: Read this carefully, we will close and ignore your issue if you skimmed through this. + options: + - label: This is a documentation problem, not a question or a bug report. + required: true + - label: I have searched for this issue before posting it and there isn't a duplicate. + required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index dc38f2db1..000000000 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Feature Request -about: Suggest ideas, changes or other enhancements for the library -title: '' -labels: enhancement -assignees: '' - ---- - -Please describe your idea. Would you like another friendly method? Renaming them to something more appropriated? Changing the way something works? diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml new file mode 100644 index 000000000..68254a357 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -0,0 +1,22 @@ +name: Feature Request +description: Suggest ideas, changes or other enhancements for the library. +labels: [enhancement] +body: + + - type: textarea + id: feature-description + attributes: + label: Describe your suggested feature + description: Please describe your idea. Would you like another friendly method? Renaming them to something more appropriate? Changing the way something works? + placeholder: "It should work like this..." + validations: + required: true + + - type: checkboxes + id: checklist + attributes: + label: Checklist + description: Read this carefully, we will close and ignore your issue if you skimmed through this. + options: + - label: I have searched for this issue before posting it and there isn't a duplicate. + required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..3f7074fb0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,5 @@ + diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..12c1f0a83 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,18 @@ +# https://docs.readthedocs.io/en/stable/config-file/v2.html +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +sphinx: + configuration: readthedocs/conf.py + +formats: + - pdf + - epub + +python: + install: + - requirements: readthedocs/requirements.txt diff --git a/readthedocs/basic/updates.rst b/readthedocs/basic/updates.rst index 6e22ae64a..cd935fdc3 100644 --- a/readthedocs/basic/updates.rst +++ b/readthedocs/basic/updates.rst @@ -16,7 +16,7 @@ For that, you can use **events**. .. code-block:: python import logging - logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', + logging.basicConfig(format='[%(levelname) %(asctime)s] %(name)s: %(message)s', level=logging.WARNING) diff --git a/readthedocs/concepts/entities.rst b/readthedocs/concepts/entities.rst index 40bfac30e..8d6a61703 100644 --- a/readthedocs/concepts/entities.rst +++ b/readthedocs/concepts/entities.rst @@ -268,7 +268,7 @@ That means you can do this: .. code-block:: python message.user_id - await message.get_input_user() + await message.get_input_sender() message.user # ...etc diff --git a/readthedocs/misc/changelog.rst b/readthedocs/misc/changelog.rst index 4b2de63c7..0155a9344 100644 --- a/readthedocs/misc/changelog.rst +++ b/readthedocs/misc/changelog.rst @@ -13,6 +13,262 @@ it can take advantage of new goodies! .. contents:: List of All Versions +New layer (v1.38) +================= + ++------------------------+ +| Scheme layer used: 193 | ++------------------------+ + +`View new and changed raw API methods `__. + +Bug fixes +~~~~~~~~~ + +* Formatting entities misbehaved with albums. +* Sending a Message object with a file did not use the new file. + + +New layer (v1.37) +================= + ++------------------------+ +| Scheme layer used: 188 | ++------------------------+ + +`View new and changed raw API methods `__. + +Additions +~~~~~~~~~ + +* Support for CDN downloads should be back. Telethon still prefers no CDN by default. + +Enhancements +~~~~~~~~~~~~ + +* ``FloodWaitPremium`` should now be handled like any other floodwaits. + +Bug fixes +~~~~~~~~~ + +* Fixed edge-case when using ``get_messages(..., reverse=True)``. +* ``ConnectionError`` when using proxies should be raised properly. + + +New layer (v1.36) +================= + ++------------------------+ +| Scheme layer used: 181 | ++------------------------+ + +`View new and changed raw API methods `__. + +Bug fixes +~~~~~~~~~ + +* Certain updates, such as :tl:`UpdateBotStopped`, should now be processed reliably. + + +New layer (v1.35) +================= + ++------------------------+ +| Scheme layer used: 178 | ++------------------------+ + +`View new and changed raw API methods `__. + +Additions +~~~~~~~~~ + +* ``drop_author`` parameter now exposed in ``forward_messages``. + +Enhancements +~~~~~~~~~~~~ + +* "Custom secret support" should work with ``TcpMTProxy``. +* Some type hints should now be more accurate. + +Bug fixes +~~~~~~~~~ + +* Session path couldn't be a ``pathlib.Path`` or ``None``. +* Python versions older than 3.9 should now be supported again. +* Readthedocs should hopefully build the v1 documentation again. + + +New layer (v1.34) +================= + ++------------------------+ +| Scheme layer used: 173 | ++------------------------+ + +`View new and changed raw API methods `__. + +Additions +~~~~~~~~~ + +* ``reply_to_chat`` and ``reply_to_sender`` are now in ``Message``. + This is useful when you lack access to the chat, but Telegram still included some basic information. + +Bug fixes +~~~~~~~~~ + +* ``parse_mode`` with a custom instance containing both ``parse`` and ``unparse`` should now work. +* Parsing and unparsing message entities should now behave better in certain corner-cases. + + +New layer (v1.33) +================= + ++------------------------+ +| Scheme layer used: 167 | ++------------------------+ + +`View new and changed raw API methods `__. + +Enhancements +~~~~~~~~~~~~ + +* ``webbrowser`` is now imported conditionally, to support niche environments. +* Library should now retry on the suddenly-common ``TimedOutError``. + +Bug fixes +~~~~~~~~~ + +* Sending photos which were automatically resized should work again (included in the v1.32 series). + + +New layer (v1.32) +================= + ++------------------------+ +| Scheme layer used: 166 | ++------------------------+ + +`View new and changed raw API methods `__. + +This enables you to use custom languages in preformatted blocks using HTML: + +.. code-block:: html + +
+    from telethon import TelegramClient
+  
+ +Note that Telethon v1's markdown is a custom format and won't support language tags. +If you want to set a custom language, you have to use HTML or a custom formatter. + + +Dropped imghdr support (v1.31) +============================== + ++------------------------+ +| Scheme layer used: 165 | ++------------------------+ + +This release contains a breaking change in preparation for Python 3.12. +If you were sending photos from in-memory ``bytes`` or ``BytesIO`` containing images, +you should now use ``BytesIO`` and set the ``.name`` property to a dummy name. +This will allow Telethon to detect the correct extension (and file type). + +.. code-block:: python + + # before + image_data = b'...' + client.send_file(chat, image_data) + + # after + from io import BytesIO + image_data = BytesIO(b'...') + image_data.name = 'a.jpg' # any name, only the extension matters + client.send_file(chat, image_data) + + +Bug fixes +~~~~~~~~~ + +* Code generation wasn't working under PyPy. +* Obtaining markdown or HTML from message text could produce unexpected results sometimes. +* Other fixes for bugs from the previous version, which were already fixed in patch versions. + +Breaking Changes +~~~~~~~~~~~~~~~~ + +* ``imghdr`` is deprecated in newer Python versions, so Telethon no longer uses it. + This means there might be some cases where Telethon fails to infer the file extension for buffers containing images. + If you were relying on this, add ``.name = 'a.jpg'`` (or other extension) to the ``BytesIO`` buffers you upload. + +Layer bump and small changes (v1.30) +==================================== + ++------------------------+ +| Scheme layer used: 162 | ++------------------------+ + +Some of the bug fixes were already present in patch versions of ``v1.29``, but +the new layer necessitated a minor bump. + +Enhancements +~~~~~~~~~~~~ + +* Removed client-side checks for editing messages. + This only affects ``Message.edit``, as ``client.edit_message`` already had + no checks. +* Library should not understand more server-side errors during update handling + which should reduce crashes. +* Client-side image compression should behave better now. + +Bug fixes +~~~~~~~~~ + +* Some updates such as ``UpdateChatParticipant`` were being missed due to the + order in which Telegram sent them. The library now more carefully checks for + the sequence and pts contained in them to avoid dropping them. +* Fixed ``is_inline`` check for :tl:`KeyboardButtonWebView`. +* Fixed some issues getting entity from cache by ID. +* ``reply_to`` should now work when sending albums. + + +More bug fixing (v1.29) +======================= + ++------------------------+ +| Scheme layer used: 160 | ++------------------------+ + +This layer introduces the necessary raw API methods to work with stories. + +The library is aiming to be "feature-frozen" for as long as v1 is active, +so friendly client methods are not implemented, but example code to use +stories can be found in the GitHub wiki of the project. + +Enhancements +~~~~~~~~~~~~ + +* Removed client-side checks for methods dealing with chat permissions. + In particular, this means you can now ban channels. +* Improved some error messages and added new classes for more RPC errors. +* The client-side check for valid usernames has been loosened, so that + very short premium usernames are no longer considered invalid. + +Bug fixes +~~~~~~~~~ + +* Attempting to download a thumbnail from documnets without one would fail, + rather than do nothing (since nothing can be downloaded if there is no thumb). +* More errors are caught in the update handling loop. +* HTML ``.text`` should now "unparse" any message contents correctly. +* Fixed some problems related to logging. +* ``comment_to`` should now work as expected with albums. +* ``asyncio.CancelledError`` should now correctly propagate from the update loop. +* Removed some absolute imports in favour of relative imports. +* ``UserUpdate.last_seen`` should now behave correctly. +* Fixed a rare ``ValueError`` during ``connect`` if the session cache was bad. + + New Layer and housekeeping (v1.28) ================================== diff --git a/readthedocs/quick-references/faq.rst b/readthedocs/quick-references/faq.rst index 7b714f412..21635a88d 100644 --- a/readthedocs/quick-references/faq.rst +++ b/readthedocs/quick-references/faq.rst @@ -20,7 +20,7 @@ To enable logging, at the following code to the top of your main file: .. code-block:: python import logging - logging.basicConfig(format='[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s', + logging.basicConfig(format='[%(levelname) %(asctime)s] %(name)s: %(message)s', level=logging.WARNING) You can change the logging level to be something different, from less to more information: @@ -272,7 +272,7 @@ connects to Telegram, both agree on the layer to use. If the layers don't match, Telegram may send certain objects which Telethon no longer understands. When this message is reported as a "bug", the most common patterns seem to be -that he Telethon session is being used or has been used from somewhere else. +that the Telethon session is being used or has been used from somewhere else. Make sure that you created the session from Telethon, and are not using the same session anywhere else. If you need to use the same account from multiple places, login and use a different session for each place you need. diff --git a/readthedocs/requirements.txt b/readthedocs/requirements.txt index 97c7493dc..c7029ce2c 100644 --- a/readthedocs/requirements.txt +++ b/readthedocs/requirements.txt @@ -1 +1,2 @@ -telethon \ No newline at end of file +./ +sphinx-rtd-theme~=1.3.0 diff --git a/setup.py b/setup.py index 0bb0eb6b8..a78961c23 100755 --- a/setup.py +++ b/setup.py @@ -180,8 +180,9 @@ def main(argv): # Try importing the telethon module to assert it has no errors try: import telethon - except: + except Exception as e: print('Packaging for PyPi aborted, importing the module failed.') + print(e) return remove_dirs = ['__pycache__', 'build', 'dist', 'Telethon.egg-info'] diff --git a/telethon/_updates/messagebox.py b/telethon/_updates/messagebox.py index 2b4e75ff3..f8d4ae961 100644 --- a/telethon/_updates/messagebox.py +++ b/telethon/_updates/messagebox.py @@ -45,22 +45,34 @@ # Documentation recommends 15 minutes without updates (https://core.telegram.org/api/updates). NO_UPDATES_TIMEOUT = 15 * 60 +# object() but with a tag to make it easier to debug +class Sentinel: + __slots__ = ('tag',) + + def __init__(self, tag=None): + self.tag = tag or '_' + + def __repr__(self): + return self.tag + # Entry "enum". # Account-wide `pts` includes private conversations (one-to-one) and small group chats. -ENTRY_ACCOUNT = object() +ENTRY_ACCOUNT = Sentinel('ACCOUNT') # Account-wide `qts` includes only "secret" one-to-one chats. -ENTRY_SECRET = object() +ENTRY_SECRET = Sentinel('SECRET') # Integers will be Channel-specific `pts`, and includes "megagroup", "broadcast" and "supergroup" channels. # Python's logging doesn't define a TRACE level. Pick halfway between DEBUG and NOTSET. # We don't define a name for this as libraries shouldn't do that though. LOG_LEVEL_TRACE = (logging.DEBUG - logging.NOTSET) // 2 -_sentinel = object() +_sentinel = Sentinel() def next_updates_deadline(): return get_running_loop().time() + NO_UPDATES_TIMEOUT +def epoch(): + return datetime.datetime(*time.gmtime(0)[:6]).replace(tzinfo=datetime.timezone.utc) class GapError(ValueError): def __repr__(self): @@ -99,19 +111,12 @@ def from_update(cls, update): qts = getattr(update, 'qts', None) if qts: - pts_count = 1 if isinstance(update, tl.UpdateNewEncryptedMessage) else 0 - return cls(pts=qts, pts_count=pts_count, entry=ENTRY_SECRET) + return cls(pts=qts, pts_count=1, entry=ENTRY_SECRET) return None def __repr__(self): - if self.entry is ENTRY_ACCOUNT: - entry = 'ENTRY_ACCOUNT' - elif self.entry is ENTRY_SECRET: - entry = 'ENTRY_SECRET' - else: - entry = self.entry - return f'PtsInfo(pts={self.pts}, pts_count={self.pts_count}, entry={entry})' + return f'PtsInfo(pts={self.pts}, pts_count={self.pts_count}, entry={self.entry})' # The state of a particular entry in the message box. @@ -160,7 +165,7 @@ def __repr__(self): # # See https://core.telegram.org/api/updates#message-related-event-sequences. class MessageBox: - __slots__ = ('_log', 'map', 'date', 'seq', 'next_deadline', 'possible_gaps', 'getting_diff_for', 'reset_deadlines_for') + __slots__ = ('_log', 'map', 'date', 'seq', 'next_deadline', 'possible_gaps', 'getting_diff_for') def __init__( self, @@ -169,7 +174,7 @@ def __init__( map: dict = _sentinel, # entry -> state # Additional fields beyond PTS needed by `ENTRY_ACCOUNT`. - date: datetime.datetime = datetime.datetime(*time.gmtime(0)[:6]).replace(tzinfo=datetime.timezone.utc), + date: datetime.datetime = epoch() + datetime.timedelta(seconds=1), seq: int = NO_SEQ, # Holds the entry with the closest deadline (optimization to avoid recalculating the minimum deadline). @@ -186,10 +191,6 @@ def __init__( # For which entries are we currently getting difference. getting_diff_for: set = _sentinel, # entry - - # Temporarily stores which entries should have their update deadline reset. - # Stored in the message box in order to reuse the allocation. - reset_deadlines_for: set = _sentinel # entry ): self._log = log self.map = {} if map is _sentinel else map @@ -198,20 +199,17 @@ def __init__( self.next_deadline = next_deadline self.possible_gaps = {} if possible_gaps is _sentinel else possible_gaps self.getting_diff_for = set() if getting_diff_for is _sentinel else getting_diff_for - self.reset_deadlines_for = set() if reset_deadlines_for is _sentinel else reset_deadlines_for if __debug__: - # Need this to tell them apart when printing the repr of the state map. - # Could be done once at the global level, but that makes configuring logging - # more annoying because it would need to be done before importing telethon. - self._trace('ENTRY_ACCOUNT = %r; ENTRY_SECRET = %r', ENTRY_ACCOUNT, ENTRY_SECRET) - self._trace('Created new MessageBox with map = %r, date = %r, seq = %r', self.map, self.date, self.seq) + self._trace('MessageBox initialized') def _trace(self, msg, *args, **kwargs): # Calls to trace can't really be removed beforehand without some dark magic. # So every call to trace is prefixed with `if __debug__`` instead, to remove # it when using `python -O`. Probably unnecessary, but it's nice to avoid # paying the cost for something that is not used. + self._log.log(LOG_LEVEL_TRACE, 'Current MessageBox state: seq = %r, date = %s, map = %r', + self.seq, self.date.isoformat(), self.map) self._log.log(LOG_LEVEL_TRACE, msg, *args, **kwargs) # region Creation, querying, and setting base state. @@ -280,8 +278,8 @@ def check_deadlines(self): # timeout for updates several times (it also makes sense to get difference if now is the deadline). if now >= deadline: # Check all expired entries and add them to the list that needs getting difference. - self.getting_diff_for.update(entry for entry, gap in self.possible_gaps.items() if now > gap.deadline) - self.getting_diff_for.update(entry for entry, state in self.map.items() if now > state.deadline) + self.getting_diff_for.update(entry for entry, gap in self.possible_gaps.items() if now >= gap.deadline) + self.getting_diff_for.update(entry for entry, state in self.map.items() if now >= state.deadline) if __debug__: self._trace('Deadlines met, now getting diff for %r', self.getting_diff_for) @@ -293,38 +291,29 @@ def check_deadlines(self): return deadline - # Reset the deadline for the periods without updates for a given entry. + # Reset the deadline for the periods without updates for the given entries. # # It also updates the next deadline time to reflect the new closest deadline. - def reset_deadline(self, entry, deadline): - if entry not in self.map: - raise RuntimeError('Called reset_deadline on an entry for which we do not have state') - self.map[entry].deadline = deadline + def reset_deadlines(self, entries, deadline): + if not entries: + return + for entry in entries: + if entry not in self.map: + raise RuntimeError('Called reset_deadline on an entry for which we do not have state') + self.map[entry].deadline = deadline - if self.next_deadline == entry: + if self.next_deadline in entries: # If the updated deadline was the closest one, recalculate the new minimum. self.next_deadline = min(self.map.items(), key=lambda entry_state: entry_state[1].deadline)[0] elif self.next_deadline in self.map and deadline < self.map[self.next_deadline].deadline: # If the updated deadline is smaller than the next deadline, change the next deadline to be the new one. + # Any entry will do, so the one from the last iteration is fine. self.next_deadline = entry # else an unrelated deadline was updated, so the closest one remains unchanged. # Convenience to reset a channel's deadline, with optional timeout. def reset_channel_deadline(self, channel_id, timeout): - self.reset_deadline(channel_id, get_running_loop().time() + (timeout or NO_UPDATES_TIMEOUT)) - - # Reset all the deadlines in `reset_deadlines_for` and then empty the set. - def apply_deadlines_reset(self): - next_deadline = next_updates_deadline() - - reset_deadlines_for = self.reset_deadlines_for - self.reset_deadlines_for = set() # "move" the set to avoid self.reset_deadline() from touching it during iter - - for entry in reset_deadlines_for: - self.reset_deadline(entry, next_deadline) - - reset_deadlines_for.clear() # reuse allocation, the other empty set was a temporary dummy value - self.reset_deadlines_for = reset_deadlines_for + self.reset_deadlines({channel_id}, get_running_loop().time() + (timeout or NO_UPDATES_TIMEOUT)) # Sets the update state. # @@ -370,15 +359,18 @@ def try_set_channel_state(self, id, pts): # Fails if the entry does not have a previously-known state that can be used to get its difference. # # Clears any previous gaps. - def try_begin_get_diff(self, entry): + def try_begin_get_diff(self, entry, reason): if entry not in self.map: # Won't actually be able to get difference for this entry if we don't have a pts to start off from. if entry in self.possible_gaps: raise RuntimeError('Should not have a possible_gap for an entry not in the state map') - # TODO it would be useful to log when this happens + if __debug__: + self._trace('Should get difference for %r because %s but cannot due to missing hash', entry, reason) return + if __debug__: + self._trace('Marking %r as needing difference because %s', entry, reason) self.getting_diff_for.add(entry) self.possible_gaps.pop(entry, None) @@ -391,7 +383,7 @@ def end_get_diff(self, entry): except KeyError: raise RuntimeError('Called end_get_diff on an entry which was not getting diff for') - self.reset_deadline(entry, next_updates_deadline()) + self.reset_deadlines({entry}, next_updates_deadline()) assert entry not in self.possible_gaps, "gaps shouldn't be created while getting difference" # endregion Creation, querying, and setting base state. @@ -416,14 +408,6 @@ def process_updates( chat_hashes, result, # out list of updates; returns list of user, chat, or raise if gap ): - if __debug__: - self._trace('Processing updates %s', updates) - - date = getattr(updates, 'date', None) - if date is None: - # updatesTooLong is the only one with no date (we treat it as a gap) - self.try_begin_get_diff(ENTRY_ACCOUNT) - raise GapError # v1 has never sent updates produced by the client itself to the handlers. # However proper update handling requires those to be processed. @@ -432,11 +416,25 @@ def process_updates( real_result = result result = [] - seq = getattr(updates, 'seq', None) or NO_SEQ - seq_start = getattr(updates, 'seq_start', None) or seq + date = getattr(updates, 'date', None) + seq = getattr(updates, 'seq', None) + seq_start = getattr(updates, 'seq_start', None) users = getattr(updates, 'users', None) or [] chats = getattr(updates, 'chats', None) or [] + if __debug__: + self._trace('Processing updates with seq = %r, seq_start = %r, date = %s: %s', + seq, seq_start, date.isoformat() if date else None, updates) + + if date is None: + # updatesTooLong is the only one with no date (we treat it as a gap) + self.try_begin_get_diff(ENTRY_ACCOUNT, 'received updatesTooLong') + raise GapError + if seq is None: + seq = NO_SEQ + if seq_start is None: + seq_start = seq + # updateShort is the only update which cannot be dispatched directly but doesn't have 'updates' field updates = getattr(updates, 'updates', None) or [updates.update if isinstance(updates, tl.UpdateShort) else updates] @@ -448,38 +446,50 @@ def process_updates( if seq_start != NO_SEQ: if self.seq + 1 > seq_start: # Skipping updates that were already handled + if __debug__: + self._trace('Skipping updates as they should have already been handled') return (users, chats) elif self.seq + 1 < seq_start: # Gap detected - self.try_begin_get_diff(ENTRY_ACCOUNT) + self.try_begin_get_diff(ENTRY_ACCOUNT, 'detected gap') raise GapError # else apply - self.date = date - if seq != NO_SEQ: - self.seq = seq - def _sort_gaps(update): pts = PtsInfo.from_update(update) return pts.pts - pts.pts_count if pts else 0 - # Telegram can send updates out of order (e.g. ReadChannelInbox first - # and then NewChannelMessage, both with the same pts, but the count is - # 0 and 1 respectively). - # - # We can't know beforehand if this would cause issues (i.e. if any of - # the updates is the first one we get to know about a specific channel) - # (other than doing a pre-scan to check if any has info about an entry - # we lack), so instead we sort preemptively. As a bonus there's less - # likelyhood of "possible gaps" by doing this. - # TODO give this more thought, perhaps possible gaps can't happen at all - # (not ones which would be resolved by sorting anyway) + reset_deadlines = set() # temporary buffer + any_pts_applied = [False] # using a list to pass "by reference" + result.extend(filter(None, ( - self.apply_pts_info(u, reset_deadline=True) for u in sorted(updates, key=_sort_gaps)))) + self.apply_pts_info(u, reset_deadlines=reset_deadlines, any_pts_applied=any_pts_applied) + # Telegram can send updates out of order (e.g. ReadChannelInbox first + # and then NewChannelMessage, both with the same pts, but the count is + # 0 and 1 respectively), so we sort them first. + for u in sorted(updates, key=_sort_gaps)))) + + # > If the updates were applied, local *Updates* state must be updated + # > with `seq` (unless it's 0) and `date` from the constructor. + # + # By "were applied", we assume it means "some other pts was applied". + # Updates which can be applied in any order, such as `UpdateChat`, + # should not cause `seq` to be updated (or upcoming updates such as + # `UpdateChatParticipant` could be missed). + if any_pts_applied[0]: + if __debug__: + self._trace('Updating seq as local pts was updated too') + if date != epoch(): + self.date = date + if seq != NO_SEQ: + self.seq = seq - self.apply_deadlines_reset() + self.reset_deadlines(reset_deadlines, next_updates_deadline()) if self.possible_gaps: + if __debug__: + self._trace('Trying to re-apply %r possible gaps', len(self.possible_gaps)) + # For each update in possible gaps, see if the gap has been resolved already. for key in list(self.possible_gaps.keys()): self.possible_gaps[key].updates.sort(key=_sort_gaps) @@ -489,9 +499,11 @@ def _sort_gaps(update): # If this fails to apply, it will get re-inserted at the end. # All should fail, so the order will be preserved (it would've cycled once). - update = self.apply_pts_info(update, reset_deadline=False) + update = self.apply_pts_info(update, reset_deadlines=None) if update: result.append(update) + if __debug__: + self._trace('Resolved gap with %r: %s', PtsInfo.from_update(update), update) # Clear now-empty gaps. self.possible_gaps = {entry: gap for entry, gap in self.possible_gaps.items() if gap.updates} @@ -509,16 +521,19 @@ def apply_pts_info( self, update, *, - reset_deadline, + reset_deadlines, + any_pts_applied=[True], # mutable default is fine as it's write-only ): # This update means we need to call getChannelDifference to get the updates from the channel if isinstance(update, tl.UpdateChannelTooLong): - self.try_begin_get_diff(update.channel_id) + self.try_begin_get_diff(update.channel_id, 'received updateChannelTooLong') return None pts = PtsInfo.from_update(update) if not pts: # No pts means that the update can be applied in any order. + if __debug__: + self._trace('No pts in update, so it can be applied in any order: %s', update) return update # As soon as we receive an update of any form related to messages (has `PtsInfo`), @@ -527,22 +542,28 @@ def apply_pts_info( # Build the `HashSet` to avoid calling `reset_deadline` more than once for the same entry. # # By the time this method returns, self.map will have an entry for which we can reset its deadline. - if reset_deadline: - self.reset_deadlines_for.add(pts.entry) + if reset_deadlines: + reset_deadlines.add(pts.entry) if pts.entry in self.getting_diff_for: # Note: early returning here also prevents gap from being inserted (which they should # not be while getting difference). + if __debug__: + self._trace('Skipping update with %r as its difference is being fetched', pts) return None if pts.entry in self.map: local_pts = self.map[pts.entry].pts if local_pts + pts.pts_count > pts.pts: # Ignore + if __debug__: + self._trace('Skipping update since local pts %r > %r: %s', local_pts, pts, update) return None elif local_pts + pts.pts_count < pts.pts: # Possible gap # TODO store chats too? + if __debug__: + self._trace('Possible gap since local pts %r < %r: %s', local_pts, pts, update) if pts.entry not in self.possible_gaps: self.possible_gaps[pts.entry] = PossibleGap( deadline=get_running_loop().time() + POSSIBLE_GAP_TIMEOUT, @@ -553,7 +574,9 @@ def apply_pts_info( return None else: # Apply - pass + any_pts_applied[0] = True + if __debug__: + self._trace('Applying update pts since local pts %r = %r: %s', local_pts, pts, update) # In a channel, we may immediately receive: # * ReadChannelInbox (pts = X, pts_count = 0) @@ -668,7 +691,7 @@ def apply_difference_type( updates=diff.other_updates, users=diff.users, chats=diff.chats, - date=1, # anything not-None + date=epoch(), seq=NO_SEQ, # this way date is not used ), chat_hashes, updates) @@ -777,7 +800,7 @@ def apply_channel_difference( updates=diff.other_updates, users=diff.users, chats=diff.chats, - date=1, # anything not-None + date=epoch(), seq=NO_SEQ, # this way date is not used ), chat_hashes, updates) diff --git a/telethon/client/auth.py b/telethon/client/auth.py index 9ca5b4587..52d671acf 100644 --- a/telethon/client/auth.py +++ b/telethon/client/auth.py @@ -19,8 +19,8 @@ class AuthMethods: def start( self: 'TelegramClient', - phone: typing.Callable[[], str] = lambda: input('Please enter your phone (or bot token): '), - password: typing.Callable[[], str] = lambda: getpass.getpass('Please enter your password: '), + phone: typing.Union[typing.Callable[[], str], str] = lambda: input('Please enter your phone (or bot token): '), + password: typing.Union[typing.Callable[[], str], str] = lambda: getpass.getpass('Please enter your password: '), *, bot_token: str = None, force_sms: bool = False, diff --git a/telethon/client/chats.py b/telethon/client/chats.py index 73dc0312b..64f60d5de 100644 --- a/telethon/client/chats.py +++ b/telethon/client/chats.py @@ -926,9 +926,6 @@ async def edit_admin( """ entity = await self.get_input_entity(entity) user = await self.get_input_entity(user) - ty = helpers._entity_type(user) - if ty != helpers._EntityType.USER: - raise ValueError('You must pass a user entity') perm_names = ( 'change_info', 'post_messages', 'edit_messages', 'delete_messages', @@ -1115,12 +1112,6 @@ async def edit_permissions( )) user = await self.get_input_entity(user) - ty = helpers._entity_type(user) - if ty != helpers._EntityType.USER: - raise ValueError('You must pass a user entity') - - if isinstance(user, types.InputPeerSelf): - raise ValueError('You cannot restrict yourself') return await self(functions.channels.EditBannedRequest( channel=entity, @@ -1167,8 +1158,6 @@ async def kick_participant( """ entity = await self.get_input_entity(entity) user = await self.get_input_entity(user) - if helpers._entity_type(user) != helpers._EntityType.USER: - raise ValueError('You must pass a user entity') ty = helpers._entity_type(entity) if ty == helpers._EntityType.CHAT: @@ -1245,8 +1234,6 @@ async def get_permissions( entity = await self.get_input_entity(entity) user = await self.get_input_entity(user) - if helpers._entity_type(user) != helpers._EntityType.USER: - raise ValueError('You must pass a user entity') if helpers._entity_type(entity) == helpers._EntityType.CHANNEL: participant = await self(functions.channels.GetParticipantRequest( entity, diff --git a/telethon/client/downloads.py b/telethon/client/downloads.py index d7ae5a9ca..14dbe2ca9 100644 --- a/telethon/client/downloads.py +++ b/telethon/client/downloads.py @@ -27,21 +27,31 @@ # 2021-01-15, users reported that `errors.TimeoutError` can occur while downloading files. TIMED_OUT_SLEEP = 1 + +class _CdnRedirect(Exception): + def __init__(self, cdn_redirect=None): + self.cdn_redirect = cdn_redirect + + class _DirectDownloadIter(RequestIter): async def _init( - self, file, dc_id, offset, stride, chunk_size, request_size, file_size, msg_data - ): + self, file, dc_id, offset, stride, chunk_size, request_size, file_size, msg_data, cdn_redirect=None): self.request = functions.upload.GetFileRequest( - file, offset=offset, limit=request_size) - + file, offset=offset, limit=request_size) + self._client = self.client + self._cdn_redirect = cdn_redirect + if cdn_redirect is not None: + self.request = functions.upload.GetCdnFileRequest(cdn_redirect.file_token, offset=offset, limit=request_size) + self._client = await self.client._get_cdn_client(cdn_redirect) + self.total = file_size self._stride = stride self._chunk_size = chunk_size self._last_part = None self._msg_data = msg_data self._timed_out = False - - self._exported = dc_id and self.client.session.dc_id != dc_id + + self._exported = dc_id and self._client.session.dc_id != dc_id if not self._exported: # The used sender will also change if ``FileMigrateError`` occurs self._sender = self.client._sender @@ -73,14 +83,20 @@ async def _load_next_chunk(self): async def _request(self): try: - result = await self.client._call(self._sender, self.request) + result = await self._client._call(self._sender, self.request) self._timed_out = False if isinstance(result, types.upload.FileCdnRedirect): - raise NotImplementedError # TODO Implement + if self.client._mb_entity_cache.self_bot: + raise ValueError('FileCdnRedirect but the GetCdnFileRequest API access for bot users is restricted. Try to change api_id to avoid FileCdnRedirect') + raise _CdnRedirect(result) + if isinstance(result, types.upload.CdnFileReuploadNeeded): + await self.client._call(self.client._sender, functions.upload.ReuploadCdnFileRequest(file_token=self._cdn_redirect.file_token, request_token=result.request_token)) + result = await self._client._call(self._sender, self.request) + return result.bytes else: return result.bytes - except errors.TimeoutError as e: + except errors.TimedOutError as e: if self._timed_out: self.client._log[__name__].warning('Got two timeouts in a row while downloading file') raise @@ -96,7 +112,7 @@ async def _request(self): self._exported = True return await self._request() - except errors.FilerefUpgradeNeededError as e: + except (errors.FilerefUpgradeNeededError, errors.FileReferenceExpiredError) as e: # Only implemented for documents which are the ones that may take that long to download if not self._msg_data \ or not isinstance(self.request.location, types.InputDocumentFileLocation) \ @@ -516,7 +532,9 @@ async def _download_file( dc_id: int = None, key: bytes = None, iv: bytes = None, - msg_data: tuple = None) -> typing.Optional[bytes]: + msg_data: tuple = None, + cdn_redirect: types.upload.FileCdnRedirect = None + ) -> typing.Optional[bytes]: if not part_size_kb: if not file_size: part_size_kb = 64 # Reasonable default @@ -543,7 +561,7 @@ async def _download_file( try: async for chunk in self._iter_download( - input_location, request_size=part_size, dc_id=dc_id, msg_data=msg_data): + input_location, request_size=part_size, dc_id=dc_id, msg_data=msg_data, cdn_redirect=cdn_redirect): if iv and key: chunk = AES.decrypt_ige(chunk, key, iv) r = f.write(chunk) @@ -561,6 +579,20 @@ async def _download_file( if in_memory: return f.getvalue() + except _CdnRedirect as e: + self._log[__name__].info('FileCdnRedirect to CDN data center %s', e.cdn_redirect.dc_id) + return await self._download_file( + input_location=input_location, + file=file, + part_size_kb=part_size_kb, + file_size=file_size, + progress_callback=progress_callback, + dc_id=e.cdn_redirect.dc_id, + key=e.cdn_redirect.encryption_key, + iv=e.cdn_redirect.encryption_iv, + msg_data=msg_data, + cdn_redirect=e.cdn_redirect + ) finally: if isinstance(file, str) or in_memory: f.close() @@ -682,7 +714,8 @@ def _iter_download( request_size: int = MAX_CHUNK_SIZE, file_size: int = None, dc_id: int = None, - msg_data: tuple = None + msg_data: tuple = None, + cdn_redirect: types.upload.FileCdnRedirect = None ): info = utils._get_file_info(file) if info.dc_id is not None: @@ -733,6 +766,7 @@ def _iter_download( request_size=request_size, file_size=file_size, msg_data=msg_data, + cdn_redirect=cdn_redirect ) # endregion @@ -741,6 +775,9 @@ def _iter_download( @staticmethod def _get_thumb(thumbs, thumb): + if not thumbs: + return None + # Seems Telegram has changed the order and put `PhotoStrippedSize` # last while this is the smallest (layer 116). Ensure we have the # sizes sorted correctly with a custom function. @@ -883,6 +920,9 @@ async def _download_document( else: file = self._get_proper_filename(file, 'photo', '.jpg', date=date) size = self._get_thumb(document.thumbs, thumb) + if not size or isinstance(size, types.PhotoSizeEmpty): + return + if isinstance(size, (types.PhotoCachedSize, types.PhotoStrippedSize)): return self._download_cached_photo_size(size, file) diff --git a/telethon/client/messages.py b/telethon/client/messages.py index abe435da4..5dcd2ee63 100644 --- a/telethon/client/messages.py +++ b/telethon/client/messages.py @@ -221,7 +221,7 @@ async def _load_next_chunk(self): # # We also assume the API will always return, at least, one message if # there is more to fetch. - if not r.messages or r.messages[0].id <= self.request.limit: + if not r.messages or (not self.reverse and r.messages[0].id <= self.request.limit): return True # Get the last message that's not empty (in some rare cases @@ -553,7 +553,9 @@ def iter_messages( scheduled=scheduled ) - async def get_messages(self: 'TelegramClient', *args, **kwargs) -> 'hints.TotalList': + async def get_messages( + self: 'TelegramClient', *args, **kwargs + ) -> typing.Union['hints.TotalList', typing.Optional['types.Message']]: """ Same as `iter_messages()`, but returns a `TotalList ` instead. @@ -617,7 +619,7 @@ async def _get_comment_data( peer=entity, msg_id=utils.get_message_id(message) )) - m = r.messages[0] + m = min(r.messages, key=lambda msg: msg.id) chat = next(c for c in r.chats if c.id == m.peer_id.channel_id) return utils.get_input_peer(chat), m.id @@ -824,6 +826,9 @@ async def callback(event): await client.send_message(chat, 'Hi, future!', schedule=timedelta(minutes=5)) """ if file is not None: + if isinstance(message, types.Message): + formatting_entities = formatting_entities or message.entities + message = message.message return await self.send_file( entity, file, caption=message, reply_to=reply_to, attributes=attributes, parse_mode=parse_mode, @@ -838,6 +843,8 @@ async def callback(event): entity = await self.get_input_entity(entity) if comment_to is not None: entity, reply_to = await self._get_comment_data(entity, comment_to) + else: + reply_to = utils.get_message_id(reply_to) if isinstance(message, types.Message): if buttons is None: @@ -868,7 +875,7 @@ async def callback(event): message=message.message or '', silent=silent, background=background, - reply_to_msg_id=utils.get_message_id(reply_to), + reply_to=None if reply_to is None else types.InputReplyToMessage(reply_to), reply_markup=markup, entities=message.entities, clear_draft=clear_draft, @@ -890,7 +897,7 @@ async def callback(event): message=message, entities=formatting_entities, no_webpage=not link_preview, - reply_to_msg_id=utils.get_message_id(reply_to), + reply_to=None if reply_to is None else types.InputReplyToMessage(reply_to), clear_draft=clear_draft, silent=silent, background=background, @@ -910,7 +917,7 @@ async def callback(event): entities=result.entities, reply_markup=request.reply_markup, ttl_period=result.ttl_period, - reply_to=types.MessageReplyHeader(request.reply_to_msg_id) + reply_to=request.reply_to ) message._finish_init(self, {}, entity) return message @@ -927,7 +934,8 @@ async def forward_messages( with_my_score: bool = None, silent: bool = None, as_album: bool = None, - schedule: 'hints.DateLike' = None + schedule: 'hints.DateLike' = None, + drop_author: bool = None, ) -> 'typing.Sequence[types.Message]': """ Forwards the given messages to the specified entity. @@ -1039,7 +1047,8 @@ def get_key(m): silent=silent, background=background, with_my_score=with_my_score, - schedule_date=schedule + schedule_date=schedule, + drop_author=drop_author ) result = await self(req) sent.extend(self._get_response_message(req, result, entity)) diff --git a/telethon/client/telegrambaseclient.py b/telethon/client/telegrambaseclient.py index dd1276542..95c28532f 100644 --- a/telethon/client/telegrambaseclient.py +++ b/telethon/client/telegrambaseclient.py @@ -7,6 +7,7 @@ import time import typing import datetime +import pathlib from .. import version, helpers, __name__ as __base_name__ from ..crypto import rsa @@ -235,7 +236,7 @@ class TelegramBaseClient(abc.ABC): def __init__( self: 'TelegramClient', - session: 'typing.Union[str, Session]', + session: 'typing.Union[str, pathlib.Path, Session]', api_id: int, api_hash: str, *, @@ -284,9 +285,9 @@ def __missing__(self, key): self._log = _Loggers() # Determine what session object we have - if isinstance(session, str) or session is None: + if isinstance(session, (str, pathlib.Path)): try: - session = SQLiteSession(session) + session = SQLiteSession(str(session)) except ImportError: import warnings warnings.warn( @@ -297,6 +298,8 @@ def __missing__(self, key): 'you use another session storage' ) session = MemorySession() + elif session is None: + session = MemorySession() elif not isinstance(session, Session): raise TypeError( 'The given session must be a str or a Session instance.' @@ -310,6 +313,7 @@ def __missing__(self, key): DEFAULT_IPV6_IP if self._use_ipv6 else DEFAULT_IPV4_IP, DEFAULT_PORT ) + session.save() self.flood_sleep_threshold = flood_sleep_threshold @@ -398,6 +402,7 @@ def __missing__(self, key): # Cache ``{dc_id: (_ExportState, MTProtoSender)}`` for all borrowed senders self._borrowed_senders = {} self._borrow_sender_lock = asyncio.Lock() + self._exported_sessions = {} self._loop = None # only used as a sanity check self._updates_error = None @@ -782,7 +787,8 @@ async def _get_dc(self: 'TelegramClient', dc_id, cdn=False): if cdn and not self._cdn_config: cls._cdn_config = await self(functions.help.GetCdnConfigRequest()) for pk in cls._cdn_config.public_keys: - rsa.add_key(pk.public_key) + if pk.dc_id == dc_id: + rsa.add_key(pk.public_key, old=False) try: return next( @@ -795,10 +801,13 @@ async def _get_dc(self: 'TelegramClient', dc_id, cdn=False): 'Failed to get DC %s (cdn = %s) with use_ipv6 = %s; retrying ignoring IPv6 check', dc_id, cdn, self._use_ipv6 ) - return next( - dc for dc in cls._config.dc_options - if dc.id == dc_id and bool(dc.cdn) == cdn - ) + try: + return next( + dc for dc in cls._config.dc_options + if dc.id == dc_id and bool(dc.cdn) == cdn + ) + except StopIteration: + raise ValueError(f'Failed to get DC {dc_id} (cdn = {cdn})') async def _create_exported_sender(self: 'TelegramClient', dc_id): """ @@ -886,8 +895,6 @@ async def _clean_exported_senders(self: 'TelegramClient'): async def _get_cdn_client(self: 'TelegramClient', cdn_redirect): """Similar to ._borrow_exported_client, but for CDNs""" - # TODO Implement - raise NotImplementedError session = self._exported_sessions.get(cdn_redirect.dc_id) if not session: dc = await self._get_dc(cdn_redirect.dc_id, cdn=True) @@ -896,18 +903,22 @@ async def _get_cdn_client(self: 'TelegramClient', cdn_redirect): self._exported_sessions[cdn_redirect.dc_id] = session self._log[__name__].info('Creating new CDN client') - client = TelegramBaseClient( + client = self.__class__( session, self.api_id, self.api_hash, - proxy=self._sender.connection.conn.proxy, - timeout=self._sender.connection.get_timeout() + proxy=self._proxy, + timeout=self._timeout, + loop=self.loop ) - # This will make use of the new RSA keys for this specific CDN. - # - # We won't be calling GetConfigRequest because it's only called - # when needed by ._get_dc, and also it's static so it's likely - # set already. Avoid invoking non-CDN methods by not syncing updates. - client.connect(_sync_updates=False) + session.auth_key = self._sender.auth_key + await client._sender.connect(self._connection( + session.server_address, + session.port, + session.dc_id, + loggers=self._log, + proxy=self._proxy, + local_addr=self._local_addr + )) return client # endregion diff --git a/telethon/client/updates.py b/telethon/client/updates.py index e4ac608bc..f06b28e8a 100644 --- a/telethon/client/updates.py +++ b/telethon/client/updates.py @@ -9,6 +9,7 @@ import logging import warnings from collections import deque +import sqlite3 from .. import events, utils, errors from ..events.common import EventBuilder, EventCommon @@ -305,7 +306,12 @@ async def _update_loop(self: 'TelegramClient'): self._log[__name__].debug('Getting difference for account updates') try: diff = await self(get_diff) - except (errors.ServerError, errors.TimeoutError, ValueError) as e: + except ( + errors.ServerError, + errors.TimedOutError, + errors.FloodWaitError, + ValueError + ) as e: # Telegram is having issues self._log[__name__].info('Cannot get difference since Telegram is having issues: %s', type(e).__name__) self._message_box.end_difference() @@ -319,7 +325,7 @@ async def _update_loop(self: 'TelegramClient'): await self.disconnect() break continue - except errors.TypeNotFoundError as e: + except (errors.TypeNotFoundError, sqlite3.OperationalError) as e: # User is likely doing weird things with their account or session and Telegram gets confused as to what layer they use self._log[__name__].warning('Cannot get difference since the account is likely misusing the session: %s', e) self._message_box.end_difference() @@ -361,9 +367,9 @@ async def _update_loop(self: 'TelegramClient'): await self.disconnect() break continue - except errors.TypeNotFoundError as e: + except (errors.TypeNotFoundError, sqlite3.OperationalError) as e: self._log[__name__].warning( - 'Cannot get difference since the account is likely misusing the session: %s', + 'Cannot get difference for channel %s since the account is likely misusing the session: %s', get_diff.channel.channel_id, e ) self._message_box.end_channel_difference( @@ -378,7 +384,8 @@ async def _update_loop(self: 'TelegramClient'): errors.PersistentTimestampOutdatedError, errors.PersistentTimestampInvalidError, errors.ServerError, - errors.TimeoutError, + errors.TimedOutError, + errors.FloodWaitError, ValueError ) as e: # According to Telegram's docs: diff --git a/telethon/client/uploads.py b/telethon/client/uploads.py index 59228a72b..c8b8d9517 100644 --- a/telethon/client/uploads.py +++ b/telethon/client/uploads.py @@ -18,7 +18,6 @@ except ImportError: PIL = None - if typing.TYPE_CHECKING: from .telegramclient import TelegramClient @@ -47,7 +46,17 @@ def _resize_photo_if_needed( if isinstance(file, bytes): file = io.BytesIO(file) - before = file.tell() if isinstance(file, io.IOBase) else None + if isinstance(file, io.IOBase): + # Pillow seeks to 0 unconditionally later anyway + old_pos = file.tell() + file.seek(0, io.SEEK_END) + before = file.tell() + elif isinstance(file, str) and os.path.exists(file): + # Check if file exists as a path and if so, get its size on disk + before = os.path.getsize(file) + else: + # Would be weird... + before = None try: # Don't use a `with` block for `image`, or `file` would be closed. @@ -58,10 +67,11 @@ def _resize_photo_if_needed( except KeyError: kwargs = {} - if image.width <= width and image.height <= height: + # Check if image is within acceptable bounds, if so, check if the image is at or below 10 MB, or assume it isn't if size is None or 0 + if image.width <= width and image.height <= height and (before <= 10000000 if before else False): return file - image.thumbnail((width, height), PIL.Image.ANTIALIAS) + image.thumbnail((width, height), PIL.Image.LANCZOS) alpha_index = image.mode.find('A') if alpha_index == -1: @@ -79,13 +89,14 @@ def _resize_photo_if_needed( buffer = io.BytesIO() result.save(buffer, 'JPEG', progressive=True, **kwargs) buffer.seek(0) + buffer.name = 'a.jpg' return buffer - except IOError: return file finally: - if before is not None: - file.seek(before, io.SEEK_SET) + # The original position might matter + if isinstance(file, io.IOBase): + file.seek(old_pos) class UploadMethods: @@ -107,7 +118,11 @@ async def send_file( thumb: 'hints.FileLike' = None, allow_cache: bool = True, parse_mode: str = (), - formatting_entities: typing.Optional[typing.List[types.TypeMessageEntity]] = None, + formatting_entities: typing.Optional[ + typing.Union[ + typing.List[types.TypeMessageEntity], typing.List[typing.List[types.TypeMessageEntity]] + ] + ] = None, voice_note: bool = False, video_note: bool = False, buttons: typing.Optional['hints.MarkupLike'] = None, @@ -118,7 +133,7 @@ async def send_file( comment_to: 'typing.Union[int, types.Message]' = None, ttl: int = None, nosound_video: bool = None, - **kwargs) -> 'types.Message': + **kwargs) -> typing.Union[typing.List[typing.Any], typing.Any]: """ Sends message with the given file to the specified entity. @@ -231,7 +246,11 @@ async def send_file( default. formatting_entities (`list`, optional): - A list of message formatting entities. When provided, the ``parse_mode`` is ignored. + Optional formatting entities for the sent media message. When sending an album, + `formatting_entities` can be a list of lists, where each inner list contains + `types.TypeMessageEntity`. Each inner list will be assigned to the corresponding + file in a pairwise manner with the caption. If provided, the ``parse_mode`` + parameter will be ignored. voice_note (`bool`, optional): If `True` the audio will be sent as a voice note. @@ -353,6 +372,9 @@ def callback(current, total): if not caption: caption = '' + if not formatting_entities: + formatting_entities = [] + entity = await self.get_input_entity(entity) if comment_to is not None: entity, reply_to = await self._get_comment_data(entity, comment_to) @@ -372,10 +394,22 @@ def callback(current, total): else: captions = [caption] + # Check that formatting_entities list is valid + if all(utils.is_list_like(obj) for obj in formatting_entities): + formatting_entities = formatting_entities + elif utils.is_list_like(formatting_entities): + formatting_entities = [formatting_entities] + else: + raise TypeError('The formatting_entities argument must be a list or a sequence of lists') + + # Check that all entities in all lists are of the correct type + if not all(isinstance(ent, types.TypeMessageEntity) for sublist in formatting_entities for ent in sublist): + raise TypeError('All entities must be instances of ') + result = [] while file: result += await self._send_album( - entity, file[:10], caption=captions[:10], + entity, file[:10], caption=captions[:10], formatting_entities=formatting_entities[:10], progress_callback=used_callback, reply_to=reply_to, parse_mode=parse_mode, silent=silent, schedule=schedule, supports_streaming=supports_streaming, clear_draft=clear_draft, @@ -383,11 +417,12 @@ def callback(current, total): ) file = file[10:] captions = captions[10:] + formatting_entities = formatting_entities[10:] sent_count += 10 return result - if formatting_entities is not None: + if formatting_entities: msg_entities = formatting_entities else: caption, msg_entities =\ @@ -397,7 +432,7 @@ def callback(current, total): file, force_document=force_document, file_size=file_size, progress_callback=progress_callback, - attributes=attributes, allow_cache=allow_cache, thumb=thumb, + attributes=attributes, allow_cache=allow_cache, thumb=thumb, voice_note=voice_note, video_note=video_note, supports_streaming=supports_streaming, ttl=ttl, nosound_video=nosound_video, @@ -408,8 +443,9 @@ def callback(current, total): raise TypeError('Cannot use {!r} as file'.format(file)) markup = self.build_reply_markup(buttons) + reply_to = None if reply_to is None else types.InputReplyToMessage(reply_to) request = functions.messages.SendMediaRequest( - entity, media, reply_to_msg_id=reply_to, message=caption, + entity, media, reply_to=reply_to, message=caption, entities=msg_entities, reply_markup=markup, silent=silent, schedule_date=schedule, clear_draft=clear_draft, background=background @@ -417,6 +453,7 @@ def callback(current, total): return self._get_response_message(request, await self(request), entity) async def _send_album(self: 'TelegramClient', entity, files, caption='', + formatting_entities=None, progress_callback=None, reply_to=None, parse_mode=(), silent=None, schedule=None, supports_streaming=None, clear_draft=None, @@ -428,16 +465,25 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='', # cache only makes a difference for documents where the user may # want the attributes used on them to change. # - # In theory documents can be sent inside the albums but they appear + # In theory documents can be sent inside the albums, but they appear # as different messages (not inside the album), and the logic to set # the attributes/avoid cache is already written in .send_file(). entity = await self.get_input_entity(entity) if not utils.is_list_like(caption): caption = (caption,) + if not all(isinstance(obj, list) for obj in formatting_entities): + formatting_entities = (formatting_entities,) captions = [] - for c in reversed(caption): # Pop from the end (so reverse) - captions.append(await self._parse_message_text(c or '', parse_mode)) + # If the formatting_entities argument is provided, we don't use parse_mode + if formatting_entities: + # Pop from the end (so reverse) + capt_with_ent = itertools.zip_longest(reversed(caption), reversed(formatting_entities), fillvalue=None) + for msg_caption, msg_entities in capt_with_ent: + captions.append((msg_caption, msg_entities)) + else: + for c in reversed(caption): # Pop from the end (so reverse) + captions.append(await self._parse_message_text(c or '', parse_mode)) reply_to = utils.get_message_id(reply_to) @@ -469,7 +515,7 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='', )) fm = utils.get_input_media( - r.document, supports_streaming=supports_streaming) + r.document, supports_streaming=supports_streaming) if captions: caption, msg_entities = captions.pop() @@ -484,7 +530,7 @@ async def _send_album(self: 'TelegramClient', entity, files, caption='', # Now we can construct the multi-media request request = functions.messages.SendMultiMediaRequest( - entity, reply_to_msg_id=reply_to, multi_media=media, + entity, reply_to=None if reply_to is None else types.InputReplyToMessage(reply_to), multi_media=media, silent=silent, schedule_date=schedule, clear_draft=clear_draft, background=background ) @@ -622,7 +668,7 @@ async def upload_file( part_count = (file_size + part_size - 1) // part_size self._log[__name__].info('Uploading file of %d bytes in %d chunks of %d', - file_size, part_count, part_size) + file_size, part_count, part_size) pos = 0 for part_index in range(part_count): @@ -699,7 +745,7 @@ async def _file_to_media( # `aiofiles` do not base `io.IOBase` but do have `read`, so we # just check for the read attribute to see if it's file-like. - if not isinstance(file, (str, bytes, types.InputFile, types.InputFileBig))\ + if not isinstance(file, (str, bytes, types.InputFile, types.InputFileBig)) \ and not hasattr(file, 'read'): # The user may pass a Message containing media (or the media, # or anything similar) that should be treated as a file. Try diff --git a/telethon/client/users.py b/telethon/client/users.py index eda3e0402..de6709a6a 100644 --- a/telethon/client/users.py +++ b/telethon/client/users.py @@ -89,6 +89,7 @@ async def _call(self: 'TelegramClient', sender, request, ordered=False, flood_sl return result except (errors.ServerError, errors.RpcCallFailError, errors.RpcMcgetFailError, errors.InterdcCallErrorError, + errors.TimedOutError, errors.InterdcCallRichErrorError) as e: last_error = e self._log[__name__].warning( @@ -96,7 +97,8 @@ async def _call(self: 'TelegramClient', sender, request, ordered=False, flood_sl e.__class__.__name__, e) await asyncio.sleep(2) - except (errors.FloodWaitError, errors.SlowModeWaitError, errors.FloodTestPhoneWaitError) as e: + except (errors.FloodWaitError, errors.FloodPremiumWaitError, + errors.SlowModeWaitError, errors.FloodTestPhoneWaitError) as e: last_error = e if utils.is_list_like(request): request = request[request_index] @@ -221,7 +223,7 @@ async def is_user_authorized(self: 'TelegramClient') -> bool: async def get_entity( self: 'TelegramClient', - entity: 'hints.EntitiesLike') -> 'hints.Entity': + entity: 'hints.EntitiesLike') -> typing.Union['hints.Entity', typing.List['hints.Entity']]: """ Turns the given entity into a valid Telegram :tl:`User`, :tl:`Chat` or :tl:`Channel`. You can also pass a list or iterable of entities, diff --git a/telethon/events/callbackquery.py b/telethon/events/callbackquery.py index 408e33995..29ffd0533 100644 --- a/telethon/events/callbackquery.py +++ b/telethon/events/callbackquery.py @@ -338,6 +338,8 @@ async def delete(self, *args, **kwargs): This method will likely fail if `via_inline` is `True`. """ self._client.loop.create_task(self.answer()) + if isinstance(self.query.msg_id, (types.InputBotInlineMessageID, types.InputBotInlineMessageID64)): + raise TypeError('Inline messages cannot be deleted as there is no API request available to do so') return await self._client.delete_messages( await self.get_input_chat(), [self.query.msg_id], *args, **kwargs diff --git a/telethon/extensions/html.py b/telethon/extensions/html.py index a25ed58b4..0e2e8f334 100644 --- a/telethon/extensions/html.py +++ b/telethon/extensions/html.py @@ -1,13 +1,13 @@ """ Simple HTML -> Telegram entity parser. """ -import struct from collections import deque from html import escape from html.parser import HTMLParser -from typing import Iterable, Optional, Tuple, List +from typing import Iterable, Tuple, List -from .. import helpers +from ..helpers import add_surrogate, del_surrogate, within_surrogate, strip_text +from ..tl import TLObject from ..tl.types import ( MessageEntityBold, MessageEntityItalic, MessageEntityCode, MessageEntityPre, MessageEntityEmail, MessageEntityUrl, @@ -17,18 +17,6 @@ ) -# Helpers from markdown.py -def _add_surrogate(text): - return ''.join( - ''.join(chr(y) for y in struct.unpack(' Tuple[str, List[TypeMessageEntity]]: return html, [] parser = HTMLToTelegramParser() - parser.feed(_add_surrogate(html)) - text = helpers.strip_text(parser.text, parser.entities) - return _del_surrogate(text), parser.entities - - -def unparse(text: str, entities: Iterable[TypeMessageEntity], _offset: int = 0, - _length: Optional[int] = None) -> str: + parser.feed(add_surrogate(html)) + text = strip_text(parser.text, parser.entities) + parser.entities.reverse() + parser.entities.sort(key=lambda entity: entity.offset) + return del_surrogate(text), parser.entities + + +ENTITY_TO_FORMATTER = { + MessageEntityBold: ('', ''), + MessageEntityItalic: ('', ''), + MessageEntityCode: ('', ''), + MessageEntityUnderline: ('', ''), + MessageEntityStrike: ('', ''), + MessageEntityBlockquote: ('
', '
'), + MessageEntityPre: lambda e, _: ( + "
\n"
+        "    \n"
+        "        ".format(e.language), "{}\n"
+        "    \n"
+        "
" + ), + MessageEntityEmail: lambda _, t: (''.format(t), ''), + MessageEntityUrl: lambda _, t: (''.format(t), ''), + MessageEntityTextUrl: lambda e, _: (''.format(escape(e.url)), ''), + MessageEntityMentionName: lambda e, _: (''.format(e.user_id), ''), +} + + +def unparse(text: str, entities: Iterable[TypeMessageEntity]) -> str: """ Performs the reverse operation to .parse(), effectively returning HTML given a normal text and its MessageEntity's. @@ -153,77 +163,32 @@ def unparse(text: str, entities: Iterable[TypeMessageEntity], _offset: int = 0, elif not entities: return escape(text) - text = _add_surrogate(text) - if _length is None: - _length = len(text) - html = [] - last_offset = 0 + if isinstance(entities, TLObject): + entities = (entities,) + + text = add_surrogate(text) + insert_at = [] for i, entity in enumerate(entities): - if entity.offset >= _offset + _length: - break - relative_offset = entity.offset - _offset - if relative_offset > last_offset: - html.append(escape(text[last_offset:relative_offset])) - elif relative_offset < last_offset: - continue - - skip_entity = False - length = entity.length - - # If we are in the middle of a surrogate nudge the position by +1. - # Otherwise we would end up with malformed text and fail to encode. - # For example of bad input: "Hi \ud83d\ude1c" - # https://en.wikipedia.org/wiki/UTF-16#U+010000_to_U+10FFFF - while helpers.within_surrogate(text, relative_offset, length=_length): - relative_offset += 1 - - while helpers.within_surrogate(text, relative_offset + length, length=_length): - length += 1 - - entity_text = unparse(text=text[relative_offset:relative_offset + length], - entities=entities[i + 1:], - _offset=entity.offset, _length=length) - entity_type = type(entity) - - if entity_type == MessageEntityBold: - html.append('{}'.format(entity_text)) - elif entity_type == MessageEntityItalic: - html.append('{}'.format(entity_text)) - elif entity_type == MessageEntityCode: - html.append('{}'.format(entity_text)) - elif entity_type == MessageEntityUnderline: - html.append('{}'.format(entity_text)) - elif entity_type == MessageEntityStrike: - html.append('{}'.format(entity_text)) - elif entity_type == MessageEntityBlockquote: - html.append('
{}
'.format(entity_text)) - elif entity_type == MessageEntityPre: - if entity.language: - html.append( - "
\n"
-                    "    \n"
-                    "        {}\n"
-                    "    \n"
-                    "
".format(entity.language, entity_text)) - else: - html.append('
{}
' - .format(entity_text)) - elif entity_type == MessageEntityEmail: - html.append('{0}'.format(entity_text)) - elif entity_type == MessageEntityUrl: - html.append('{0}'.format(entity_text)) - elif entity_type == MessageEntityTextUrl: - html.append('{}' - .format(escape(entity.url), entity_text)) - elif entity_type == MessageEntityMentionName: - html.append('{}' - .format(entity.user_id, entity_text)) - else: - skip_entity = True - last_offset = relative_offset + (0 if skip_entity else length) - - while helpers.within_surrogate(text, last_offset, length=_length): - last_offset += 1 - - html.append(escape(text[last_offset:])) - return _del_surrogate(''.join(html)) + s = entity.offset + e = entity.offset + entity.length + delimiter = ENTITY_TO_FORMATTER.get(type(entity), None) + if delimiter: + if callable(delimiter): + delimiter = delimiter(entity, text[s:e]) + insert_at.append((s, i, delimiter[0])) + insert_at.append((e, -i, delimiter[1])) + + insert_at.sort(key=lambda t: (t[0], t[1])) + next_escape_bound = len(text) + while insert_at: + # Same logic as markdown.py + at, _, what = insert_at.pop() + while within_surrogate(text, at): + at += 1 + + text = text[:at] + what + escape(text[at:next_escape_bound]) + text[next_escape_bound:] + next_escape_bound = at + + text = escape(text[:next_escape_bound]) + text[next_escape_bound:] + + return del_surrogate(text) diff --git a/telethon/extensions/markdown.py b/telethon/extensions/markdown.py index d52fc3478..82e903457 100644 --- a/telethon/extensions/markdown.py +++ b/telethon/extensions/markdown.py @@ -164,13 +164,13 @@ def unparse(text, entities, delimiters=None, url_fmt=None): text = add_surrogate(text) delimiters = {v: k for k, v in delimiters.items()} insert_at = [] - for entity in entities: + for i, entity in enumerate(entities): s = entity.offset e = entity.offset + entity.length delimiter = delimiters.get(type(entity), None) if delimiter: - insert_at.append((s, delimiter)) - insert_at.append((e, delimiter)) + insert_at.append((s, i, delimiter)) + insert_at.append((e, -i, delimiter)) else: url = None if isinstance(entity, MessageEntityTextUrl): @@ -178,12 +178,12 @@ def unparse(text, entities, delimiters=None, url_fmt=None): elif isinstance(entity, MessageEntityMentionName): url = 'tg://user?id={}'.format(entity.user_id) if url: - insert_at.append((s, '[')) - insert_at.append((e, ']({})'.format(url))) + insert_at.append((s, i, '[')) + insert_at.append((e, -i, ']({})'.format(url))) - insert_at.sort(key=lambda t: t[0]) + insert_at.sort(key=lambda t: (t[0], t[1])) while insert_at: - at, what = insert_at.pop() + at, _, what = insert_at.pop() # If we are in the middle of a surrogate nudge the position by -1. # Otherwise we would end up with malformed text and fail to encode. diff --git a/telethon/helpers.py b/telethon/helpers.py index 81f9a607b..f4abe2969 100644 --- a/telethon/helpers.py +++ b/telethon/helpers.py @@ -58,7 +58,7 @@ def within_surrogate(text, index, *, length=None): return ( 1 < index < len(text) and # in bounds - '\ud800' <= text[index - 1] <= '\udfff' and # previous is + '\ud800' <= text[index - 1] <= '\udbff' and # previous is '\ud800' <= text[index] <= '\udfff' # current is ) @@ -348,21 +348,22 @@ async def __aenter__(self): self._size = os.path.getsize(self._file) self._stream = open(self._file, 'rb') self._close_stream = True + return self - elif isinstance(self._file, bytes): + if isinstance(self._file, bytes): self._size = len(self._file) self._stream = io.BytesIO(self._file) self._close_stream = True + return self - elif not callable(getattr(self._file, 'read', None)): + if not callable(getattr(self._file, 'read', None)): raise TypeError('file description should have a `read` method') - elif self._size is not None: - self._name = getattr(self._file, 'name', None) - self._stream = self._file - self._close_stream = False + self._name = getattr(self._file, 'name', None) + self._stream = self._file + self._close_stream = False - else: + if self._size is None: if callable(getattr(self._file, 'seekable', None)): seekable = await _maybe_await(self._file.seekable()) else: @@ -373,8 +374,6 @@ async def __aenter__(self): await _maybe_await(self._file.seek(0, os.SEEK_END)) self._size = await _maybe_await(self._file.tell()) await _maybe_await(self._file.seek(pos, os.SEEK_SET)) - self._stream = self._file - self._close_stream = False else: _log.warning( 'Could not determine file size beforehand so the entire ' diff --git a/telethon/network/connection/connection.py b/telethon/network/connection/connection.py index 838b3b883..8236bc0c3 100644 --- a/telethon/network/connection/connection.py +++ b/telethon/network/connection/connection.py @@ -116,9 +116,15 @@ async def _proxy_connect(self, timeout=None, local_addr=None): # python_socks internal errors are not inherited from # builtin IOError (just from Exception). Instead of adding those # in exceptions clauses everywhere through the code, we - # rather monkey-patch them in place. + # rather monkey-patch them in place. Keep in mind that + # ProxyError takes error_code as keyword argument. - python_socks._errors.ProxyError = ConnectionError + class ConnectionErrorExtra(ConnectionError): + def __init__(self, message, error_code=None): + super().__init__(message) + self.error_code = error_code + + python_socks._errors.ProxyError = ConnectionErrorExtra python_socks._errors.ProxyConnectionError = ConnectionError python_socks._errors.ProxyTimeoutError = ConnectionError diff --git a/telethon/network/connection/tcpmtproxy.py b/telethon/network/connection/tcpmtproxy.py index 69a43bce9..e3ef98a57 100644 --- a/telethon/network/connection/tcpmtproxy.py +++ b/telethon/network/connection/tcpmtproxy.py @@ -1,5 +1,6 @@ import asyncio import hashlib +import base64 import os from .connection import ObfuscatedConnection @@ -98,7 +99,7 @@ class TcpMTProxy(ObfuscatedConnection): def __init__(self, ip, port, dc_id, *, loggers, proxy=None, local_addr=None): # connect to proxy's host and port instead of telegram's ones proxy_host, proxy_port = self.address_info(proxy) - self._secret = bytes.fromhex(proxy[2]) + self._secret = self.normalize_secret(proxy[2]) super().__init__( proxy_host, proxy_port, dc_id, loggers=loggers) @@ -130,6 +131,18 @@ def address_info(proxy_info): raise ValueError("No proxy info specified for MTProxy connection") return proxy_info[:2] + @staticmethod + def normalize_secret(secret): + if secret[:2] in ("ee", "dd"): # Remove extra bytes + secret = secret[2:] + + try: + secret_bytes = bytes.fromhex(secret) + except ValueError: + secret = secret + '=' * (-len(secret) % 4) + secret_bytes = base64.b64decode(secret.encode()) + + return secret_bytes[:16] # Remove the domain from the secret (until domain support is added) class ConnectionTcpMTProxyAbridged(TcpMTProxy): """ diff --git a/telethon/network/mtprotosender.py b/telethon/network/mtprotosender.py index c1a839d9a..d53f9ce88 100644 --- a/telethon/network/mtprotosender.py +++ b/telethon/network/mtprotosender.py @@ -1,6 +1,8 @@ import asyncio import collections import struct +import datetime +import time from . import authenticator from ..extensions.messagepacker import MessagePacker @@ -503,8 +505,10 @@ async def _recv_loop(self): self._log.debug('Receiving items from the network...') try: body = await self._connection.recv() - except IOError as e: - self._log.info('Connection closed while receiving data') + except asyncio.CancelledError: + raise # bypass except Exception + except (IOError, asyncio.IncompleteReadError) as e: + self._log.info('Connection closed while receiving data: %s', e) self._start_reconnect(e) return except InvalidBufferError as e: @@ -698,16 +702,23 @@ def _store_own_updates(self, obj, *, _update_ids=frozenset(( elif obj.CONSTRUCTOR_ID in _update_like_ids: # Ugly "hack" (?) - otherwise bots reliably detect gaps when deleting messages. # - # Note: the `date` being `None` is used to check for `updatesTooLong`, so `0` is - # used instead. It is still not read, because `updateShort` has no `seq`. + # Note: the `date` being `None` is used to check for `updatesTooLong`, so epoch + # is used instead. It is still not read, because `updateShort` has no `seq`. # # Some requests, such as `readHistory`, also return these types. But the `pts_count` # seems to be zero, so while this will produce some bogus `updateDeleteMessages`, # it's still one of the "cleaner" approaches to handling the new `pts`. # `updateDeleteMessages` is probably the "least-invasive" update that can be used. - upd = _tl.UpdateShort(_tl.UpdateDeleteMessages([], obj.pts, obj.pts_count), 0) + upd = _tl.UpdateShort( + _tl.UpdateDeleteMessages([], obj.pts, obj.pts_count), + datetime.datetime(*time.gmtime(0)[:6]).replace(tzinfo=datetime.timezone.utc) + ) upd._self_outgoing = True self._updates_queue.put_nowait(upd) + elif obj.CONSTRUCTOR_ID == _tl.messages.InvitedUsers.CONSTRUCTOR_ID: + obj.updates._self_outgoing = True + self._updates_queue.put_nowait(obj.updates) + except AttributeError: pass diff --git a/telethon/sessions/memory.py b/telethon/sessions/memory.py index 721b6d9ab..5aed60397 100644 --- a/telethon/sessions/memory.py +++ b/telethon/sessions/memory.py @@ -174,7 +174,7 @@ def get_entity_rows_by_name(self, name): def get_entity_rows_by_id(self, id, exact=True): try: if exact: - return next((id, hash) for found_id, hash, _, _, _ + return next((found_id, hash) for found_id, hash, _, _, _ in self._entities if found_id == id) else: ids = ( @@ -182,7 +182,7 @@ def get_entity_rows_by_id(self, id, exact=True): utils.get_peer_id(PeerChat(id)), utils.get_peer_id(PeerChannel(id)) ) - return next((id, hash) for found_id, hash, _, _, _ + return next((found_id, hash) for found_id, hash, _, _, _ in self._entities if found_id in ids) except StopIteration: pass diff --git a/telethon/tl/custom/button.py b/telethon/tl/custom/button.py index 0ed9a43d3..1b7d71e4f 100644 --- a/telethon/tl/custom/button.py +++ b/telethon/tl/custom/button.py @@ -54,7 +54,8 @@ def _is_inline(button): types.KeyboardButtonGame, types.KeyboardButtonSwitchInline, types.KeyboardButtonUrl, - types.InputKeyboardButtonUrlAuth + types.InputKeyboardButtonUrlAuth, + types.KeyboardButtonWebView, )) @staticmethod diff --git a/telethon/tl/custom/draft.py b/telethon/tl/custom/draft.py index c482b64fd..bde965e88 100644 --- a/telethon/tl/custom/draft.py +++ b/telethon/tl/custom/draft.py @@ -1,6 +1,6 @@ import datetime -from .. import TLObject +from .. import TLObject, types from ..functions.messages import SaveDraftRequest from ..types import DraftMessage from ...errors import RPCError @@ -37,7 +37,7 @@ def __init__(self, client, entity, draft): self._raw_text = draft.message self.date = draft.date self.link_preview = not draft.no_webpage - self.reply_to_msg_id = draft.reply_to_msg_id + self.reply_to_msg_id = draft.reply_to.reply_to_msg_id if isinstance(draft.reply_to, types.InputReplyToMessage) else None @property def entity(self): @@ -139,7 +139,7 @@ async def set_message( peer=self._peer, message=raw_text, no_webpage=not link_preview, - reply_to_msg_id=reply_to, + reply_to=None if reply_to is None else types.InputReplyToMessage(reply_to), entities=entities )) diff --git a/telethon/tl/custom/inlineresult.py b/telethon/tl/custom/inlineresult.py index 15639aa51..d56b2fe25 100644 --- a/telethon/tl/custom/inlineresult.py +++ b/telethon/tl/custom/inlineresult.py @@ -158,7 +158,7 @@ async def click(self, entity=None, reply_to=None, comment_to=None, background=background, clear_draft=clear_draft, hide_via=hide_via, - reply_to_msg_id=reply_id + reply_to=None if reply_id is None else types.InputReplyToMessage(reply_id) ) return self._client._get_response_message( req, await self._client(req), entity) diff --git a/telethon/tl/custom/message.py b/telethon/tl/custom/message.py index 4959ed0f3..3356868c5 100644 --- a/telethon/tl/custom/message.py +++ b/telethon/tl/custom/message.py @@ -68,6 +68,12 @@ class Message(ChatGetter, SenderGetter, TLObject): noforwards (`bool`): Whether this message can be forwarded or not. + invert_media (`bool`): + Whether the media in this message should be inverted. + + offline (`bool`): + Whether the message was sent by an implicit action, for example, as an away or a greeting business message, or as a scheduled message. + id (`int`): The ID of this message. This field is *always* present. Any other member is optional and may be `None`. @@ -160,55 +166,26 @@ class Message(ChatGetter, SenderGetter, TLObject): action (:tl:`MessageAction`): The message action object of the message for :tl:`MessageService` instances, which will be `None` for other types of messages. + + saved_peer_id (:tl:`Peer`) """ # region Initialization def __init__( - # Common to all - self, id: int, - - # Common to Message and MessageService (mandatory) - peer_id: types.TypePeer = None, - date: Optional[datetime] = None, - - # Common to Message and MessageService (flags) - out: Optional[bool] = None, - mentioned: Optional[bool] = None, - media_unread: Optional[bool] = None, - silent: Optional[bool] = None, - post: Optional[bool] = None, - from_id: Optional[types.TypePeer] = None, - reply_to: Optional[types.TypeMessageReplyHeader] = None, - ttl_period: Optional[int] = None, - - # For Message (mandatory) - message: Optional[str] = None, - - # For Message (flags) - fwd_from: Optional[types.TypeMessageFwdHeader] = None, - via_bot_id: Optional[int] = None, - media: Optional[types.TypeMessageMedia] = None, - reply_markup: Optional[types.TypeReplyMarkup] = None, - entities: Optional[List[types.TypeMessageEntity]] = None, - views: Optional[int] = None, - edit_date: Optional[datetime] = None, - post_author: Optional[str] = None, - grouped_id: Optional[int] = None, - from_scheduled: Optional[bool] = None, - legacy: Optional[bool] = None, - edit_hide: Optional[bool] = None, - pinned: Optional[bool] = None, - noforwards: Optional[bool] = None, - reactions: Optional[types.TypeMessageReactions] = None, - restriction_reason: Optional[types.TypeRestrictionReason] = None, - forwards: Optional[int] = None, - replies: Optional[types.TypeMessageReplies] = None, - - # For MessageAction (mandatory) - action: Optional[types.TypeMessageAction] = None + self, + id: int, peer_id: types.TypePeer, + date: Optional[datetime]=None, message: Optional[str]=None, + # Copied from Message.__init__ signature + out: Optional[bool]=None, mentioned: Optional[bool]=None, media_unread: Optional[bool]=None, silent: Optional[bool]=None, post: Optional[bool]=None, from_scheduled: Optional[bool]=None, legacy: Optional[bool]=None, edit_hide: Optional[bool]=None, pinned: Optional[bool]=None, noforwards: Optional[bool]=None, invert_media: Optional[bool]=None, offline: Optional[bool]=None, video_processing_pending: Optional[bool]=None, from_id: Optional[types.TypePeer]=None, from_boosts_applied: Optional[int]=None, saved_peer_id: Optional[types.TypePeer]=None, fwd_from: Optional[types.TypeMessageFwdHeader]=None, via_bot_id: Optional[int]=None, via_business_bot_id: Optional[int]=None, reply_to: Optional[types.TypeMessageReplyHeader]=None, media: Optional[types.TypeMessageMedia]=None, reply_markup: Optional[types.TypeReplyMarkup]=None, entities: Optional[List[types.TypeMessageEntity]]=None, views: Optional[int]=None, forwards: Optional[int]=None, replies: Optional[types.TypeMessageReplies]=None, edit_date: Optional[datetime]=None, post_author: Optional[str]=None, grouped_id: Optional[int]=None, reactions: Optional[types.TypeMessageReactions]=None, restriction_reason: Optional[List[types.TypeRestrictionReason]]=None, ttl_period: Optional[int]=None, quick_reply_shortcut_id: Optional[int]=None, effect: Optional[int]=None, factcheck: Optional[types.TypeFactCheck]=None, + # Copied from MessageService.__init__ signature + action: Optional[types.TypeMessageAction]=None ): - # Common properties to messages, then to service (in the order they're defined in the `.tl`) + # Copied from Message.__init__ body + self.id = id + self.peer_id = peer_id + self.date = date + self.message = message self.out = bool(out) self.mentioned = mentioned self.media_unread = media_unread @@ -217,28 +194,34 @@ def __init__( self.from_scheduled = from_scheduled self.legacy = legacy self.edit_hide = edit_hide - self.id = id + self.pinned = pinned + self.noforwards = noforwards + self.invert_media = invert_media + self.offline = offline + self.video_processing_pending = video_processing_pending self.from_id = from_id - self.peer_id = peer_id + self.from_boosts_applied = from_boosts_applied + self.saved_peer_id = saved_peer_id self.fwd_from = fwd_from self.via_bot_id = via_bot_id + self.via_business_bot_id = via_business_bot_id self.reply_to = reply_to - self.date = date - self.message = message - self.media = None if isinstance(media, types.MessageMediaEmpty) else media + self.media = None if isinstance(media, types.MessageMediaEmpty) else media self.reply_markup = reply_markup self.entities = entities self.views = views self.forwards = forwards self.replies = replies self.edit_date = edit_date - self.pinned = pinned - self.noforwards = noforwards self.post_author = post_author self.grouped_id = grouped_id self.reactions = reactions self.restriction_reason = restriction_reason self.ttl_period = ttl_period + self.quick_reply_shortcut_id = quick_reply_shortcut_id + self.effect = effect + self.factcheck = factcheck + # Copied from MessageService.__init__ body self.action = action # Convenient storage for custom functions @@ -271,6 +254,8 @@ def __init__( SenderGetter.__init__(self, sender_id) self._forward = None + self._reply_to_chat = None + self._reply_to_sender = None def _finish_init(self, client, entities, input_chat): """ @@ -323,6 +308,14 @@ def _finish_init(self, client, entities, input_chat): if self.replies and self.replies.channel_id: self._linked_chat = entities.get(utils.get_peer_id( types.PeerChannel(self.replies.channel_id))) + + if isinstance(self.reply_to, types.MessageReplyHeader): + if self.reply_to.reply_to_peer_id: + self._reply_to_chat = entities.get(utils.get_peer_id(self.reply_to.reply_to_peer_id)) + if self.reply_to.reply_from: + if self.reply_to.reply_from.from_id: + self._reply_to_sender = entities.get(utils.get_peer_id(self.reply_to.reply_from.from_id)) + # endregion Initialization @@ -399,6 +392,22 @@ def forward(self): """ return self._forward + @property + def reply_to_chat(self): + """ + The :tl:`Channel` in which the replied-to message was sent, + if this message is a reply in another chat + """ + return self._reply_to_chat + + @property + def reply_to_sender(self): + """ + The :tl:`User`, :tl:`Channel`, or whatever other entity that + sent the replied-to message, if this message is a reply in another chat. + """ + return self._reply_to_sender + @property def buttons(self): """ @@ -784,12 +793,26 @@ async def forward_to(self, *args, **kwargs): async def edit(self, *args, **kwargs): """ - Edits the message iff it's outgoing. Shorthand for + Edits the message if it's outgoing. Shorthand for `telethon.client.messages.MessageMethods.edit_message` with both ``entity`` and ``message`` already set. - Returns `None` if the message was incoming, - or the edited `Message` otherwise. + Returns + The edited `Message `, + unless `entity` was a :tl:`InputBotInlineMessageID` or :tl:`InputBotInlineMessageID64` in which + case this method returns a boolean. + + Raises + ``MessageAuthorRequiredError`` if you're not the author of the + message but tried editing it anyway. + + ``MessageNotModifiedError`` if the contents of the message were + not modified at all. + + ``MessageIdInvalidError`` if the ID of the message is invalid + (the ID itself may be correct, but the message with that ID + cannot be edited). For example, when trying to edit messages + with a reply markup (or clear markup) this error will be raised. .. note:: @@ -803,9 +826,6 @@ async def edit(self, *args, **kwargs): This is generally the most desired and convenient behaviour, and will work for link previews and message buttons. """ - if self.fwd_from or not self.out or not self._client: - return None # We assume self.out was patched for our chat - if 'link_preview' not in kwargs: kwargs['link_preview'] = bool(self.web_preview) diff --git a/telethon/tl/custom/messagebutton.py b/telethon/tl/custom/messagebutton.py index 7f6490b23..6ec17fbd8 100644 --- a/telethon/tl/custom/messagebutton.py +++ b/telethon/tl/custom/messagebutton.py @@ -1,7 +1,11 @@ from .. import types, functions from ... import password as pwd_mod from ...errors import BotResponseTimeoutError -import webbrowser +try: + import webbrowser +except ModuleNotFoundError: + pass +import sys import os @@ -112,7 +116,8 @@ async def click(self, share_phone=None, share_geo=None, *, password=None): bot=self._bot, peer=self._chat, start_param=self.button.query )) elif isinstance(self.button, types.KeyboardButtonUrl): - return webbrowser.open(self.button.url) + if "webbrowser" in sys.modules: + return webbrowser.open(self.button.url) elif isinstance(self.button, types.KeyboardButtonGame): req = functions.messages.GetBotCallbackAnswerRequest( peer=self._chat, msg_id=self._msg_id, game=True diff --git a/telethon/utils.py b/telethon/utils.py index f7b830e7e..1c939e98c 100644 --- a/telethon/utils.py +++ b/telethon/utils.py @@ -4,7 +4,6 @@ """ import base64 import binascii -import imghdr import inspect import io import itertools @@ -60,14 +59,8 @@ r'tg://(join)\?invite=' ) -# The only shorter-than-five-characters usernames are those used for some -# special, very well known bots. This list may be incomplete though: -# "[...] @gif, @vid, @pic, @bing, @wiki, @imdb and @bold [...]" -# -# See https://telegram.org/blog/inline-bots#how-does-it-work VALID_USERNAME_RE = re.compile( - r'^([a-z](?:(?!__)\w){3,30}[a-z\d]' - r'|gif|vid|pic|bing|wiki|imdb|bold|vote|like|coub)$', + r'^[a-z](?:(?!__)\w){1,30}[a-z\d]$', re.IGNORECASE ) @@ -763,7 +756,10 @@ def sanitize_parse_mode(mode): if not mode: return None - if callable(mode): + if (all(hasattr(mode, x) for x in ('parse', 'unparse')) + and all(callable(x) for x in (mode.parse, mode.unparse))): + return mode + elif callable(mode): class CustomMode: @staticmethod def unparse(text, entities): @@ -771,9 +767,6 @@ def unparse(text, entities): CustomMode.parse = mode return CustomMode - elif (all(hasattr(mode, x) for x in ('parse', 'unparse')) - and all(callable(x) for x in (mode.parse, mode.unparse))): - return mode elif isinstance(mode, str): try: return { @@ -841,12 +834,6 @@ def _get_extension(file): return os.path.splitext(file)[-1] elif isinstance(file, pathlib.Path): return file.suffix - elif isinstance(file, bytes): - kind = imghdr.what(io.BytesIO(file)) - return ('.' + kind) if kind else '' - elif isinstance(file, io.IOBase) and not isinstance(file, io.TextIOBase) and file.seekable(): - kind = imghdr.what(file) - return ('.' + kind) if kind is not None else '' elif getattr(file, 'name', None): # Note: ``file.name`` works for :tl:`InputFile` and some `IOBase` return _get_extension(file.name) diff --git a/telethon/version.py b/telethon/version.py index 7b1626f6e..f27eec372 100644 --- a/telethon/version.py +++ b/telethon/version.py @@ -1,3 +1,3 @@ # Versions should comply with PEP440. # This line is parsed in setup.py: -__version__ = '1.28.5' +__version__ = '1.38.1' diff --git a/telethon_generator/data/api.tl b/telethon_generator/data/api.tl index 6a606b743..c6b4a89af 100644 --- a/telethon_generator/data/api.tl +++ b/telethon_generator/data/api.tl @@ -1,33 +1,3 @@ -/////////////////////////////// -/////////////////// Layer cons -/////////////////////////////// - -//invokeAfterMsg#cb9f372d msg_id:long query:!X = X; -//invokeAfterMsgs#3dc4b4f0 msg_ids:Vector 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 - -/////////////////////////////// -///////// Main application API -/////////////////////////////// - boolFalse#bc799737 = Bool; boolTrue#997275b5 = Bool; @@ -56,6 +26,7 @@ inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_na inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile; inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile; +inputFileStoryDocument#62dc8b48 id:InputDocument = InputFile; inputMediaEmpty#9664f57f = InputMedia; inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; @@ -68,10 +39,13 @@ inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string pro inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaDocumentExternal#fb52dc99 flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; inputMediaGame#d33f43f3 id:InputGame = InputMedia; -inputMediaInvoice#8eb5a6d5 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia; +inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia; inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia; inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector solution:flags.1?string solution_entities:flags.1?Vector = InputMedia; inputMediaDice#e66fbf7b emoticon:string = InputMedia; +inputMediaStory#89fdd778 peer:InputPeer id:int = InputMedia; +inputMediaWebPage#c21b8849 flags:# force_large_media:flags.0?true force_small_media:flags.1?true optional:flags.2?true url:string = InputMedia; +inputMediaPaidMedia#c4103386 flags:# stars_amount:long extended_media:Vector payload:flags.0?string = InputMedia; inputChatPhotoEmpty#1ca48f57 = InputChatPhoto; inputChatUploadedPhoto#bdcdaec0 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double video_emoji_markup:flags.3?VideoSize = InputChatPhoto; @@ -110,7 +84,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; userEmpty#d3bc4b7a id:long = User; -user#8f97c628 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector = User; +user#83314fca flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int = User; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto; @@ -118,18 +92,18 @@ userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true p userStatusEmpty#9d05049 = UserStatus; userStatusOnline#edb93949 expires:int = UserStatus; userStatusOffline#8c703f was_online:int = UserStatus; -userStatusRecently#e26f42f1 = UserStatus; -userStatusLastWeek#7bf09fc = UserStatus; -userStatusLastMonth#77ebc742 = UserStatus; +userStatusRecently#7b197dc8 flags:# by_me:flags.0?true = UserStatus; +userStatusLastWeek#541a1d1a flags:# by_me:flags.0?true = UserStatus; +userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus; chatEmpty#29562865 id:long = Chat; chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#6592a1a7 id:long title:string = Chat; -channel#83259464 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector = Chat; +channel#fe4478bd flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int = Chat; channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions = ChatFull; -channelFull#f2355507 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions = ChatFull; +chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; +channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -142,7 +116,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto; messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message; -message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int = Message; +message#94345242 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true flags2:# offline:flags2.1?true video_processing_pending:flags2.4?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck = Message; messageService#2b085862 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message; messageMediaEmpty#3ded6320 = MessageMedia; @@ -150,14 +124,18 @@ messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_ messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia; -messageMediaDocument#9cb070d7 flags:# nopremium:flags.3?true spoiler:flags.4?true document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia; -messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia; +messageMediaDocument#dd570bd5 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector ttl_seconds:flags.2?int = MessageMedia; +messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia; messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia; messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia; messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; +messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; +messageMediaGiveaway#aa073beb flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector countries_iso2:flags.1?Vector prize_description:flags.3?string quantity:int months:flags.4?int stars:flags.5?long until_date:int = MessageMedia; +messageMediaGiveawayResults#ceaa3ea1 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector months:flags.4?int stars:flags.5?long prize_description:flags.1?string until_date:int = MessageMedia; +messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector = MessageMedia; messageActionEmpty#b6aef7b0 = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector = MessageAction; @@ -173,12 +151,12 @@ messageActionChannelMigrateFrom#ea3948e9 title:string chat_id:long = MessageActi messageActionPinMessage#94bd38ed = MessageAction; messageActionHistoryClear#9fbab604 = MessageAction; messageActionGameScore#92a72876 game_id:long score:int = MessageAction; -messageActionPaymentSentMe#8f31b327 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction; -messageActionPaymentSent#96163f56 flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string = MessageAction; +messageActionPaymentSentMe#ffa00ccc flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge subscription_until_date:flags.4?int = MessageAction; +messageActionPaymentSent#c624b16e flags:# recurring_init:flags.2?true recurring_used:flags.3?true currency:string total_amount:long invoice_slug:flags.0?string subscription_until_date:flags.4?int = MessageAction; messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction; messageActionScreenshotTaken#4792929b = MessageAction; messageActionCustomAction#fae69f56 message:string = MessageAction; -messageActionBotAllowed#c516d679 flags:# attach_menu:flags.1?true domain:flags.0?string app:flags.2?BotApp = MessageAction; +messageActionBotAllowed#c516d679 flags:# attach_menu:flags.1?true from_request:flags.3?true domain:flags.0?string app:flags.2?BotApp = MessageAction; messageActionSecureValuesSentMe#1b287353 values:Vector credentials:SecureCredentialsEncrypted = MessageAction; messageActionSecureValuesSent#d95c6154 types:Vector = MessageAction; messageActionContactSignUp#f3f25f76 = MessageAction; @@ -191,15 +169,23 @@ messageActionSetChatTheme#aa786345 emoticon:string = MessageAction; messageActionChatJoinedByRequest#ebbca3cb = MessageAction; messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction; messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction; -messageActionGiftPremium#c83d6aec flags:# currency:string amount:long months:int crypto_currency:flags.0?string crypto_amount:flags.0?long = MessageAction; +messageActionGiftPremium#6c6274fa flags:# currency:string amount:long months:int crypto_currency:flags.0?string crypto_amount:flags.0?long message:flags.1?TextWithEntities = MessageAction; messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction; messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction; messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction; -messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction; -messageActionSetChatWallPaper#bc44a927 wallpaper:WallPaper = MessageAction; -messageActionSetSameChatWallPaper#c0787d6d wallpaper:WallPaper = MessageAction; - -dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; +messageActionRequestedPeer#31518e9b button_id:int peers:Vector = MessageAction; +messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction; +messageActionGiftCode#56d03994 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long message:flags.4?TextWithEntities = MessageAction; +messageActionGiveawayLaunch#a80f51e4 flags:# stars:flags.0?long = MessageAction; +messageActionGiveawayResults#87e2f155 flags:# stars:flags.0?true winners_count:int unclaimed_count:int = MessageAction; +messageActionBoostApply#cc02aa6d boosts:int = MessageAction; +messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector = MessageAction; +messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction; +messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction; +messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction; +messageActionStarGift#8557637 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long = MessageAction; + +dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; photoEmpty#2331b22d id:long = Photo; @@ -229,11 +215,11 @@ inputNotifyChats#4a95e84e = InputNotifyPeer; inputNotifyBroadcasts#b1db7c7e = InputNotifyPeer; inputNotifyForumTopic#5c467992 peer:InputPeer top_msg_id:int = InputNotifyPeer; -inputPeerNotifySettings#df1f002b flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound = InputPeerNotifySettings; +inputPeerNotifySettings#cacb6ae2 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_sound:flags.8?NotificationSound = InputPeerNotifySettings; -peerNotifySettings#a83b0426 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound = PeerNotifySettings; +peerNotifySettings#99622c0c flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int ios_sound:flags.3?NotificationSound android_sound:flags.4?NotificationSound other_sound:flags.5?NotificationSound stories_muted:flags.6?Bool stories_hide_sender:flags.7?Bool stories_ios_sound:flags.8?NotificationSound stories_android_sound:flags.9?NotificationSound stories_other_sound:flags.10?NotificationSound = PeerNotifySettings; -peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings; +peerSettings#acd66c5e flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true business_bot_paused:flags.11?true business_bot_can_reply:flags.12?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int business_bot_id:flags.13?long business_bot_manage_url:flags.13?string = PeerSettings; wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper; wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper; @@ -249,7 +235,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason; -userFull#93eadb53 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector wallpaper:flags.24?WallPaper = UserFull; +userFull#979d2376 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -307,6 +293,7 @@ updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction updateChatParticipants#7761198 participants:ChatParticipants = Update; updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update; updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector = Update; +updateNewAuthorization#8951abef flags:# unconfirmed:flags.0?true hash:long date:flags.0?int device:flags.0?string location:flags.0?string = Update; updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update; updateEncryptedChatTyping#1710f156 chat_id:int = Update; updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update; @@ -315,13 +302,13 @@ updateChatParticipantAdd#3dda5451 chat_id:long user_id:long inviter_id:long date updateChatParticipantDelete#e32f3d77 chat_id:long user_id:long version:int = Update; updateDcOptions#8e5e9873 dc_options:Vector = Update; updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update; -updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector = Update; +updateServiceNotification#ebe46819 flags:# popup:flags.0?true invert_media:flags.2?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector = Update; updatePrivacy#ee3b272a key:PrivacyKey rules:Vector = Update; updateUserPhone#5492a13 user_id:long phone:string = Update; updateReadHistoryInbox#9c974fdf flags:# folder_id:flags.0?int peer:Peer max_id:int still_unread_count:int pts:int pts_count:int = Update; updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update; updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update; -updateReadMessagesContents#68c13933 messages:Vector pts:int pts_count:int = Update; +updateReadMessagesContents#f8227181 flags:# messages:Vector pts:int pts_count:int date:flags.0?int = Update; updateChannelTooLong#108d941f flags:# channel_id:long pts:flags.0?int = Update; updateChannel#635b4c09 channel_id:long = Update; updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update; @@ -366,11 +353,11 @@ updateFolderPeers#19360dc0 folder_peers:Vector pts:int pts_count:int updatePeerSettings#6a7e7366 peer:Peer settings:PeerSettings = Update; updatePeerLocated#b4afcfb0 peers:Vector = Update; updateNewScheduledMessage#39a51dfb message:Message = Update; -updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector = Update; +updateDeleteScheduledMessages#f2a71983 flags:# peer:Peer messages:Vector sent_messages:flags.0?Vector = Update; updateTheme#8216fba3 theme:Theme = Update; updateGeoLiveViewed#871fb939 peer:Peer msg_id:int = Update; updateLoginToken#564fe691 = Update; -updateMessagePollVote#106395c9 poll_id:long user_id:long options:Vector qts:int = Update; +updateMessagePollVote#24f40e77 poll_id:long peer:Peer options:Vector qts:int = Update; updateDialogFilter#26ffde7d flags:# id:int filter:flags.0?DialogFilter = Update; updateDialogFilterOrder#a5d72105 order:Vector = Update; updateDialogFilters#3504914f = Update; @@ -378,7 +365,7 @@ updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update; updateChannelMessageForwards#d29a27f4 channel_id:long id:int forwards:int = Update; updateReadChannelDiscussionInbox#d6b19546 flags:# channel_id:long top_msg_id:int read_max_id:int broadcast_id:flags.0?long broadcast_post:flags.0?int = Update; updateReadChannelDiscussionOutbox#695c9e7c channel_id:long top_msg_id:int read_max_id:int = Update; -updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update; +updatePeerBlocked#ebe07752 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer = Update; updateChannelUserTyping#8c88c923 flags:# channel_id:long top_msg_id:flags.0?int from_id:Peer action:SendMessageAction = Update; updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vector pts:int pts_count:int = Update; updatePinnedChannelMessages#5bb98608 flags:# pinned:flags.0?true channel_id:long messages:Vector pts:int pts_count:int = Update; @@ -404,12 +391,41 @@ updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update; updateRecentEmojiStatuses#30f443db = Update; updateRecentReactions#6f7863f4 = Update; updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update; -updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = Update; +updateMessageExtendedMedia#d5a41724 peer:Peer msg_id:int extended_media:Vector = Update; updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long topic_id:int = Update; updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector = Update; updateUser#20529438 user_id:long = Update; updateAutoSaveSettings#ec05b097 = Update; -updateGroupInvitePrivacyForbidden#ccf08ad6 user_id:long = Update; +updateStory#75b3b798 peer:Peer story:StoryItem = Update; +updateReadStories#f74e932b peer:Peer max_id:int = Update; +updateStoryID#1bf335b9 id:int random_id:long = Update; +updateStoriesStealthMode#2c084dc1 stealth_mode:StoriesStealthMode = Update; +updateSentStoryReaction#7d627683 peer:Peer story_id:int reaction:Reaction = Update; +updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update; +updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update; +updatePeerWallpaper#ae3f101d flags:# wallpaper_overridden:flags.1?true peer:Peer wallpaper:flags.0?WallPaper = Update; +updateBotMessageReaction#ac21d3ce peer:Peer msg_id:int date:int actor:Peer old_reactions:Vector new_reactions:Vector qts:int = Update; +updateBotMessageReactions#9cb7759 peer:Peer msg_id:int date:int reactions:Vector qts:int = Update; +updateSavedDialogPinned#aeaf9e74 flags:# pinned:flags.0?true peer:DialogPeer = Update; +updatePinnedSavedDialogs#686c85a6 flags:# order:flags.0?Vector = Update; +updateSavedReactionTags#39c67432 = Update; +updateSmsJob#f16269d4 job_id:string = Update; +updateQuickReplies#f9470ab2 quick_replies:Vector = Update; +updateNewQuickReply#f53da717 quick_reply:QuickReply = Update; +updateDeleteQuickReply#53e6f1ec shortcut_id:int = Update; +updateQuickReplyMessage#3e050d0f message:Message = Update; +updateDeleteQuickReplyMessages#566fe7cd shortcut_id:int messages:Vector = Update; +updateBotBusinessConnect#8ae5c97a connection:BotBusinessConnection qts:int = Update; +updateBotNewBusinessMessage#9ddb347c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update; +updateBotEditBusinessMessage#7df587c flags:# connection_id:string message:Message reply_to_message:flags.0?Message qts:int = Update; +updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages:Vector qts:int = Update; +updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update; +updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update; +updateStarsBalance#4e80a379 balance:StarsAmount = Update; +updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update; +updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update; +updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update; +updatePaidReactionPrivacy#51ca7aec private:Bool = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -514,6 +530,9 @@ inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey; inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey; inputPrivacyKeyAddedByPhone#d1219bdd = InputPrivacyKey; inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey; +inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey; +inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey; +inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; @@ -524,6 +543,9 @@ privacyKeyProfilePhoto#96151fed = PrivacyKey; privacyKeyPhoneNumber#d19ae46d = PrivacyKey; privacyKeyAddedByPhone#42ffd42b = PrivacyKey; privacyKeyVoiceMessages#697f414 = PrivacyKey; +privacyKeyAbout#a486b761 = PrivacyKey; +privacyKeyBirthday#2000a518 = PrivacyKey; +privacyKeyStarGiftsAutoSave#2ca4fdf8 = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; @@ -533,6 +555,10 @@ inputPrivacyValueDisallowAll#d66b66c9 = InputPrivacyRule; inputPrivacyValueDisallowUsers#90110467 users:Vector = InputPrivacyRule; inputPrivacyValueAllowChatParticipants#840649cf chats:Vector = InputPrivacyRule; inputPrivacyValueDisallowChatParticipants#e94f0f86 chats:Vector = InputPrivacyRule; +inputPrivacyValueAllowCloseFriends#2f453e49 = InputPrivacyRule; +inputPrivacyValueAllowPremium#77cdc9f1 = InputPrivacyRule; +inputPrivacyValueAllowBots#5a4fcce5 = InputPrivacyRule; +inputPrivacyValueDisallowBots#c4e57915 = InputPrivacyRule; privacyValueAllowContacts#fffe1bac = PrivacyRule; privacyValueAllowAll#65427b82 = PrivacyRule; @@ -542,6 +568,10 @@ privacyValueDisallowAll#8b73e763 = PrivacyRule; privacyValueDisallowUsers#e4621141 users:Vector = PrivacyRule; privacyValueAllowChatParticipants#6b134e8e chats:Vector = PrivacyRule; privacyValueDisallowChatParticipants#41c87565 chats:Vector = PrivacyRule; +privacyValueAllowCloseFriends#f7e8d89b = PrivacyRule; +privacyValueAllowPremium#ece9814b = PrivacyRule; +privacyValueAllowBots#21461b5d = PrivacyRule; +privacyValueDisallowBots#f6a5f82f = PrivacyRule; account.privacyRules#50a04e45 rules:Vector chats:Vector users:Vector = account.PrivacyRules; @@ -550,7 +580,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL; documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute; documentAttributeAnimated#11b58939 = DocumentAttribute; documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute; -documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int = DocumentAttribute; +documentAttributeVideo#43c57c48 flags:# round_message:flags.0?true supports_streaming:flags.1?true nosound:flags.3?true duration:double w:int h:int preload_prefix_size:flags.2?int video_start_ts:flags.4?double video_codec:flags.5?string = DocumentAttribute; documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute; documentAttributeFilename#15590068 file_name:string = DocumentAttribute; documentAttributeHasStickers#9801d2f7 = DocumentAttribute; @@ -566,12 +596,12 @@ messages.allStickers#cdbbcebb hash:long sets:Vector = messages.AllSt messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages; -webPageEmpty#eb1477e8 id:long = WebPage; -webPagePending#c586da1c id:long date:int = WebPage; -webPage#e89c45b2 flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector = WebPage; +webPageEmpty#211a1788 flags:# id:long url:flags.0?string = WebPage; +webPagePending#b0d13e47 flags:# id:long url:flags.0?string date:int = WebPage; +webPage#e89c45b2 flags:# has_large_media:flags.13?true id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector = WebPage; webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage; -authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization; +authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true unconfirmed:flags.5?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization; account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector = account.Authorizations; @@ -585,11 +615,11 @@ auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery; receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage; -chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int title:flags.8?string = ExportedChatInvite; +chatInviteExported#a22cbd96 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int subscription_expired:flags.10?int title:flags.8?string subscription_pricing:flags.9?StarsSubscriptionPricing = ExportedChatInvite; chatInvitePublicJoinRequests#ed107ab7 = ExportedChatInvite; chatInviteAlready#5a686d7c chat:Chat = ChatInvite; -chatInvite#300c44c1 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector = ChatInvite; +chatInvite#fe65389d flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true verified:flags.7?true scam:flags.8?true fake:flags.9?true can_refulfill_subscription:flags.11?true title:string about:flags.5?string photo:Photo participants_count:int participants:flags.4?Vector color:int subscription_pricing:flags.10?StarsSubscriptionPricing subscription_form_id:flags.12?long = ChatInvite; chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite; inputStickerSetEmpty#ffb62b95 = InputStickerSet; @@ -602,15 +632,16 @@ inputStickerSetPremiumGifts#c88b3b02 = InputStickerSet; inputStickerSetEmojiGenericAnimations#4c4d4ce = InputStickerSet; inputStickerSetEmojiDefaultStatuses#29d0f5ee = InputStickerSet; inputStickerSetEmojiDefaultTopicIcons#44c1f8e9 = InputStickerSet; +inputStickerSetEmojiChannelDefaultStatuses#49748553 = InputStickerSet; -stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true videos:flags.6?true emojis:flags.7?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet; +stickerSet#2dd14edc flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true emojis:flags.7?true text_color:flags.9?true channel_emoji_status:flags.10?true creator:flags.11?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector thumb_dc_id:flags.4?int thumb_version:flags.4?int thumb_document_id:flags.8?long count:int hash:int = StickerSet; messages.stickerSet#6e153f16 set:StickerSet packs:Vector keywords:Vector documents:Vector = messages.StickerSet; messages.stickerSetNotModified#d3f924eb = messages.StickerSet; botCommand#c27ac8c7 command:string description:string = BotCommand; -botInfo#8f300b57 flags:# user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector menu_button:flags.3?BotMenuButton = BotInfo; +botInfo#36607333 flags:# has_preview_medias:flags.6?true user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector menu_button:flags.3?BotMenuButton privacy_policy_url:flags.7?string app_settings:flags.8?BotAppSettings = BotInfo; keyboardButton#a2fa4880 text:string = KeyboardButton; keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton; @@ -627,7 +658,9 @@ inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = Keyboard keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton; keyboardButtonWebView#13767230 text:string url:string = KeyboardButton; keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton; -keyboardButtonRequestPeer#d0b468c text:string button_id:int peer_type:RequestPeerType = KeyboardButton; +keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; +inputKeyboardButtonRequestPeer#c9662d05 flags:# name_requested:flags.0?true username_requested:flags.1?true photo_requested:flags.2?true text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; +keyboardButtonCopy#75d2698e text:string copy_text:string = KeyboardButton; keyboardButtonRow#77608b83 buttons:Vector = KeyboardButtonRow; @@ -653,10 +686,10 @@ messageEntityPhone#9b69e34b offset:int length:int = MessageEntity; messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity; messageEntityUnderline#9c4e7e8b offset:int length:int = MessageEntity; messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity; -messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity; messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity; +messageEntityBlockquote#f1ccaaac flags:# collapsed:flags.0?true offset:int length:int = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; @@ -673,8 +706,8 @@ updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:fl channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector = ChannelMessagesFilter; -channelParticipant#c00c07c0 user_id:long date:int = ChannelParticipant; -channelParticipantSelf#35a8bfa7 flags:# via_request:flags.0?true user_id:long inviter_id:long date:int = ChannelParticipant; +channelParticipant#cb397619 flags:# user_id:long date:int subscription_until_date:flags.0?int = ChannelParticipant; +channelParticipantSelf#4f607bef flags:# via_request:flags.0?true user_id:long inviter_id:long date:int subscription_until_date:flags.1?int = ChannelParticipant; channelParticipantCreator#2fe601d3 flags:# user_id:long admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant; channelParticipantAdmin#34c3bb53 flags:# can_edit:flags.0?true self:flags.1?true user_id:long inviter_id:flags.1?long promoted_by:long date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant; channelParticipantBanned#6df8014e flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights = ChannelParticipant; @@ -699,25 +732,27 @@ help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string messages.savedGifsNotModified#e8025ca2 = messages.SavedGifs; messages.savedGifs#84a02a0d hash:long gifs:Vector = messages.SavedGifs; -inputBotInlineMessageMediaAuto#3380c786 flags:# message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; -inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; +inputBotInlineMessageMediaAuto#3380c786 flags:# invert_media:flags.3?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; +inputBotInlineMessageText#3dcd7a87 flags:# no_webpage:flags.0?true invert_media:flags.3?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaGeo#96929a85 flags:# geo_point:InputGeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaVenue#417bbf11 flags:# geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaContact#a6edbffd flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageGame#4b425864 flags:# reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; inputBotInlineMessageMediaInvoice#d7e78225 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; +inputBotInlineMessageMediaWebPage#bddcc510 flags:# invert_media:flags.3?true force_large_media:flags.4?true force_small_media:flags.5?true optional:flags.6?true message:string entities:flags.1?Vector url:string reply_markup:flags.2?ReplyMarkup = InputBotInlineMessage; 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; -botInlineMessageMediaAuto#764cf810 flags:# message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; -botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; +botInlineMessageMediaAuto#764cf810 flags:# invert_media:flags.3?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; +botInlineMessageText#8c7f65e2 flags:# no_webpage:flags.0?true invert_media:flags.3?true message:string entities:flags.1?Vector reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaGeo#51846fd flags:# geo:GeoPoint heading:flags.0?int period:flags.1?int proximity_notification_radius:flags.3?int reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaContact#18d1cdc2 flags:# phone_number:string first_name:string last_name:string vcard:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage; botInlineMessageMediaInvoice#354a9b09 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument currency:string total_amount:long reply_markup:flags.2?ReplyMarkup = BotInlineMessage; +botInlineMessageMediaWebPage#809ad9a6 flags:# invert_media:flags.3?true force_large_media:flags.4?true force_small_media:flags.5?true manual:flags.7?true safe:flags.8?true message:string entities:flags.1?Vector url:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage; 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; @@ -726,7 +761,7 @@ messages.botResults#e021f2f6 flags:# gallery:flags.0?true query_id:long next_off exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink; -messageFwdHeader#5f777dce flags:# imported:flags.7?true from_id:flags.0?Peer from_name:flags.5?string date:int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int psa_type:flags.6?string = MessageFwdHeader; +messageFwdHeader#4e4df4bb flags:# imported:flags.7?true saved_out:flags.11?true from_id:flags.0?Peer from_name:flags.5?string date:int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int saved_from_id:flags.8?Peer saved_from_name:flags.9?string saved_date:flags.10?int psa_type:flags.6?string = MessageFwdHeader; auth.codeTypeSms#72a3158c = auth.CodeType; auth.codeTypeCall#741cd3e3 = auth.CodeType; @@ -742,7 +777,9 @@ auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeTyp auth.sentCodeTypeEmailCode#f450f59b flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int reset_available_period:flags.3?int reset_pending_date:flags.4?int = auth.SentCodeType; auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType; auth.sentCodeTypeFragmentSms#d9565c39 url:string length:int = auth.SentCodeType; -auth.sentCodeTypeFirebaseSms#e57b1432 flags:# nonce:flags.0?bytes receipt:flags.1?string push_timeout:flags.1?int length:int = auth.SentCodeType; +auth.sentCodeTypeFirebaseSms#9fd736 flags:# nonce:flags.0?bytes play_integrity_project_id:flags.2?long play_integrity_nonce:flags.2?bytes receipt:flags.1?string push_timeout:flags.1?int length:int = auth.SentCodeType; +auth.sentCodeTypeSmsWord#a416ac81 flags:# beginning:flags.0?string = auth.SentCodeType; +auth.sentCodeTypeSmsPhrase#b37794af flags:# beginning:flags.0?string = auth.SentCodeType; messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer; @@ -765,6 +802,7 @@ topPeerCategoryChannels#161d9628 = TopPeerCategory; topPeerCategoryPhoneCalls#1e76a78c = TopPeerCategory; topPeerCategoryForwardUsers#a8406ca9 = TopPeerCategory; topPeerCategoryForwardChats#fbeec0f0 = TopPeerCategory; +topPeerCategoryBotsApp#fd9e7bec = TopPeerCategory; topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector = TopPeerCategoryPeers; @@ -773,7 +811,7 @@ contacts.topPeers#70b772a8 categories:Vector chats:Vector< contacts.topPeersDisabled#b52c939d = contacts.TopPeers; draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage; -draftMessage#fd8e711f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int message:string entities:flags.3?Vector date:int = DraftMessage; +draftMessage#2d65321f flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo message:string entities:flags.3?Vector media:flags.5?InputMedia date:int effect:flags.7?long = DraftMessage; messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers; messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector unread:Vector = messages.FeaturedStickers; @@ -861,7 +899,7 @@ dataJSON#7d748d04 data:string = DataJSON; labeledPrice#cb296bf8 label:string amount:long = LabeledPrice; -invoice#3e85a91b flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector recurring_terms_url:flags.9?string = Invoice; +invoice#49ee584 flags:# test:flags.0?true name_requested:flags.1?true phone_requested:flags.2?true email_requested:flags.3?true shipping_address_requested:flags.4?true flexible:flags.5?true phone_to_provider:flags.6?true email_to_provider:flags.7?true recurring:flags.9?true currency:string prices:Vector max_tip_amount:flags.8?long suggested_tip_amounts:flags.8?Vector terms_url:flags.10?string subscription_period:flags.11?int = Invoice; paymentCharge#ea02c27e id:string provider_charge_id:string = PaymentCharge; @@ -883,6 +921,8 @@ inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# small:flags.2?true document upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile; payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector users:Vector = payments.PaymentForm; +payments.paymentFormStars#7bf6b15c flags:# form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice users:Vector = payments.PaymentForm; +payments.paymentFormStarGift#b425cfe1 form_id:long invoice:Invoice = payments.PaymentForm; payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector = payments.ValidatedRequestedInfo; @@ -890,6 +930,7 @@ payments.paymentResult#4e5f810d updates:Updates = payments.PaymentResult; payments.paymentVerificationNeeded#d8411139 url:string = payments.PaymentResult; payments.paymentReceipt#70c4fe03 flags:# date:int bot_id:long provider_id:long title:string description:string photo:flags.2?WebDocument invoice:Invoice info:flags.0?PaymentRequestedInfo shipping:flags.1?ShippingOption tip_amount:flags.3?long currency:string total_amount:long credentials_title:string users:Vector = payments.PaymentReceipt; +payments.paymentReceiptStars#dabbf83a flags:# date:int bot_id:long title:string description:string photo:flags.2?WebDocument invoice:Invoice currency:string total_amount:long transaction_id:string users:Vector = payments.PaymentReceipt; payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_info:flags.0?PaymentRequestedInfo = payments.SavedInfo; @@ -910,7 +951,7 @@ phoneCallEmpty#5366c915 id:long = PhoneCall; phoneCallWaiting#c5226f17 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall; phoneCallRequested#14b0ed0c flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall; phoneCallAccepted#3660c311 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol = PhoneCall; -phoneCall#967f7c67 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int = PhoneCall; +phoneCall#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector start_date:int custom_parameters:flags.7?DataJSON = PhoneCall; phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall; phoneConnection#9cc123c7 flags:# tcp:flags.0?true id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection; @@ -978,12 +1019,19 @@ channelAdminLogEventActionEditTopic#f06fe208 prev_topic:ForumTopic new_topic:For channelAdminLogEventActionDeleteTopic#ae168909 topic:ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionPinTopic#5d8d353b flags:# prev_topic:flags.0?ForumTopic new_topic:flags.1?ForumTopic = ChannelAdminLogEventAction; channelAdminLogEventActionToggleAntiSpam#64f36dfc new_value:Bool = ChannelAdminLogEventAction; +channelAdminLogEventActionChangePeerColor#5796e780 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeProfilePeerColor#5e477b25 prev_value:PeerColor new_value:PeerColor = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeWallpaper#31bb5d52 prev_value:WallPaper new_value:WallPaper = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_value:EmojiStatus = ChannelAdminLogEventAction; +channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction; +channelAdminLogEventActionToggleSignatureProfiles#60a79c79 new_value:Bool = ChannelAdminLogEventAction; +channelAdminLogEventActionParticipantSubExtend#64642db3 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; channels.adminLogResults#ed8af74d events:Vector chats:Vector users:Vector = channels.AdminLogResults; -channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true = ChannelAdminLogEventsFilter; +channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true sub_extend:flags.18?true = ChannelAdminLogEventsFilter; popularContact#5ce14175 client_id:long importers:int = PopularContact; @@ -1129,19 +1177,19 @@ help.supportName#8c05f1c9 name:string = help.SupportName; help.userInfoEmpty#f3ae2eed = help.UserInfo; help.userInfo#1eb3758 message:string entities:Vector author:string date:int = help.UserInfo; -pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer; +pollAnswer#ff16e2ca text:TextWithEntities option:bytes = PollAnswer; -poll#86e18161 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:string answers:Vector close_period:flags.4?int close_date:flags.5?int = Poll; +poll#58747131 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:TextWithEntities answers:Vector close_period:flags.4?int close_date:flags.5?int = Poll; pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:int = PollAnswerVoters; -pollResults#dcb82ea3 flags:# min:flags.0?true results:flags.1?Vector total_voters:flags.2?int recent_voters:flags.3?Vector solution:flags.4?string solution_entities:flags.4?Vector = PollResults; +pollResults#7adf2420 flags:# min:flags.0?true results:flags.1?Vector total_voters:flags.2?int recent_voters:flags.3?Vector solution:flags.4?string solution_entities:flags.4?Vector = PollResults; chatOnlines#f041e250 onlines:int = ChatOnlines; statsURL#47a971e0 url:string = StatsURL; -chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true = ChatAdminRights; +chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true post_stories:flags.14?true edit_stories:flags.15?true delete_stories:flags.16?true = ChatAdminRights; chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true manage_topics:flags.18?true send_photos:flags.19?true send_videos:flags.20?true send_roundvideos:flags.21?true send_audios:flags.22?true send_voices:flags.23?true send_docs:flags.24?true send_plain:flags.25?true until_date:int = ChatBannedRights; @@ -1152,11 +1200,11 @@ inputWallPaperNoFile#967a462e id:long = InputWallPaper; account.wallPapersNotModified#1c199183 = account.WallPapers; account.wallPapers#cdc3858c hash:long wallpapers:Vector = account.WallPapers; -codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true logout_tokens:flags.6?Vector token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings; +codeSettings#ad253d78 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true allow_firebase:flags.7?true unknown_number:flags.9?true logout_tokens:flags.6?Vector token:flags.8?string app_sandbox:flags.8?Bool = CodeSettings; -wallPaperSettings#1dc1bca4 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int = WallPaperSettings; +wallPaperSettings#372efcd0 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int emoticon:flags.7?string = WallPaperSettings; -autoDownloadSettings#8efab953 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int = AutoDownloadSettings; +autoDownloadSettings#baa57628 flags:# disabled:flags.0?true video_preload_large:flags.1?true audio_preload_next:flags.2?true phonecalls_less_data:flags.3?true stories_preload:flags.4?true photo_size_max:int video_size_max:long file_size_max:long video_upload_maxbitrate:int small_queue_active_operations_max:int large_queue_active_operations_max:int = AutoDownloadSettings; account.autoDownloadSettings#63cacf26 low:AutoDownloadSettings medium:AutoDownloadSettings high:AutoDownloadSettings = account.AutoDownloadSettings; @@ -1216,20 +1264,18 @@ inputThemeSettings#8fde504f flags:# message_colors_animated:flags.2?true base_th themeSettings#fa58b6d4 flags:# message_colors_animated:flags.2?true base_theme:BaseTheme accent_color:int outbox_accent_color:flags.3?int message_colors:flags.0?Vector wallpaper:flags.1?WallPaper = ThemeSettings; webPageAttributeTheme#54b56617 flags:# documents:flags.0?Vector settings:flags.1?ThemeSettings = WebPageAttribute; +webPageAttributeStory#2e94c3e7 flags:# peer:Peer id:int story:flags.0?StoryItem = WebPageAttribute; +webPageAttributeStickerSet#50cc03d3 flags:# emojis:flags.0?true text_color:flags.1?true stickers:Vector = WebPageAttribute; -messageUserVote#34d247b4 user_id:long option:bytes date:int = MessageUserVote; -messageUserVoteInputOption#3ca5b0ec user_id:long date:int = MessageUserVote; -messageUserVoteMultiple#8a65e557 user_id:long options:Vector date:int = MessageUserVote; - -messages.votesList#823f649 flags:# count:int votes:Vector users:Vector next_offset:flags.0?string = messages.VotesList; +messages.votesList#4899484e flags:# count:int votes:Vector chats:Vector users:Vector next_offset:flags.0?string = messages.VotesList; bankCardOpenUrl#f568028a url:string name:string = BankCardOpenUrl; payments.bankCardData#3e24e573 title:string open_urls:Vector = payments.BankCardData; -dialogFilter#7438f7e8 flags:# contacts:flags.0?true non_contacts:flags.1?true groups:flags.2?true broadcasts:flags.3?true bots:flags.4?true exclude_muted:flags.11?true exclude_read:flags.12?true exclude_archived:flags.13?true id:int title:string emoticon:flags.25?string pinned_peers:Vector include_peers:Vector exclude_peers:Vector = DialogFilter; +dialogFilter#5fb5523b flags:# contacts:flags.0?true non_contacts:flags.1?true groups:flags.2?true broadcasts:flags.3?true bots:flags.4?true exclude_muted:flags.11?true exclude_read:flags.12?true exclude_archived:flags.13?true id:int title:string emoticon:flags.25?string color:flags.27?int pinned_peers:Vector include_peers:Vector exclude_peers:Vector = DialogFilter; dialogFilterDefault#363293ae = DialogFilter; -dialogFilterChatlist#d64a04a8 flags:# has_my_invites:flags.26?true id:int title:string emoticon:flags.25?string pinned_peers:Vector include_peers:Vector = DialogFilter; +dialogFilterChatlist#9fe28ea4 flags:# has_my_invites:flags.26?true id:int title:string emoticon:flags.25?string color:flags.27?int pinned_peers:Vector include_peers:Vector = DialogFilter; dialogFilterSuggested#77744d4a filter:DialogFilter description:string = DialogFilterSuggested; @@ -1243,9 +1289,7 @@ statsGraphAsync#4a27eb2d token:string = StatsGraph; statsGraphError#bedc9822 error:string = StatsGraph; statsGraph#8ea464b6 flags:# json:DataJSON zoom_token:flags.0?string = StatsGraph; -messageInteractionCounters#ad4fc9bd msg_id:int views:int forwards:int = MessageInteractionCounters; - -stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueAndPrev views_per_post:StatsAbsValueAndPrev shares_per_post:StatsAbsValueAndPrev enabled_notifications:StatsPercentValue growth_graph:StatsGraph followers_graph:StatsGraph mute_graph:StatsGraph top_hours_graph:StatsGraph interactions_graph:StatsGraph iv_interactions_graph:StatsGraph views_by_source_graph:StatsGraph new_followers_by_source_graph:StatsGraph languages_graph:StatsGraph recent_message_interactions:Vector = stats.BroadcastStats; +stats.broadcastStats#396ca5fc period:StatsDateRangeDays followers:StatsAbsValueAndPrev views_per_post:StatsAbsValueAndPrev shares_per_post:StatsAbsValueAndPrev reactions_per_post:StatsAbsValueAndPrev views_per_story:StatsAbsValueAndPrev shares_per_story:StatsAbsValueAndPrev reactions_per_story:StatsAbsValueAndPrev enabled_notifications:StatsPercentValue growth_graph:StatsGraph followers_graph:StatsGraph mute_graph:StatsGraph top_hours_graph:StatsGraph interactions_graph:StatsGraph iv_interactions_graph:StatsGraph views_by_source_graph:StatsGraph new_followers_by_source_graph:StatsGraph languages_graph:StatsGraph reactions_by_emotion_graph:StatsGraph story_interactions_graph:StatsGraph story_reactions_by_emotion_graph:StatsGraph recent_posts_interactions:Vector = stats.BroadcastStats; help.promoDataEmpty#98f6ac75 expires:int = help.PromoData; help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector users:Vector psa_type:flags.1?string psa_message:flags.2?string = help.PromoData; @@ -1262,7 +1306,7 @@ statsGroupTopInviter#535f779d user_id:long invitations:int = StatsGroupTopInvite stats.megagroupStats#ef7ff916 period:StatsDateRangeDays members:StatsAbsValueAndPrev messages:StatsAbsValueAndPrev viewers:StatsAbsValueAndPrev posters:StatsAbsValueAndPrev growth_graph:StatsGraph members_graph:StatsGraph new_members_by_source_graph:StatsGraph languages_graph:StatsGraph messages_graph:StatsGraph actions_graph:StatsGraph top_hours_graph:StatsGraph weekdays_graph:StatsGraph top_posters:Vector top_admins:Vector top_inviters:Vector users:Vector = stats.MegagroupStats; -globalPrivacySettings#bea2f424 flags:# archive_and_mute_new_noncontact_peers:flags.0?Bool = GlobalPrivacySettings; +globalPrivacySettings#734c4ccb flags:# archive_and_mute_new_noncontact_peers:flags.0?true keep_archived_unmuted:flags.1?true keep_archived_folders:flags.2?true hide_read_marks:flags.3?true new_noncontact_peers_require_premium:flags.4?true = GlobalPrivacySettings; help.countryCode#4203c5ef flags:# country_code:string prefixes:flags.0?Vector patterns:flags.1?Vector = help.CountryCode; @@ -1277,13 +1321,14 @@ messages.messageViews#b6c4f543 views:Vector chats:Vector use messages.discussionMessage#a6341782 flags:# messages:Vector max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector users:Vector = messages.DiscussionMessage; -messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader; +messageReplyHeader#afbc09db flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector quote_offset:flags.10?int = MessageReplyHeader; +messageReplyStoryHeader#e5af939 peer:Peer story_id:int = MessageReplyHeader; messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies; peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked; -stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats; +stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats; groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall; groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int = GroupCall; @@ -1346,7 +1391,7 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult; account.resetPasswordOk#e926d63e = account.ResetPasswordResult; -sponsoredMessage#fc25b828 flags:# recommended:flags.5?true show_peer_photo:flags.6?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string message:string entities:flags.1?Vector sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage; +sponsoredMessage#4d93a990 flags:# recommended:flags.5?true can_report:flags.12?true random_id:bytes url:string title:string message:string entities:flags.1?Vector photo:flags.6?Photo media:flags.14?MessageMedia color:flags.13?PeerColor button_text:string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage; messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector chats:Vector users:Vector = messages.SponsoredMessages; messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages; @@ -1369,7 +1414,7 @@ auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut reactionCount#a3d1cb80 flags:# chosen_order:flags.0?int reaction:Reaction count:int = ReactionCount; -messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector recent_reactions:flags.1?Vector = MessageReactions; +messageReactions#a339f0b flags:# min:flags.0?true can_see_list:flags.2?true reactions_as_tags:flags.3?true results:Vector recent_reactions:flags.1?Vector top_reactors:flags.4?Vector = MessageReactions; messages.messageReactionsList#31bd492d flags:# count:int reactions:Vector chats:Vector users:Vector next_offset:flags.0?string = messages.MessageReactionsList; @@ -1378,7 +1423,7 @@ availableReaction#c077ec01 flags:# inactive:flags.0?true premium:flags.2?true re messages.availableReactionsNotModified#9f071957 = messages.AvailableReactions; messages.availableReactions#768e3aad hash:int reactions:Vector = messages.AvailableReactions; -messagePeerReaction#8c79b63c flags:# big:flags.0?true unread:flags.1?true peer_id:Peer date:int reaction:Reaction = MessagePeerReaction; +messagePeerReaction#8c79b63c flags:# big:flags.0?true unread:flags.1?true my:flags.2?true peer_id:Peer date:int reaction:Reaction = MessagePeerReaction; groupCallStreamChannel#80eb48af channel:int scale:int last_timestamp_ms:long = GroupCallStreamChannel; @@ -1390,16 +1435,14 @@ attachMenuBotIconColor#4576f3f0 name:string color:int = AttachMenuBotIconColor; attachMenuBotIcon#b2a7386b flags:# name:string icon:Document colors:flags.0?Vector = AttachMenuBotIcon; -attachMenuBot#c8aa2cd2 flags:# inactive:flags.0?true has_settings:flags.1?true request_write_access:flags.2?true bot_id:long short_name:string peer_types:Vector icons:Vector = AttachMenuBot; +attachMenuBot#d90d8dfe flags:# inactive:flags.0?true has_settings:flags.1?true request_write_access:flags.2?true show_in_attach_menu:flags.3?true show_in_side_menu:flags.4?true side_menu_disclaimer_needed:flags.5?true bot_id:long short_name:string peer_types:flags.3?Vector icons:Vector = AttachMenuBot; attachMenuBotsNotModified#f1d88a5c = AttachMenuBots; attachMenuBots#3c4301c0 hash:long bots:Vector users:Vector = AttachMenuBots; attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector = AttachMenuBotsBot; -webViewResultUrl#c14557c query_id:long url:string = WebViewResult; - -simpleWebViewResultUrl#882f76bb url:string = SimpleWebViewResult; +webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true fullscreen:flags.2?true query_id:flags.0?long url:string = WebViewResult; webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent; @@ -1426,15 +1469,24 @@ attachMenuPeerTypeBroadcast#7bfbdefc = AttachMenuPeerType; inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice; inputInvoiceSlug#c326caef slug:string = InputInvoice; +inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; +inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; +inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice; +inputInvoiceStarGift#25d8c1d8 flags:# hide_name:flags.0?true user_id:InputUser gift_id:long message:flags.1?TextWithEntities = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; -messages.transcribedAudio#93752c52 flags:# pending:flags.0?true transcription_id:long text:string = messages.TranscribedAudio; +messages.transcribedAudio#cfb9d957 flags:# pending:flags.0?true transcription_id:long text:string trial_remains_num:flags.1?int trial_remains_until_date:flags.1?int = messages.TranscribedAudio; help.premiumPromo#5334759c status_text:string status_entities:Vector video_sections:Vector videos:Vector period_options:Vector users:Vector = help.PremiumPromo; inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgrade:flags.1?true = InputStorePaymentPurpose; inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentPremiumGiftCode#fb790393 flags:# users:Vector boost_peer:flags.0?InputPeer currency:string amount:long message:flags.1?TextWithEntities = InputStorePaymentPurpose; +inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector countries_iso2:flags.2?Vector prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentStarsGiveaway#751f08fa flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true stars:long boost_peer:InputPeer additional_peers:flags.1?Vector countries_iso2:flags.2?Vector prize_description:flags.4?string random_id:long until_date:int currency:string amount:long users:int = InputStorePaymentPurpose; premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; @@ -1450,6 +1502,7 @@ account.emojiStatuses#90c467d1 hash:long statuses:Vector = account. reactionEmpty#79f5d419 = Reaction; reactionEmoji#1b2286b8 emoticon:string = Reaction; reactionCustomEmoji#8935fc73 document_id:long = Reaction; +reactionPaid#523da4eb = Reaction; chatReactionsNone#eafc32bc = ChatReactions; chatReactionsAll#52928bca flags:# allow_custom:flags.0?true = ChatReactions; @@ -1497,6 +1550,8 @@ emojiListNotModified#481eadfa = EmojiList; emojiList#7a1e11d1 hash:long document_id:Vector = EmojiList; emojiGroup#7a9abda9 title:string icon_emoji_id:long emoticons:Vector = EmojiGroup; +emojiGroupGreeting#80d26cc7 title:string icon_emoji_id:long emoticons:Vector = EmojiGroup; +emojiGroupPremium#93bcf34 title:string icon_emoji_id:long = EmojiGroup; messages.emojiGroupsNotModified#6fb4ad87 = messages.EmojiGroups; messages.emojiGroups#881fb94b hash:int groups:Vector = messages.EmojiGroups; @@ -1520,9 +1575,7 @@ inputBotAppShortName#908c0407 bot_id:InputUser short_name:string = InputBotApp; botAppNotModified#5da674b7 = BotApp; botApp#95fcd1d6 flags:# id:long access_hash:long short_name:string title:string description:string photo:Photo document:flags.0?Document hash:long = BotApp; -messages.botApp#eb50adf5 flags:# inactive:flags.0?true request_write_access:flags.1?true app:BotApp = messages.BotApp; - -appWebViewResultUrl#3c1b4f0d url:string = AppWebViewResult; +messages.botApp#eb50adf5 flags:# inactive:flags.0?true request_write_access:flags.1?true has_settings:flags.2?true app:BotApp = messages.BotApp; inlineBotWebView#b57295d5 text:string url:string = InlineBotWebView; @@ -1543,6 +1596,313 @@ chatlists.chatlistUpdates#93bd878d missing_peers:Vector chats:Vector bots.botInfo#e8a775b0 name:string about:string description:string = bots.BotInfo; +messagePeerVote#b6cc2d5c peer:Peer option:bytes date:int = MessagePeerVote; +messagePeerVoteInputOption#74cda504 peer:Peer date:int = MessagePeerVote; +messagePeerVoteMultiple#4628f6e6 peer:Peer options:Vector date:int = MessagePeerVote; + +storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_count:flags.2?int reactions:flags.3?Vector reactions_count:flags.4?int recent_viewers:flags.0?Vector = StoryViews; + +storyItemDeleted#51e6ee4f id:int = StoryItem; +storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem; +storyItem#79b26a24 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int from_id:flags.18?Peer fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector media:MessageMedia media_areas:flags.14?Vector privacy:flags.2?Vector views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem; + +stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories; +stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector chats:Vector users:Vector stealth_mode:StoriesStealthMode = stories.AllStories; + +stories.stories#63c3dd0a flags:# count:int stories:Vector pinned_to_top:flags.0?Vector chats:Vector users:Vector = stories.Stories; + +storyView#b0bdeac5 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true user_id:long date:int reaction:flags.2?Reaction = StoryView; +storyViewPublicForward#9083670b flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true message:Message = StoryView; +storyViewPublicRepost#bd74cf49 flags:# blocked:flags.0?true blocked_my_stories_from:flags.1?true peer_id:Peer story:StoryItem = StoryView; + +stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count:int reactions_count:int views:Vector chats:Vector users:Vector next_offset:flags.0?string = stories.StoryViewsList; + +stories.storyViews#de9eed1d views:Vector users:Vector = stories.StoryViews; + +inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector quote_offset:flags.4?int = InputReplyTo; +inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo; + +exportedStoryLink#3fc9053b link:string = ExportedStoryLink; + +storiesStealthMode#712e27fd flags:# active_until_date:flags.0?int cooldown_until_date:flags.1?int = StoriesStealthMode; + +mediaAreaCoordinates#cfc9e002 flags:# x:double y:double w:double h:double rotation:double radius:flags.0?double = MediaAreaCoordinates; + +mediaAreaVenue#be82db9c coordinates:MediaAreaCoordinates geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MediaArea; +inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea; +mediaAreaGeoPoint#cad5452d flags:# coordinates:MediaAreaCoordinates geo:GeoPoint address:flags.0?GeoPointAddress = MediaArea; +mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea; +mediaAreaChannelPost#770416af coordinates:MediaAreaCoordinates channel_id:long msg_id:int = MediaArea; +inputMediaAreaChannelPost#2271f2bf coordinates:MediaAreaCoordinates channel:InputChannel msg_id:int = MediaArea; +mediaAreaUrl#37381085 coordinates:MediaAreaCoordinates url:string = MediaArea; +mediaAreaWeather#49a6549c coordinates:MediaAreaCoordinates emoji:string temperature_c:double color:int = MediaArea; + +peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector = PeerStories; + +stories.peerStories#cae68768 stories:PeerStories chats:Vector users:Vector = stories.PeerStories; + +messages.webPage#fd5e12bd webpage:WebPage chats:Vector users:Vector = messages.WebPage; + +premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption; + +payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector users:Vector = payments.CheckedGiftCode; + +payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; +payments.giveawayInfoResults#e175e66f flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.3?string stars_prize:flags.4?long finish_date:int winners_count:int activated_count:flags.2?int = payments.GiveawayInfo; + +prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway; +prepaidStarsGiveaway#9a9d77e0 id:long stars:long quantity:int boosts:int date:int = PrepaidGiveaway; + +boost#4b3e14d6 flags:# gift:flags.1?true giveaway:flags.2?true unclaimed:flags.3?true id:string user_id:flags.0?long giveaway_msg_id:flags.2?int date:int expires:int used_gift_slug:flags.4?string multiplier:flags.5?int stars:flags.6?long = Boost; + +premium.boostsList#86f8613c flags:# count:int boosts:Vector next_offset:flags.0?string users:Vector = premium.BoostsList; + +myBoost#c448415c flags:# slot:int peer:flags.0?Peer date:int expires:int cooldown_until_date:flags.1?int = MyBoost; + +premium.myBoosts#9ae228e2 my_boosts:Vector chats:Vector users:Vector = premium.MyBoosts; + +premium.boostsStatus#4959427a flags:# my_boost:flags.2?true level:int current_level_boosts:int boosts:int gift_boosts:flags.4?int next_level_boosts:flags.0?int premium_audience:flags.1?StatsPercentValue boost_url:string prepaid_giveaways:flags.3?Vector my_boost_slots:flags.2?Vector = premium.BoostsStatus; + +storyFwdHeader#b826e150 flags:# modified:flags.3?true from:flags.0?Peer from_name:flags.1?string story_id:flags.2?int = StoryFwdHeader; + +postInteractionCountersMessage#e7058e7f msg_id:int views:int forwards:int reactions:int = PostInteractionCounters; +postInteractionCountersStory#8a480e27 story_id:int views:int forwards:int reactions:int = PostInteractionCounters; + +stats.storyStats#50cd067c views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.StoryStats; + +publicForwardMessage#1f2bf4a message:Message = PublicForward; +publicForwardStory#edf3add0 peer:Peer story:StoryItem = PublicForward; + +stats.publicForwards#93037e20 flags:# count:int forwards:Vector next_offset:flags.0?string chats:Vector users:Vector = stats.PublicForwards; + +peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = PeerColor; + +help.peerColorSet#26219a58 colors:Vector = help.PeerColorSet; +help.peerColorProfileSet#767d61eb palette_colors:Vector bg_colors:Vector story_colors:Vector = help.PeerColorSet; + +help.peerColorOption#adec6ebe flags:# hidden:flags.0?true color_id:int colors:flags.1?help.PeerColorSet dark_colors:flags.2?help.PeerColorSet channel_min_level:flags.3?int group_min_level:flags.4?int = help.PeerColorOption; + +help.peerColorsNotModified#2ba1f5ce = help.PeerColors; +help.peerColors#f8ed08 hash:int colors:Vector = help.PeerColors; + +storyReaction#6090d6d5 peer_id:Peer date:int reaction:Reaction = StoryReaction; +storyReactionPublicForward#bbab2643 message:Message = StoryReaction; +storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction; + +stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector chats:Vector users:Vector next_offset:flags.0?string = stories.StoryReactionsList; + +savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog; + +messages.savedDialogs#f83ae221 dialogs:Vector messages:Vector chats:Vector users:Vector = messages.SavedDialogs; +messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector messages:Vector chats:Vector users:Vector = messages.SavedDialogs; +messages.savedDialogsNotModified#c01f6fe8 count:int = messages.SavedDialogs; + +savedReactionTag#cb6ff828 flags:# reaction:Reaction title:flags.0?string count:int = SavedReactionTag; + +messages.savedReactionTagsNotModified#889b59ef = messages.SavedReactionTags; +messages.savedReactionTags#3259950a tags:Vector hash:long = messages.SavedReactionTags; + +outboxReadDate#3bb842ac date:int = OutboxReadDate; + +smsjobs.eligibleToJoin#dc8b44cf terms_url:string monthly_sent_sms:int = smsjobs.EligibilityToJoin; + +smsjobs.status#2aee9191 flags:# allow_international:flags.0?true recent_sent:int recent_since:int recent_remains:int total_sent:int total_since:int last_gift_slug:flags.1?string terms_url:string = smsjobs.Status; + +smsJob#e6a1eeb8 job_id:string phone_number:string text:string = SmsJob; + +businessWeeklyOpen#120b1ab9 start_minute:int end_minute:int = BusinessWeeklyOpen; + +businessWorkHours#8c92b098 flags:# open_now:flags.0?true timezone_id:string weekly_open:Vector = BusinessWorkHours; + +businessLocation#ac5c1af7 flags:# geo_point:flags.0?GeoPoint address:string = BusinessLocation; + +inputBusinessRecipients#6f8b32aa flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector = InputBusinessRecipients; + +businessRecipients#21108ff7 flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector = BusinessRecipients; + +businessAwayMessageScheduleAlways#c9b9e2b9 = BusinessAwayMessageSchedule; +businessAwayMessageScheduleOutsideWorkHours#c3f2f501 = BusinessAwayMessageSchedule; +businessAwayMessageScheduleCustom#cc4d9ecc start_date:int end_date:int = BusinessAwayMessageSchedule; + +inputBusinessGreetingMessage#194cb3b shortcut_id:int recipients:InputBusinessRecipients no_activity_days:int = InputBusinessGreetingMessage; + +businessGreetingMessage#e519abab shortcut_id:int recipients:BusinessRecipients no_activity_days:int = BusinessGreetingMessage; + +inputBusinessAwayMessage#832175e0 flags:# offline_only:flags.0?true shortcut_id:int schedule:BusinessAwayMessageSchedule recipients:InputBusinessRecipients = InputBusinessAwayMessage; + +businessAwayMessage#ef156a5c flags:# offline_only:flags.0?true shortcut_id:int schedule:BusinessAwayMessageSchedule recipients:BusinessRecipients = BusinessAwayMessage; + +timezone#ff9289f5 id:string name:string utc_offset:int = Timezone; + +help.timezonesListNotModified#970708cc = help.TimezonesList; +help.timezonesList#7b74ed71 timezones:Vector hash:int = help.TimezonesList; + +quickReply#697102b shortcut_id:int shortcut:string top_message:int count:int = QuickReply; + +inputQuickReplyShortcut#24596d41 shortcut:string = InputQuickReplyShortcut; +inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut; + +messages.quickReplies#c68d6695 quick_replies:Vector messages:Vector chats:Vector users:Vector = messages.QuickReplies; +messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies; + +connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot; + +account.connectedBots#17d7f87b connected_bots:Vector users:Vector = account.ConnectedBots; + +messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector = messages.DialogFilters; + +birthday#6c8e1e06 flags:# day:int month:int year:flags.0?int = Birthday; + +botBusinessConnection#896433b4 flags:# can_reply:flags.0?true disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int = BotBusinessConnection; + +inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro; + +businessIntro#5a0a066d flags:# title:string description:string sticker:flags.0?Document = BusinessIntro; + +messages.myStickers#faff629d count:int sets:Vector = messages.MyStickers; + +inputCollectibleUsername#e39460a9 username:string = InputCollectible; +inputCollectiblePhone#a2e214a4 phone:string = InputCollectible; + +fragment.collectibleInfo#6ebdff91 purchase_date:int currency:string amount:long crypto_currency:string crypto_amount:long url:string = fragment.CollectibleInfo; + +inputBusinessBotRecipients#c4e5921e flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector exclude_users:flags.6?Vector = InputBusinessBotRecipients; + +businessBotRecipients#b88cf373 flags:# existing_chats:flags.0?true new_chats:flags.1?true contacts:flags.2?true non_contacts:flags.3?true exclude_selected:flags.5?true users:flags.4?Vector exclude_users:flags.6?Vector = BusinessBotRecipients; + +contactBirthday#1d998733 contact_id:long birthday:Birthday = ContactBirthday; + +contacts.contactBirthdays#114ff30d contacts:Vector users:Vector = contacts.ContactBirthdays; + +missingInvitee#628c9224 flags:# premium_would_allow_invite:flags.0?true premium_required_for_pm:flags.1?true user_id:long = MissingInvitee; + +messages.invitedUsers#7f5defa6 updates:Updates missing_invitees:Vector = messages.InvitedUsers; + +inputBusinessChatLink#11679fa7 flags:# message:string entities:flags.0?Vector title:flags.1?string = InputBusinessChatLink; + +businessChatLink#b4ae666f flags:# link:string message:string entities:flags.0?Vector title:flags.1?string views:int = BusinessChatLink; + +account.businessChatLinks#ec43a2d1 links:Vector chats:Vector users:Vector = account.BusinessChatLinks; + +account.resolvedBusinessChatLinks#9a23af21 flags:# peer:Peer message:string entities:flags.0?Vector chats:Vector users:Vector = account.ResolvedBusinessChatLinks; + +requestedPeerUser#d62ff46a flags:# user_id:long first_name:flags.0?string last_name:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer; +requestedPeerChat#7307544f flags:# chat_id:long title:flags.0?string photo:flags.2?Photo = RequestedPeer; +requestedPeerChannel#8ba403e4 flags:# channel_id:long title:flags.0?string username:flags.1?string photo:flags.2?Photo = RequestedPeer; + +sponsoredMessageReportOption#430d3150 text:string option:bytes = SponsoredMessageReportOption; + +channels.sponsoredMessageReportResultChooseOption#846f9e42 title:string options:Vector = channels.SponsoredMessageReportResult; +channels.sponsoredMessageReportResultAdsHidden#3e3bcf2f = channels.SponsoredMessageReportResult; +channels.sponsoredMessageReportResultReported#ad798849 = channels.SponsoredMessageReportResult; + +stats.broadcastRevenueStats#5407e297 top_hours_graph:StatsGraph revenue_graph:StatsGraph balances:BroadcastRevenueBalances usd_rate:double = stats.BroadcastRevenueStats; + +stats.broadcastRevenueWithdrawalUrl#ec659737 url:string = stats.BroadcastRevenueWithdrawalUrl; + +broadcastRevenueTransactionProceeds#557e2cc4 amount:long from_date:int to_date:int = BroadcastRevenueTransaction; +broadcastRevenueTransactionWithdrawal#5a590978 flags:# pending:flags.0?true failed:flags.2?true amount:long date:int provider:string transaction_date:flags.1?int transaction_url:flags.1?string = BroadcastRevenueTransaction; +broadcastRevenueTransactionRefund#42d30d2e amount:long date:int provider:string = BroadcastRevenueTransaction; + +stats.broadcastRevenueTransactions#87158466 count:int transactions:Vector = stats.BroadcastRevenueTransactions; + +reactionNotificationsFromContacts#bac3a61a = ReactionNotificationsFrom; +reactionNotificationsFromAll#4b9e22a0 = ReactionNotificationsFrom; + +reactionsNotifySettings#56e34970 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings; + +broadcastRevenueBalances#c3ff71e7 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long = BroadcastRevenueBalances; + +availableEffect#93c3e27e flags:# premium_required:flags.2?true id:long emoticon:string static_icon_id:flags.0?long effect_sticker_id:long effect_animation_id:flags.1?long = AvailableEffect; + +messages.availableEffectsNotModified#d1ed9a5b = messages.AvailableEffects; +messages.availableEffects#bddb616e hash:int effects:Vector documents:Vector = messages.AvailableEffects; + +factCheck#b89bfccf flags:# need_check:flags.0?true country:flags.1?string text:flags.1?TextWithEntities hash:long = FactCheck; + +starsTransactionPeerUnsupported#95f2bfe4 = StarsTransactionPeer; +starsTransactionPeerAppStore#b457b375 = StarsTransactionPeer; +starsTransactionPeerPlayMarket#7b560a0b = StarsTransactionPeer; +starsTransactionPeerPremiumBot#250dbaf8 = StarsTransactionPeer; +starsTransactionPeerFragment#e92fd902 = StarsTransactionPeer; +starsTransactionPeer#d80da15d peer:Peer = StarsTransactionPeer; +starsTransactionPeerAds#60682812 = StarsTransactionPeer; +starsTransactionPeerAPI#f9677aad = StarsTransactionPeer; + +starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; + +starsTransaction#64dfc926 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true id:string stars:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount = StarsTransaction; + +payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; + +foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory; + +stories.foundStories#e2de7737 flags:# count:int stories:Vector next_offset:flags.0?string chats:Vector users:Vector = stories.FoundStories; + +geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress; + +starsRevenueStatus#febe5491 flags:# withdrawal_enabled:flags.0?true current_balance:StarsAmount available_balance:StarsAmount overall_revenue:StarsAmount next_withdrawal_at:flags.1?int = StarsRevenueStatus; + +payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats; + +payments.starsRevenueWithdrawalUrl#1dab80b7 url:string = payments.StarsRevenueWithdrawalUrl; + +payments.starsRevenueAdsAccountUrl#394e7f21 url:string = payments.StarsRevenueAdsAccountUrl; + +inputStarsTransaction#206ae6d1 flags:# refund:flags.0?true id:string = InputStarsTransaction; + +starsGiftOption#5e0589f1 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsGiftOption; + +bots.popularAppBots#1991b13b flags:# next_offset:flags.0?string users:Vector = bots.PopularAppBots; + +botPreviewMedia#23e91ba3 date:int media:MessageMedia = BotPreviewMedia; + +bots.previewInfo#ca71d64 media:Vector lang_codes:Vector = bots.PreviewInfo; + +starsSubscriptionPricing#5416d58 period:int amount:long = StarsSubscriptionPricing; + +starsSubscription#2e6eab1a flags:# canceled:flags.0?true can_refulfill:flags.1?true missing_balance:flags.2?true bot_canceled:flags.7?true id:string peer:Peer until_date:int pricing:StarsSubscriptionPricing chat_invite_hash:flags.3?string title:flags.4?string photo:flags.5?WebDocument invoice_slug:flags.6?string = StarsSubscription; + +messageReactor#4ba3a95a flags:# top:flags.0?true my:flags.1?true anonymous:flags.2?true peer_id:flags.3?Peer count:int = MessageReactor; + +starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true stars:long yearly_boosts:int store_product:flags.2?string currency:string amount:long winners:Vector = StarsGiveawayOption; + +starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; + +starGift#49c577cd flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int = StarGift; + +payments.starGiftsNotModified#a388a368 = payments.StarGifts; +payments.starGifts#901689ea hash:int gifts:Vector = payments.StarGifts; + +userStarGift#eea49a6e flags:# name_hidden:flags.0?true unsaved:flags.5?true from_id:flags.1?long date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int convert_stars:flags.4?long = UserStarGift; + +payments.userStarGifts#6b65b517 flags:# count:int gifts:Vector next_offset:flags.0?string users:Vector = payments.UserStarGifts; + +messageReportOption#7903e3d9 text:string option:bytes = MessageReportOption; + +reportResultChooseOption#f0e4e0b6 title:string options:Vector = ReportResult; +reportResultAddComment#6f09ac31 flags:# optional:flags.0?true option:bytes = ReportResult; +reportResultReported#8db33c4b = ReportResult; + +messages.botPreparedInlineMessage#8ecf0511 id:string expire_date:int = messages.BotPreparedInlineMessage; + +messages.preparedInlineMessage#ff57708d query_id:long result:BotInlineResult peer_types:Vector cache_time:int users:Vector = messages.PreparedInlineMessage; + +botAppSettings#c99b1950 flags:# placeholder_path:flags.0?bytes background_color:flags.1?int background_dark_color:flags.2?int header_color:flags.3?int header_dark_color:flags.4?int = BotAppSettings; + +starRefProgram#dd0c66f2 flags:# bot_id:long commission_permille:int duration_months:flags.0?int end_date:flags.1?int daily_revenue_per_user:flags.2?StarsAmount = StarRefProgram; + +connectedBotStarRef#19a13f71 flags:# revoked:flags.1?true url:string date:int bot_id:long commission_permille:int duration_months:flags.0?int participants:long revenue:long = ConnectedBotStarRef; + +payments.connectedStarRefBots#98d5ea1d count:int connected_bots:Vector users:Vector = payments.ConnectedStarRefBots; + +payments.suggestedStarRefBots#b4d5d859 flags:# count:int suggested_bots:Vector users:Vector next_offset:flags.0?string = payments.SuggestedStarRefBots; + +starsAmount#bbb6b4a3 amount:long nanos:int = StarsAmount; + +messages.foundStickersNotModified#6010c534 flags:# next_offset:flags.0?int = messages.FoundStickers; +messages.foundStickers#82c9e290 flags:# next_offset:flags.0?int hash:long stickers:Vector = messages.FoundStickers; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1552,9 +1912,12 @@ invokeWithLayer#da9b0d0d {X:Type} layer:int query:!X = X; invokeWithoutUpdates#bf9459b7 {X:Type} query:!X = X; invokeWithMessagesRange#365275f2 {X:Type} range:MessageRange query:!X = X; invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X; +invokeWithBusinessConnection#dd289f8e {X:Type} connection_id:string query:!X = X; +invokeWithGooglePlayIntegrity#1df92984 {X:Type} nonce:string token:string query:!X = X; +invokeWithApnsSecret#0dae54f8 {X:Type} nonce:string secret:string query:!X = X; auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode; -auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization; +auth.signUp#aac7b717 flags:# no_joined_notifications:flags.0?true phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization; auth.signIn#8d52a951 flags:# phone_number:string phone_code_hash:string phone_code:flags.0?string email_verification:flags.1?EmailVerification = auth.Authorization; auth.logOut#3e72ba19 = auth.LoggedOut; auth.resetAuthorizations#9fab0d1a = Bool; @@ -1565,7 +1928,7 @@ auth.importBotAuthorization#67a3ff2c flags:int api_id:int api_hash:string bot_au auth.checkPassword#d18b4d16 password:InputCheckPasswordSRP = auth.Authorization; auth.requestPasswordRecovery#d897bc66 = auth.PasswordRecovery; auth.recoverPassword#37096c70 flags:# code:string new_settings:flags.0?account.PasswordInputSettings = auth.Authorization; -auth.resendCode#3ef1a9bf phone_number:string phone_code_hash:string = auth.SentCode; +auth.resendCode#cae47523 flags:# phone_number:string phone_code_hash:string reason:flags.0?string = auth.SentCode; auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool; auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector = Bool; auth.exportLoginToken#b7e085fe api_id:int api_hash:string except_ids:Vector = auth.LoginToken; @@ -1573,8 +1936,9 @@ auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken; auth.acceptLoginToken#e894ad4d token:bytes = Authorization; auth.checkRecoveryPassword#d36bf79 code:string = Bool; auth.importWebTokenAuthorization#2db873a9 api_id:int api_hash:string web_auth_token:string = auth.Authorization; -auth.requestFirebaseSms#89464b50 flags:# phone_number:string phone_code_hash:string safety_net_token:flags.0?string ios_push_secret:flags.1?string = Bool; +auth.requestFirebaseSms#8e39261e flags:# phone_number:string phone_code_hash:string safety_net_token:flags.0?string play_integrity_token:flags.2?string ios_push_secret:flags.1?string = Bool; auth.resetLoginEmail#7e960193 phone_number:string phone_code_hash:string = auth.SentCode; +auth.reportMissingCode#cb9deff6 phone_number:string phone_code_hash:string mnc:string = Bool; account.registerDevice#ec86017a flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector = Bool; account.unregisterDevice#6a0d3206 token_type:int token:string other_uids:Vector = Bool; @@ -1623,7 +1987,7 @@ account.resendPasswordEmail#7a7f2a15 = Bool; account.cancelPasswordEmail#c1cbd5b6 = Bool; account.getContactSignUpNotification#9f07c728 = Bool; account.setContactSignUpNotification#cff43f61 silent:Bool = Bool; -account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true peer:flags.0?InputNotifyPeer = Updates; +account.getNotifyExceptions#53577479 flags:# compare_sound:flags.1?true compare_stories:flags.2?true peer:flags.0?InputNotifyPeer = Updates; account.getWallPaper#fc8ddbea wallpaper:InputWallPaper = WallPaper; account.uploadWallPaper#e39a8f03 flags:# for_chat:flags.0?true file:InputFile mime_type:string settings:WallPaperSettings = WallPaper; account.saveWallPaper#6c5a5b37 wallpaper:InputWallPaper unsave:Bool settings:WallPaperSettings = Bool; @@ -1648,7 +2012,7 @@ account.resetPassword#9308ce1b = account.ResetPasswordResult; account.declinePasswordReset#4c9409f6 = Bool; account.getChatThemes#d638de89 hash:long = account.Themes; account.setAuthorizationTTL#bf899aa0 authorization_ttl_days:int = Bool; -account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_requests_disabled:flags.0?Bool call_requests_disabled:flags.1?Bool = Bool; +account.changeAuthorizationSettings#40f48462 flags:# confirmed:flags.3?true hash:long encrypted_requests_disabled:flags.0?Bool call_requests_disabled:flags.1?Bool = Bool; account.getSavedRingtones#e1902288 hash:long = account.SavedRingtones; account.saveRingtone#3dea5b03 id:InputDocument unsave:Bool = account.SavedRingtone; account.uploadRingtone#831a83a2 file:InputFile file_name:string mime_type:string = Document; @@ -1663,10 +2027,36 @@ account.getDefaultGroupPhotoEmojis#915860ae hash:long = EmojiList; account.getAutoSaveSettings#adcbbcda = account.AutoSaveSettings; account.saveAutoSaveSettings#d69b8361 flags:# users:flags.0?true chats:flags.1?true broadcasts:flags.2?true peer:flags.3?InputPeer settings:AutoSaveSettings = Bool; account.deleteAutoSaveExceptions#53bc0020 = Bool; +account.invalidateSignInCodes#ca8ae8ba codes:Vector = Bool; +account.updateColor#7cefa15d flags:# for_profile:flags.1?true color:flags.2?int background_emoji_id:flags.0?long = Bool; +account.getDefaultBackgroundEmojis#a60ab9ce hash:long = EmojiList; +account.getChannelDefaultEmojiStatuses#7727a7d5 hash:long = account.EmojiStatuses; +account.getChannelRestrictedStatusEmojis#35a9e0d5 hash:long = EmojiList; +account.updateBusinessWorkHours#4b00e066 flags:# business_work_hours:flags.0?BusinessWorkHours = Bool; +account.updateBusinessLocation#9e6b131a flags:# geo_point:flags.1?InputGeoPoint address:flags.0?string = Bool; +account.updateBusinessGreetingMessage#66cdafc4 flags:# message:flags.0?InputBusinessGreetingMessage = Bool; +account.updateBusinessAwayMessage#a26a7fa5 flags:# message:flags.0?InputBusinessAwayMessage = Bool; +account.updateConnectedBot#43d8521d flags:# can_reply:flags.0?true deleted:flags.1?true bot:InputUser recipients:InputBusinessBotRecipients = Updates; +account.getConnectedBots#4ea4c80f = account.ConnectedBots; +account.getBotBusinessConnection#76a86270 connection_id:string = Updates; +account.updateBusinessIntro#a614d034 flags:# intro:flags.0?InputBusinessIntro = Bool; +account.toggleConnectedBotPaused#646e1097 peer:InputPeer paused:Bool = Bool; +account.disablePeerConnectedBot#5e437ed9 peer:InputPeer = Bool; +account.updateBirthday#cc6e0c11 flags:# birthday:flags.0?Birthday = Bool; +account.createBusinessChatLink#8851e68e link:InputBusinessChatLink = BusinessChatLink; +account.editBusinessChatLink#8c3410af slug:string link:InputBusinessChatLink = BusinessChatLink; +account.deleteBusinessChatLink#60073674 slug:string = Bool; +account.getBusinessChatLinks#6f70dde1 = account.BusinessChatLinks; +account.resolveBusinessChatLink#5492e5ee slug:string = account.ResolvedBusinessChatLinks; +account.updatePersonalChannel#d94305e0 channel:InputChannel = Bool; +account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool; +account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings; +account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings; users.getUsers#d91a548 id:Vector = Vector; users.getFullUser#b60f5918 id:InputUser = users.UserFull; users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector = Bool; +users.getIsPremiumRequiredToContact#a622aa10 id:Vector = Vector; contacts.getContactIDs#7adc669d hash:long = Vector; contacts.getStatuses#c4a353ee = Vector; @@ -1674,12 +2064,12 @@ contacts.getContacts#5dd69e12 hash:long = contacts.Contacts; contacts.importContacts#2c800be5 contacts:Vector = contacts.ImportedContacts; contacts.deleteContacts#96a0e00 id:Vector = Updates; contacts.deleteByPhones#1013fd9e phones:Vector = Bool; -contacts.block#68cc1411 id:InputPeer = Bool; -contacts.unblock#bea65d50 id:InputPeer = Bool; -contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked; +contacts.block#2e2e8734 flags:# my_stories_from:flags.0?true id:InputPeer = Bool; +contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bool; +contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked; contacts.search#11f812d8 q:string limit:int = contacts.Found; -contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; -contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:long = contacts.TopPeers; +contacts.resolveUsername#725afbbc flags:# username:string referer:flags.0?string = contacts.ResolvedPeer; +contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers; contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool; contacts.resetSaved#879537f1 = Bool; contacts.getSaved#82f1e39f = Vector; @@ -1691,29 +2081,32 @@ contacts.blockFromReplies#29a8962c flags:# delete_message:flags.0?true delete_hi contacts.resolvePhone#8af94344 phone:string = contacts.ResolvedPeer; contacts.exportContactToken#f8654027 = ExportedContactToken; contacts.importContactToken#13005788 token:string = User; +contacts.editCloseFriends#ba6705f0 id:Vector = Bool; +contacts.setBlocked#94c65c76 flags:# my_stories_from:flags.0?true id:Vector limit:int = Bool; +contacts.getBirthdays#daeda864 = contacts.ContactBirthdays; messages.getMessages#63c66506 id:Vector = messages.Messages; messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.Dialogs; messages.getHistory#4423e6c5 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages; -messages.search#a0fda762 flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages; +messages.search#29ee847a flags:# peer:InputPeer q:string from_id:flags.0?InputPeer saved_peer_id:flags.2?InputPeer saved_reaction:flags.3?Vector top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages; messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages; messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory; messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; -messages.sendMessage#1cc20387 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; -messages.sendMedia#7547c966 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; -messages.forwardMessages#c661bbc4 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMessage#983f9745 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; +messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; +messages.forwardMessages#d5039208 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; -messages.report#8953ab4e peer:InputPeer id:Vector reason:ReportReason message:string = Bool; +messages.report#fc78af9b peer:InputPeer id:Vector option:bytes message:string = ReportResult; messages.getChats#49e9528f id:Vector = messages.Chats; messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull; messages.editChatTitle#73783ffd chat_id:long title:string = Updates; messages.editChatPhoto#35ddd674 chat_id:long photo:InputChatPhoto = Updates; -messages.addChatUser#f24753e3 chat_id:long user_id:InputUser fwd_limit:int = Updates; +messages.addChatUser#cbc6d107 chat_id:long user_id:InputUser fwd_limit:int = messages.InvitedUsers; messages.deleteChatUser#a2185cab flags:# revoke_history:flags.0?true chat_id:long user_id:InputUser = Updates; -messages.createChat#34a818 flags:# users:Vector title:string ttl_period:flags.0?int = Updates; +messages.createChat#92ceddd4 flags:# users:Vector title:string ttl_period:flags.0?int = messages.InvitedUsers; messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig; messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat; messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat; @@ -1729,7 +2122,7 @@ messages.readMessageContents#36a73f77 id:Vector = messages.AffectedMessages messages.getStickers#d5a5d3a1 emoticon:string hash:long = messages.Stickers; messages.getAllStickers#b8a0a1a8 hash:long = messages.AllStickers; messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector = MessageMedia; -messages.exportChatInvite#a02ce5d5 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string = ExportedChatInvite; +messages.exportChatInvite#a455de90 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string subscription_pricing:flags.5?StarsSubscriptionPricing = ExportedChatInvite; messages.checkChatInvite#3eadb1bb hash:string = ChatInvite; messages.importChatInvite#6c50051c hash:string = Updates; messages.getStickerSet#c8a0ec74 stickerset:InputStickerSet hash:int = messages.StickerSet; @@ -1739,21 +2132,21 @@ messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_par messages.getMessagesViews#5784d3e1 peer:InputPeer id:Vector increment:Bool = messages.MessageViews; messages.editChatAdmin#a85bd1c2 chat_id:long user_id:InputUser is_admin:Bool = Bool; messages.migrateChat#a2875319 chat_id:long = Updates; -messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; +messages.searchGlobal#4bc6589a flags:# broadcasts_only:flags.1?true folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; messages.reorderStickerSets#78337739 flags:# masks:flags.0?true emojis:flags.1?true order:Vector = Bool; messages.getDocumentByHash#b1f2061f sha256:bytes size:long mime_type:string = Document; messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs; messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool; messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults; messages.setInlineBotResults#bb12a419 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM switch_webview:flags.4?InlineBotWebView = Bool; -messages.sendInlineBotResult#d3fbdccb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendInlineBotResult#3ebee86a flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to:flags.0?InputReplyTo random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut = Updates; messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData; -messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.15?int = Updates; -messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Bool; +messages.editMessage#dfd14005 flags:# no_webpage:flags.1?true invert_media:flags.16?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.15?int quick_reply_shortcut_id:flags.17?int = Updates; +messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true invert_media:flags.16?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Bool; messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = 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#e470bcfd peers:Vector = messages.PeerDialogs; -messages.saveDraft#b4331e3f flags:# no_webpage:flags.1?true reply_to_msg_id:flags.0?int top_msg_id:flags.2?int peer:InputPeer message:string entities:flags.3?Vector = Bool; +messages.saveDraft#d372c5ce flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo peer:InputPeer message:string entities:flags.3?Vector media:flags.5?InputMedia effect:flags.7?long = Bool; messages.getAllDrafts#6a3f8d65 = Updates; messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers; messages.readFeaturedStickers#5b118126 id:Vector = Bool; @@ -1768,21 +2161,20 @@ messages.setInlineGameScore#15ad9f64 flags:# edit_message:flags.0?true force:fla messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores; messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores; messages.getCommonChats#e40ca104 user_id:InputUser max_id:long limit:int = messages.Chats; -messages.getAllChats#875f74be except_ids:Vector = messages.Chats; -messages.getWebPage#32ca8f91 url:string hash:int = WebPage; +messages.getWebPage#8d9692a3 url:string hash:int = messages.WebPage; messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool; messages.reorderPinnedDialogs#3b1adf37 flags:# force:flags.0?true folder_id:int order:Vector = Bool; messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs; messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector = Bool; messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool; -messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia; -messages.sendScreenshotNotification#c97df020 peer:InputPeer reply_to_msg_id:int random_id:long = Updates; +messages.uploadMedia#14967978 flags:# business_connection_id:flags.0?string peer:InputPeer media:InputMedia = MessageMedia; +messages.sendScreenshotNotification#a1405817 peer:InputPeer reply_to:InputReplyTo random_id:long = Updates; messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers; messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool; messages.getUnreadMentions#f107e790 flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.readMentions#36e5bf4d flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory; messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages; -messages.sendMultiMedia#b6f11a1c flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMultiMedia#37b74355 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates; messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile; messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; messages.getSplitRanges#1cff7e08 = Vector; @@ -1799,7 +2191,7 @@ messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference; messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference; messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector = Vector; messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL; -messages.getSearchCounters#ae7cc1 flags:# peer:InputPeer top_msg_id:flags.0?int filters:Vector = Vector; +messages.getSearchCounters#1bbcf300 flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer top_msg_id:flags.0?int filters:Vector = Vector; messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult; messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult; messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool; @@ -1809,7 +2201,7 @@ messages.sendScheduledMessages#bd38850a peer:InputPeer id:Vector = Updates; messages.deleteScheduledMessages#59ae2b16 peer:InputPeer id:Vector = Updates; messages.getPollVotes#b86e380e flags:# peer:InputPeer id:int option:flags.0?bytes offset:flags.1?string limit:int = messages.VotesList; messages.toggleStickerSets#b5052fea flags:# uninstall:flags.0?true archive:flags.1?true unarchive:flags.2?true stickersets:Vector = Bool; -messages.getDialogFilters#f19ed96d = Vector; +messages.getDialogFilters#efd48c89 = messages.DialogFilters; messages.getSuggestedDialogFilters#a29cd42c = Vector; messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool; messages.updateDialogFiltersOrder#c563c1e4 order:Vector = Bool; @@ -1830,13 +2222,13 @@ messages.editExportedChatInvite#bdca2f75 flags:# revoked:flags.2?true peer:Input messages.deleteRevokedExportedChatInvites#56987bd5 peer:InputPeer admin_id:InputUser = Bool; messages.deleteExportedChatInvite#d464a42b peer:InputPeer link:string = Bool; messages.getAdminsWithInvites#3920e6ef peer:InputPeer = messages.ChatAdminsWithInvites; -messages.getChatInviteImporters#df04dd4e flags:# requested:flags.0?true peer:InputPeer link:flags.1?string q:flags.2?string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters; +messages.getChatInviteImporters#df04dd4e flags:# requested:flags.0?true subscription_expired:flags.3?true peer:InputPeer link:flags.1?string q:flags.2?string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters; messages.setHistoryTTL#b80e5fe4 peer:InputPeer period:int = Updates; messages.checkHistoryImportPeer#5dc60f03 peer:InputPeer = messages.CheckedHistoryImportPeer; messages.setChatTheme#e63be13f peer:InputPeer emoticon:string = Updates; messages.getMessageReadParticipants#31c1c44f peer:InputPeer msg_id:int = Vector; -messages.getSearchResultsCalendar#49f0bde9 peer:InputPeer filter:MessagesFilter offset_id:int offset_date:int = messages.SearchResultsCalendar; -messages.getSearchResultsPositions#6e9583a3 peer:InputPeer filter:MessagesFilter offset_id:int limit:int = messages.SearchResultsPositions; +messages.getSearchResultsCalendar#6aa3f6bd flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer filter:MessagesFilter offset_id:int offset_date:int = messages.SearchResultsCalendar; +messages.getSearchResultsPositions#9c7f2f10 flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer filter:MessagesFilter offset_id:int limit:int = messages.SearchResultsPositions; messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPeer user_id:InputUser = Updates; messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates; messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates; @@ -1844,7 +2236,7 @@ messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool; messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector = Updates; messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector = Updates; messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = messages.MessageReactionsList; -messages.setChatAvailableReactions#feb16771 peer:InputPeer available_reactions:ChatReactions = Updates; +messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_reactions:ChatReactions reactions_limit:flags.0?int paid_enabled:flags.1?Bool = Updates; messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions; messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool; messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector text:flags.1?Vector to_lang:string = messages.TranslatedText; @@ -1854,9 +2246,9 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots; messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot; messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool; -messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult; -messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool; -messages.requestSimpleWebView#299bec8e flags:# from_switch_webview:flags.1?true bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult; +messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; +messages.prolongWebView#b0d81a83 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = Bool; +messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true fullscreen:flags.8?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult; messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent; messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates; messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio; @@ -1871,18 +2263,55 @@ messages.clearRecentReactions#9dfeefb4 = Bool; messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector = Updates; messages.setDefaultHistoryTTL#9eb51445 period:int = Bool; messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL; -messages.sendBotRequestedPeer#fe38d01b peer:InputPeer msg_id:int button_id:int requested_peer:InputPeer = Updates; +messages.sendBotRequestedPeer#91b2d060 peer:InputPeer msg_id:int button_id:int requested_peers:Vector = Updates; messages.getEmojiGroups#7488ce5b hash:int = messages.EmojiGroups; messages.getEmojiStatusGroups#2ecd56cd hash:int = messages.EmojiGroups; messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups; messages.searchCustomEmoji#2c11c0d7 emoticon:string hash:long = EmojiList; messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool; messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp; -messages.requestAppWebView#8c5a3b3c flags:# write_allowed:flags.0?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = AppWebViewResult; -messages.setChatWallPaper#8ffacae1 flags:# peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates; +messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true fullscreen:flags.8?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult; +messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates; +messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; +messages.getSavedDialogs#5381d21a flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs; +messages.getSavedHistory#3d9a414d peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages; +messages.deleteSavedHistory#6e98102b flags:# peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory; +messages.getPinnedSavedDialogs#d63d94e0 = messages.SavedDialogs; +messages.toggleSavedDialogPin#ac81bbde flags:# pinned:flags.0?true peer:InputDialogPeer = Bool; +messages.reorderPinnedSavedDialogs#8b716587 flags:# force:flags.0?true order:Vector = Bool; +messages.getSavedReactionTags#3637e05b flags:# peer:flags.0?InputPeer hash:long = messages.SavedReactionTags; +messages.updateSavedReactionTag#60297dec flags:# reaction:Reaction title:flags.0?string = Bool; +messages.getDefaultTagReactions#bdf93428 hash:long = messages.Reactions; +messages.getOutboxReadDate#8c4bfe5d peer:InputPeer msg_id:int = OutboxReadDate; +messages.getQuickReplies#d483f2a8 hash:long = messages.QuickReplies; +messages.reorderQuickReplies#60331907 order:Vector = Bool; +messages.checkQuickReplyShortcut#f1d0fbd3 shortcut:string = Bool; +messages.editQuickReplyShortcut#5c003cef shortcut_id:int shortcut:string = Bool; +messages.deleteQuickReplyShortcut#3cc04740 shortcut_id:int = Bool; +messages.getQuickReplyMessages#94a495c3 flags:# shortcut_id:int id:flags.0?Vector hash:long = messages.Messages; +messages.sendQuickReplyMessages#6c750de1 peer:InputPeer shortcut_id:int id:Vector random_id:Vector = Updates; +messages.deleteQuickReplyMessages#e105e910 shortcut_id:int id:Vector = Updates; +messages.toggleDialogFilterTags#fd2dda49 enabled:Bool = Bool; +messages.getMyStickers#d0b5e1fc offset_id:long limit:int = messages.MyStickers; +messages.getEmojiStickerGroups#1dd840f5 hash:int = messages.EmojiGroups; +messages.getAvailableEffects#dea20a39 hash:int = messages.AvailableEffects; +messages.editFactCheck#589ee75 peer:InputPeer msg_id:int text:TextWithEntities = Updates; +messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates; +messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector = Vector; +messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:flags.8?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult; +messages.sendPaidReaction#9dd6a67b flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?Bool = Updates; +messages.togglePaidReactionPrivacy#849ad397 peer:InputPeer msg_id:int private:Bool = Bool; +messages.getPaidReactionPrivacy#472455aa = Updates; +messages.viewSponsoredMessage#673ad8f1 peer:InputPeer random_id:bytes = Bool; +messages.clickSponsoredMessage#f093465 flags:# media:flags.0?true fullscreen:flags.1?true peer:InputPeer random_id:bytes = Bool; +messages.reportSponsoredMessage#1af3dbb8 peer:InputPeer random_id:bytes option:bytes = channels.SponsoredMessageReportResult; +messages.getSponsoredMessages#9bd2f439 peer:InputPeer = messages.SponsoredMessages; +messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult user_id:InputUser peer_types:flags.0?Vector = messages.BotPreparedInlineMessage; +messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage; +messages.searchStickers#29b1c66a flags:# emojis:flags.0?true q:string emoticon:string lang_code:Vector offset:int limit:int hash:long = messages.FoundStickers; updates.getState#edd4882a = updates.State; -updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; +updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference; updates.getChannelDifference#3173d78 flags:# force:flags.0?true channel:InputChannel filter:ChannelMessagesFilter pts:int limit:int = updates.ChannelDifference; photos.updateProfilePhoto#9e82039 flags:# fallback:flags.0?true bot:flags.1?InputUser id:InputPhoto = photos.Photo; @@ -1905,7 +2334,6 @@ help.getNearestDc#1fb33026 = NearestDc; help.getAppUpdate#522d5a7d source:string = help.AppUpdate; help.getInviteText#4d392343 = help.InviteText; help.getSupport#9cdf08cd = help.Support; -help.getAppChangelog#9010ef6f prev_app_version:string = Updates; help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; help.getCdnConfig#52029342 = CdnConfig; help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; @@ -1923,6 +2351,9 @@ help.hidePromoData#1e251c95 peer:InputPeer = Bool; help.dismissSuggestion#f50dbaa1 peer:InputPeer suggestion:string = Bool; help.getCountriesList#735787a8 lang_code:string hash:int = help.CountriesList; help.getPremiumPromo#b81b93d4 = help.PremiumPromo; +help.getPeerColors#da80f42f hash:int = help.PeerColors; +help.getPeerProfileColors#abcfa9fd hash:int = help.PeerColors; +help.getTimezonesList#49b30240 hash:int = help.TimezonesList; channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool; channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector = messages.AffectedMessages; @@ -1940,11 +2371,11 @@ channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool; channels.updateUsername#3514b3de channel:InputChannel username:string = Bool; channels.joinChannel#24b524c5 channel:InputChannel = Updates; channels.leaveChannel#f836aa95 channel:InputChannel = Updates; -channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector = Updates; +channels.inviteToChannel#c9e33d54 channel:InputChannel users:Vector = messages.InvitedUsers; channels.deleteChannel#c0111fe3 channel:InputChannel = Updates; channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink; -channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates; -channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats; +channels.toggleSignatures#418d549c flags:# signatures_enabled:flags.0?true profiles_enabled:flags.1?true channel:InputChannel = Updates; +channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true for_personal:flags.2?true = messages.Chats; channels.editBanned#96e6cd81 channel:InputChannel participant:InputPeer banned_rights:ChatBannedRights = Updates; channels.getAdminLog#33ddf480 flags:# channel:InputChannel q:string events_filter:flags.0?ChannelAdminLogEventsFilter admins:flags.1?Vector max_id:long min_id:long limit:int = channels.AdminLogResults; channels.setStickers#ea8ca4f9 channel:InputChannel stickerset:InputStickerSet = Bool; @@ -1959,8 +2390,6 @@ channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint addr channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.getInactiveChannels#11e831ee = messages.InactiveChats; channels.convertToGigagroup#b290c69 channel:InputChannel = Updates; -channels.viewSponsoredMessage#beaedb94 channel:InputChannel random_id:bytes = Bool; -channels.getSponsoredMessages#ec210fbf channel:InputChannel = messages.SponsoredMessages; channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers; channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory; channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates; @@ -1979,6 +2408,14 @@ channels.reorderPinnedForumTopics#2950a18f flags:# force:flags.0?true channel:In channels.toggleAntiSpam#68f3e4eb channel:InputChannel enabled:Bool = Updates; channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool; channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates; +channels.updateColor#d8aa3671 flags:# for_profile:flags.1?true channel:InputChannel color:flags.2?int background_emoji_id:flags.0?long = Updates; +channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates; +channels.getChannelRecommendations#25a71742 flags:# channel:flags.0?InputChannel = messages.Chats; +channels.updateEmojiStatus#f0d3e6a8 channel:InputChannel emoji_status:EmojiStatus = Updates; +channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int = Updates; +channels.setEmojiStickers#3cd930b7 channel:InputChannel stickerset:InputStickerSet = Bool; +channels.restrictSponsoredMessages#9ae91519 channel:InputChannel restricted:Bool = Updates; +channels.searchPosts#d19f987b hashtag:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; @@ -1993,6 +2430,21 @@ bots.setBotInfo#10cf3123 flags:# bot:flags.2?InputUser lang_code:string name:fla bots.getBotInfo#dcd914fd flags:# bot:flags.0?InputUser lang_code:string = bots.BotInfo; bots.reorderUsernames#9709b1c2 bot:InputUser order:Vector = Bool; bots.toggleUsername#53ca973 bot:InputUser username:string active:Bool = Bool; +bots.canSendMessage#1359f4e6 bot:InputUser = Bool; +bots.allowSendMessage#f132e3ef bot:InputUser = Updates; +bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON; +bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots; +bots.addPreviewMedia#17aeb75a bot:InputUser lang_code:string media:InputMedia = BotPreviewMedia; +bots.editPreviewMedia#8525606f bot:InputUser lang_code:string media:InputMedia new_media:InputMedia = BotPreviewMedia; +bots.deletePreviewMedia#2d0135b3 bot:InputUser lang_code:string media:Vector = Bool; +bots.reorderPreviewMedias#b627f3aa bot:InputUser lang_code:string order:Vector = Bool; +bots.getPreviewInfo#423ab3ad bot:InputUser lang_code:string = bots.PreviewInfo; +bots.getPreviewMedias#a2a5594d bot:InputUser = Vector; +bots.updateUserEmojiStatus#ed9f30c5 user_id:InputUser emoji_status:EmojiStatus = Bool; +bots.toggleUserEmojiStatusPermission#6de6392 bot:InputUser enabled:Bool = Bool; +bots.checkDownloadFileParams#50077589 bot:InputUser file_name:string url:string = Bool; +bots.getAdminedBots#b0711d83 = Vector; +bots.updateStarRefProgram#778b5ab3 flags:# bot:InputUser commission_permille:int duration_months:flags.0?int = StarRefProgram; payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm; payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt; @@ -2005,8 +2457,37 @@ payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoi payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates; payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates; payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool; - -stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true animated:flags.1?true videos:flags.4?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; +payments.getPremiumGiftCodeOptions#2757ba54 flags:# boost_peer:flags.0?InputPeer = Vector; +payments.checkGiftCode#8e51b4c1 slug:string = payments.CheckedGiftCode; +payments.applyGiftCode#f6e26854 slug:string = Updates; +payments.getGiveawayInfo#f4239425 peer:InputPeer msg_id:int = payments.GiveawayInfo; +payments.launchPrepaidGiveaway#5ff58f20 peer:InputPeer giveaway_id:long purpose:InputStorePaymentPurpose = Updates; +payments.getStarsTopupOptions#c00ec7d3 = Vector; +payments.getStarsStatus#104fcfa7 peer:InputPeer = payments.StarsStatus; +payments.getStarsTransactions#69da4557 flags:# inbound:flags.0?true outbound:flags.1?true ascending:flags.2?true subscription_id:flags.3?string peer:InputPeer offset:string limit:int = payments.StarsStatus; +payments.sendStarsForm#7998c914 form_id:long invoice:InputInvoice = payments.PaymentResult; +payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates; +payments.getStarsRevenueStats#d91ffad6 flags:# dark:flags.0?true peer:InputPeer = payments.StarsRevenueStats; +payments.getStarsRevenueWithdrawalUrl#13bbe8b3 peer:InputPeer stars:long password:InputCheckPasswordSRP = payments.StarsRevenueWithdrawalUrl; +payments.getStarsRevenueAdsAccountUrl#d1d7efc5 peer:InputPeer = payments.StarsRevenueAdsAccountUrl; +payments.getStarsTransactionsByID#27842d2e peer:InputPeer id:Vector = payments.StarsStatus; +payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector; +payments.getStarsSubscriptions#32512c5 flags:# missing_balance:flags.0?true peer:InputPeer offset:string = payments.StarsStatus; +payments.changeStarsSubscription#c7770878 flags:# peer:InputPeer subscription_id:string canceled:flags.0?Bool = Bool; +payments.fulfillStarsSubscription#cc5bebb3 peer:InputPeer subscription_id:string = Bool; +payments.getStarsGiveawayOptions#bd1efd3e = Vector; +payments.getStarGifts#c4563590 hash:int = payments.StarGifts; +payments.getUserStarGifts#5e72c7e1 user_id:InputUser offset:string limit:int = payments.UserStarGifts; +payments.saveStarGift#87acf08e flags:# unsave:flags.0?true user_id:InputUser msg_id:int = Bool; +payments.convertStarGift#421e027 user_id:InputUser msg_id:int = Bool; +payments.botCancelStarsSubscription#6dfa0622 flags:# restore:flags.0?true user_id:InputUser charge_id:string = Bool; +payments.getConnectedStarRefBots#5869a553 flags:# peer:InputPeer offset_date:flags.2?int offset_link:flags.2?string limit:int = payments.ConnectedStarRefBots; +payments.getConnectedStarRefBot#b7d998f0 peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots; +payments.getSuggestedStarRefBots#d6b48f7 flags:# order_by_revenue:flags.0?true order_by_date:flags.1?true peer:InputPeer offset:string limit:int = payments.SuggestedStarRefBots; +payments.connectStarRefBot#7ed5348a peer:InputPeer bot:InputUser = payments.ConnectedStarRefBots; +payments.editConnectedStarRefBot#e4fca4a3 flags:# revoked:flags.0?true peer:InputPeer link:string = payments.ConnectedStarRefBots; + +stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = messages.StickerSet; stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet; @@ -2016,6 +2497,7 @@ stickers.suggestShortName#4dafc503 title:string = stickers.SuggestedShortName; stickers.changeSticker#f5537ebc flags:# sticker:InputDocument emoji:flags.0?string mask_coords:flags.1?MaskCoords keywords:flags.2?string = messages.StickerSet; stickers.renameStickerSet#124b1c00 stickerset:InputStickerSet title:string = messages.StickerSet; stickers.deleteStickerSet#87704394 stickerset:InputStickerSet = Bool; +stickers.replaceSticker#4696459a sticker:InputDocument new_sticker:InputStickerSetItem = messages.StickerSet; phone.getCallConfig#55451fa9 = DataJSON; phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall; @@ -2060,8 +2542,13 @@ folders.editPeerFolders#6847d0ab folder_peers:Vector = Updates; stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats; -stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; +stats.getMessagePublicForwards#5f150144 channel:InputChannel msg_id:int offset:string limit:int = stats.PublicForwards; stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats; +stats.getStoryStats#374fef40 flags:# dark:flags.0?true peer:InputPeer id:int = stats.StoryStats; +stats.getStoryPublicForwards#a6437ef6 peer:InputPeer id:int offset:string limit:int = stats.PublicForwards; +stats.getBroadcastRevenueStats#f788ee19 flags:# dark:flags.0?true peer:InputPeer = stats.BroadcastRevenueStats; +stats.getBroadcastRevenueWithdrawalUrl#9df4faad peer:InputPeer password:InputCheckPasswordSRP = stats.BroadcastRevenueWithdrawalUrl; +stats.getBroadcastRevenueTransactions#70990b6d peer:InputPeer offset:int limit:int = stats.BroadcastRevenueTransactions; chatlists.exportChatlistInvite#8472478e chatlist:InputChatlist title:string peers:Vector = chatlists.ExportedChatlistInvite; chatlists.deleteExportedInvite#719c5c5e chatlist:InputChatlist slug:string = Bool; @@ -2075,4 +2562,47 @@ chatlists.hideChatlistUpdates#66e486fb chatlist:InputChatlist = Bool; chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector; chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector = Updates; -// LAYER 158 +stories.canSendStory#c7dfdfdd peer:InputPeer = Bool; +stories.sendStory#e4e6694b flags:# pinned:flags.2?true noforwards:flags.4?true fwd_modified:flags.7?true peer:InputPeer media:InputMedia media_areas:flags.5?Vector caption:flags.0?string entities:flags.1?Vector privacy_rules:Vector random_id:long period:flags.3?int fwd_from_id:flags.6?InputPeer fwd_from_story:flags.6?int = Updates; +stories.editStory#b583ba46 flags:# peer:InputPeer id:int media:flags.0?InputMedia media_areas:flags.3?Vector caption:flags.1?string entities:flags.1?Vector privacy_rules:flags.2?Vector = Updates; +stories.deleteStories#ae59db5f peer:InputPeer id:Vector = Vector; +stories.togglePinned#9a75a1ef peer:InputPeer id:Vector pinned:Bool = Vector; +stories.getAllStories#eeb0d625 flags:# next:flags.1?true hidden:flags.2?true state:flags.0?string = stories.AllStories; +stories.getPinnedStories#5821a5dc peer:InputPeer offset_id:int limit:int = stories.Stories; +stories.getStoriesArchive#b4352016 peer:InputPeer offset_id:int limit:int = stories.Stories; +stories.getStoriesByID#5774ca74 peer:InputPeer id:Vector = stories.Stories; +stories.toggleAllStoriesHidden#7c2557c4 hidden:Bool = Bool; +stories.readStories#a556dac8 peer:InputPeer max_id:int = Vector; +stories.incrementStoryViews#b2028afb peer:InputPeer id:Vector = Bool; +stories.getStoryViewsList#7ed23c57 flags:# just_contacts:flags.0?true reactions_first:flags.2?true forwards_first:flags.3?true peer:InputPeer q:flags.1?string id:int offset:string limit:int = stories.StoryViewsList; +stories.getStoriesViews#28e16cc8 peer:InputPeer id:Vector = stories.StoryViews; +stories.exportStoryLink#7b8def20 peer:InputPeer id:int = ExportedStoryLink; +stories.report#19d8eb45 peer:InputPeer id:Vector option:bytes message:string = ReportResult; +stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?true = Updates; +stories.sendReaction#7fd736b2 flags:# add_to_recent:flags.0?true peer:InputPeer story_id:int reaction:Reaction = Updates; +stories.getPeerStories#2c4ada50 peer:InputPeer = stories.PeerStories; +stories.getAllReadPeerStories#9b5ae7f9 = Updates; +stories.getPeerMaxIDs#535983c3 id:Vector = Vector; +stories.getChatsToSend#a56a8b60 = messages.Chats; +stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; +stories.getStoryReactionsList#b9b2881f flags:# forwards_first:flags.2?true peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList; +stories.togglePinnedToTop#b297e9b peer:InputPeer id:Vector = Bool; +stories.searchPosts#d1810907 flags:# hashtag:flags.0?string area:flags.1?MediaArea peer:flags.2?InputPeer offset:string limit:int = stories.FoundStories; + +premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; +premium.getMyBoosts#be77b4a = premium.MyBoosts; +premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector peer:InputPeer = premium.MyBoosts; +premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus; +premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList; + +smsjobs.isEligibleToJoin#edc39d0 = smsjobs.EligibilityToJoin; +smsjobs.join#a74ece2d = Bool; +smsjobs.leave#9898ad73 = Bool; +smsjobs.updateSettings#93fa0bf flags:# allow_international:flags.0?true = Bool; +smsjobs.getStatus#10a698e8 = smsjobs.Status; +smsjobs.getSmsJob#778d902f job_id:string = SmsJob; +smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; + +fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; + +// LAYER 195 diff --git a/telethon_generator/data/errors.csv b/telethon_generator/data/errors.csv index 374362bca..3a23d5422 100644 --- a/telethon_generator/data/errors.csv +++ b/telethon_generator/data/errors.csv @@ -67,6 +67,7 @@ CHANNELS_ADMIN_LOCATED_TOO_MUCH,400,The user has reached the limit of public geo CHANNELS_ADMIN_PUBLIC_TOO_MUCH,400,"You're admin of too many public channels, make some channels private to change the username of this channel" CHANNELS_TOO_MUCH,400,You have joined too many channels/supergroups CHANNEL_BANNED,400,The channel is banned +CHANNEL_FORUM_MISSING,400, CHANNEL_ID_INVALID,400,The specified supergroup ID is invalid CHANNEL_INVALID,400,"Invalid channel object. Make sure to pass the right types, for instance making sure that the request is designed for channels or otherwise look for a different one more suited" CHANNEL_PARICIPANT_MISSING,400,The current user is not in the channel @@ -81,6 +82,7 @@ CHAT_ADMIN_REQUIRED,400 403,"Chat admin privileges are required to do that in th CHAT_DISCUSSION_UNALLOWED,400, CHAT_FORBIDDEN,403,You cannot write in this chat CHAT_FORWARDS_RESTRICTED,400 406,You can't forward messages from a protected chat +CHAT_GET_FAILED,500, CHAT_GUEST_SEND_FORBIDDEN,403,"You join the discussion group before commenting, see [here](/api/discussion#requiring-users-to-join-the-group) for more info" CHAT_ID_EMPTY,400,The provided chat ID is empty CHAT_ID_GENERATE_FAILED,500,Failure while generating the chat ID @@ -177,6 +179,7 @@ FILTER_TITLE_EMPTY,400,The title field of the filter is empty FIRSTNAME_INVALID,400,The first name is invalid FLOOD_TEST_PHONE_WAIT_X,420,A wait of {seconds} seconds is required in the test servers FLOOD_WAIT_X,420,A wait of {seconds} seconds is required +FLOOD_PREMIUM_WAIT_X,420,A wait of {seconds} seconds is required in non-premium accounts FOLDER_ID_EMPTY,400,The folder you tried to delete was already empty FOLDER_ID_INVALID,400,The folder you tried to use was not valid FRESH_CHANGE_ADMINS_FORBIDDEN,400 406,Recently logged-in users cannot add or change admins @@ -462,6 +465,7 @@ TTL_MEDIA_INVALID,400,The provided media cannot be used with a TTL TTL_PERIOD_INVALID,400,The provided TTL Period is invalid TYPES_EMPTY,400,The types field is empty TYPE_CONSTRUCTOR_INVALID,400,The type constructor is invalid +Timedout,-503,Timeout while fetching data Timeout,-503,Timeout while fetching data UNKNOWN_ERROR,400, UNKNOWN_METHOD,500,The method you tried to call cannot be called on non-CDN DCs diff --git a/telethon_generator/generators/tlobject.py b/telethon_generator/generators/tlobject.py index 535ff38d2..f7ce8d4b1 100644 --- a/telethon_generator/generators/tlobject.py +++ b/telethon_generator/generators/tlobject.py @@ -197,7 +197,7 @@ def _write_class_init(tlobject, kind, type_constructors, builder): if not tlobject.real_args: return - if any(a.name in __builtins__ for a in tlobject.real_args): + if any(hasattr(__builtins__, a.name) for a in tlobject.real_args): builder.writeln('# noinspection PyShadowingBuiltins') builder.writeln("def __init__({}):", ', '.join(['self'] + args)) @@ -667,6 +667,7 @@ def _write_all_tlobjects(tlobjects, layer, builder): builder.current_indent += 1 # Fill the dictionary (0x1a2b3c4f: tl.full.type.path.Class) + tlobjects.sort(key=lambda x: x.name) for tlobject in tlobjects: builder.write('{:#010x}: ', tlobject.id) builder.write('functions' if tlobject.is_function else 'types') diff --git a/telethon_generator/parsers/tlobject/tlarg.py b/telethon_generator/parsers/tlobject/tlarg.py index 9e1bee2ac..92724005e 100644 --- a/telethon_generator/parsers/tlobject/tlarg.py +++ b/telethon_generator/parsers/tlobject/tlarg.py @@ -96,7 +96,12 @@ def __init__(self, name, arg_type, generic_definition): :param generic_definition: Is the argument a generic definition? (i.e. {X:Type}) """ - self.name = 'is_self' if name == 'self' else name + if name == 'self': + self.name = 'is_self' + elif name == 'from': + self.name = 'from_' + else: + self.name = name # Default values self.is_vector = False @@ -204,17 +209,21 @@ def real_type(self): return real_type def __str__(self): + name = self.orig_name() if self.generic_definition: - return '{{{}:{}}}'.format(self.name, self.real_type()) + return '{{{}:{}}}'.format(name, self.real_type()) else: - return '{}:{}'.format(self.name, self.real_type()) + return '{}:{}'.format(name, self.real_type()) def __repr__(self): return str(self).replace(':date', ':int').replace('?date', '?int') + def orig_name(self): + return self.name.replace('is_self', 'self').strip('_') + def to_dict(self): return { - 'name': self.name.replace('is_self', 'self'), + 'name': self.orig_name(), 'type': re.sub(r'\bdate$', 'int', self.real_type()) } diff --git a/tests/readthedocs/quick_references/test_client_reference.py b/tests/readthedocs/quick_references/test_client_reference.py index ad720d541..5cd5ac6b7 100644 --- a/tests/readthedocs/quick_references/test_client_reference.py +++ b/tests/readthedocs/quick_references/test_client_reference.py @@ -10,5 +10,5 @@ def test_all_methods_present(docs_dir): assert len(present_methods) > 0 for name in dir(TelegramClient): attr = getattr(TelegramClient, name) - if callable(attr) and not name.startswith('_'): + if callable(attr) and not name.startswith('_') and name != 'sign_up': assert name in present_methods diff --git a/tests/telethon/client/test_messages.py b/tests/telethon/client/test_messages.py index d47fcf459..2bdbb9e78 100644 --- a/tests/telethon/client/test_messages.py +++ b/tests/telethon/client/test_messages.py @@ -1,8 +1,12 @@ import inspect +from unittest import mock +from unittest.mock import MagicMock import pytest from telethon import TelegramClient +from telethon.client import MessageMethods +from telethon.tl.types import PeerChat, MessageMediaDocument, Message, MessageEntityBold @pytest.mark.asyncio @@ -38,3 +42,42 @@ async def send_file(self, entity, file, **kwargs): client = MockedClient() assert (await client.send_message('a', file='b', **arguments)) == sentinel + + +class TestMessageMethods: + @pytest.mark.asyncio + @pytest.mark.parametrize( + 'formatting_entities', + ([MessageEntityBold(offset=0, length=0)], None) + ) + async def test_send_msg_and_file(self, formatting_entities): + async def async_func(result): # AsyncMock was added only in 3.8 + return result + msg_methods = MessageMethods() + expected_result = Message( + id=0, peer_id=PeerChat(chat_id=0), message='', date=None, + ) + entity = 'test_entity' + message = Message( + id=1, peer_id=PeerChat(chat_id=0), message='expected_caption', date=None, + entities=[MessageEntityBold(offset=9, length=9)], + ) + media_file = MessageMediaDocument() + + with mock.patch.object( + target=MessageMethods, attribute='send_file', + new=MagicMock(return_value=async_func(expected_result)), create=True, + ) as mock_obj: + result = await msg_methods.send_message( + entity=entity, message=message, file=media_file, + formatting_entities=formatting_entities, + ) + mock_obj.assert_called_once_with( + entity, media_file, caption=message.message, + formatting_entities=formatting_entities or message.entities, + reply_to=None, silent=None, attributes=None, parse_mode=(), + force_document=False, thumb=None, buttons=None, + clear_draft=False, schedule=None, supports_streaming=False, + comment_to=None, background=None, nosound_video=None, + ) + assert result == expected_result diff --git a/tests/telethon/extensions/test_html.py b/tests/telethon/extensions/test_html.py index 59d96e0dd..302913cc0 100644 --- a/tests/telethon/extensions/test_html.py +++ b/tests/telethon/extensions/test_html.py @@ -53,6 +53,22 @@ def test_entities_together(): assert text == original +def test_nested_entities(): + """ + Test that an entity nested inside another one behaves well. + """ + original = 'Example' + original_entities = [MessageEntityTextUrl(0, 7, url='https://example.com'), MessageEntityBold(0, 7)] + stripped = 'Example' + + text, entities = html.parse(original) + assert text == stripped + assert entities == original_entities + + text = html.unparse(text, entities) + assert text == original + + def test_offset_at_emoji(): """ Tests that an entity starting at a emoji preserves the emoji. diff --git a/tests/telethon/extensions/test_markdown.py b/tests/telethon/extensions/test_markdown.py index bd78e4d8a..2eb94b062 100644 --- a/tests/telethon/extensions/test_markdown.py +++ b/tests/telethon/extensions/test_markdown.py @@ -53,6 +53,21 @@ def test_entities_together(): assert text == original +def test_nested_entities(): + """ + Test that an entity nested inside another one behaves well. + """ + original = '**[Example](https://example.com)**' + stripped = 'Example' + + text, entities = markdown.parse(original) + assert text == stripped + assert entities == [MessageEntityBold(0, 7), MessageEntityTextUrl(0, 7, url='https://example.com')] + + text = markdown.unparse(text, entities) + assert text == original + + def test_offset_at_emoji(): """ Tests that an entity starting at a emoji preserves the emoji. diff --git a/tests/telethon/test_utils.py b/tests/telethon/test_utils.py index b0cfb33fa..99a46efb1 100644 --- a/tests/telethon/test_utils.py +++ b/tests/telethon/test_utils.py @@ -34,9 +34,6 @@ def __init__(self, name): assert utils._get_extension('foo.bar.baz') == '.baz' assert utils._get_extension(pathlib.Path('foo.bar.baz')) == '.baz' - assert utils._get_extension(png_header) == '.png' - assert utils._get_extension(png_buffer) == '.png' - assert utils._get_extension(png_buffer) == '.png' # make sure it did seek back assert utils._get_extension(CustomFd('foo.bar.baz')) == '.baz' # Negative cases