Compare commits

...

73 commits

Author SHA1 Message Date
dependabot[bot]
cc4eb21b84
build(deps): bump sphinx-immaterial from 0.12.4 to 0.13.4
Bumps [sphinx-immaterial](https://github.com/jbms/sphinx-immaterial) from 0.12.4 to 0.13.4.
- [Release notes](https://github.com/jbms/sphinx-immaterial/releases)
- [Commits](https://github.com/jbms/sphinx-immaterial/compare/v0.12.4...v0.13.4)

---
updated-dependencies:
- dependency-name: sphinx-immaterial
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-09 15:11:37 +00:00
wulan17
12d9297c02
pyrofork: Bump version to 2.3.67
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:16:02 +07:00
wulan17
52abec6e01
pyrofork: fix NoneType exception in filters
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:15:12 +07:00
KurimuzonAkuma
fd4eb09f7a
Add get_call_members method
Signed-off-by: gudmeong <privatemymail758@gmail.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:15:12 +07:00
wulan17
dbcbadc400
pyrofork: Add back reverse parameter in get_chat_history
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:15:12 +07:00
KurimuzonAkuma
b65279046e
Update upgraded gift regex
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:15:12 +07:00
wulan17
9ff40dc90b
pyrofork: fix typo in KeyboardButton
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-25 19:15:06 +07:00
wulan17
6f616ebed8
pyrofork: Bump version to 2.3.66
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:48:38 +07:00
wulan17
e33d0bde65
pyrofork: fix typo
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:45:51 +07:00
wulan17
e5b5ef5072
pyrofork: Bump version to 2.3.65
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:59 +07:00
KurimuzonAkuma
a1e3f0f5db
Add transfer_business_account_stars method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:08 +07:00
KurimuzonAkuma
b6c615df7a
Add get_business_account_gifts and get_business_account_star_balance method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:08 +07:00
wulan17
a2f3a6a27b
pyrofork: Add reply_to_monoforum_id parameter to supported send_*
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:08 +07:00
wulan17
bd5603a6a7
pyrofork: Add STARS_AMOUNT_INVALID exception
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
wulan17
1ed7add4dd
pyrofork: Add paid_message_price_changed field to Message
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
wulan17
068181682e
pyrofork: Add ALLOW_PAYMENT_REQUIRED_X exception
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
wulan17
c0dcac1fde
pyrofork: Add linked_forum field to Chat
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
wulan17
ffec107a2c
pyrofork: Drop Chat.is_forum and add new ChatType (FORUM)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
wulan17
390786d92c
pyrofork: Add new ChatType (MONOFORUM)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:07 +07:00
KurimuzonAkuma
a9c4ef4c2e
pyrofork: Add privileges to RequestPeer buttons
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
KurimuzonAkuma
78467e30a2
pyrofork: Add search_gifts_for_resale, send_resold_gift, set_gift_resale_price, set_pinned_gifts methods
Co-authored-by: "ALi.w" <aminnimaj@gmail.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
uNickz
3d343a49ff
pyrofork: Add file_name param on InputMedia
* Add file_name param on InputMedia

Add file_name param on:
 - InputMediaVideo
 - InputMediaAudio
 - InputMediaDocument

---------

Co-authored-by: KurimuzonAkuma <31959970+KurimuzonAkuma@users.noreply.github.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
wulan17
83f3f52681
pyrofork: Refactor Message.link
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
wulan17
8880a92483
pyrofork: types: Wallpaper: Make document optional
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
wulan17
71c0a1176a
pyrofork: fix typo in filters
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:38:06 +07:00
wulan17
ddf90f26cf
pyrofork: Update API schema to Layer 204
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 22:37:58 +07:00
wulan17
907f03197a
pyrofork: Bump version to 2.3.64
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:10:08 +07:00
Ling-ex
eb2b854ea6
Update Gift class: add ton_address and clarify owner info.
Signed-off-by: Ling-ex <nekochan@rizkiofficial.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:08:43 +07:00
Ling-ex
7d10a6fb9c
Fix: Register RawUpdateHandler and Refactor Dispatcher for Better Modularity.
Signed-off-by: Ling-ex <nekochan@rizkiofficial.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:08:42 +07:00
wulan17
315f61d1ed
pyrofork: fix enums typo in Message (#135)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:08:42 +07:00
wulan17
f6599d8ef4
pyrofork: Add missing Username docs
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:08:41 +07:00
wulan17
47b054c996
pyrofork: filters: Add support for fragments usernames
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-06 19:08:40 +07:00
wulan17
2a84c33607
pyrofork: Bump version to 2.3.63
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:55 +07:00
wulan17
6c07a1b165
pyrofork: Add missing MessageOriginType enums docs
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:28 +07:00
wulan17
2c3fb1caa6
Revert "fix: handle connection closure and retry logic in session management"
This reverts commit 4df4478a80.

Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:20 +07:00
wulan17
ce74587e4f
pyrofork: set Client.hide_password default value to True
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:20 +07:00
wulan17
910e7fe730
pyrofork: Drop accept_terms_of_service and sign_up method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:19 +07:00
Ling-ex
7f5547a6a8
Add Ping method
Signed-off-by: Ling-ex <nekochan@rizkiofficial.com>
2025-05-18 19:57:19 +07:00
Ling-ex
04c25b760f
Add progress and progress_args parameters to Client.send_media_group and Message.reply_media_group
Signed-off-by: Ling-ex <nekochan@rizkiofficial.com>
2025-05-18 19:57:19 +07:00
wulan17
1b6d86ea77
pyrofork: Add is_frozen and frozen_icon field to User
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:19 +07:00
wulan17
5e35c47b61
pyrofork: Refactor Qr Code Signin
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:18 +07:00
wulan17
99e6005cf1
pyrofork: fix MESSAGE_IDS_EMPTY error on get_scheduled_messages method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-18 19:57:05 +07:00
57feed8b45
Merge pull request #131 from Ling-ex/main
Add group Parameter to the Decorator.on_error.
2025-05-18 19:54:47 +07:00
Ling-ex
d749f50140 Feat: Add group Parameter to the Decorator.on_error.
Signed-off-by: Ling-ex <nekochan@rizkiofficial.com>
2025-05-16 08:47:47 +00:00
wulan17
2992b6cc2f
pyrofork: Bump version to 2.3.62
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:49:34 +07:00
wulan17
ac7ad7d3bc
pyrofork: fix on_error help
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
wulan17
40cd7badd5
pyrofork: Implement QrCode Login
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
wulan17
c0c76342d5
pyrofork: Add is_auto_translation_enabled field to Chat
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
KurimuzonAkuma
37d0e5ae72
Add delete_business_messages method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
wulan17
52c13cdd48
pyrofork: Add missing parameter to Message.reply_photo and Message.reply_video
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
wulan17
e2e4f13946
pyrofork: Add view_once parameter to send_video and Message.reply_video
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:31 +07:00
wulan17
beb5b5138b
pyrofork: Update API schema to Layer 203
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:30 +07:00
wulan17
95e97b11f6
pyrofork: Update API schema to Layer 202
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:30 +07:00
wulan17
548f404d67
pyrofork: Sync with telegramdesktop layer 201
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:30 +07:00
Hitalo M.
4df4478a80
fix: handle connection closure and retry logic in session management
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:30 +07:00
wulan17
4a8e73fc97
pyrofork: Adapt filters.forwarded to latest changes
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-05-14 20:48:09 +07:00
wulan17
3a632d4590
pyrofork: Bump version to 2.3.61
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-04-03 22:40:18 +07:00
wulan17
8655deb92c
pyrofork: moar cleanups
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-04-03 22:31:37 +07:00
wulan17
b6fdbb0a07
pyrofork: types: MessageReactor: fix derps
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-04-03 22:31:37 +07:00
wulan17
aac5425334
pyrofork: Bump version to 2.3.60
Some checks failed
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:26:26 +07:00
wulan17
3e24f006e0
pyrofork: Cleanup codes
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:25:16 +07:00
wulan17
f5296145cd
pyrofork: Add support for parsing Reaction as channel
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:24:52 +07:00
wulan17
24d3ea0e48
pyrofork: Update API schema to Layer 201
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:24:47 +07:00
wulan17
70fc7d9eff
pyrofork: Refactor GiveawayResult
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:24:42 +07:00
wulan17
8c47410bba
pyrofork: Refactor ShippingQuery
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:24:35 +07:00
wulan17
c427601210
pyrofork: Refactor Giveaway
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:24:29 +07:00
wulan17
aa1757676c
pyrofork: utils: Don't append message to messages_with_replies if reply_to_msg_id is None
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:23:03 +07:00
wulan17
c4166957d3
Revert "Pyrofork: types: message: Fix cross chat reply parsing"
This reverts commit b4cb8ff17c.

Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:22:41 +07:00
KurimuzonAkuma
389a135883
Add ExternalReplyInfo
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:21:47 +07:00
KurimuzonAkuma
6b28d305c0
Add MessageOriginImport
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:21:26 +07:00
KurimuzonAkuma
7ae98099db
Refactor Message
- Refactor Message.quote
- Add forward_origin

Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:20:53 +07:00
KurimuzonAkuma
96917949a9
Make url parameter optional for send_web_page
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:20:31 +07:00
wulan17
757b081eeb
pyrofork: Update API schema to Layer 200
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-03-29 00:19:52 +07:00
185 changed files with 4395 additions and 882 deletions

651
.pylintrc Normal file
View file

@ -0,0 +1,651 @@
[MAIN]
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Clear in-memory caches upon conclusion of linting. Useful if running pylint
# in a server-like mode.
clear-cache-post-run=no
# Load and enable all available extensions. Use --list-extensions to see a list
# all available extensions.
#enable-all-extensions=
# In error mode, messages with a category besides ERROR or FATAL are
# suppressed, and no reports are done by default. Error mode is compatible with
# disabling specific errors.
#errors-only=
# Always return a 0 (non-error) status code, even if lint errors are found.
# This is primarily useful in continuous integration scripts.
#exit-zero=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code.
extension-pkg-allow-list=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
# for backward compatibility.)
extension-pkg-whitelist=
# Return non-zero exit code if any of these messages/categories are detected,
# even if score is above --fail-under value. Syntax same as enable. Messages
# specified are enabled, while categories only check already-enabled messages.
fail-on=
# Specify a score threshold under which the program will exit with error.
fail-under=10
# Interpret the stdin as a python script, whose filename needs to be passed as
# the module_or_package argument.
#from-stdin=
# Files or directories to be skipped. They should be base names, not paths.
ignore=CVS
# Add files or directories matching the regular expressions patterns to the
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems,
# it can't be used as an escape character.
ignore-paths=
# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
# Emacs file locks
ignore-patterns=^\.#
# List of module names for which member attributes should not be checked and
# will not be imported (useful for modules/projects where namespaces are
# manipulated during runtime and thus existing member attributes cannot be
# deduced by static analysis). It supports qualified module names, as well as
# Unix pattern matching.
ignored-modules=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
# number of processors available to use, and will cap the count on Windows to
# avoid hangs.
jobs=1
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
# complex, nested conditions.
limit-inference-results=100
# List of plugins (as comma separated values of python module names) to load,
# usually to register additional checkers.
load-plugins=
# Pickle collected data for later comparisons.
persistent=yes
# Resolve imports to .pyi stubs if available. May reduce no-member messages and
# increase not-an-iterable messages.
prefer-stubs=no
# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.13
# Discover python modules and packages in the file system subtree.
recursive=no
# Add paths to the list of the source roots. Supports globbing patterns. The
# source root is an absolute path or a path relative to the current working
# directory used to determine a package namespace for modules located under the
# source root.
source-roots=
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# In verbose mode, extra non-checker-related info will be displayed.
#verbose=
[BASIC]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Regular expression matching correct argument names. Overrides argument-
# naming-style. If left empty, argument names will be checked with the set
# naming style.
#argument-rgx=
# Naming style matching correct attribute names.
attr-naming-style=snake_case
# Regular expression matching correct attribute names. Overrides attr-naming-
# style. If left empty, attribute names will be checked with the set naming
# style.
#attr-rgx=
# Bad variable names which should always be refused, separated by a comma.
bad-names=foo,
bar,
baz,
toto,
tutu,
tata
# Bad variable names regexes, separated by a comma. If names match any regex,
# they will always be refused
bad-names-rgxs=
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style. If left empty, class attribute names will be checked
# with the set naming style.
#class-attribute-rgx=
# Naming style matching correct class constant names.
class-const-naming-style=UPPER_CASE
# Regular expression matching correct class constant names. Overrides class-
# const-naming-style. If left empty, class constant names will be checked with
# the set naming style.
#class-const-rgx=
# Naming style matching correct class names.
class-naming-style=PascalCase
# Regular expression matching correct class names. Overrides class-naming-
# style. If left empty, class names will be checked with the set naming style.
#class-rgx=
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# Regular expression matching correct constant names. Overrides const-naming-
# style. If left empty, constant names will be checked with the set naming
# style.
#const-rgx=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style. If left empty, function names will be checked with the set
# naming style.
#function-rgx=
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style. If left empty, inline iteration names will be checked
# with the set naming style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style. If left empty, method names will be checked with the set naming style.
#method-rgx=
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style. If left empty, module names will be checked with the set naming style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Regular expression matching correct type alias names. If left empty, type
# alias names will be checked with the set naming style.
#typealias-rgx=
# Regular expression matching correct type variable names. If left empty, type
# variable names will be checked with the set naming style.
#typevar-rgx=
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style. If left empty, variable names will be checked with the set
# naming style.
#variable-rgx=
[CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp,
asyncSetUp,
__post_init__
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# List of regular expressions of class ancestor names to ignore when counting
# public methods (see R0903)
exclude-too-few-public-methods=
# List of qualified class names to ignore when counting class parents (see
# R0901)
ignored-parents=
# Maximum number of arguments for function / method.
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in an if statement (see R0916).
max-bool-expr=5
# Maximum number of branch for function / method body.
max-branches=12
# Maximum number of locals for function / method body.
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of positional arguments for function / method.
max-positional-arguments=5
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
# Maximum number of return / yield for function / method body.
max-returns=6
# Maximum number of statements in function / method body.
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[EXCEPTIONS]
# Exceptions that will emit a warning when caught.
overgeneral-exceptions=builtins.BaseException,builtins.Exception
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of lines in a module.
max-module-lines=1000
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[IMPORTS]
# List of modules that can be imported at any level, not just the top level
# one.
allow-any-import-level=
# Allow explicit reexports by alias from a package __init__.
allow-reexport-from-package=no
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=
# Output a graph (.gv or any supported image format) of external dependencies
# to the given file (report RP0402 must not be disabled).
ext-import-graph=
# Output a graph (.gv or any supported image format) of all (i.e. internal and
# external) dependencies to the given file (report RP0402 must not be
# disabled).
import-graph=
# Output a graph (.gv or any supported image format) of internal dependencies
# to the given file (report RP0402 must not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Couples of modules and preferred modules, separated by a comma.
preferred-modules=
[LOGGING]
# The type of string formatting that logging methods do. `old` means using %
# formatting, `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=logging
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,
# UNDEFINED.
confidence=HIGH,
CONTROL_FLOW,
INFERENCE,
INFERENCE_FAILURE,
UNDEFINED
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once). You can also use "--disable=all" to
# disable everything first and then re-enable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use "--disable=all --enable=classes
# --disable=W".
disable=raw-checker-failed,
bad-inline-option,
locally-disabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
use-implicit-booleaness-not-comparison-to-string,
use-implicit-booleaness-not-comparison-to-zero,
use-symbolic-message-instead,
missing-module-docstring,
missing-class-docstring,
missing-function-docstring,
redefined-builtin
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=
[METHOD_ARGS]
# List of qualified names (i.e., library.method) which require a timeout
# parameter e.g. 'requests.api.get,requests.api.post'
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
# Regular expression of note tags to take in consideration.
notes-rgx=
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
# Complete name of functions that never returns. When checking for
# inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be
# printed.
never-returning-functions=sys.exit,argparse.parse_error
# Let 'consider-using-join' be raised when the separator to join on would be
# non-empty (resulting in expected fixes of the type: ``"- " + " -
# ".join(items)``)
suggest-join-with-non-empty-separator=yes
[REPORTS]
# Python expression which should return a score less than or equal to 10. You
# have access to the variables 'fatal', 'error', 'warning', 'refactor',
# 'convention', and 'info' which contain the number of messages in each
# category, as well as 'statement' which is the total number of statements
# analyzed. This score is used by the global evaluation report (RP0004).
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
msg-template=
# Set the output format. Available formats are: 'text', 'parseable',
# 'colorized', 'json2' (improved json format), 'json' (old json format), msvs
# (visual studio) and 'github' (GitHub actions). You can also give a reporter
# class, e.g. mypackage.mymodule.MyReporterClass.
#output-format=
# Tells whether to display a full report or only the messages.
reports=no
# Activate the evaluation score.
score=yes
[SIMILARITIES]
# Comments are removed from the similarity computation
ignore-comments=yes
# Docstrings are removed from the similarity computation
ignore-docstrings=yes
# Imports are removed from the similarity computation
ignore-imports=yes
# Signatures are removed from the similarity computation
ignore-signatures=yes
# Minimum lines number of a similarity.
min-similarity-lines=4
[SPELLING]
# Limits count of emitted suggestions for spelling mistakes.
max-spelling-suggestions=4
# Spelling dictionary name. No available dictionaries : You need to install
# both the python package and the system dependency for enchant to work.
spelling-dict=
# List of comma separated words that should be considered directives if they
# appear at the beginning of a comment and should not be checked.
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains the private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to the private dictionary (see the
# --spelling-private-dict-file option) instead of raising a message.
spelling-store-unknown-words=no
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=no
# This flag controls whether the implicit-str-concat should generate a warning
# on implicit string concatenation in sequences defined over several lines.
check-str-concat-over-line-jumps=no
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
ignore-none=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of symbolic message names to ignore for Mixin members.
ignored-checks-for-mixins=no-member,
not-async-context-manager,
not-context-manager,
attribute-defined-outside-init
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
# Regex pattern to define which classes are considered mixins.
mixin-class-rgx=.*[Mm]ixin
# List of decorators that change the signature of a decorated function.
signature-mutators=
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid defining new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of names allowed to shadow builtins
allowed-redefined-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,
_cb
# A regular expression matching the name of dummy variables (i.e. expected to
# not be used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored.
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io

View file

@ -130,7 +130,7 @@ def get_type_hint(type: str) -> str:
return f"Optional[{type}] = None" if is_flag else type
else:
ns, name = type.split(".") if "." in type else ("", type)
type = f'"raw.base.' + ".".join([ns, name]).strip(".") + '"'
type = '"raw.base.' + ".".join([ns, name]).strip(".") + '"'
return f'{type}{" = None" if is_flag else ""}'
@ -430,11 +430,11 @@ def start(format: bool = False):
if function_docs:
docstring += function_docs["desc"] + "\n"
else:
docstring += f"Telegram API function."
docstring += "Telegram API function."
docstring += f"\n\n Details:\n - Layer: ``{layer}``\n - ID: ``{c.id[2:].upper()}``\n\n"
docstring += f" Parameters:\n " + \
(f"\n ".join(docstring_args) if docstring_args else "No parameters required.\n")
docstring += " Parameters:\n " + \
("\n ".join(docstring_args) if docstring_args else "No parameters required.\n")
if c.section == "functions":
docstring += "\n Returns:\n " + get_docstring_arg_type(c.qualtype)
@ -442,12 +442,12 @@ def start(format: bool = False):
references, count = get_references(c.qualname, "constructors")
if references:
docstring += f"\n Functions:\n This object can be returned by " \
docstring += "\n Functions:\n This object can be returned by " \
f"{count} function{'s' if count > 1 else ''}.\n\n" \
f" .. currentmodule:: pyrogram.raw.functions\n\n" \
f" .. autosummary::\n" \
f" :nosignatures:\n\n" \
f" " + references
" .. currentmodule:: pyrogram.raw.functions\n\n" \
" .. autosummary::\n" \
" :nosignatures:\n\n" \
" " + references
write_types = read_types = "" if c.has_flags else "# No flags\n "

View file

@ -93,7 +93,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;
userEmpty#d3bc4b7a id:long = User;
user#4b46c37e 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<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long = User;
user#20b1422 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<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = 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;
@ -108,11 +108,11 @@ 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#e00998b7 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<RestrictionReason> 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<Username> 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 bot_verification_icon:flags2.13?long = Chat;
channel#fe685355 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 autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> 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<Username> 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 bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = 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#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<BotInfo> 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<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull;
channelFull#52d6806b 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 stargifts_available:flags2.19?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<BotInfo> 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<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> 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 bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
channelFull#52d6806b 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 stargifts_available:flags2.19?true paid_messages_available:flags2.20?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<BotInfo> 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<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> 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 bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -125,7 +125,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#96fdbbe9 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<MessageEntity> 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<RestrictionReason> ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int = Message;
message#eabcdd4d 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<MessageEntity> 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<RestrictionReason> ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int paid_message_stars:flags2.6?long = Message;
messageService#d3d28540 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true reactions_are_possible:flags.9?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 reactions:flags.20?MessageReactions ttl_period:flags.25?int = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
@ -184,7 +184,7 @@ messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
messageActionRequestedPeer#31518e9b button_id:int peers:Vector<Peer> = 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;
messageActionGiftCode#56d03994 flags:# via_giveaway:flags.0?true unclaimed:flags.5?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;
@ -193,7 +193,10 @@ messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_am
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#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction;
messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction;
messageActionStarGiftUnique#2e3ae60e flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long can_transfer_at:flags.9?int can_resell_at:flags.10?int = MessageAction;
messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction;
messageActionPaidMessagesPrice#84b88578 flags:# broadcast_messages_allowed:flags.0?true stars:long = MessageAction;
messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector<Peer> = 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;
@ -213,6 +216,7 @@ geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radiu
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
auth.sentCodeSuccess#2390fe44 authorization:auth.Authorization = auth.SentCode;
auth.sentCodePaymentRequired#d7cef980 store_product:string phone_code_hash:string = auth.SentCode;
auth.authorization#2ea2c0d4 flags:# setup_password_required:flags.1?true otherwise_relogin_days:flags.1?int tmp_sessions:flags.0?int future_auth_token:flags.2?bytes user:User = auth.Authorization;
auth.authorizationSignUpRequired#44747e9a flags:# terms_of_service:flags.0?help.TermsOfService = auth.Authorization;
@ -229,7 +233,7 @@ inputPeerNotifySettings#cacb6ae2 flags:# show_previews:flags.0?Bool silent:flags
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#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;
peerSettings#f47741f7 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 charge_paid_message_stars:flags.14?long registration_month:flags.15?string phone_country:flags.16?string name_change_date:flags.17?int photo_change_date:flags.18?int = 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;
@ -245,7 +249,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason;
inputReportReasonIllegalDrugs#a8eb2be = ReportReason;
inputReportReasonPersonalDetails#9ec7863d = ReportReason;
userFull#4d975bbc 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<PremiumGiftOption> 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 bot_verification:flags2.12?BotVerification = UserFull;
userFull#99e78045 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 display_gifts_button:flags2.16?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 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 bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_gifts:flags2.15?DisallowedGiftsSettings = UserFull;
contact#145ade0b user_id:long mutual:Bool = Contact;
@ -337,7 +341,7 @@ updateBotCallbackQuery#b9cfc48d flags:# query_id:long user_id:long peer:Peer msg
updateEditMessage#e40370a3 message:Message pts:int pts_count:int = Update;
updateInlineBotCallbackQuery#691e9052 flags:# query_id:long user_id:long msg_id:InputBotInlineMessageID chat_instance:long data:flags.0?bytes game_short_name:flags.1?string = Update;
updateReadChannelOutbox#b75f99a9 channel_id:long max_id:int = Update;
updateDraftMessage#1b49ec6d flags:# peer:Peer top_msg_id:flags.0?int draft:DraftMessage = Update;
updateDraftMessage#edfc111e flags:# peer:Peer top_msg_id:flags.0?int saved_peer_id:flags.1?Peer draft:DraftMessage = Update;
updateReadFeaturedStickers#571d2742 = Update;
updateRecentStickers#9a422c20 = Update;
updateConfig#a229dd06 = Update;
@ -353,10 +357,10 @@ updatePhoneCall#ab0f6b1e phone_call:PhoneCall = Update;
updateLangPackTooLong#46560264 lang_code:string = Update;
updateLangPack#56022f4d difference:LangPackDifference = Update;
updateFavedStickers#e511996d = Update;
updateChannelReadMessagesContents#ea29055d flags:# channel_id:long top_msg_id:flags.0?int messages:Vector<int> = Update;
updateChannelReadMessagesContents#25f324f7 flags:# channel_id:long top_msg_id:flags.0?int saved_peer_id:flags.1?Peer messages:Vector<int> = Update;
updateContactsReset#7084a7be = Update;
updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update;
updateDialogUnreadMark#e16459c3 flags:# unread:flags.0?true peer:DialogPeer = Update;
updateDialogUnreadMark#b658f23e flags:# unread:flags.0?true peer:DialogPeer saved_peer_id:flags.1?Peer = Update;
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
@ -390,7 +394,7 @@ updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJ
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
updateMessageReactions#5e1b3cb8 flags:# peer:Peer msg_id:int top_msg_id:flags.0?int reactions:MessageReactions = Update;
updateMessageReactions#1e297bfa flags:# peer:Peer msg_id:int top_msg_id:flags.0?int saved_peer_id:flags.1?Peer reactions:MessageReactions = Update;
updateAttachMenuBots#17b7a20b = Update;
updateWebViewResultSent#1592b79d query_id:long = Update;
updateBotMenuButton#14b85813 bot_id:long button:BotMenuButton = Update;
@ -436,6 +440,10 @@ updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long conne
updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update;
updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Update;
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
updateReadMonoForumInbox#77b0e372 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
updateReadMonoForumOutbox#a4a79376 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -543,6 +551,7 @@ inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey;
inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey;
inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey;
inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey;
inputPrivacyKeyNoPaidMessages#bdc597b4 = InputPrivacyKey;
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
privacyKeyChatInvite#500e6dfa = PrivacyKey;
@ -556,6 +565,7 @@ privacyKeyVoiceMessages#697f414 = PrivacyKey;
privacyKeyAbout#a486b761 = PrivacyKey;
privacyKeyBirthday#2000a518 = PrivacyKey;
privacyKeyStarGiftsAutoSave#2ca4fdf8 = PrivacyKey;
privacyKeyNoPaidMessages#17d348d2 = PrivacyKey;
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
@ -608,7 +618,7 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
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<WebPageAttribute> = WebPage;
webPage#e89c45b2 flags:# has_large_media:flags.13?true video_cover_photo:flags.14?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<WebPageAttribute> = 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 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;
@ -904,7 +914,7 @@ phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
phoneCallDiscardReasonDisconnect#e095c1a0 = PhoneCallDiscardReason;
phoneCallDiscardReasonHangup#57adc690 = PhoneCallDiscardReason;
phoneCallDiscardReasonBusy#faf7e8c9 = PhoneCallDiscardReason;
phoneCallDiscardReasonAllowGroupCall#afe2b839 encrypted_key:bytes = PhoneCallDiscardReason;
phoneCallDiscardReasonMigrateConferenceCall#9fbbf1f7 slug:string = PhoneCallDiscardReason;
dataJSON#7d748d04 data:string = DataJSON;
@ -959,11 +969,11 @@ inputStickerSetItem#32da9e9c flags:# document:InputDocument emoji:string mask_co
inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall;
phoneCallEmpty#5366c915 id:long = PhoneCall;
phoneCallWaiting#eed42858 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 conference_call:flags.8?InputGroupCall = PhoneCall;
phoneCallRequested#45361c63 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_a_hash:bytes protocol:PhoneCallProtocol conference_call:flags.8?InputGroupCall = PhoneCall;
phoneCallAccepted#22fd7181 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:long participant_id:long g_b:bytes protocol:PhoneCallProtocol conference_call:flags.8?InputGroupCall = PhoneCall;
phoneCall#3ba5940c 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<PhoneConnection> start_date:int custom_parameters:flags.7?DataJSON conference_call:flags.8?InputGroupCall = PhoneCall;
phoneCallDiscarded#f9d25503 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 conference_call:flags.8?InputGroupCall = 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#30535af5 flags:# p2p_allowed:flags.5?true video:flags.6?true conference_supported:flags.8?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<PhoneConnection> 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;
phoneConnectionWebrtc#635fe375 flags:# turn:flags.0?true stun:flags.1?true id:long ip:string ipv6:string port:int username:string password:string = PhoneConnection;
@ -1037,6 +1047,7 @@ channelAdminLogEventActionChangeEmojiStatus#3ea9feb1 prev_value:EmojiStatus new_
channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputStickerSet new_stickerset:InputStickerSet = ChannelAdminLogEventAction;
channelAdminLogEventActionToggleSignatureProfiles#60a79c79 new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEventActionParticipantSubExtend#64642db3 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction;
channelAdminLogEventActionToggleAutotranslation#c517f77e new_value:Bool = ChannelAdminLogEventAction;
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
@ -1304,7 +1315,7 @@ statsGraph#8ea464b6 flags:# json:DataJSON zoom_token:flags.0?string = StatsGraph
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<PostInteractionCounters> = stats.BroadcastStats;
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
help.promoData#8a4d87a flags:# proxy:flags.0?true expires:int peer:flags.3?Peer psa_type:flags.1?string psa_message:flags.2?string pending_suggestions:Vector<string> dismissed_suggestions:Vector<string> custom_pending_suggestion:flags.4?PendingSuggestion chats:Vector<Chat> users:Vector<User> = help.PromoData;
videoSize#de33b094 flags:# type:string w:int h:int size:int video_start_ts:flags.0?double = VideoSize;
videoSizeEmojiMarkup#f85c413c emoji_id:long background_colors:Vector<int> = VideoSize;
@ -1318,7 +1329,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<StatsGroupTopPoster> top_admins:Vector<StatsGroupTopAdmin> top_inviters:Vector<StatsGroupTopInviter> users:Vector<User> = stats.MegagroupStats;
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;
globalPrivacySettings#fe41b34f 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 display_gifts_button:flags.7?true noncontact_peers_paid_stars:flags.5?long disallowed_gifts:flags.6?DisallowedGiftsSettings = GlobalPrivacySettings;
help.countryCode#4203c5ef flags:# country_code:string prefixes:flags.0?Vector<string> patterns:flags.1?Vector<string> = help.CountryCode;
@ -1343,9 +1354,11 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats;
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
groupCall#cdf8d3e3 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 conference_from_call:flags.14?long = GroupCall;
groupCall#553b0ba1 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 conference:flags.14?true creator:flags.15?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 invite_link:flags.16?string = GroupCall;
inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall;
inputGroupCallSlug#fe06823f slug:string = InputGroupCall;
inputGroupCallInviteMessage#8c10603f msg_id:int = InputGroupCall;
groupCallParticipant#eba636fe flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true video_joined:flags.15?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long video:flags.6?GroupCallParticipantVideo presentation:flags.14?GroupCallParticipantVideo = GroupCallParticipant;
@ -1487,6 +1500,9 @@ inputInvoiceChatInviteSubscription#34e793f1 hash:string = InputInvoice;
inputInvoiceStarGift#e8625e92 flags:# hide_name:flags.0?true include_upgrade:flags.2?true peer:InputPeer gift_id:long message:flags.1?TextWithEntities = InputInvoice;
inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true stargift:InputSavedStarGift = InputInvoice;
inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice;
inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice;
inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice;
inputInvoiceStarGiftResale#63cbc38c slug:string to_id:InputPeer = InputInvoice;
payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice;
@ -1501,8 +1517,7 @@ inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?t
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<InputPeer> countries_iso2:flags.2?Vector<string> 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;
inputStorePaymentAuthCode#9bb2636d flags:# restore:flags.0?true phone_number:string phone_code_hash:string currency:string amount:long = InputStorePaymentPurpose;
paymentFormMethod#88f8f21b url:string title:string = PaymentFormMethod;
@ -1634,8 +1649,9 @@ stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = 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<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
inputReplyToMessage#b07038b0 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<MessageEntity> quote_offset:flags.4?int monoforum_peer_id:flags.5?InputPeer = InputReplyTo;
inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo;
inputReplyToMonoForum#69d66c45 monoforum_peer_id:InputPeer = InputReplyTo;
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
@ -1708,6 +1724,7 @@ storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
monoForumDialog#64407ea7 flags:# unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_reactions_count:int draft:flags.1?DraftMessage = SavedDialog;
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
@ -1761,7 +1778,7 @@ inputQuickReplyShortcutId#1190cf1 shortcut_id:int = InputQuickReplyShortcut;
messages.quickReplies#c68d6695 quick_replies:Vector<QuickReply> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.QuickReplies;
messages.quickRepliesNotModified#5f91eb5b = messages.QuickReplies;
connectedBot#bd068601 flags:# can_reply:flags.0?true bot_id:long recipients:BusinessBotRecipients = ConnectedBot;
connectedBot#cd64636c flags:# bot_id:long recipients:BusinessBotRecipients rights:BusinessBotRights = ConnectedBot;
account.connectedBots#17d7f87b connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
@ -1769,7 +1786,7 @@ messages.dialogFilters#2ad93719 flags:# tags_enabled:flags.0?true filters:Vector
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;
botBusinessConnection#8f34b2f5 flags:# disabled:flags.1?true connection_id:string user_id:long dc_id:int date:int rights:flags.2?BusinessBotRights = BotBusinessConnection;
inputBusinessIntro#9c469cd flags:# title:string description:string sticker:flags.0?InputDocument = InputBusinessIntro;
@ -1847,7 +1864,7 @@ 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 stargift_upgrade:flags.18?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<MessageMedia> 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;
starsTransaction#a39fd94a flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true stargift_upgrade:flags.18?true business_transfer:flags.21?true stargift_resale:flags.22?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<MessageMedia> 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 paid_messages:flags.19?int premium_gift_months:flags.20?int = StarsTransaction;
payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector<StarsSubscription> subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector<StarsTransaction> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.StarsStatus;
@ -1885,8 +1902,8 @@ starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true
starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption;
starGift#2cc73c8 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 upgrade_stars:flags.3?long = StarGift;
starGiftUnique#5c62d151 flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int gift_address:flags.3?string = StarGift;
starGift#c62aca28 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 availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string = StarGift;
starGiftUnique#6411db89 flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector<StarGiftAttribute> availability_issued:int availability_total:int gift_address:flags.3?string resell_stars:flags.4?long = StarGift;
payments.starGiftsNotModified#a388a368 = payments.StarGifts;
payments.starGifts#901689ea hash:int gifts:Vector<StarGift> = payments.StarGifts;
@ -1922,7 +1939,7 @@ botVerification#f93cd45c bot_id:long icon:long description:string = BotVerificat
starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute;
starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute;
starGiftAttributeBackdrop#d93d859c name:string backdrop_id:int center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute;
starGiftAttributeOriginalDetails#e0bff26c flags:# sender_id:flags.0?Peer recipient_id:Peer date:int message:flags.1?TextWithEntities = StarGiftAttribute;
payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector<StarGiftAttribute> = payments.StarGiftUpgradePreview;
@ -1934,12 +1951,13 @@ payments.uniqueStarGift#caa2f60b gift:StarGift users:Vector<User> = payments.Uni
messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector<User> = messages.WebPagePreview;
savedStarGift#6056dba5 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long = SavedStarGift;
savedStarGift#dfda0499 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true pinned_to_top:flags.12?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long can_transfer_at:flags.13?int can_resell_at:flags.14?int = SavedStarGift;
payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:flags.1?Bool gifts:Vector<SavedStarGift> next_offset:flags.0?string chats:Vector<Chat> users:Vector<User> = payments.SavedStarGifts;
inputSavedStarGiftUser#69279795 msg_id:int = InputSavedStarGift;
inputSavedStarGiftChat#f101aa7f peer:InputPeer saved_id:long = InputSavedStarGift;
inputSavedStarGiftSlug#2085c238 slug:string = InputSavedStarGift;
payments.starGiftWithdrawalUrl#84aa3a9c url:string = payments.StarGiftWithdrawalUrl;
@ -1947,6 +1965,33 @@ paidReactionPrivacyDefault#206ad49e = PaidReactionPrivacy;
paidReactionPrivacyAnonymous#1f0c1ad9 = PaidReactionPrivacy;
paidReactionPrivacyPeer#dc6cfcf0 peer:InputPeer = PaidReactionPrivacy;
account.paidMessagesRevenue#1e109708 stars_amount:long = account.PaidMessagesRevenue;
requirementToContactEmpty#50a9839 = RequirementToContact;
requirementToContactPremium#e581e4e9 = RequirementToContact;
requirementToContactPaidMessages#b4f67e93 stars_amount:long = RequirementToContact;
businessBotRights#a0624cf7 flags:# reply:flags.0?true read_messages:flags.1?true delete_sent_messages:flags.2?true delete_received_messages:flags.3?true edit_name:flags.4?true edit_bio:flags.5?true edit_profile_photo:flags.6?true edit_username:flags.7?true view_gifts:flags.8?true sell_gifts:flags.9?true change_gift_settings:flags.10?true transfer_and_upgrade_gifts:flags.11?true transfer_stars:flags.12?true manage_stories:flags.13?true = BusinessBotRights;
disallowedGiftsSettings#71f276c4 flags:# disallow_unlimited_stargifts:flags.0?true disallow_limited_stargifts:flags.1?true disallow_unique_stargifts:flags.2?true disallow_premium_gifts:flags.3?true = DisallowedGiftsSettings;
sponsoredPeer#c69708d3 flags:# random_id:bytes peer:Peer sponsor_info:flags.0?string additional_info:flags.1?string = SponsoredPeer;
contacts.sponsoredPeersEmpty#ea32b4b1 = contacts.SponsoredPeers;
contacts.sponsoredPeers#eb032884 peers:Vector<SponsoredPeer> chats:Vector<Chat> users:Vector<User> = contacts.SponsoredPeers;
starGiftAttributeIdModel#48aaae3c document_id:long = StarGiftAttributeId;
starGiftAttributeIdPattern#4a162433 document_id:long = StarGiftAttributeId;
starGiftAttributeIdBackdrop#1f01c757 backdrop_id:int = StarGiftAttributeId;
starGiftAttributeCounter#2eb1b658 attribute:StarGiftAttributeId count:int = StarGiftAttributeCounter;
payments.resaleStarGifts#947a12df flags:# count:int gifts:Vector<StarGift> next_offset:flags.0?string attributes:flags.1?Vector<StarGiftAttribute> attributes_hash:flags.1?long chats:Vector<Chat> counters:flags.2?Vector<StarGiftAttributeCounter> users:Vector<User> = payments.ResaleStarGifts;
stories.canSendStoryCount#c387c04e count_remains:int = stories.CanSendStoryCount;
pendingSuggestion#e7e82e12 suggestion:string title:TextWithEntities description:TextWithEntities url:string = PendingSuggestion;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -2081,7 +2126,7 @@ account.updateBusinessWorkHours#4b00e066 flags:# business_work_hours:flags.0?Bus
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.updateConnectedBot#66a08c7e flags:# deleted:flags.1?true rights:flags.0?BusinessBotRights 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;
@ -2098,11 +2143,13 @@ account.toggleSponsoredMessages#b9d9a38d enabled:Bool = Bool;
account.getReactionsNotifySettings#6dd654c = ReactionsNotifySettings;
account.setReactionsNotifySettings#316ce548 settings:ReactionsNotifySettings = ReactionsNotifySettings;
account.getCollectibleEmojiStatuses#2e7b4543 hash:long = account.EmojiStatuses;
account.addNoPaidMessagesException#6f688aa7 flags:# refund_charged:flags.0?true user_id:InputUser = Bool;
account.getPaidMessagesRevenue#f1266f38 user_id:InputUser = account.PaidMessagesRevenue;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
users.getIsPremiumRequiredToContact#a622aa10 id:Vector<InputUser> = Vector<Bool>;
users.getRequirementsToContact#d89a83a3 id:Vector<InputUser> = Vector<RequirementToContact>;
contacts.getContactIDs#7adc669d hash:long = Vector<int>;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
@ -2130,6 +2177,7 @@ contacts.importContactToken#13005788 token:string = User;
contacts.editCloseFriends#ba6705f0 id:Vector<long> = Bool;
contacts.setBlocked#94c65c76 flags:# my_stories_from:flags.0?true id:Vector<InputPeer> limit:int = Bool;
contacts.getBirthdays#daeda864 = contacts.ContactBirthdays;
contacts.getSponsoredPeers#b6c8c393 q:string = contacts.SponsoredPeers;
messages.getMessages#63c66506 id:Vector<InputMessage> = 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;
@ -2140,9 +2188,9 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
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<MessageEntity> 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<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.forwardMessages#6d74da08 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<int> random_id:Vector<long> 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 video_timestamp:flags.20?int = Updates;
messages.sendMessage#fbf2340a 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<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
messages.sendMedia#a550cd78 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<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long = Updates;
messages.forwardMessages#38f0188c 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<int> random_id:Vector<long> to_peer:InputPeer top_msg_id:flags.9?int reply_to:flags.22?InputReplyTo schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
messages.report#fc78af9b peer:InputPeer id:Vector<int> option:bytes message:string = ReportResult;
@ -2185,7 +2233,7 @@ 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<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM switch_webview:flags.4?InlineBotWebView = Bool;
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.sendInlineBotResult#c0cf7646 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 allow_paid_stars:flags.21?long = Updates;
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
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<MessageEntity> 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<MessageEntity> = Bool;
@ -2220,12 +2268,12 @@ 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#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<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;
messages.sendMultiMedia#1bf89d74 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<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?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<MessageRange>;
messages.markDialogUnread#c286d98f flags:# unread:flags.0?true peer:InputDialogPeer = Bool;
messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
messages.markDialogUnread#8c5006f8 flags:# unread:flags.0?true parent_peer:flags.1?InputPeer peer:InputDialogPeer = Bool;
messages.getDialogUnreadMarks#21202222 flags:# parent_peer:flags.0?InputPeer = Vector<DialogPeer>;
messages.clearAllDrafts#7e58ee9c = Bool;
messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates;
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
@ -2255,7 +2303,7 @@ messages.getOldFeaturedStickers#7ed094a1 offset:int limit:int hash:long = messag
messages.getReplies#22ddd30c peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
messages.unpinAllMessages#ee22b9a8 flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
messages.unpinAllMessages#62dd747 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
messages.deleteChat#5bd0ee50 chat_id:long = Bool;
messages.deletePhoneCallHistory#f9cbe409 flags:# revoke:flags.0?true = messages.AffectedFoundMessages;
messages.checkHistoryImport#43fe19f3 import_head:string = messages.HistoryImportParsed;
@ -2286,8 +2334,8 @@ messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_rea
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<int> text:flags.1?Vector<TextWithEntities> to_lang:string = messages.TranslatedText;
messages.getUnreadReactions#3223495b 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.readReactions#54aa7f8e flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory;
messages.getUnreadReactions#bd7f90ac flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
messages.readReactions#9ec44f93 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory;
messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages;
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
@ -2319,9 +2367,9 @@ messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
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.getSavedDialogs#1e91fc99 flags:# exclude_pinned:flags.0?true parent_peer:flags.1?InputPeer offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs;
messages.getSavedHistory#998ab009 flags:# parent_peer:flags.0?InputPeer 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#4dc5085f flags:# parent_peer:flags.0?InputPeer 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<InputDialogPeer> = Bool;
@ -2348,14 +2396,16 @@ messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true fullscreen:fla
messages.sendPaidReaction#58bbcb50 flags:# peer:InputPeer msg_id:int count:int random_id:long private:flags.0?PaidReactionPrivacy = Updates;
messages.togglePaidReactionPrivacy#435885b5 peer:InputPeer msg_id:int private:PaidReactionPrivacy = 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.viewSponsoredMessage#269e3643 random_id:bytes = Bool;
messages.clickSponsoredMessage#8235057e flags:# media:flags.0?true fullscreen:flags.1?true random_id:bytes = Bool;
messages.reportSponsoredMessage#12cbf0c4 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<InlineQueryPeerType> = 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<string> offset:int limit:int hash:long = messages.FoundStickers;
messages.reportMessagesDelivery#5a6d7395 flags:# push:flags.0?true peer:InputPeer id:Vector<int> = Bool;
messages.getSavedDialogsByID#6f6f9c96 flags:# parent_peer:flags.1?InputPeer ids:Vector<InputPeer> = messages.SavedDialogs;
messages.readSavedHistory#ba4a3b5b parent_peer:InputPeer peer:InputPeer max_id:int = Bool;
updates.getState#edd4882a = updates.State;
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;
@ -2444,7 +2494,7 @@ channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates;
channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector<string> = Bool;
channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool;
channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool;
channels.toggleForum#a4298b29 channel:InputChannel enabled:Bool = Updates;
channels.toggleForum#3ff75734 channel:InputChannel enabled:Bool tabs:Bool = Updates;
channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates;
channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics;
channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector<int> = messages.ForumTopics;
@ -2463,6 +2513,9 @@ channels.setBoostsToUnblockRestrictions#ad399cee channel:InputChannel boosts:int
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;
channels.updatePaidMessagesPrice#4b12327b flags:# broadcast_messages_allowed:flags.0?true channel:InputChannel send_paid_messages_stars:long = Updates;
channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Updates;
channels.getMessageAuthor#ece2a0e6 channel:InputChannel id:int = User;
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
@ -2505,7 +2558,6 @@ payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
payments.exportInvoice#f91b065 invoice_media:InputMedia = payments.ExportedInvoice;
payments.assignAppStoreTransaction#80ed747d receipt:bytes purpose:InputStorePaymentPurpose = Updates;
payments.assignPlayMarketTransaction#dffd50d3 receipt:DataJSON purpose:InputStorePaymentPurpose = Updates;
payments.canPurchasePremium#9fc19eb6 purpose:InputStorePaymentPurpose = Bool;
payments.getPremiumGiftCodeOptions#2757ba54 flags:# boost_peer:flags.0?InputPeer = Vector<PremiumGiftCodeOption>;
payments.checkGiftCode#8e51b4c1 slug:string = payments.CheckedGiftCode;
payments.applyGiftCode#f6e26854 slug:string = Updates;
@ -2542,6 +2594,10 @@ payments.getSavedStarGifts#23830de9 flags:# exclude_unsaved:flags.0?true exclude
payments.getSavedStarGift#b455a106 stargift:Vector<InputSavedStarGift> = payments.SavedStarGifts;
payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password:InputCheckPasswordSRP = payments.StarGiftWithdrawalUrl;
payments.toggleChatStarGiftNotifications#60eaefa1 flags:# enabled:flags.0?true peer:InputPeer = Bool;
payments.toggleStarGiftsPinnedToTop#1513e7b0 peer:InputPeer stargift:Vector<InputSavedStarGift> = Bool;
payments.canPurchaseStore#4fdc5ea7 purpose:InputStorePaymentPurpose = Bool;
payments.getResaleStarGifts#7a5fa236 flags:# sort_by_price:flags.1?true sort_by_num:flags.2?true attributes_hash:flags.0?long gift_id:long attributes:flags.3?Vector<StarGiftAttributeId> offset:string limit:int = payments.ResaleStarGifts;
payments.updateStarGiftPrice#3baea4e1 stargift:InputSavedStarGift resell_stars:long = Updates;
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<InputStickerSetItem> software:flags.3?string = messages.StickerSet;
stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet;
@ -2556,7 +2612,7 @@ stickers.deleteStickerSet#87704394 stickerset:InputStickerSet = Bool;
stickers.replaceSticker#4696459a sticker:InputDocument new_sticker:InputStickerSetItem = messages.StickerSet;
phone.getCallConfig#55451fa9 = DataJSON;
phone.requestCall#a6c4600c flags:# video:flags.0?true user_id:InputUser conference_call:flags.1?InputGroupCall random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
@ -2565,7 +2621,7 @@ phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhon
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
phone.sendSignalingData#ff7a9383 peer:InputPhoneCall data:bytes = Bool;
phone.createGroupCall#48cdc6d8 flags:# rtmp_stream:flags.2?true peer:InputPeer random_id:int title:flags.0?string schedule_date:flags.1?int = Updates;
phone.joinGroupCall#d61e1df3 flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string key_fingerprint:flags.3?long params:DataJSON = Updates;
phone.joinGroupCall#8fb53057 flags:# muted:flags.0?true video_stopped:flags.2?true call:InputGroupCall join_as:InputPeer invite_hash:flags.1?string public_key:flags.3?int256 block:flags.3?bytes params:DataJSON = Updates;
phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates;
phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector<InputUser> = Updates;
phone.discardGroupCall#7a777135 call:InputGroupCall = Updates;
@ -2586,7 +2642,12 @@ phone.leaveGroupCallPresentation#1c50d144 call:InputGroupCall = Updates;
phone.getGroupCallStreamChannels#1ab21940 call:InputGroupCall = phone.GroupCallStreamChannels;
phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl;
phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool;
phone.createConferenceCall#dfc909ab peer:InputPhoneCall key_fingerprint:long = phone.PhoneCall;
phone.createConferenceCall#7d0444bb flags:# muted:flags.0?true video_stopped:flags.2?true join:flags.3?true random_id:int public_key:flags.3?int256 block:flags.3?bytes params:flags.3?DataJSON = Updates;
phone.deleteConferenceCallParticipants#8ca60525 flags:# only_left:flags.0?true kick:flags.1?true call:InputGroupCall ids:Vector<long> block:bytes = Updates;
phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Updates;
phone.inviteConferenceCallParticipant#bcf22685 flags:# video:flags.0?true call:InputGroupCall user_id:InputUser = Updates;
phone.declineConferenceCallInvite#3c479971 msg_id:int = Updates;
phone.getGroupCallChainBlocks#ee9f88a6 call:InputGroupCall sub_chain_id:int offset:int limit:int = Updates;
langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<string> = Vector<LangPackString>;
@ -2619,7 +2680,7 @@ chatlists.hideChatlistUpdates#66e486fb chatlist:InputChatlist = Bool;
chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector<Peer>;
chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector<InputPeer> = Updates;
stories.canSendStory#c7dfdfdd peer:InputPeer = Bool;
stories.canSendStory#30eb63f0 peer:InputPeer = stories.CanSendStoryCount;
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<MediaArea> caption:flags.0?string entities:flags.1?Vector<MessageEntity> privacy_rules:Vector<InputPrivacyRule> 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<MediaArea> caption:flags.1?string entities:flags.1?Vector<MessageEntity> privacy_rules:flags.2?Vector<InputPrivacyRule> = Updates;
stories.deleteStories#ae59db5f peer:InputPeer id:Vector<int> = Vector<int>;
@ -2662,4 +2723,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool;
fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo;
// LAYER 199
// LAYER 204

View file

@ -146,6 +146,7 @@ def pyrogram_api():
stop_transmission
export_session_string
set_parse_mode
ping
""",
conversation="""
Conversation
@ -364,16 +365,24 @@ def pyrogram_api():
get_chat_gifts
hide_gift
refund_star_payment
search_gifts_for_resale
send_invoice
send_paid_media
send_paid_reaction
send_payment_form
send_gift
send_resold_gift
set_gift_resale_price
set_pinned_gifts
show_gift
transfer_gift
upgrade_gift
get_stars_balance
""",
phone="""
Phone
get_call_members
""",
password="""
Password
enable_cloud_password
@ -408,7 +417,11 @@ def pyrogram_api():
Telegram Business
answer_pre_checkout_query
answer_shipping_query
delete_business_messages
get_business_connection
get_business_account_gifts
get_business_account_star_balance
transfer_business_account_stars
""",
authorization="""
Authorization
@ -420,12 +433,11 @@ def pyrogram_api():
resend_code
sign_in
sign_in_bot
sign_up
sign_in_qrcode
get_password_hint
check_password
send_recovery_code
recover_password
accept_terms_of_service
log_out
get_active_sessions
""",
@ -449,7 +461,7 @@ def pyrogram_api():
fmt_keys = {}
for k, v in categories.items():
name, *methods = get_title_list(v)
_, *methods = get_title_list(v)
fmt_keys.update({k: "\n ".join("{0} <{0}>".format(m) for m in methods)})
for method in methods:
@ -483,6 +495,7 @@ def pyrogram_api():
BusinessWeeklyOpen
BusinessWorkingHours
User
Username
Chat
ChatPreview
ChatPhoto
@ -505,6 +518,7 @@ def pyrogram_api():
PeerUser
PeerChannel
BotInfo
GroupCallMember
ChatColor
CollectibleItemInfo
BotVerification
@ -513,11 +527,18 @@ def pyrogram_api():
Messages & Media
Message
MessageEntity
MessageOriginChannel
MessageOriginChat
MessageOriginHiddenUser
MessageOriginImport
MessageOriginUser
MessageOrigin
Photo
Thumbnail
Audio
AvailableEffect
Document
ExternalReplyInfo
AlternativeVideo
Animation
Video
@ -540,6 +561,7 @@ def pyrogram_api():
WebPagePreview
TranscribedAudio
TranslatedText
TextQuote
Poll
PollOption
Dice
@ -595,6 +617,7 @@ def pyrogram_api():
Invoice
LabeledPrice
PaidMedia
PaidMessagePriceChanged
PaymentForm
PaymentInfo
PaymentRefunded
@ -704,6 +727,7 @@ def pyrogram_api():
InputMessageContent
InputMessageContent
InputReplyToMessage
InputReplyToMonoforum
InputReplyToStory
InputTextMessageContent
InputLocationMessageContent
@ -715,6 +739,7 @@ def pyrogram_api():
Authorization
ActiveSession
ActiveSessions
LoginToken
SentCode
TermsOfService
"""
@ -732,7 +757,7 @@ def pyrogram_api():
fmt_keys = {}
for k, v in categories.items():
name, *types = get_title_list(v)
_, *types = get_title_list(v)
fmt_keys.update({k: "\n ".join(types)})

View file

@ -17,6 +17,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import ast
import csv
import os
import re
@ -37,6 +38,13 @@ def caml(s):
s = snek(s).split("_")
return "".join([str(i.title()) for i in s])
def get_classes_from_file(file_path):
with open(file_path, "r", encoding="utf-8") as f:
tree = ast.parse(f.read())
classes = [node.name for node in ast.walk(tree) if isinstance(node, ast.ClassDef)]
return classes
def start():
shutil.rmtree(DEST, ignore_errors=True)
@ -127,6 +135,20 @@ def start():
f_all.write(" },\n")
f_all.write("}\n")
with open(init, "a", encoding="utf-8") as f_init:
f_init.write("\n")
all_classes = []
for i in files:
code, name = re.search(r"(\d+)_([A-Z_]+)", i).groups()
classes = get_classes_from_file("{}/{}_{}.py".format(DEST, name.lower(), code))
for j in classes:
if j not in ["BaseException", "Exception", "PyrogramException"]:
all_classes.append(j)
f_init.write("__all__ = [\n")
all_classes = sorted(set(all_classes))
for i in all_classes:
f_init.write(" \"{}\",\n".format(i))
f_init.write("]\n")
with open("{}/all.py".format(DEST), encoding="utf-8") as f:
content = f.read()

View file

@ -35,6 +35,7 @@ BOT_GAMES_DISABLED Bot games cannot be used in this type of chat
BOT_GROUPS_BLOCKED This bot can't be added to groups
BOT_INLINE_DISABLED The inline feature of the bot is disabled
BOT_INVALID This is not a valid bot
BOT_INVOICE_INVALID The provided invoice is invalid
BOT_METHOD_INVALID The method can't be used by bots
BOT_MISSING This method can only be run by a bot
BOT_ONESIDE_NOT_AVAIL Bots can't pin messages for one side only in private chats
@ -46,6 +47,7 @@ BROADCAST_CALLS_DISABLED Broadcast calls disabled
BROADCAST_ID_INVALID The channel is invalid
BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels
BROADCAST_REQUIRED The request can only be used with a channel
BUSINESS_BOT_MISSING Business bot missing
BUTTON_DATA_INVALID The button callback data is invalid or too large
BUTTON_ID_INVALID The button_id parameter is invalid
BUTTON_TEXT_INVALID The specified button text is invalid
@ -503,3 +505,4 @@ BOOSTS_EMPTY You can't modify the icon of the General topic.
BOOST_NOT_MODIFIED You're already boosting the specified channel.
PAYMENT_REQUIRED The payment is required
BOOST_PEER_INVALID The specified `boost_peer` is invalid.
STARS_AMOUNT_INVALID The specified `amount` is invalid.
1 id message
35 BOT_GROUPS_BLOCKED This bot can't be added to groups
36 BOT_INLINE_DISABLED The inline feature of the bot is disabled
37 BOT_INVALID This is not a valid bot
38 BOT_INVOICE_INVALID The provided invoice is invalid
39 BOT_METHOD_INVALID The method can't be used by bots
40 BOT_MISSING This method can only be run by a bot
41 BOT_ONESIDE_NOT_AVAIL Bots can't pin messages for one side only in private chats
47 BROADCAST_ID_INVALID The channel is invalid
48 BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels
49 BROADCAST_REQUIRED The request can only be used with a channel
50 BUSINESS_BOT_MISSING Business bot missing
51 BUTTON_DATA_INVALID The button callback data is invalid or too large
52 BUTTON_ID_INVALID The button_id parameter is invalid
53 BUTTON_TEXT_INVALID The specified button text is invalid
505 BOOST_NOT_MODIFIED You're already boosting the specified channel.
506 PAYMENT_REQUIRED The payment is required
507 BOOST_PEER_INVALID The specified `boost_peer` is invalid.
508 STARS_AMOUNT_INVALID The specified `amount` is invalid.

View file

@ -44,3 +44,4 @@ GROUPCALL_ALREADY_STARTED The groupcall has already started, you can join direct
GROUPCALL_FORBIDDEN The group call has already ended
LIVE_DISABLED Story is disabled server-side
CHAT_GUEST_SEND_FORBIDDEN You need to join the discussion group before commenting
ALLOW_PAYMENT_REQUIRED_X Payment of {value} stars is required to perform this action
1 id message
44 GROUPCALL_FORBIDDEN The group call has already ended
45 LIVE_DISABLED Story is disabled server-side
46 CHAT_GUEST_SEND_FORBIDDEN You need to join the discussion group before commenting
47 ALLOW_PAYMENT_REQUIRED_X Payment of {value} stars is required to perform this action

View file

@ -0,0 +1,8 @@
GiftAttributeType
=================
.. autoclass:: pyrogram.enums.GiftForResaleOrder()
:members:
.. raw:: html
:file: ./cleanup.html

View file

@ -0,0 +1,8 @@
MessageOriginType
=================
.. autoclass:: pyrogram.enums.MessageOriginType()
:members:
.. raw:: html
:file: ./cleanup.html

View file

@ -29,7 +29,7 @@ from pygments.styles.friendly import FriendlyStyle
FriendlyStyle.background_color = "#f3f2f1"
project = "Pyrofork"
copyright = f"2022-present, Mayuri-Chan"
copyright = "2022-present, Mayuri-Chan"
author = "Mayuri-Chan"
version = ".".join(__version__.split(".")[:-1])

View file

@ -60,7 +60,7 @@ dev = [
docs = [
"sphinx",
"sphinx-immaterial==0.12.4",
"sphinx-immaterial==0.12.5",
"sphinx_copybutton",
"sphinx-autobuild",
"tornado>=6.3.3"

View file

@ -18,7 +18,7 @@
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
__fork_name__ = "PyroFork"
__version__ = "2.3.59"
__version__ = "2.3.67"
__license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)"
__copyright__ = "Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>"
@ -37,8 +37,24 @@ class ContinuePropagation(StopAsyncIteration):
pass
from . import raw, types, filters, handlers, emoji, enums
from .client import Client
from .sync import idle, compose
from . import raw, types, filters, handlers, emoji, enums # pylint: disable=wrong-import-position
from .client import Client # pylint: disable=wrong-import-position
from .sync import idle, compose # pylint: disable=wrong-import-position
crypto_executor = ThreadPoolExecutor(1, thread_name_prefix="CryptoWorker")
__all__ = [
"Client",
"idle",
"compose",
"crypto_executor",
"StopTransmission",
"StopPropagation",
"ContinuePropagation",
"raw",
"types",
"filters",
"handlers",
"emoji",
"enums",
]

View file

@ -33,12 +33,13 @@ from importlib import import_module
from io import StringIO, BytesIO
from mimetypes import MimeTypes
from pathlib import Path
from typing import Union, List, Optional, Callable, AsyncGenerator, Type, Tuple
from typing import Union, List, Optional, Callable, AsyncGenerator, Tuple
import pyrogram
from pyrogram import __version__, __license__
from pyrogram import enums
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
from pyrogram.crypto import aes
from pyrogram.errors import CDNFileHashMismatch
@ -51,24 +52,26 @@ from pyrogram.handlers.handler import Handler
from pyrogram.methods import Methods
from pyrogram.session import Auth, Session
from pyrogram.storage import FileStorage, MemoryStorage, Storage
from pyrogram.types import User
from pyrogram.utils import ainput
from .connection import Connection
from .connection.transport import TCPAbridged
from .dispatcher import Dispatcher
from .file_id import FileId, FileType, ThumbnailSource
from .mime_types import mime_types
from .parser import Parser
from .session.internals import MsgId
log = logging.getLogger(__name__)
MONGO_AVAIL = False
try:
import pymongo
except Exception:
pass
else:
from pyrogram.storage import MongoStorage
from pyrogram.types import User, TermsOfService
from pyrogram.utils import ainput
from .connection import Connection
from .connection.transport import TCP, TCPAbridged
from .dispatcher import Dispatcher
from .file_id import FileId, FileType, ThumbnailSource
from .filters import Filter
from .mime_types import mime_types
from .parser import Parser
from .session.internals import MsgId
log = logging.getLogger(__name__)
MONGO_AVAIL = True
class Client(Methods):
@ -128,6 +131,9 @@ class Client(Methods):
Pass a session string to load the session in-memory.
Implies ``in_memory=True``.
use_qrcode (``bool``, *optional*):
Pass True to login using a QR code.
in_memory (``bool``, *optional*):
Pass True to start an in-memory session that will be discarded as soon as the client stops.
In order to reconnect again using an in-memory session without having to login again, you can use
@ -225,6 +231,7 @@ class Client(Methods):
PARENT_DIR = Path(sys.argv[0]).parent
INVITE_LINK_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:joinchat/|\+))([\w-]+)$")
UPGRADED_GIFT_RE = re.compile(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:nft/|\+))([\w-]+)$")
WORKERS = min(32, (os.cpu_count() or 0) + 4) # os.cpu_count() can be None
WORKDIR = PARENT_DIR
@ -252,6 +259,7 @@ class Client(Methods):
test_mode: Optional[bool] = False,
bot_token: Optional[str] = None,
session_string: Optional[str] = None,
use_qrcode: Optional[bool] = False,
in_memory: Optional[bool] = None,
mongodb: Optional[dict] = None,
storage: Optional[Storage] = None,
@ -266,7 +274,7 @@ class Client(Methods):
skip_updates: bool = True,
takeout: bool = None,
sleep_threshold: int = Session.SLEEP_THRESHOLD,
hide_password: Optional[bool] = False,
hide_password: Optional[bool] = True,
max_concurrent_transmissions: int = MAX_CONCURRENT_TRANSMISSIONS,
client_platform: "enums.ClientPlatform" = enums.ClientPlatform.OTHER,
max_message_cache_size: int = MAX_CACHE_SIZE,
@ -287,6 +295,7 @@ class Client(Methods):
self.test_mode = test_mode
self.bot_token = bot_token
self.session_string = session_string
self.use_qrcode = use_qrcode
self.in_memory = in_memory
self.mongodb = mongodb
self.phone_number = phone_number
@ -316,9 +325,7 @@ class Client(Methods):
elif self.in_memory:
self.storage = MemoryStorage(self.name)
elif self.mongodb:
try:
import pymongo
except Exception:
if not MONGO_AVAIL:
log.warning(
"pymongo is missing! "
"Using MemoryStorage as session storage"
@ -397,6 +404,15 @@ class Client(Methods):
if datetime.now() - self.last_update_time > timedelta(seconds=self.UPDATES_WATCHDOG_INTERVAL):
await self.invoke(raw.functions.updates.GetState())
async def _wait_for_update_login_token(self):
"""
Wait for an UpdateLoginToken update from Telegram.
"""
while True:
update, _, _ = await self.dispatcher.updates_queue.get()
if isinstance(update, raw.types.UpdateLoginToken):
break
async def authorize(self) -> User:
if self.bot_token:
return await self.sign_in_bot(self.bot_token)
@ -404,52 +420,60 @@ class Client(Methods):
print(f"Welcome to Pyrogram (version {__version__})")
print(f"Pyrogram is free software and comes with ABSOLUTELY NO WARRANTY. Licensed\n"
f"under the terms of the {__license__}.\n")
if not self.use_qrcode:
while True:
try:
if not self.phone_number:
while True:
print("Enter 'qrcode' if you want to login with qrcode.")
value = await ainput("Enter phone number or bot token: ")
if not value:
continue
if value.lower() == "qrcode":
self.use_qrcode = True
break
confirm = (await ainput(f'Is "{value}" correct? (y/N): ')).lower()
if confirm == "y":
break
if ":" in value:
self.bot_token = value
return await self.sign_in_bot(value)
else:
self.phone_number = value
sent_code = await self.send_code(self.phone_number)
except BadRequest as e:
print(e.MESSAGE)
self.phone_number = None
self.bot_token = None
else:
break
sent_code_descriptions = {
enums.SentCodeType.APP: "Telegram app",
enums.SentCodeType.SMS: "SMS",
enums.SentCodeType.CALL: "phone call",
enums.SentCodeType.FLASH_CALL: "phone flash call",
enums.SentCodeType.FRAGMENT_SMS: "Fragment SMS",
enums.SentCodeType.EMAIL_CODE: "email code"
}
print(f"The confirmation code has been sent via {sent_code_descriptions[sent_code.type]}")
while True:
try:
if not self.phone_number:
while True:
value = await ainput("Enter phone number or bot token: ")
if not value:
continue
confirm = (await ainput(f'Is "{value}" correct? (y/N): ')).lower()
if confirm == "y":
break
if ":" in value:
self.bot_token = value
return await self.sign_in_bot(value)
else:
self.phone_number = value
sent_code = await self.send_code(self.phone_number)
except BadRequest as e:
print(e.MESSAGE)
self.phone_number = None
self.bot_token = None
else:
break
sent_code_descriptions = {
enums.SentCodeType.APP: "Telegram app",
enums.SentCodeType.SMS: "SMS",
enums.SentCodeType.CALL: "phone call",
enums.SentCodeType.FLASH_CALL: "phone flash call",
enums.SentCodeType.FRAGMENT_SMS: "Fragment SMS",
enums.SentCodeType.EMAIL_CODE: "email code"
}
print(f"The confirmation code has been sent via {sent_code_descriptions[sent_code.type]}")
while True:
if not self.phone_code:
if not self.use_qrcode and not self.phone_code:
self.phone_code = await ainput("Enter confirmation code: ")
try:
signed_in = await self.sign_in(self.phone_number, sent_code.phone_code_hash, self.phone_code)
if self.use_qrcode:
signed_in = await self.sign_in_qrcode()
else:
signed_in = await self.sign_in(self.phone_number, sent_code.phone_code_hash, self.phone_code)
except BadRequest as e:
print(e.MESSAGE)
self.phone_code = None
@ -488,33 +512,18 @@ class Client(Methods):
print(e.MESSAGE)
self.password = None
else:
if self.use_qrcode and isinstance(signed_in, types.LoginToken):
time_out = signed_in.expires - datetime.timestamp(datetime.now())
try:
await asyncio.wait_for(self._wait_for_update_login_token(), timeout=time_out)
except asyncio.TimeoutError:
print("QR code expired, Requesting new Qr code...")
continue
break
if isinstance(signed_in, User):
return signed_in
while True:
first_name = await ainput("Enter first name: ")
last_name = await ainput("Enter last name (empty to skip): ")
try:
signed_up = await self.sign_up(
self.phone_number,
sent_code.phone_code_hash,
first_name,
last_name
)
except BadRequest as e:
print(e.MESSAGE)
else:
break
if isinstance(signed_in, TermsOfService):
print("\n" + signed_in.text + "\n")
await self.accept_terms_of_service(signed_in.id)
return signed_up
def set_parse_mode(self, parse_mode: Optional["enums.ParseMode"]):
"""Set the parse mode to be used globally by the client.
@ -888,7 +897,7 @@ class Client(Methods):
count = 0
if not include:
for current_root, dirnames, filenames in os.walk(root.replace(".", "/")):
for current_root, _, filenames in os.walk(root.replace(".", "/")):
namespace = current_root.replace("/", ".").replace("\\", ".")
if "__pycache__" in namespace:
continue
@ -953,7 +962,7 @@ class Client(Methods):
)
count += 1
except Exception as e:
except Exception:
pass
else:
for path, handlers in include:
@ -1042,7 +1051,7 @@ class Client(Methods):
)
count += 1
except Exception as e:
except Exception:
pass
if handlers is None:
@ -1106,7 +1115,7 @@ class Client(Methods):
async def handle_download(self, packet):
file_id, directory, file_name, in_memory, file_size, progress, progress_args = packet
os.makedirs(directory, exist_ok=True) if not in_memory else None
_ = os.makedirs(directory, exist_ok=True) if not in_memory else None
temp_file_path = os.path.abspath(re.sub("\\\\", "/", os.path.join(directory, file_name))) + ".temp"
file = BytesIO() if in_memory else open(temp_file_path, "wb")

View file

@ -18,3 +18,7 @@
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from .connection import Connection
__all__ = [
"Connection"
]

View file

@ -52,7 +52,7 @@ class Connection:
self.protocol: Optional[TCP] = None
async def connect(self) -> None:
for i in range(Connection.MAX_CONNECTION_ATTEMPTS):
for _ in range(Connection.MAX_CONNECTION_ATTEMPTS):
self.protocol = self.protocol_factory(ipv6=self.ipv6, proxy=self.proxy)
try:

View file

@ -18,3 +18,6 @@
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from .tcp import *
__all__ = []
__all__.extend(tcp.__all__)

View file

@ -23,3 +23,13 @@ from .tcp_abridged_o import TCPAbridgedO
from .tcp_full import TCPFull
from .tcp_intermediate import TCPIntermediate
from .tcp_intermediate_o import TCPIntermediateO
__all__ = [
"TCP",
"Proxy",
"TCPAbridged",
"TCPAbridgedO",
"TCPFull",
"TCPIntermediate",
"TCPIntermediateO"
]

View file

@ -21,7 +21,6 @@ import asyncio
import ipaddress
import logging
import socket
from concurrent.futures import ThreadPoolExecutor
from typing import Tuple, Dict, TypedDict, Optional
import socks

View file

@ -71,7 +71,7 @@ def unpack(
message = Message.read(data)
except KeyError as e:
if e.args[0] == 0:
raise ConnectionError(f"Received empty data. Check your internet connection.")
raise ConnectionError("Received empty data. Check your internet connection.")
left = data.read().hex()

View file

@ -55,7 +55,7 @@ def decompose(pq: int) -> int:
while g == 1:
x = y
for i in range(r):
for _ in range(r):
y = (pow(y, 2, pq) + c) % pq
k = 0
@ -63,7 +63,7 @@ def decompose(pq: int) -> int:
while k < r and g == 1:
ys = y
for i in range(min(m, r - k)):
for _ in range(min(m, r - k)):
y = (pow(y, 2, pq) + c) % pq
q = q * (abs(x - y)) % pq

View file

@ -21,9 +21,10 @@ import asyncio
import inspect
import logging
from collections import OrderedDict
from typing import Any
import pyrogram
from pyrogram import errors, raw, types, utils
from pyrogram import raw, types, utils
from pyrogram.handlers.handler import Handler
from pyrogram.handlers import (
BotBusinessConnectHandler,
@ -266,7 +267,7 @@ class Dispatcher:
async def start(self):
if not self.client.no_updates:
for i in range(self.client.workers):
for _ in range(self.client.workers):
self.locks_list.append(asyncio.Lock())
self.handler_worker_tasks.append(
@ -337,59 +338,88 @@ class Dispatcher:
async def handler_worker(self, lock: asyncio.Lock):
while True:
packet = await self.updates_queue.get()
if packet is None:
break
await self._process_packet(packet, lock)
async def _process_packet(
self,
packet: tuple[raw.core.TLObject, dict[int, types.Update], dict[int, types.Update]],
lock: asyncio.Lock,
try:
await self._handle_packet(packet, lock)
except pyrogram.StopPropagation:
pass
except Exception as e:
log.exception(e)
finally:
self.updates_queue.task_done()
async def _handle_packet(self, packet, lock: asyncio.Lock):
update, users, chats = packet
parser = self.update_parsers.get(type(update))
parsed_update, handler_type = (
await parser(update, users, chats)
if parser is not None else (None, type(None))
)
async with lock:
await self._dispatch_to_handlers(update, users, chats, parsed_update, handler_type)
async def _dispatch_to_handlers(
self, update, users, chats, parsed_update, handler_type,
):
for group in self.groups.values():
for handler in group:
args = await self._match_handler(
handler, update, users, chats, parsed_update, handler_type,
)
if args is None:
continue
try:
await self._execute_handler(handler, *args)
except pyrogram.StopPropagation:
raise
except pyrogram.ContinuePropagation:
continue
except Exception as error:
if parsed_update is not None:
await self._handle_exception(parsed_update, error)
break
async def _match_handler(
self, handler, update, users, chats, parsed_update, handler_type,
):
try:
update, users, chats = packet
parser = self.update_parsers.get(type(update))
if parser is not None:
parsed_result = parser(update, users, chats)
if inspect.isawaitable(parsed_result):
parsed_update, handler_type = await parsed_result
else:
parsed_update, handler_type = parsed_result
else:
parsed_update, handler_type = (None, type(None))
async with lock:
for group in self.groups.values():
for handler in group:
try:
if parsed_update is not None:
if isinstance(handler, handler_type) and await handler.check(
self.client, parsed_update
):
await self._execute_callback(handler, parsed_update)
break
elif isinstance(handler, RawUpdateHandler):
await self._execute_callback(handler, update, users, chats)
break
except (pyrogram.StopPropagation, pyrogram.ContinuePropagation) as e:
if isinstance(e, pyrogram.StopPropagation):
raise
except Exception as exception:
if parsed_update is not None:
await self._handle_exception(parsed_update, exception)
except pyrogram.StopPropagation:
pass
if isinstance(handler, handler_type):
if await handler.check(self.client, parsed_update):
return (parsed_update,)
elif isinstance(handler, RawUpdateHandler):
if await handler.check(self.client, update):
return (update, users, chats)
except Exception as e:
log.exception(e)
finally:
self.updates_queue.task_done()
async def _handle_exception(self, parsed_update: types.Update, exception: Exception):
return None
async def _execute_handler(self, handler, *args: Any):
if inspect.iscoroutinefunction(handler.callback):
await handler.callback(self.client, *args)
else:
await self.loop.run_in_executor(
self.client.executor,
handler.callback,
self.client,
*args
)
async def _handle_exception(
self, parsed_update: types.Update, exception: Exception,
):
handled_error = False
for error_handler in self.error_handlers:
try:
if await error_handler.check(self.client, parsed_update, exception):
if await error_handler.check(
self.client, parsed_update, exception,
):
handled_error = True
break
except pyrogram.StopPropagation:
@ -401,11 +431,3 @@ class Dispatcher:
if not handled_error:
log.exception("Unhandled exception: %s", exception)
async def _execute_callback(self, handler: Handler, *args):
if inspect.iscoroutinefunction(handler.callback):
await handler.callback(self.client, *args)
else:
await self.client.loop.run_in_executor(
self.client.executor, handler.callback, self.client, *args
)

View file

@ -27,9 +27,11 @@ from .chat_type import ChatType
from .client_platform import ClientPlatform
from .folder_color import FolderColor
from .gift_attribute_type import GiftAttributeType
from .gift_for_resale_order import GiftForResaleOrder
from .listerner_types import ListenerTypes
from .message_entity_type import MessageEntityType
from .message_media_type import MessageMediaType
from .message_origin_type import MessageOriginType
from .message_service_type import MessageServiceType
from .messages_filter import MessagesFilter
from .next_code_type import NextCodeType
@ -54,9 +56,11 @@ __all__ = [
'ClientPlatform',
'FolderColor',
'GiftAttributeType',
'GiftForResaleOrder',
'ListenerTypes',
'MessageEntityType',
'MessageMediaType',
'MessageOriginType',
'MessageServiceType',
'MessagesFilter',
'NextCodeType',

View file

@ -35,13 +35,13 @@ class ChatEventAction(AutoName):
"The linked chat has been changed (see ``old_linked_chat`` and ``new_linked_chat``)"
# LOCATION_CHANGED = auto()
""
# ""
PHOTO_CHANGED = auto()
"The chat photo has been changed (see ``old_photo`` and ``new_photo``)"
# STICKER_SET_CHANGED = auto()
""
# ""
TITLE_CHANGED = auto()
"the chat title has been changed (see ``old_title`` and ``new_title``)"
@ -56,7 +56,7 @@ class ChatEventAction(AutoName):
"a message has been deleted (see ``deleted_message``)"
# VOICE_CHAT_DISCARDED = auto()
""
# ""
MESSAGE_EDITED = auto()
"a message has been edited (see ``old_message`` and ``new_message``)"
@ -77,13 +77,13 @@ class ChatEventAction(AutoName):
"a member joined by themselves. (see ``user``)"
# MEMBER_JOINED_BY_LINK = auto()
""
# ""
MEMBER_LEFT = auto()
"a member left by themselves. (see ``user``)"
# MEMBER_MUTED = auto()
""
# ""
ADMINISTRATOR_PRIVILEGES_CHANGED = auto()
"a chat member has been promoted/demoted or their administrator privileges has changed (see ``old_administrator_privileges`` and ``new_administrator_privileges``)"
@ -92,19 +92,19 @@ class ChatEventAction(AutoName):
"a chat member has been restricted/unrestricted or banned/unbanned, or their permissions has changed (see ``old_member_permissions`` and ``new_member_permissions``)"
# MEMBER_UNMUTED = auto()
""
# ""
# MEMBER_VOLUME_CHANGED = auto()
""
# ""
# VIDEO_CHAT_STARTED = auto()
""
# ""
POLL_STOPPED = auto()
"a poll has been stopped (see ``stopped_poll``)"
# VOICE_CHAT_SETTINGS_CHANGED = auto()
""
# ""
INVITES_ENABLED = auto()
"the chat invitation has been enabled or disabled (see ``invites_enabled``)"

View file

@ -39,3 +39,9 @@ class ChatType(AutoName):
CHANNEL = auto()
"Chat is a channel"
FORUM = auto()
"Chat is a forum"
MONOFORUM = auto()
"Chat is a monoforum"

View file

@ -17,29 +17,19 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from enum import auto
from .auto_name import AutoName
class AcceptTermsOfService:
async def accept_terms_of_service(
self: "pyrogram.Client",
terms_of_service_id: str
) -> bool:
"""Accept the given terms of service.
class GiftForResaleOrder(AutoName):
"""Describes order in which upgraded gifts for resale will be sorted. Used in :meth:`~pyrogram.Client.search_gifts_for_resale`."""
.. include:: /_includes/usable-by/users.rst
PRICE = auto()
"The gifts will be sorted by their price from the lowest to the highest"
Parameters:
terms_of_service_id (``str``):
The terms of service identifier.
"""
r = await self.invoke(
raw.functions.help.AcceptTermsOfService(
id=raw.types.DataJSON(
data=terms_of_service_id
)
)
)
CHANGE_DATE = auto()
"The gifts will be sorted by the last date when their price was changed from the newest to the oldest"
return bool(r)
NUMBER = auto()
"The gifts will be sorted by their number from the smallest to the largest"

View file

@ -0,0 +1,42 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from enum import auto
from .auto_name import AutoName
class MessageOriginType(AutoName):
"""Message origin type enumeration used in :obj:`~pyrogram.types.MessageOrigin`."""
CHANNEL = auto()
"The message was originally a post in a channel"
CHAT = auto()
"The message was originally sent on behalf of a chat"
HIDDEN_USER = auto()
"The message was originally sent by a user, which is hidden by their privacy settings"
IMPORT = auto()
"The message was imported from a foreign chat service"
USER = auto()
"The message was originally sent by a known user"

View file

@ -132,3 +132,6 @@ class MessageServiceType(AutoName):
SCREENSHOT_TAKEN = auto()
"Screenshot taken"
PAID_MESSAGE_PRICE_CHANGED = auto()
"Paid message price changed"

View file

@ -17,9 +17,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from .exceptions import *
EXCEPTION_AVAIL = False
try:
from .exceptions import *
except ImportError:
pass
else:
EXCEPTION_AVAIL = True
from .pyromod import *
from .rpc_error import UnknownError
from .rpc_error import RPCError, UnknownError
class BadMsgNotification(Exception):
@ -65,3 +71,15 @@ class CDNFileHashMismatch(SecurityError):
def __init__(self, msg: str = None):
super().__init__("A CDN file hash mismatch has occurred." if msg is None else msg)
__all__ = [
"BadMsgNotification",
"SecurityError",
"SecurityCheckMismatch",
"CDNFileHashMismatch",
"RPCError",
"UnknownError"
]
if EXCEPTION_AVAIL:
__all__.extend(exceptions.__all__)
__all__.extend(pyromod.__all__)

View file

@ -1,3 +1,4 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
@ -250,7 +251,7 @@ react = create(reaction_filter)
# region forwarded_filter
async def forwarded_filter(_, __, m: Message):
return bool(m.forward_date)
return bool(m.forward_origin)
forwarded = create(forwarded_filter)
@ -889,7 +890,12 @@ def command(commands: Union[str, List[str]], prefixes: Union[str, List[str]] = "
command_re = re.compile(r"([\"'])(.*?)(?<!\\)\1|(\S+)")
async def func(flt, client: pyrogram.Client, message: Message):
usernames = []
username = client.me.username or ""
if client.me.usernames:
usernames.append(username)
for user in client.me.usernames:
usernames.append(user.username)
text = message.text or message.caption
message.command = None
@ -903,6 +909,24 @@ def command(commands: Union[str, List[str]], prefixes: Union[str, List[str]] = "
without_prefix = text[len(prefix):]
for cmd in flt.commands:
if usernames:
for username in usernames:
if not re.match(rf"^(?:{cmd}(?:@?{username})?)(?:\s|$)", without_prefix,
flags=re.IGNORECASE if not flt.case_sensitive else 0):
continue
without_command = re.sub(rf"{cmd}(?:@?{username})?\s?", "", without_prefix, count=1,
flags=re.IGNORECASE if not flt.case_sensitive else 0)
# match.groups are 1-indexed, group(1) is the quote, group(2) is the text
# between the quotes, group(3) is unquoted, whitespace-split text
# Remove the escape character from the arguments
message.command = [cmd] + [
re.sub(r"\\([\"'])", r"\1", m.group(2) or m.group(3) or "")
for m in command_re.finditer(without_command)
]
return True
if not re.match(rf"^(?:{cmd}(?:@?{username})?)(?:\s|$)", without_prefix,
flags=re.IGNORECASE if not flt.case_sensitive else 0):
continue
@ -1010,12 +1034,22 @@ class user(Filter, set):
)
async def __call__(self, _, message: Message):
is_usernames_in_filters = False
if message.from_user and message.from_user.usernames:
for username in message.from_user.usernames:
if (
username.username in self
or username.username.lower() in self
):
is_usernames_in_filters = True
break
return (message.from_user
and (message.from_user.id in self
or (message.from_user.username
and message.from_user.username.lower() in self)
or ("me" in self
and message.from_user.is_self)))
and message.from_user.is_self))
or is_usernames_in_filters)
# noinspection PyPep8Naming
@ -1043,6 +1077,15 @@ class chat(Filter, set):
async def __call__(self, _, message: Union[Message, Story]):
if isinstance(message, Story):
is_usernames_in_filters = False
if message.sender_chat and message.sender_chat.usernames:
for username in message.sender_chat.usernames:
if (
username.username in self
or username.username.lower() in self
):
is_usernames_in_filters = True
break
return (
message.sender_chat
and (
@ -1061,8 +1104,17 @@ class chat(Filter, set):
and message.from_user.username.lower() in self
)
)
)
) or is_usernames_in_filters
else:
is_usernames_in_filters = False
if message.chat and message.chat.usernames:
for username in message.chat.usernames:
if (
username.username in self
or username.username.lower() in self
):
is_usernames_in_filters = True
break
return (message.chat
and (message.chat.id in self
or (message.chat.username
@ -1070,7 +1122,10 @@ class chat(Filter, set):
or ("me" in self
and message.from_user
and message.from_user.is_self
and not message.outgoing)))
and not message.outgoing))
or (is_usernames_in_filters
and not message.outgoing)
)
# noinspection PyPep8Naming

View file

@ -33,7 +33,6 @@ from .error_handler import ErrorHandler
from .inline_query_handler import InlineQueryHandler
from .message_handler import MessageHandler
from .poll_handler import PollHandler
from .pre_checkout_query_handler import PreCheckoutQueryHandler
from .purchased_paid_media_handler import PurchasedPaidMediaHandler
from .raw_update_handler import RawUpdateHandler
from .user_status_handler import UserStatusHandler
@ -42,3 +41,31 @@ from .message_reaction_updated_handler import MessageReactionUpdatedHandler
from .message_reaction_count_updated_handler import MessageReactionCountUpdatedHandler
from .pre_checkout_query_handler import PreCheckoutQueryHandler
from .shipping_query_handler import ShippingQueryHandler
__all__ = [
"BotBusinessConnectHandler",
"BotBusinessMessageHandler",
"CallbackQueryHandler",
"ChatJoinRequestHandler",
"ChatMemberUpdatedHandler",
"ConversationHandler",
"ChosenInlineResultHandler",
"DeletedMessagesHandler",
"DeletedBotBusinessMessagesHandler",
"DisconnectHandler",
"EditedMessageHandler",
"EditedBotBusinessMessageHandler",
"ErrorHandler",
"InlineQueryHandler",
"MessageHandler",
"PollHandler",
"PreCheckoutQueryHandler",
"PurchasedPaidMediaHandler",
"RawUpdateHandler",
"UserStatusHandler",
"StoryHandler",
"MessageReactionUpdatedHandler",
"MessageReactionCountUpdatedHandler",
"PreCheckoutQueryHandler",
"ShippingQueryHandler",
]

View file

@ -61,6 +61,7 @@ class ConversationHandler(MessageHandler, CallbackQueryHandler):
return True
@staticmethod
# pylint: disable=method-hidden
async def callback(_, __):
pass

View file

@ -58,5 +58,4 @@ class DeletedBotBusinessMessagesHandler(Handler):
for message in messages:
if await super().check(client, message):
return True
else:
return False
return False

View file

@ -58,5 +58,4 @@ class DeletedMessagesHandler(Handler):
for message in messages:
if await super().check(client, message):
return True
else:
return False
return False

View file

@ -14,3 +14,14 @@ You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>.
"""
from .helpers import ikb, bki, ntb, btn, kb, kbtn, array_chunk, force_reply
__all__ = [
"ikb",
"bki",
"ntb",
"btn",
"kb",
"kbtn",
"array_chunk",
"force_reply"
]

View file

@ -101,9 +101,9 @@ def kb(rows=None, **kwargs):
line = []
for button in row:
button_type = type(button)
if button_type == str:
if isinstance(button_type, str):
button = KeyboardButton(button)
elif button_type == dict:
elif isinstance(button_type, dict):
button = KeyboardButton(**button)
line.append(button)

View file

@ -29,6 +29,7 @@ from .password import Password
from .pyromod import Pyromod
from .stickers import Stickers
from .payments import Payments
from .phone import Phone
from .users import Users
from .utilities import Utilities
from .business import TelegramBusiness
@ -42,6 +43,7 @@ class Methods(
Password,
Pyromod,
Payments,
Phone,
Chats,
Stickers,
Users,

View file

@ -23,7 +23,6 @@ import inspect
import io
import logging
import math
import os
from hashlib import md5
from pathlib import PurePath
from typing import Union, BinaryIO, Callable

View file

@ -17,7 +17,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from .accept_terms_of_service import AcceptTermsOfService
from .check_password import CheckPassword
from .connect import Connect
from .disconnect import Disconnect
@ -31,12 +30,11 @@ from .send_code import SendCode
from .send_recovery_code import SendRecoveryCode
from .sign_in import SignIn
from .sign_in_bot import SignInBot
from .sign_up import SignUp
from .sign_in_qrcode import SignInQrcode
from .terminate import Terminate
class Auth(
AcceptTermsOfService,
CheckPassword,
Connect,
Disconnect,
@ -50,7 +48,7 @@ class Auth(
SendRecoveryCode,
SignIn,
SignInBot,
SignUp,
SignInQrcode,
Terminate
):
pass

View file

@ -35,6 +35,7 @@ class Connect:
Raises:
ConnectionError: In case you try to connect an already connected client.
"""
# pylint: disable=access-member-before-definition
if self.is_connected:
raise ConnectionError("Client is already connected")

View file

@ -30,6 +30,7 @@ class Disconnect:
ConnectionError: In case you try to disconnect an already disconnected client or in case you try to
disconnect a client that needs to be terminated first.
"""
# pylint: disable=access-member-before-definition
if not self.is_connected:
raise ConnectionError("Client is already disconnected")

View file

@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import List
import pyrogram
from pyrogram import raw, types

View file

@ -41,6 +41,7 @@ class Initialize:
if not self.is_connected:
raise ConnectionError("Can't initialize a disconnected client")
# pylint: disable=access-member-before-definition
if self.is_initialized:
raise ConnectionError("Client is already initialized")

View file

@ -61,6 +61,7 @@ class SendCode:
)
)
except (PhoneMigrate, NetworkMigrate) as e:
# pylint: disable=access-member-before-definition
await self.session.stop()
await self.storage.dc_id(e.value)

View file

@ -23,6 +23,7 @@ from typing import Union
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram.errors import PhoneNumberUnoccupied
log = logging.getLogger(__name__)
@ -49,15 +50,13 @@ class SignIn:
The valid confirmation code you received (either as Telegram message or as SMS in your phone number).
Returns:
:obj:`~pyrogram.types.User` | :obj:`~pyrogram.types.TermsOfService` | bool: On success, in case the
authorization completed, the user is returned. In case the phone number needs to be registered first AND the
terms of services accepted (with :meth:`~pyrogram.Client.accept_terms_of_service`), an object containing
them is returned. In case the phone number needs to be registered, but the terms of services don't need to
be accepted, False is returned instead.
:obj:`~pyrogram.types.User` | bool: On success, in case the
authorization completed, the user is returned.
Raises:
BadRequest: In case the arguments are invalid.
SessionPasswordNeeded: In case a password is needed to sign in.
PhoneNumberUnoccupied: In case the phone number is not registered on Telegram.
"""
phone_number = phone_number.strip(" +")
@ -70,10 +69,7 @@ class SignIn:
)
if isinstance(r, raw.types.auth.AuthorizationSignUpRequired):
if r.terms_of_service:
return types.TermsOfService._parse(terms_of_service=r.terms_of_service)
return False
raise PhoneNumberUnoccupied("The phone number is not registered on Telegram. Please use official Telegram app to register it.")
else:
await self.storage.user_id(r.user.id)
await self.storage.is_bot(False)

View file

@ -58,6 +58,7 @@ class SignInBot:
)
)
except UserMigrate as e:
# pylint: disable=access-member-before-definition
await self.session.stop()
await self.storage.dc_id(e.value)

View file

@ -0,0 +1,111 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import logging
from base64 import b64encode
from typing import Union
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram.session import Session, Auth
log = logging.getLogger(__name__)
class SignInQrcode:
async def sign_in_qrcode(
self: "pyrogram.Client"
) -> Union["types.User", "types.LoginToken"]:
"""Authorize a user in Telegram with a QR code.
.. include:: /_includes/usable-by/users.rst
Returns:
:obj:`~pyrogram.types.User` | :obj:`pyrogram.types.LoginToken`, in case the
authorization completed, the user is returned. In case the QR code is
not scanned, a login token is returned.
Raises:
ImportError: In case the qrcode library is not installed.
SessionPasswordNeeded: In case a password is needed to sign in.
"""
try:
import qrcode
except ImportError:
raise ImportError("qrcode is missing! "
"Please install it with `pip install qrcode`")
r = await self.session.invoke(
raw.functions.auth.ExportLoginToken(
api_id=self.api_id,
api_hash=self.api_hash,
except_ids=[]
)
)
if isinstance(r, raw.types.auth.LoginToken):
base64_token = b64encode(r.token).decode("utf-8")
login_url = f"tg://login?token={base64_token}"
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(login_url)
qr.make(fit=True)
print("Scan the QR code with your Telegram app.")
qr.print_ascii()
return types.LoginToken._parse(r)
if isinstance(r, raw.types.auth.LoginTokenSuccess):
await self.storage.user_id(r.authorization.user.id)
await self.storage.is_bot(False)
return types.User._parse(self, r.authorization.user)
if isinstance(r, raw.types.auth.LoginTokenMigrateTo):
# pylint: disable=access-member-before-definition
await self.session.stop()
await self.storage.dc_id(r.dc_id)
await self.storage.auth_key(
await Auth(
self, await self.storage.dc_id(),
await self.storage.test_mode()
).create()
)
self.session = Session(
self, await self.storage.dc_id(),
await self.storage.auth_key(), await self.storage.test_mode()
)
await self.session.start()
r = await self.session.invoke(
raw.functions.auth.ImportLoginToken(
token=r.token
)
)
if isinstance(r, raw.types.auth.LoginTokenSuccess):
await self.storage.user_id(r.authorization.user.id)
await self.storage.is_bot(False)
return types.User._parse(self, r.authorization.user)
raise pyrogram.exceptions.RPCError(
"Unknown response type from Telegram API"
)

View file

@ -1,74 +0,0 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import logging
import pyrogram
from pyrogram import raw
from pyrogram import types
log = logging.getLogger(__name__)
class SignUp:
async def sign_up(
self: "pyrogram.Client",
phone_number: str,
phone_code_hash: str,
first_name: str,
last_name: str = ""
) -> "types.User":
"""Register a new user in Telegram.
.. include:: /_includes/usable-by/users.rst
Parameters:
phone_number (``str``):
Phone number in international format (includes the country prefix).
phone_code_hash (``str``):
Code identifier taken from the result of :meth:`~pyrogram.Client.send_code`.
first_name (``str``):
New user first name.
last_name (``str``, *optional*):
New user last name. Defaults to "" (empty string, no last name).
Returns:
:obj:`~pyrogram.types.User`: On success, the new registered user is returned.
Raises:
BadRequest: In case the arguments are invalid.
"""
phone_number = phone_number.strip(" +")
r = await self.invoke(
raw.functions.auth.SignUp(
phone_number=phone_number,
first_name=first_name,
last_name=last_name,
phone_code_hash=phone_code_hash
)
)
await self.storage.user_id(r.user.id)
await self.storage.is_bot(False)
return types.User._parse(self, r.user)

View file

@ -37,6 +37,7 @@ class Terminate:
Raises:
ConnectionError: In case you try to terminate a client that is already terminated.
"""
# pylint: disable=access-member-before-definition
if not self.is_initialized:
raise ConnectionError("Client is already terminated")

View file

@ -1,5 +1,6 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
@ -18,12 +19,20 @@
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .answer_shipping_query import AnswerShippingQuery
from .delete_business_messages import DeleteBusinessMessages
from .get_business_connection import GetBusinessConnection
from .get_business_account_gifts import GetBusinessAccountGifts
from .get_business_account_star_balance import GetBusinessAccountStarBalance
from .transfer_business_account_stars import TransferBusinessAccountStars
class TelegramBusiness(
AnswerPreCheckoutQuery,
AnswerShippingQuery,
DeleteBusinessMessages,
GetBusinessConnection,
GetBusinessAccountGifts,
GetBusinessAccountStarBalance,
TransferBusinessAccountStars,
):
pass

View file

@ -0,0 +1,71 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Iterable, Union
import pyrogram
from pyrogram import raw
class DeleteBusinessMessages:
async def delete_business_messages(
self: "pyrogram.Client",
business_connection_id: str,
message_ids: Union[int, Iterable[int]]
) -> int:
"""Delete messages on behalf of a business account.
.. note::
Requires the `can_delete_sent_messages` business bot right to delete messages sent by the bot itself,
or the `can_delete_all_messages` business bot right to delete any message.
.. include:: /_includes/usable-by/bots.rst
Parameters:
business_connection_id (``str``):
Unique identifier of business connection on behalf of which to send the request.
message_ids (``int`` | Iterable of ``int``):
An iterable of message identifiers to delete (integers) or a single message id.
All messages must be from the same chat.
Returns:
``int``: Amount of affected messages
Example:
.. code-block:: python
# Delete one message
await app.delete_business_messages(connection_id, message_id)
# Delete multiple messages at once
await app.delete_business_messages(connection_id, list_of_message_ids)
"""
message_ids = list(message_ids) if not isinstance(message_ids, int) else [message_ids]
r = await self.invoke(
raw.functions.messages.DeleteMessages(
id=message_ids,
revoke=True
),
business_connection_id=business_connection_id
)
return r.pts_count

View file

@ -0,0 +1,129 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
import pyrogram
from pyrogram import raw, types
class GetBusinessAccountGifts:
async def get_business_account_gifts(
self: "pyrogram.Client",
business_connection_id: str,
exclude_unsaved: Optional[bool] = None,
exclude_saved: Optional[bool] = None,
exclude_unlimited: Optional[bool] = None,
exclude_limited: Optional[bool] = None,
exclude_upgraded: Optional[bool] = None,
sort_by_price: Optional[bool] = None,
limit: int = 0,
offset: str = "",
):
"""Return the gifts received and owned by a managed business account.
.. note::
Requires the `can_view_gifts_and_stars` business bot right.
.. include:: /_includes/usable-by/bots.rst
Parameters:
business_connection_id (``str``):
Unique identifier of business connection on behalf of which to send the request.
exclude_unsaved (``bool``, *optional*):
Pass True to exclude gifts that arent saved to the accounts profile page.
exclude_saved (``bool``, *optional*):
Pass True to exclude gifts that are saved to the accounts profile page.
exclude_unlimited (``bool``, *optional*):
Pass True to exclude gifts that can be purchased an unlimited number of times.
exclude_limited (``bool``, *optional*):
Pass True to exclude gifts that can be purchased a limited number of times.
exclude_upgraded (``bool``, *optional*):
Pass True to exclude upgraded gifts.
sort_by_price (``bool``, *optional*):
Pass True to sort results by gift price instead of send date. Sorting is applied before pagination.
offset (``str``, *optional*):
Offset of the first entry to return as received from the previous request.
limit (``int``, *optional*):
The maximum number of gifts to be returned.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Gift` objects.
Example:
.. code-block:: python
async for gift in app.get_business_account_gifts(connection_id):
print(gift)
"""
current = 0
total = abs(limit) or (1 << 31) - 1
limit = min(100, total)
connection_info = await self.get_business_connection(business_connection_id)
while True:
r = await self.invoke(
raw.functions.payments.GetSavedStarGifts(
peer=await self.resolve_peer(connection_info.user.id),
offset=offset,
limit=limit,
exclude_unsaved=exclude_unsaved,
exclude_saved=exclude_saved,
exclude_unlimited=exclude_unlimited,
exclude_limited=exclude_limited,
exclude_unique=exclude_upgraded,
sort_by_value=sort_by_price
),
sleep_threshold=60,
business_connection_id=business_connection_id
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
user_star_gifts = [
await types.Gift._parse_saved(self, gift, users, chats)
for gift in r.gifts
]
if not user_star_gifts:
return
for gift in user_star_gifts:
yield gift
current += 1
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -0,0 +1,61 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, Union
import pyrogram
from pyrogram import raw
class GetBusinessAccountStarBalance:
async def get_business_account_star_balance(
self: "pyrogram.Client",
business_connection_id: str,
) -> int:
"""Return the amount of Telegram Stars owned by a managed business account.
.. note::
Requires the `can_view_gifts_and_stars` business bot right.
.. include:: /_includes/usable-by/bots.rst
Parameters:
business_connection_id (``str``):
Unique identifier of business connection on behalf of which to send the request.
Returns:
``int``: On success, the current stars balance is returned.
Example:
.. code-block:: python
# Get stars balance
await app.get_business_account_star_balance("connection_id")
"""
connection_info = await self.get_business_connection(business_connection_id)
r = await self.invoke(
raw.functions.payments.GetStarsStatus(
peer=await self.resolve_peer(connection_info.user.id),
),
business_connection_id=business_connection_id
)
return r.balance.amount

View file

@ -16,11 +16,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from typing import Union, List
import pyrogram
from pyrogram import types, utils, raw
from pyrogram import types, raw
class GetBusinessConnection:

View file

@ -0,0 +1,72 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
class TransferBusinessAccountStars:
async def transfer_business_account_stars(
self: "pyrogram.Client",
business_connection_id: str,
star_count: int,
) -> bool:
"""Transfers Telegram Stars from the business account balance to the bots balance.
.. note::
Requires the `can_transfer_stars` business bot right.
.. include:: /_includes/usable-by/users.rst
Parameters:
business_connection_id (``str``):
Unique identifier of the business connection.
star_count (``int`` | ``str``):
Number of Telegram Stars to transfer, 1-10000.
Returns:
``bool``: On success, True is returned.
"""
# Why telegram won't let us just use InputPeerSelf :(
if self.me:
bot_id = self.me.id
else:
bot_id = (
await self.invoke(raw.functions.users.GetUsers(id=[raw.types.InputPeerSelf()]))
)[0].id
invoice = raw.types.InputInvoiceBusinessBotTransferStars(
bot=await self.resolve_peer(bot_id), stars=star_count
)
payment_form = await self.invoke(
raw.functions.payments.GetPaymentForm(invoice=invoice),
business_connection_id=business_connection_id,
)
await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=payment_form.form_id,
invoice=invoice,
),
business_connection_id=business_connection_id,
)
return True

View file

@ -117,5 +117,4 @@ class BanChatMember:
{i.id: i for i in r.users},
{i.id: i for i in r.chats}
)
else:
return True
return True

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -77,8 +77,7 @@ class GetChatMember:
else:
if member.user.id == user.user_id:
return member
else:
raise UserNotParticipant
raise UserNotParticipant
elif isinstance(chat, raw.types.InputPeerChannel):
r = await self.invoke(
raw.functions.channels.GetParticipant(

View file

@ -23,7 +23,6 @@ from typing import Union, Optional, AsyncGenerator
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
log = logging.getLogger(__name__)

View file

@ -23,7 +23,6 @@ from typing import Union, List, Iterable
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
log = logging.getLogger(__name__)
@ -63,7 +62,7 @@ class GetForumTopicsByID:
Raises:
ValueError: In case of invalid arguments.
"""
ids, ids_type = (
ids, _ = (
(topic_ids, int) if topic_ids
else (None, None)
)

View file

@ -17,7 +17,6 @@
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -164,5 +164,4 @@ class SetChatPhoto:
{i.id: i for i in r.users},
{i.id: i for i in r.chats}
)
else:
return True
return True

View file

@ -15,9 +15,9 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import pyrogram
from pyrogram import raw
from pyrogram import types
from typing import Union

View file

@ -24,26 +24,33 @@ from pyrogram.filters import Filter
class OnError:
def on_error(self=None, errors=None) -> Callable:
def on_error(
self=None,
errors=None,
group: int = 0,
) -> Callable:
"""Decorator for handling new errors.
This does the same thing as :meth:`~pyrogram.Client.add_handler` using the
:obj:`~pyrogram.handlers.MessageHandler`.
:obj:`~pyrogram.handlers.ErrorHandler`.
Parameters:
errors (:obj:`~Exception`, *optional*):
Pass one or more errors to allow only a subset of errors to be passed
in your function.
group (``int``, *optional*):
The group identifier, defaults to 0.
"""
def decorator(func: Callable) -> Callable:
if isinstance(self, pyrogram.Client):
self.add_handler(pyrogram.handlers.ErrorHandler(func, errors), 0)
self.add_handler(pyrogram.handlers.ErrorHandler(func, errors), group)
elif isinstance(self, Filter) or self is None:
if not hasattr(func, "handlers"):
func.handlers = []
func.handlers.append((pyrogram.handlers.ErrorHandler(func, self), 0))
func.handlers.append((pyrogram.handlers.ErrorHandler(func, self), group))
return func

View file

@ -16,7 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Callable, Optional, Union
from typing import Callable
import pyrogram
from pyrogram.filters import Filter

View file

@ -180,8 +180,12 @@ class CopyMediaGroup:
**await self.parser.parse(
captions[i] if isinstance(captions, list) and i < len(captions) and captions[i] else
captions if isinstance(captions, str) and i == 0 else
message.caption if message.caption and message.caption != "None" and not type(
captions) is str else "")
message.caption if (
message.caption
and message.caption != "None"
and not isinstance(captions, str)
) else ""
)
)
)

View file

@ -33,7 +33,8 @@ async def get_chunk(
from_message_id: int = 0,
from_date: datetime = utils.zero_datetime(),
min_id: int = 0,
max_id: int = 0
max_id: int = 0,
reverse: Optional[bool] = None
):
messages = await client.invoke(
raw.functions.messages.GetHistory(
@ -48,6 +49,8 @@ async def get_chunk(
),
sleep_threshold=60
)
if reverse:
messages.messages.reverse()
return await utils.parse_messages(client, messages, replies=0)
@ -61,7 +64,8 @@ class GetChatHistory:
offset_id: int = 0,
offset_date: datetime = utils.zero_datetime(),
min_id: int = 0,
max_id: int = 0
max_id: int = 0,
reverse: Optional[bool] = None
) -> Optional[AsyncGenerator["types.Message", None]]:
"""Get messages from a chat history.
@ -96,6 +100,9 @@ class GetChatHistory:
max_id: (``int``, *optional*):
The maximum message id. you will not get any message which have id greater than max_id.
reverse (``bool``, *optional*):
Pass True to retrieve the messages in reversed order (from older to most recent).
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Message` objects.
@ -118,7 +125,8 @@ class GetChatHistory:
from_message_id=offset_id,
from_date=offset_date,
min_id=min_id,
max_id=max_id
max_id=max_id,
reverse=reverse
)
if not messages:

View file

@ -104,7 +104,7 @@ class GetMessages:
is_iterable = not isinstance(ids, int)
ids = list(ids) if is_iterable else [ids]
ids = [ids_type(id=i) for i in ids]
ids = [ids_type(id=i) for i in ids] # pylint: disable=not-callable
if replies < 0:
replies = (1 << 31) - 1

View file

@ -78,6 +78,6 @@ class GetScheduledMessages:
r = await self.invoke(rpc, sleep_threshold=-1)
messages = await utils.parse_messages(self, r)
messages = await utils.parse_messages(self, r, is_scheduled=True)
return messages if is_iterable else messages[0] if messages else None

View file

@ -52,6 +52,7 @@ class SendAnimation:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -145,6 +146,11 @@ class SendAnimation:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -226,6 +232,7 @@ class SendAnimation:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -50,6 +50,7 @@ class SendAudio:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
message_effect_id: int = None,
@ -137,6 +138,11 @@ class SendAudio:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -216,6 +222,7 @@ class SendAudio:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -40,6 +40,7 @@ class SendCachedMedia:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -104,6 +105,11 @@ class SendCachedMedia:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -144,6 +150,7 @@ class SendCachedMedia:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -38,6 +38,7 @@ class SendContact:
business_connection_id: str = None,
reply_to_message_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -95,6 +96,11 @@ class SendContact:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -139,6 +145,7 @@ class SendContact:
reply_to_message_id=reply_to_message_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -36,6 +36,7 @@ class SendDice:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -91,6 +92,11 @@ class SendDice:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -143,6 +149,7 @@ class SendDice:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -48,6 +48,7 @@ class SendDocument:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
message_effect_id: int = None,
@ -129,6 +130,11 @@ class SendDocument:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -203,6 +209,7 @@ class SendDocument:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -38,6 +38,7 @@ class SendLocation:
business_connection_id: str = None,
reply_to_message_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -89,6 +90,11 @@ class SendLocation:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message
@ -136,6 +142,7 @@ class SendLocation:
reply_to_message_id=reply_to_message_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -22,7 +22,12 @@ import os
import re
from datetime import datetime
from pymediainfo import MediaInfo
from typing import Union, List, Optional
from typing import (
Union,
List,
Optional,
Callable,
)
import pyrogram
from pyrogram import enums
@ -35,7 +40,6 @@ log = logging.getLogger(__name__)
class SendMediaGroup:
# TODO: Add progress parameter
async def send_media_group(
self: "pyrogram.Client",
chat_id: Union[int, str],
@ -52,6 +56,7 @@ class SendMediaGroup:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -59,7 +64,9 @@ class SendMediaGroup:
protect_content: bool = None,
allow_paid_broadcast: bool = None,
message_effect_id: int = None,
invert_media: bool = None
invert_media: bool = None,
progress: Callable = None,
progress_args: tuple = (),
) -> List["types.Message"]:
"""Send a group of photos or videos as an album.
@ -98,6 +105,11 @@ class SendMediaGroup:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -126,6 +138,28 @@ class SendMediaGroup:
invert_media (``bool``, *optional*):
Inverts the position of the media and caption.
progress (``Callable``, *optional*):
Pass a callback function to view the file transmission progress.
The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
detailed description) and will be called back each time a new file chunk has been successfully
transmitted.
progress_args (``tuple``, *optional*):
Extra custom arguments for the progress callback function.
You can pass anything you need to be available in the progress callback scope; for example, a Message
object or a Client instance in order to edit the message with the updated progress status.
Other Parameters:
current (``int``):
The amount of bytes transmitted so far.
total (``int``):
The total size of the file.
*args (``tuple``, *optional*):
Extra custom arguments as defined in the ``progress_args`` parameter.
You can either keep ``*args`` or add every single extra argument in your function signature.
Returns:
List of :obj:`~pyrogram.types.Message`: On success, a list of the sent messages is returned.
@ -152,23 +186,25 @@ class SendMediaGroup:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode
parse_mode=parse_mode,
)
for i in media:
if isinstance(i, types.InputMediaPhoto):
if isinstance(i.media, str):
if os.path.isfile(i.media):
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedPhoto(
file=await self.save_file(i.media),
spoiler=i.has_spoiler
)
)
file=file,
spoiler=i.has_spoiler,
),
),
)
media = raw.types.InputMediaPhoto(
@ -177,7 +213,7 @@ class SendMediaGroup:
access_hash=media.photo.access_hash,
file_reference=media.photo.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
elif re.match("^https?://", i.media):
media = await self.invoke(
@ -185,9 +221,9 @@ class SendMediaGroup:
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaPhotoExternal(
url=i.media,
spoiler=i.has_spoiler
)
)
spoiler=i.has_spoiler,
),
),
)
media = raw.types.InputMediaPhoto(
@ -196,19 +232,20 @@ class SendMediaGroup:
access_hash=media.photo.access_hash,
file_reference=media.photo.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.PHOTO)
else:
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedPhoto(
file=await self.save_file(i.media),
spoiler=i.has_spoiler
)
)
file=file,
spoiler=i.has_spoiler,
),
),
)
media = raw.types.InputMediaPhoto(
@ -217,7 +254,7 @@ class SendMediaGroup:
access_hash=media.photo.access_hash,
file_reference=media.photo.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
elif (
isinstance(i, types.InputMediaVideo)
@ -241,22 +278,25 @@ class SendMediaGroup:
w=i.width,
h=i.height
),
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media))
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
]
if is_animation:
attributes.append(raw.types.DocumentAttributeAnimated())
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
spoiler=i.has_spoiler,
mime_type=self.guess_mime_type(i.media) or "video/mp4",
nosound_video=is_animation,
attributes=attributes
)
)
attributes=attributes,
),
),
)
media = raw.types.InputMediaDocument(
@ -265,7 +305,7 @@ class SendMediaGroup:
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
elif re.match("^https?://", i.media):
media = await self.invoke(
@ -273,9 +313,9 @@ class SendMediaGroup:
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaDocumentExternal(
url=i.media,
spoiler=i.has_spoiler
)
)
spoiler=i.has_spoiler,
),
),
)
media = raw.types.InputMediaDocument(
@ -284,17 +324,19 @@ class SendMediaGroup:
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.VIDEO)
else:
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
spoiler=i.has_spoiler,
mime_type=self.guess_mime_type(getattr(i.media, "name", "video.mp4")) or "video/mp4",
attributes=[
@ -304,10 +346,10 @@ class SendMediaGroup:
w=i.width,
h=i.height
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "video.mp4"))
]
)
)
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "video.mp4")),
],
),
),
)
media = raw.types.InputMediaDocument(
@ -316,127 +358,135 @@ class SendMediaGroup:
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
),
spoiler=i.has_spoiler
spoiler=i.has_spoiler,
)
elif isinstance(i, types.InputMediaAudio):
if isinstance(i.media, str):
if os.path.isfile(i.media):
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(i.media) or "audio/mpeg",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeAudio(
duration=i.duration,
performer=i.performer,
title=i.title
),
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media))
]
)
)
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
],
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
elif re.match("^https?://", i.media):
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaDocumentExternal(
url=i.media
)
)
url=i.media,
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.AUDIO)
else:
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(getattr(i.media, "name", "audio.mp3")) or "audio/mpeg",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeAudio(
duration=i.duration,
performer=i.performer,
title=i.title
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "audio.mp3"))
]
)
)
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "audio.mp3")),
],
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
elif isinstance(i, types.InputMediaDocument):
if isinstance(i.media, str):
if os.path.isfile(i.media):
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(i.media) or "application/zip",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media))
]
)
)
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
],
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
elif re.match("^https?://", i.media):
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaDocumentExternal(
url=i.media
)
)
url=i.media,
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
else:
media = utils.get_input_media_from_file_id(i.media, FileType.DOCUMENT)
else:
thumb = await self.save_file(i.thumb)
file = await self.save_file(i.media, progress=progress, progress_args=progress_args)
media = await self.invoke(
raw.functions.messages.UploadMedia(
peer=await self.resolve_peer(chat_id),
@ -444,21 +494,21 @@ class SendMediaGroup:
mime_type=self.guess_mime_type(
getattr(i.media, "name", "file.zip")
) or "application/zip",
file=await self.save_file(i.media),
thumb=await self.save_file(i.thumb),
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "file.zip"))
]
)
)
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "file.zip")),
],
),
),
)
media = raw.types.InputMediaDocument(
id=raw.types.InputDocument(
id=media.document.id,
access_hash=media.document.access_hash,
file_reference=media.document.file_reference
)
file_reference=media.document.file_reference,
),
)
else:
raise ValueError(f"{i.__class__.__name__} is not a supported type for send_media_group")
@ -467,8 +517,8 @@ class SendMediaGroup:
raw.types.InputSingleMedia(
media=media,
random_id=self.rnd_id(),
**(await utils.parse_text_entities(self, i.caption, i.parse_mode, i.caption_entities))
)
**(await utils.parse_text_entities(self, i.caption, i.parse_mode, i.caption_entities)),
),
)
rpc = raw.functions.messages.SendMultiMedia(
@ -480,7 +530,7 @@ class SendMediaGroup:
noforwards=protect_content,
allow_paid_floodskip=allow_paid_broadcast,
effect=message_effect_id,
invert_media=invert_media
invert_media=invert_media,
)
if business_connection_id is not None:
@ -489,7 +539,7 @@ class SendMediaGroup:
connection_id=business_connection_id,
query=rpc
),
sleep_threshold=60
sleep_threshold=60,
)
else:
r = await self.invoke(rpc, sleep_threshold=60)
@ -505,7 +555,7 @@ class SendMediaGroup:
r.updates
)],
users=r.users,
chats=r.chats
chats=r.chats,
),
business_connection_id=business_connection_id
business_connection_id=business_connection_id,
)

View file

@ -39,6 +39,7 @@ class SendMessage:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: int = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -100,6 +101,11 @@ class SendMessage:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of the monoforum.
for reply to message from a monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -174,6 +180,7 @@ class SendMessage:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -46,6 +46,7 @@ class SendPhoto:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -122,6 +123,11 @@ class SendPhoto:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -203,6 +209,7 @@ class SendPhoto:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -109,9 +109,11 @@ class SendReaction:
add_to_recent=add_to_recent
)
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
for i in r.updates:
if isinstance(i, raw.types.UpdateMessageReactions):
return types.MessageReactions._parse(self, i.reactions)
return types.MessageReactions._parse(self, i.reactions, users, chats)
elif story_id is not None:
await self.invoke(
raw.functions.stories.SendReaction(

View file

@ -44,6 +44,7 @@ class SendSticker:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -104,6 +105,11 @@ class SendSticker:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -178,6 +184,7 @@ class SendSticker:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -50,6 +50,7 @@ class SendVideo:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
cover: Union[str, BinaryIO] = None,
@ -58,6 +59,7 @@ class SendVideo:
protect_content: bool = None,
allow_paid_broadcast: bool = None,
message_effect_id: int = None,
view_once: bool = None,
invert_media: bool = None,
reply_markup: Union[
"types.InlineKeyboardMarkup",
@ -150,6 +152,11 @@ class SendVideo:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -180,6 +187,10 @@ class SendVideo:
message_effect_id (``int`` ``64-bit``, *optional*):
Unique identifier of the message effect to be added to the message; for private chats only.
view_once (``bool``, *optional*):
Self-Destruct Timer.
If True, the photo will self-destruct after it was viewed.
invert_media (``bool``, *optional*):
Inverts the position of the video and caption.
@ -246,6 +257,7 @@ class SendVideo:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode
@ -298,7 +310,7 @@ class SendVideo:
media = raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(video) or "video/mp4",
file=file,
ttl_seconds=ttl_seconds,
ttl_seconds=(1 << 31) - 1 if view_once else ttl_seconds,
spoiler=has_spoiler,
thumb=thumb,
attributes=[
@ -316,13 +328,13 @@ class SendVideo:
elif re.match("^https?://", video):
media = raw.types.InputMediaDocumentExternal(
url=video,
ttl_seconds=ttl_seconds,
ttl_seconds=(1 << 31) - 1 if view_once else ttl_seconds,
spoiler=has_spoiler,
video_cover=vidcover_file,
video_timestamp=start_timestamp
)
else:
media = utils.get_input_media_from_file_id(video, FileType.VIDEO, ttl_seconds=ttl_seconds)
media = utils.get_input_media_from_file_id(video, FileType.VIDEO, ttl_seconds=(1 << 31) - 1 if view_once else ttl_seconds)
media.spoiler = has_spoiler
else:
thumb = await self.save_file(thumb)
@ -330,7 +342,7 @@ class SendVideo:
media = raw.types.InputMediaUploadedDocument(
mime_type=self.guess_mime_type(file_name or video.name) or "video/mp4",
file=file,
ttl_seconds=ttl_seconds,
ttl_seconds=(1 << 31) - 1 if view_once else ttl_seconds,
spoiler=has_spoiler,
thumb=thumb,
attributes=[

View file

@ -45,6 +45,7 @@ class SendVideoNote:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -118,6 +119,11 @@ class SendVideoNote:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -197,6 +203,7 @@ class SendVideoNote:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -46,6 +46,7 @@ class SendVoice:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -121,6 +122,11 @@ class SendVoice:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -189,6 +195,7 @@ class SendVoice:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import re
from datetime import datetime
from typing import Union, List, Optional
@ -28,7 +27,7 @@ class SendWebPage:
async def send_web_page(
self: "pyrogram.Client",
chat_id: Union[int, str],
url: str,
url: str = None,
text: str = "",
parse_mode: Optional["enums.ParseMode"] = None,
entities: List["types.MessageEntity"] = None,
@ -40,6 +39,7 @@ class SendWebPage:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -53,7 +53,7 @@ class SendWebPage:
"types.ForceReply"
] = None
) -> "types.Message":
"""Send text Web Page Preview.
"""Send Web Page Preview.
.. include:: /_includes/usable-by/users-bots.rst
@ -64,12 +64,13 @@ class SendWebPage:
For a contact that exists in your Telegram address book you can use his phone number (str).
You can also use chat public link in form of *t.me/<username>* (str).
url (``str``):
Link that will be previewed.
text (``str``, *optional*):
Text of the message to be sent.
url (``str``, *optional*):
Link that will be previewed.
If url not specified, the first URL found in the text will be used.
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
By default, texts are parsed using both Markdown and HTML styles.
You can combine both syntaxes together.
@ -106,6 +107,11 @@ class SendWebPage:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -131,7 +137,7 @@ class SendWebPage:
instructions to remove reply keyboard or to force a reply from the user.
Returns:
:obj:`~pyrogram.types.Message`: On success, the sent text message is returned.
:obj:`~pyrogram.types.Message`: On success, the sent message is returned.
Example:
.. code-block:: python
@ -141,6 +147,18 @@ class SendWebPage:
"""
message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
if not url:
if entities:
for entity in entities:
if isinstance(entity, enums.MessageEntityType.URL):
url = entity.url
break
if not url:
url = utils.get_first_url(message)
if not url:
raise ValueError("URL not specified")
reply_to = await utils.get_reply_to(
client=self,
@ -149,6 +167,7 @@ class SendWebPage:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -31,11 +31,15 @@ from .get_chat_gifts_count import GetChatGiftsCount
from .get_chat_gifts import GetChatGifts
from .hide_gift import HideGift
from .refund_stars_payment import RefundStarPayment
from .search_gifts_for_resale import SearchGiftsForResale
from .send_invoice import SendInvoice
from .send_paid_media import SendPaidMedia
from .send_paid_reaction import SendPaidReaction
from .send_payment_form import SendPaymentForm
from .send_gift import SendGift
from .send_resold_gift import SendResoldGift
from .set_gift_resale_price import SetGiftResalePrice
from .set_pinned_gifts import SetPinnedGifts
from .show_gift import ShowGift
from .transfer_gift import TransferGift
from .upgrade_gift import UpgradeGift
@ -55,11 +59,15 @@ class Payments(
GetChatGifts,
HideGift,
RefundStarPayment,
SearchGiftsForResale,
SendPaidReaction,
SendPaidMedia,
SendInvoice,
SendPaymentForm,
SendGift,
SendResoldGift,
SetGiftResalePrice,
SetPinnedGifts,
ShowGift,
TransferGift,
UpgradeGift

View file

@ -17,9 +17,6 @@
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from typing import Union
import pyrogram
from pyrogram import raw

View file

@ -47,7 +47,7 @@ class GetUpgradedGift:
# Get information about upgraded gift by slug
gift = await client.get_upgraded_gift("SignetRing-903")
"""
match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/(?:nft/|\+))([\w-]+)$", link)
match = self.UPGRADED_GIFT_RE.match(link)
if match:
slug = match.group(1)

View file

@ -0,0 +1,110 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from typing import List, Optional
import pyrogram
from pyrogram import enums, raw, types
class SearchGiftsForResale:
async def search_gifts_for_resale(
self: "pyrogram.Client",
gift_id: int,
order: "enums.GiftForResaleOrder" = enums.GiftForResaleOrder.CHANGE_DATE,
attributes: Optional[List["types.UpgradedGiftAttributeId"]] = None,
limit: int = 0,
offset: str = ""
):
"""Get upgraded gifts that can be bought from other owners.
.. include:: /_includes/usable-by/users.rst
Parameters:
gift_id (``int``):
Identifier of the regular gift that was upgraded to a unique gift.
order (:obj:`~pyrogram.enums.GiftForResaleOrder`):
Order in which the results will be sorted.
attributes (List of :obj:`~pyrogram.types.UpgradedGiftAttributeId`, *optional*):
Attributes used to filter received gifts.
If multiple attributes of the same type are specified, then all of them are allowed.
If none attributes of specific type are specified, then all values for this attribute type are allowed.
limit (``int``, *optional*):
The maximum number of gifts to return. Default is 0 (no limit).
offset (``str``, *optional*):
The offset from which to start returning results. Default is "" (no offset).
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Gift` objects.
Example:
.. code-block:: python
async for gift in app.search_gifts_for_resale(gift_id=123456):
print(gift)
# Buy first gift from resale market
async for gift in app.search_gifts_for_resale(gift_id=123456, limit=1):
await app.send_resold_gift(gift_link=gift.link, new_owner_chat_id="me") # or just use await gift.buy()
"""
current = 0
total = abs(limit) or (1 << 31) - 1
limit = min(100, total)
while True:
r = await self.invoke(
raw.functions.payments.GetResaleStarGifts(
gift_id=gift_id,
offset=offset,
limit=limit,
sort_by_price=order == enums.GiftForResaleOrder.PRICE,
sort_by_num=order == enums.GiftForResaleOrder.NUMBER,
attributes=[attr.write() for attr in attributes] if attributes else None,
),
sleep_threshold=60
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
gifts = [
await types.Gift._parse(self, gift, users, chats)
for gift in r.gifts
]
if not gifts:
return
for gift in gifts:
yield gift
current += 1
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -68,7 +68,8 @@ class SendPaidReaction:
)
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
for i in r.updates:
if isinstance(i, raw.types.UpdateMessageReactions):
return types.MessageReactions._parse(self, i.reactions, users)
return types.MessageReactions._parse(self, i.reactions, users, chats)

View file

@ -0,0 +1,89 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional, Union
import pyrogram
from pyrogram import raw, types, utils
class SendResoldGift:
async def send_resold_gift(
self: "pyrogram.Client",
gift_link: str,
new_owner_chat_id: Union[int, str],
) -> Optional["types.Message"]:
"""Send an upgraded gift that is available for resale to another user or channel chat.
.. note::
Gifts already owned by the current user must be transferred using :meth:`~pyrogram.Client.transfer_gift` and can't be passed to this method.
.. include:: /_includes/usable-by/users.rst
Parameters:
gift_link (``str``):
Link to the gift.
new_owner_chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat you want to transfer the star gift to.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
Returns:
:obj:`~pyrogram.types.Message`: On success, the sent message is returned.
Example:
.. code-block:: python
# Transfer gift to another user
await app.send_resold_gift(gift_link="https://t.me/nft/NekoHelmet-9215", new_owner_chat_id=123)
"""
match = self.UPGRADED_GIFT_RE.match(gift_link)
if not match:
raise ValueError(
"Invalid gift link provided."
)
peer = await self.resolve_peer(new_owner_chat_id)
invoice = raw.types.InputInvoiceStarGiftResale(
slug=match.group(1),
to_id=peer
)
r = await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=(await self.invoke(
raw.functions.payments.GetPaymentForm(
invoice=invoice
),
)).form_id,
invoice=invoice
),
)
messages = await utils.parse_messages(
client=self,
messages=r.updates if isinstance(r, raw.types.payments.PaymentResult) else r
)
return messages[0] if messages else None

View file

@ -0,0 +1,82 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import re
import pyrogram
from pyrogram import raw
class SetGiftResalePrice:
async def set_gift_resale_price(
self: "pyrogram.Client",
owned_gift_id: str,
resale_star_count: int
) -> bool:
"""Change resale price of a unique gift owned by the current user.
.. include:: /_includes/usable-by/users.rst
Parameters:
owned_gift_id (``str``):
Unique identifier of the target gift.
For a user gift, you can use the message ID (int) of the gift message.
For a channel gift, you can use the packed format `chatID_savedID` (str).
For a upgraded gift, you can use the gift link.
resale_star_count (``int``):
The new price for the unique gift. Pass 0 to disallow gift resale.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Change resale price of a unique gift
await app.set_gift_resale_price(owned_gift_id="123456", resale_star_count=100)
"""
if not isinstance(owned_gift_id, str):
raise ValueError(f"owned_gift_id has to be str, but {type(owned_gift_id)} was provided")
saved_gift_match = re.match(r"^(-\d+)_(\d+)$", owned_gift_id)
slug_match = self.UPGRADED_GIFT_RE.match(owned_gift_id)
if saved_gift_match:
stargift = raw.types.InputSavedStarGiftChat(
peer=await self.resolve_peer(saved_gift_match.group(1)),
saved_id=int(saved_gift_match.group(2))
)
elif slug_match:
stargift = raw.types.InputSavedStarGiftSlug(
slug=slug_match.group(1)
)
else:
stargift = raw.types.InputSavedStarGiftUser(
msg_id=int(owned_gift_id)
)
await self.invoke(
raw.functions.payments.UpdateStarGiftPrice(
stargift=stargift,
resell_stars=resale_star_count
)
)
return True

View file

@ -0,0 +1,95 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrofork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrofork. If not, see <http://www.gnu.org/licenses/>.
import re
from typing import List, Union
import pyrogram
from pyrogram import raw
class SetPinnedGifts:
async def set_pinned_gifts(
self: "pyrogram.Client",
owner_id: Union[int, str],
owned_gift_ids: List[str],
) -> bool:
"""Change the list of pinned gifts on the current user.
.. include:: /_includes/usable-by/users.rst
Parameters:
owner_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
owned_gift_ids (List of ``str``):
New list of pinned gifts.
All gifts must be upgraded and saved on the profile page first.
For a user gift, you can use the message ID (int) of the gift message.
For a channel gift, you can use the packed format `chatID_savedID` (str).
For a upgraded gift, you can use the gift link.
Returns:
``bool``: On success, True is returned.
Example:
.. code-block:: python
# Set pinned gifts in user profile
await app.set_pinned_gifts(received_gift_ids=["123", "456"])
"""
stargifts = []
for gift in owned_gift_ids:
if not isinstance(gift, str):
raise ValueError(f"gift id has to be str, but {type(gift)} was provided")
saved_gift_match = re.match(r"^(\d+)_(\d+)$", str(gift))
slug_match = self.UPGRADED_GIFT_RE.match(str(gift))
if saved_gift_match:
stargifts.append(
raw.types.InputSavedStarGiftChat(
peer=await self.resolve_peer(saved_gift_match.group(1)),
saved_id=int(saved_gift_match.group(2))
)
)
elif slug_match:
stargifts.append(
raw.types.InputSavedStarGiftSlug(
slug=slug_match.group(1)
)
)
else:
stargifts.append(
raw.types.InputSavedStarGiftUser(
msg_id=int(gift)
)
)
r = await self.invoke(
raw.functions.payments.ToggleStarGiftsPinnedToTop(
peer=await self.resolve_peer(owner_id),
stargift=stargifts
)
)
return r

View file

@ -0,0 +1,25 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .get_call_members import GetCallMembers
class Phone(
GetCallMembers
):
pass

View file

@ -0,0 +1,103 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
#
# This file is part of Pyrogram.
#
# Pyrogram is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pyrogram is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, AsyncGenerator
import pyrogram
from pyrogram import types, raw
class GetCallMembers:
async def get_call_members(
self: "pyrogram.Client",
chat_id: Union[int, str],
limit: int = 0
) -> AsyncGenerator["types.GroupCallMember", None]:
"""Get the members list of a chat call.
A chat can be either a basic group or a supergroup.
.. include:: /_includes/usable-by/users.rst
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
limit (``int``, *optional*):
Limits the number of members to be retrieved.
Returns:
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.GroupCallMember` objects is returned.
Example:
.. code-block:: python
# Get members
async for member in app.get_call_members(chat_id):
print(member)
"""
peer = await self.resolve_peer(chat_id)
if isinstance(peer, raw.types.InputPeerChannel):
r = await self.invoke(raw.functions.channels.GetFullChannel(channel=peer))
elif isinstance(peer, raw.types.InputPeerChat):
r = await self.invoke(raw.functions.messages.GetFullChat(chat_id=peer.chat_id))
else:
raise ValueError("Target chat should be group, supergroup or channel.")
full_chat = r.full_chat
if not getattr(full_chat, "call", None):
raise ValueError("There is no active call in this chat.")
current = 0
offset = ""
total = abs(limit) or (1 << 31) - 1
limit = min(20, total)
while True:
r = await self.invoke(
raw.functions.phone.GetGroupParticipants(
call=full_chat.call,
ids=[],
sources=[],
offset=offset,
limit=limit
),
sleep_threshold=60
)
users = {u.id: u for u in r.users}
chats = {c.id: c for c in r.chats}
members = [
types.GroupCallMember._parse(self, member, users, chats)
for member in r.participants
]
if not members:
return
offset = r.next_offset
for member in members:
yield member
current += 1
if current >= total:
return

Some files were not shown because too many files have changed in this diff Show more