Compare commits

...

301 commits

Author SHA1 Message Date
wulan17
6bbff46417
pyrofork: fix export_folder_link doc
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.14) (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.14) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:51:12 +07:00
wulan17
2c32c152cb
pyrofork: Bump version to 2.3.69
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:34:40 +07:00
97db9130bb
Merge pull request #159 from Silicon-Developer/main
Typo !
2025-12-11 01:31:55 +07:00
47a3b6179d
Merge pull request #157 from asoul-rec/patch-1
Add missing topic assignment in Message.__init__
2025-12-11 01:29:49 +07:00
yueyueL
2f2d515575
pyrofork: fix(security): sanitize file names to prevent CWE-22 path traversal
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:01 +07:00
wulan17
e9c40679d2
pyrofork: Refactor docs build script
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:01 +07:00
wulan17
b43e857ed2
pyrofork: Refactor TodoList
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:01 +07:00
wulan17
72b043b743
pyrofork: Add ExportedFolderLink types
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:01 +07:00
wulan17
ac8e8fef4d
pyrofork: Add can_manage_direct_messages field to ChatPrivileges
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:00 +07:00
wulan17
0876ac31bd
pyrofork: Update API schema to Layer 220
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:00 +07:00
wulan17
4f4988e808
pyrofork: Update API schema to Layer 219
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:00 +07:00
wulan17
94c474a646
pyrofork: Update domain
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:00 +07:00
wulan17
66753e44f2
pyrofork: access class __annotations__ instead of instance
Python 3.14 removed implicit fallback to class-level __annotations__,
causing AttributeError when accessing self.__annotations__. Updated
matches() to use self.__class__.__annotations__ for compatibility
across Python 3.10+.

Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:28:00 +07:00
wulan17
d35abe89c4
pyrofork: Adapt uvloop changes
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:53 +07:00
wulan17
77f50c6a82
pyrofork: Update API schema to Layer 218
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:42 +07:00
wulan17
c15a59e998
pyrofork: Update API schema to Layer 217
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:42 +07:00
wulan17
945dcfca56
pyrofork: Drop python 3.9 support
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:42 +07:00
wulan17
12cf466b23
pyrofork: Move forums methods to separate category and adapt to new layer
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:26 +07:00
wulan17
8c6bad6aa4
pyrofork: Update API schema to Layer 216
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
dddb0d75e7
pyrofork: Update API schema to Layer 215
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
f0cc3afe5d
pyrofork: Update API schema to Layer 214
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
7105b131dc
pyrofork: Update API schema to Layer 213
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
4afd74d26e
pyrofork: Update API schema to Layer 212
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
73027fecf7
pyrofork: Update API schema to Layer 211
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
7db5e1423f
pyrofork: Implement chunk pagination on get_forum_topics method (#114)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
802c394f91
pyrofork: Update API schema to Layer 210
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:27:10 +07:00
wulan17
4570b3b5a9
pyrofork: Update API schema to Layer 208
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-12-11 01:26:46 +07:00
Silicon Developer
fa9781d62c
Typo ! 2025-10-20 08:24:00 +05:30
asoul-rec
9a772a8c8a
add missing topic assignment in Message.__init__ 2025-09-25 01:34:00 -05:00
wulan17
cb38d6a02b
pyrofork: docs: storage: Add example for official async mongodb driver
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-07-11 20:31:21 +07:00
wulan17
cf6141feb4
pyrofork: Bump version to 2.3.68
Some checks are pending
Pyrofork / build (macos-latest, 3.10) (push) Waiting to run
Pyrofork / build (macos-latest, 3.11) (push) Waiting to run
Pyrofork / build (macos-latest, 3.12) (push) Waiting to run
Pyrofork / build (macos-latest, 3.13) (push) Waiting to run
Pyrofork / build (macos-latest, 3.9) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.10) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.11) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.12) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.13) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.9) (push) Waiting to run
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:58:10 +07:00
wulan17
8acc457458
pyrofork: types: Chat: _parse_dialog: Handle InputPeerUser and InputPeerChat
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:53 +07:00
wulan17
413556a3f2
pyrofork: Refactor folders
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:52 +07:00
wulan17
4a109b3dc2
pyrofork: Adapt filters.linked_channel to latest changes
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:52 +07:00
wulan17
46e755f297
pyrofork: client: fix looping prompt when use qrcode as input
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:52 +07:00
wulan17
c8b22bb5e7
pyrofork: Add resale_amount field to Gift (#144)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:51 +07:00
Hentinel
9b670a78b3
pyrofork: Allow to specify system_lang_code and lang_pack (#129)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:51 +07:00
Otazuki
621c690e55
pyrofork: Add transfer_chat_ownership method (#145)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:51 +07:00
wulan17
07bdefb017
pyrofork: Add todolist implementation
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:51 +07:00
wulan17
9d795911b4
pyrofork: Update API schema to Layer 207
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:50 +07:00
wulan17
cb19b742ad
pyrofork: Update API schema to Layer 206
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:50 +07:00
wulan17
1ba1a051c4
pyrofork: Update API schema to Layer 205
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-07-10 19:56:50 +07:00
6151813555
Merge pull request #121 from Mayuri-Chan/dependabot/pip/sphinx-immaterial-0.13.4
Some checks are pending
Pyrofork / build (macos-latest, 3.10) (push) Waiting to run
Pyrofork / build (macos-latest, 3.11) (push) Waiting to run
Pyrofork / build (macos-latest, 3.12) (push) Waiting to run
Pyrofork / build (macos-latest, 3.13) (push) Waiting to run
Pyrofork / build (macos-latest, 3.9) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.10) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.11) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.12) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.13) (push) Waiting to run
Pyrofork / build (ubuntu-latest, 3.9) (push) Waiting to run
build(deps): bump sphinx-immaterial from 0.12.4 to 0.13.4
2025-07-09 22:18:02 +07:00
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
wulan17
8074557922
pyrofork: Bump version to 2.3.59
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@nusantararom.org>
2025-03-08 20:53:11 +07:00
wulan17
7562d04596
pyrofork: docs: text-formatting: Add missings text format
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:10 +07:00
wulan17
149dd4a708
pyrofork: docs: text-formatting: Move up HTML section
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:10 +07:00
wulan17
4926eda4c5
pyrofork: docs: Add warning regarding markdown text formatting
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:10 +07:00
wulan17
c4b587b493
pyrofork: parser: markdown: Check if PRE is inside blockquote before unparsing it
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:09 +07:00
wulan17
1108c52f53
pyrofork: Add support for custom emoji in markdown unparser
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:09 +07:00
wulan17
fc84041397
pyrofork: Add offset_{date,id,topic} parameters to get_forum_topics method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:09 +07:00
wulan17
71c39b8e6f
pyrofork: Add support for multi-line blockquote in markdown unparser
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:09 +07:00
wulan17
bec31032cc
pyrofork: Adapt markdown unparser from telethon
* The problem with current implementation is when we have nested markdown inside a url the markdown order is messed up.
for example link with bold text will be unparsed like this [**github](https://github.com**).

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:08 +07:00
wulan17
5c9470fd4f
pyrofork: Fix nested url markdown parsing
* The problem with current implepementation is when we add another markdown inside an url markdown will not be parsed.
for example we add bold (**) markdown inside an url markdown, the url text show as `**text**` instead of making the text bold.

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:08 +07:00
KurimuzonAkuma
13681302a0
Pyrofork: Add delete_chat_history method
Signed-off-by: Yasir Aris <git@yasir.id>
2025-03-08 20:52:08 +07:00
Yasir Aris M
c31d41e3d3
Pyrofork: Fix video cover
Signed-off-by: Yasir Aris <git@yasir.id>
2025-03-08 20:52:07 +07:00
Yasir Aris M
8528eea303
Pyrofork: Fix get_chat_gifts_count description
Signed-off-by: Yasir Aris <git@yasir.id>
2025-03-08 20:52:07 +07:00
Yasir Aris M
39cd79794e
Pyrofork: Update get_chat_gifts description
Signed-off-by: Yasir Aris <git@yasir.id>
2025-03-08 20:52:07 +07:00
KurimuzonAkuma
ea8ff2806f
Pyrofork: Add message.content property
Signed-off-by: Yasir Aris <git@yasir.id>
2025-03-08 20:52:07 +07:00
wulan17
e33a9d95df
pyrofork: Update API schema to Layer 199
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:06 +07:00
wulan17
ee3e9002fc
pyrofork: Add get_chat_forum_topics_count method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:52:06 +07:00
wulan17
4e200e2a5d
pyrofork: Add ForumTopicDeleted
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-03-08 20:51:58 +07:00
Yasir Aris M
ecf469973e
pyrofork: Bump version to 2.3.58
Signed-off-by: Yasir Aris <git@yasir.id>
2025-02-03 12:54:05 +07:00
KurimuzonAkuma
5e72850eee pyrofork: Fix send_gift method
Signed-off-by: Yasir <git@yasir.id>
2025-02-03 05:40:32 +00:00
Yasir Aris M
ad0aed4cf3
Pyrofork: Fix transcribed_audio method
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2025-02-03 12:11:36 +07:00
shriMADhav U k
5c1c72f068 Pyrofork: Add cover and start_timestamp in send_video, reply_video
Signed-off-by: Yasir <git@yasir.id>
2025-02-03 04:44:29 +00:00
KurimuzonAkuma
7662cc164f Pyrofork: Sync Star Gift With Layer 198
Signed-off-by: Yasir <git@yasir.id>
2025-02-03 04:44:29 +00:00
KurimuzonAkuma
2923328bbb Pyrofork: Sync emoji status with layer 198
Signed-off-by: Yasir <git@yasir.id>
2025-02-03 04:44:29 +00:00
KurimuzonAkuma
e9eaa48650 Pyrofork: Add get_upgraded_gift method
Signed-off-by: Yasir <git@yasir.id>
2025-02-03 04:44:29 +00:00
Yasir Aris M
03c2f5ff8c
Merge pull request #110 from peerids/main
fix(pyrogram.utils.get_reply_to): function parameters
2025-01-29 08:19:06 +07:00
Yasir Aris M
3e504edcc1 Pyrofork: Add message_effect_id and allow_paid_broadcast copy_media_group method 2025-01-29 01:06:38 +00:00
Yasir Aris M
8f9797f57c
pyrofork: Add has_spoiler in get_input_media_from_file_id 2025-01-29 07:14:39 +07:00
n/a
361acdbfd7 fix(pyrogram.methods.messages.copy_media_group): reply_to: miss parameter client 2025-01-29 05:15:32 +07:00
n/a
4a50a9183d fix(pyrogram.utils.get_reply_to): function parameters 2025-01-29 04:55:55 +07:00
wulan17
0f65486aba
pyrofork: Bump version to 2.3.57
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:43:52 +07:00
wulan17
fabe0464fa
pyrofork: Add missing allow_paid_broadcast and message_effect_id parameters to Message.reply_media_group
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:27 +07:00
wulan17
0b220def26
pyrofork: Add transcribe_audio method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:27 +07:00
wulan17
3e36412e68
pyrofork: Add get_similar_bot method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:26 +07:00
wulan17
3180267107
pyrofork: types: EmojiStatus: Sync with layer 198
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:26 +07:00
wulan17
377fda434b
pyrofork: Fix Message.react returns
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:26 +07:00
Yasir Aris M
ca5c406a00
pyrofork: Update API schema to Layer 197-198
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2025-01-26 20:42:26 +07:00
wulan17
276bc0affd
Revert "Add bound method stop() to the Poll object"
This reverts commit 165ade92d5.

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:26 +07:00
wulan17
60533eb92c
pyrofork: Add message_effect_id parameter to send_invoice (#109)
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:25 +07:00
wulan17
885a832aa3
pyrofork: filters: topic: Add support for general topic
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2025-01-26 20:42:25 +07:00
a653065774
Merge pull request #102 from msx98/getdialogs-catch-peeridinvalid
Catch `PeerIdInvalid` in `get_dialogs`
2025-01-26 20:40:41 +07:00
Yasir Aris M
5676006a10
v2.3.56: pyrofork: Bump version to 2.3.56 2025-01-11 06:54:57 +07:00
Yasir Aris M
71f1147b65
pyrofork: Fix attribute error 2025-01-10 22:38:25 +07:00
Yasir Aris M
8db18a7734
pyrofork: Bump version to 2.3.55
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-10 17:34:03 +07:00
Yasir Aris M
d82a3fb1f7 pyrofork: Changed send_reaction description
Now you can react to service messages

Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
Yasir Aris M
2e0ec55dd3 pyrofork: Update set_profile_photo notes
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
KurimuzonAkuma
f767fd3e3a pyrofork: Add BotVerification Types
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
KurimuzonAkuma
b12b4a62f4 pyrofork: Fix forum topic type hints
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
KurimuzonAkuma
7cda52ac39 pyrofork: Add get_stars_balance Method
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
Yasir Aris M
7404c46d7d pyrofork: Fix some missing docs
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
KurimuzonAkuma
14fb99cf77 pyrofork: Refactor Star Gift Based On New Layer
Signed-off-by: Yasir <git@yasir.id>
2025-01-10 10:30:11 +00:00
Yasir Aris M
9e101ef4d9
Merge pull request #107 from TheRealMal/main
fix: attributes parsing
2025-01-06 19:18:29 +07:00
therealmal
a04c91db31 fix: attributes parsing 2025-01-05 00:08:57 +03:00
Yasir Aris
8ceec293ba pyrofork: Bump version to 2.3.54
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 22:17:33 +07:00
Yasir Aris
6c538f026d pyrofork: Add pay_for_upgrade in send_gift method
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:42 +07:00
Yasir Aris
1ddc2d268b pyrofork: Add upgrade_star_count and is_for_birthday in Gift
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:42 +07:00
Yasir Aris
5c93020bbe pyrofork: Refactor StarGift and remove duplicate types
Signed-off-by: Yasir Aris <git@yasir.id>

pyrofork: Refactor StarGift and remove duplicate types

Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:42 +07:00
Yasir Aris
1955de7a20 pyrofork: Add reply_to_story_id to copy_media_group and send_inline_bot_result method
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
Yasir Aris
2bb299c163 pyrofork: Add start bot method
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
KurimuzonAkuma
8e7e5fb9ff pyrofork: update StarGift type to new layer
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
Yasir Aris
e67a016828 pyrofork: Update API schema to Layer 196
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
Yasir Aris M
aaf9c0cd3d pyrofork: Fix typo on purchased paid media parser
Signed-off-by: Yasir Aris M <git@yasir.id>
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
Yasir Aris M
5187bae266 pyrofork: Fix stop_poll method
Signed-off-by: Yasir Aris M <git@yasir.id>
Signed-off-by: Yasir Aris <git@yasir.id>
2025-01-04 16:28:41 +07:00
XiaoCai
ecc15f67a4
pyrofork: fix(send_media_group.py) Fixed media.caption_entities parameter not working (#104)
* fix(send_media_group.py) Fixed media.caption_entities parameter not working.

* chore(send_media_group.py): simplify parse_text_entities handling

Refactored to use ** unpacking directly in raw.types.InputSingleMedia, reducing variable assignments.
2025-01-02 14:07:29 +07:00
Yasir Aris M
56e9173579 Merge branch 'main' of https://github.com/Mayuri-Chan/Pyrofork 2024-12-23 07:36:46 +07:00
Yasir Aris M
945ff8b642 pyrofork: Fixed some missing docs
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-23 07:32:37 +07:00
Yasir Aris M
21a3045890 pyrofork: Bump version to 2.3.53
Signed-off-by: Yasir <yasiramunandar@gmail.com>
2024-12-21 00:34:10 +00:00
Yasir Aris M
481817649b pyrofork: Add Error handler
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
Yasir Aris M
bd46ff3977 pyrofork: Add message_thread_id parameter to unpin_all_chat_messages()
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
Yasir Aris M
b21db6f931 pyrofork: Add the parameter business_connection_id to the methods pin_chat_message() and unpin_chat_message(), allowing bots to manage pinned messages on behalf of a business account
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
KurimuzonAkuma
6dcb6bfa67 pyrofork: Add custom emojis to markdown
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
KurimuzonAkuma
252882851e pyrofork: Add filters support for raw handler
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
KurimuzonAkuma
ae3bc516fb pyrofork: Add forward_media_group method
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
Shrimadhav U K
5b79294276 pyrofork: Add get_owned_bots
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
Yasir Aris M
08af7a1b66 pyrofork: Fix missing argument on Message
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
shriMADhav U k
d3c945f6b6 pyrofork: Add alternative_videos to Message 2024-12-21 00:30:11 +00:00
Yasir Aris M
f8103a2890 pyrofork: Update API schema to Layer 195
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-12-21 00:30:11 +00:00
wulan17
f6f003d25a
pyrofork: Bump version to 2.3.52
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-30 01:40:56 +07:00
wulan17
bba87d6e52
pyrofork: Add reply_to_chat_id parameter to copy_message method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-30 01:40:26 +07:00
wulan17
c9bbeec525
pyrofork: Refactor Poll
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-30 01:40:20 +07:00
msx98
dd9ae86d8b Catch PeerIdInvalid in get_dialogs 2024-11-29 13:38:29 +02:00
d7018d8ed1
Merge pull request #98 from Mayuri-Chan/dependabot/pip/sphinx-immaterial-0.12.4
build(deps): bump sphinx-immaterial from 0.12.3 to 0.12.4
2024-11-29 14:29:44 +07:00
wulan17
efc0272186
pyrofork: Bump version to 2.3.51
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-25 23:40:43 +07:00
03226965ab
Merge pull request #100 from cactoe/main
fix: resolve TypeError by correctly positioning invert_media parameter
2024-11-25 23:40:03 +07:00
n/a
45b47af9b2 fix(py3.9): use List from typing for type hinting instead of built-in list 2024-11-25 07:14:37 +07:00
n/a
ab8f854385 fix: resolve TypeError by correctly positioning invert_media parameter 2024-11-23 17:10:53 +07:00
wulan17
6f5bd1392b
pyrofork: Bump version to 2.3.50
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-22 21:55:02 +07:00
wulan17
1bcf2f7be6
pyrofork: fix search_message
* TypeError: Search.__init__() got an unexpected keyword argument 'thread_id'

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-22 21:54:17 +07:00
wulan17
efce392266
pyrofork: Add missing allow_paid_broadcast parameter to copy_message and forward_messages method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-22 21:49:15 +07:00
wulan17
5dda91d3b0
pyrofork: Bump version to 2.3.49
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:38:20 +07:00
wulan17
0c23296be5
pyrofork: Update API schema to Layer 194
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:38:10 +07:00
wulan17
4e909508e5
pyrofork: Add thread_id parameter to search_messages and search_messages_count methods
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:55 +07:00
KurimuzonAkuma
4ced5fbd8b
pyrofork: Add star_gift in Message
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:55 +07:00
shriMADhav U k
52f1b97c84
pyrofork: Add first_send_date, last_send_date, is_sold_out to Gift
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:54 +07:00
KurimuzonAkuma
680918eed7
pyrofork: Steal Star Gifts changes from KurimuzonAkuma fork (#100)
Co-authored-by: Shrimadhav U K <SpEcHiDe@users.noreply.github.com>
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:54 +07:00
Shrimadhav U K
3426ad59a2
pyrofork: Add allow_paid_broadcast parameter to methods.
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:54 +07:00
wulan17
cf67f9534c
pyrofork: Add invert_media parameter to edit_inline_{caption,message} methods
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:53 +07:00
shriMADhav U k
b437bc1c46
pyrofork: Add raw attribute to ChatMemberUpdated
Co-authored-by: wulan17 <wulan17@nusantararom.org>
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:53 +07:00
shriMADhav U k
307b700df3
Added the field via_chat_folder_invite_link to the class ChatMemberUpdated.
Bot API 6.7
April 21, 2023

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:52 +07:00
wulan17
91e7506a6a
pyrofork: Update API schema to Layer 193
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:52 +07:00
wulan17
591cd3ac86
pyrofork: Parse send_inline_bot_result result
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:51 +07:00
wulan17
7726e22161
pyrofork: Update edit_message_media and edit_inline_media description
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:51 +07:00
wulan17
072cc0cead
pyrofork: Update sphinx-immaterial to v0.12.4
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:51 +07:00
wulan17
4bcc690083
pyrofork: Remove unused animated and videos field from stickerset
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:50 +07:00
wulan17
db562461ad
pyrofork: Update API schema to Layer 192
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:50 +07:00
wulan17
261490f63b
pyrofork: Update API schema to Layer 191
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:49 +07:00
wulan17
e5ae90c335
pyrofork: Update API schema to Layer 190
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-11-21 23:32:36 +07:00
wulan17
f990b1e7f9
pyrofork: Update documentation url
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-13 01:54:55 +07:00
dependabot[bot]
2130f089d6
build(deps): bump sphinx-immaterial from 0.12.3 to 0.12.4
Bumps [sphinx-immaterial](https://github.com/jbms/sphinx-immaterial) from 0.12.3 to 0.12.4.
- [Release notes](https://github.com/jbms/sphinx-immaterial/releases)
- [Commits](https://github.com/jbms/sphinx-immaterial/compare/v0.12.3...v0.12.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-11 22:55:10 +00:00
wulan17
5086c9ccc3
pyrofork: Publish packages using Trusted Publisher
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 22:25:04 +07:00
wulan17
6e66a7d4b2
pyrofork: Bump version to 2.3.48
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:59:21 +07:00
wulan17
a6046806b8
workflows: Update checkout and setup-python
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:58:39 +07:00
wulan17
6e6a689953
pyrofork: Python 3.13 support
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:56 +07:00
KurimuzonAkuma
f30aa0077a
Add get_user_star_gifts method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:46 +07:00
KurimuzonAkuma
0a6cc8b5a4
Add show_star_gift and hide_star_gift method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
KurimuzonAkuma
f23f450c62
Add convert_star_gift method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
KurimuzonAkuma
d4649275e9
Add send_star_gift method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
KurimuzonAkuma
bb96ca8597
Add get_star_gifts method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
wulan17
e4968df4c9
pyrofork: Move some method and types to payments category
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
KurimuzonAkuma
b152bd9c84
Add new apply_gift_code, check_gift_code, get_payment_form, and send_payment_form methods
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:45 +07:00
wulan17
4e823b153e
pyrofork: Update API schema to Layer 189
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:44 +07:00
wulan17
95eba2ce77
pyrofork: Add get_message_read_participants method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:44 +07:00
wulan17
a6b69228e8
pyrofork: fix plugins loader error on windows
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:27 +07:00
wulan17
faef0b0699
pyrofork: Update funding links
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-10-08 21:56:13 +07:00
266fc738b6
Merge pull request #97 from Mayuri-Chan/dependabot/pip/sphinx-immaterial-0.12.3
build(deps): bump sphinx-immaterial from 0.12.2 to 0.12.3
2024-10-08 21:42:20 +07:00
dependabot[bot]
d594fe58cb
build(deps): bump sphinx-immaterial from 0.12.2 to 0.12.3
Bumps [sphinx-immaterial](https://github.com/jbms/sphinx-immaterial) from 0.12.2 to 0.12.3.
- [Release notes](https://github.com/jbms/sphinx-immaterial/releases)
- [Commits](https://github.com/jbms/sphinx-immaterial/compare/v0.12.2...v0.12.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 22:24:46 +00:00
wulan17
923ad51dd7
pyrofork: Bump version to 2.3.46
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:09:48 +07:00
Shrimadhav U K
c3df58b4c7
Add emoji to send_sticker and reply_sticker.
KurimuzonAkuma/pyrogram#86

Co-authored-by: Surendra9123 <Surendra9123@users.noreply.github.com>
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:33 +07:00
wulan17
2d83118f0f
pyrofork: Remove get_nearby_chats method
Removed by telegram

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:33 +07:00
wulan17
3ee16dac4e
pyrofork: Ignore excluded plugins [2/2]
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:33 +07:00
wulan17
45e2872fab
pyrofork: drop python 3.8 support
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:33 +07:00
wulan17
74376f8da5
pyrofork: Add copy_text field to InlineKeyboardButton
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:33 +07:00
wulan17
44d4c0ff55
pyrofork: Update API schema to Layer 188
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-25 20:08:23 +07:00
wulan17
65190eb195
pyrofork: Bump version to 2.3.46
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-13 22:43:29 +07:00
RabbitFoRed
a403d83f7e
pyrofork: Ignore excluded plugins
currently if you specify a plugin to exclude in pyrogram
the client first imports it (caea59cc17/pyrogram/client.py (L874))
and add_handler() (caea59cc17/pyrogram/client.py (L880))
and then after this it uses remove_handler() (caea59cc17/pyrogram/client.py (L948))
this usually works well in most case,
but in a few case if the module to exclude has an error,
this is not handled and stops the program,
so need to fix the modules even if it not the target of interest (as it is in exclude=[])

Co-authored-by: wulan17 <wulan17@nusantararom.org>
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-13 22:41:47 +07:00
wulan17
6543fa11b6
pyrofork: Add InputPeer support for utils.get_raw_peer_id and utils.get_peer_id
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-13 22:41:47 +07:00
wulan17
57155cbdfa
pyrofork: fix typo in set_chat_photo
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-13 22:41:47 +07:00
wulan17
caea59cc17
pyrofork: Bump version to 2.3.45
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:42 +07:00
shriMADhav U k
63db641f59
Try to return the service message (when applicable) in the set_chat_photo
- Documentation Fixes

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:12 +07:00
wulan17
f7e1f214c6
pyrofork: Add emoji and emoji_background parameters to set_profile_photo method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:12 +07:00
wulan17
c2cd506be9
pyrofork: Add emoji and emoji_background parameters to Chat.set_photo bound method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:12 +07:00
KurimuzonAkuma
01e200e8ce
Restart client after receiving unknown constructor
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:11 +07:00
KurimuzonAkuma
4e2d553f35
Ignore PersistentTimestamp errors
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:11 +07:00
KurimuzonAkuma
ee8f11e2a0
Extract recovering gaps into a separate method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:11 +07:00
wulan17
930da9b858
pyrofork: fix PreCheckoutQuery not defined in class ShippingQuery
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:10 +07:00
KurimuzonAkuma
d70927e5a2
Add on_purchased_paid_media decorator
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:10 +07:00
wulan17
f07d6563e3
pyrofork: Add stars field to class GiveawayLaunched
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:09 +07:00
wulan17
76deb77f1c
pyrofork: Add stars field to class Giveaway
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:09 +07:00
wulan17
02eed79861
pyrofork: Add stars and is_star_giveaway field to class GiveawayResult
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:09 +07:00
shriMADhav U k
2faae08064
Added the ability to specify a payload in send_paid_media which is not used currently
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:09 +07:00
wulan17
e5327d2216
pyrofork: Add support to set emoji as Chat Photo
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:08 +07:00
wulan17
11836faab7
pyrofork: Add is_winners_hidden field to class Giveaway
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:08 +07:00
wulan17
2a70654537
pyrofork: Update API schema to Layer 187
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-07 20:52:02 +07:00
RabbitFoRed
d062b6795f
pyrofork: fix "Ignoring non-existent module error" warning when using a paths string as plugin root dir. (#94)
example code:
app = Client(...., plugins=dict(root="bot/plugins", exlude=['toremove']))

warning:
pyrogram.client - [UNLOAD] Ignoring non-existent module "bot/plugins.toremove"
2024-09-07 20:50:12 +07:00
wulan17
053232b15a
pyrofork: Bump version to 2.3.44
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:09:20 +07:00
wulan17
b412622bc7
pyrofork: Fix get_chat_photo incase photo not found and limit param is enabled
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
74699d8bdf
pyrofork: types: Animation: Add missing import
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
489337d5d0
pyrofork: fix Message.translate docs
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
d9c6286044
pyrofork: Add example(s) to translate_message_text method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
755d23028b
pyrofork: fix typos in decorators docs
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
430cc9f534
pyrofork: Add reply_to_chat_id field to class Message
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:46 +07:00
wulan17
2ebfb80761
pyrofork: fix typos in Bound Method docs
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-09-02 23:08:36 +07:00
wulan17
37e39bd6ce
pyrofork: Bump version to 2.3.43
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-25 16:00:26 +07:00
wulan17
7a063e4a72
pyrofork: refactor add_sticker_to_set and create_sticker_set
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-25 15:58:19 +07:00
Zaid _
8e95ffcd6c
Pyrofork: Add translate methods
Signed-off-by: Yasir Aris M <git@yasirdev.my.id>
2024-08-25 15:03:00 +07:00
Yasir Aris M
8d8768cce4 Pyrofork: Add known error for subscription link 2024-08-24 23:03:39 +07:00
Yasir Aris M
efe3d90718 Pyrofork: Fix generate subcription invite link 2024-08-24 22:51:20 +07:00
wulan17
d3ffd68690
pyrofork: Bump version to 2.3.42
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-21 16:15:44 +07:00
wulan17
1d0ad21328
pyrofork: fix peer_id saved as raw id in usernames table
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-21 16:12:48 +07:00
wulan17
375d165a9c
pyrofork: Bump version to 2.3.41
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:34 +07:00
wulan17
a598ab6144
pyrofork: Add some missings service messages
CHAT_THEME_UPDATED
CHAT_WALLPAPER_UPDATED
CONTACT_REGISTERED
GIFT_CODE
SCREENSHOT_TAKEN

Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:10 +07:00
Shrimadhav U K
9697a7f3cd
Add chat_join_type to differentiate on three different types of new_chat_members
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:09 +07:00
wulan17
ecfa97f115
pyrofork: Add top_reactors field to class MessageReactions
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:09 +07:00
wulan17
3061115d57
pyrofork: Add send_paid_reaction method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:09 +07:00
wulan17
2317643727
pyrofork: methods: edit_message_media: parse caption_entities field from InputMedia
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:09 +07:00
wulan17
56efb88047
pyrofork: Add subscription_expired, subscription_period, and subscription_price field to class ChatInviteLink
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:09 +07:00
wulan17
8854710399
pyrofork: Add subscription_period and subscription_price parameters to export_chat_invite and Chat.export_invite_link
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:08 +07:00
wulan17
889c32ca2b
pyrofork: subscription_until_date field to class ChatMember
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:08 +07:00
wulan17
a138170e1e
pyrofork: Add is_paid_reactions_available, subscription_until_date field to class Chat
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:08 +07:00
wulan17
945290692e
pyrofork: Add privacy_policy_url field to class BotInfo
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:08 +07:00
wulan17
cbd632c600
pyrofork: Refactor Reactions
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:07 +07:00
wulan17
b6d9e2c782
pyrofork: Add support for sending paid media using business bot
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:07 +07:00
wulan17
4112298666
pyrofork: Add support for question/options entities in Message.reply_poll bound method
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:07 +07:00
wulan17
90dc694588
pyrofork: Add additional_price field to class Giveaway
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:07 +07:00
wulan17
4ac0fcc35f
pyrofork: Update API schema to Layer 186
Signed-off-by: wulan17 <wulan17@nusantararom.org>
2024-08-19 18:58:03 +07:00
339 changed files with 12755 additions and 2016 deletions

3
.github/FUNDING.yml vendored
View file

@ -1,3 +1,2 @@
github: Mayuri-Chan
ko_fi: wulan17
custom: ["https://saweria.co/wulan17", "https://paypal.me/wulan17", "https://trakteer.id/wulan17"]
custom: ["https://t.me/Mayuri17_bot?start=donate"]

View file

@ -14,8 +14,25 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v4
- name: Configure
run: bash build-docs.sh configure
- name: Cleanup
run: bash build-docs.sh cleanup
- name: Create virtual environment
run: bash build-docs.sh virtualenv
- name: Build
run: bash build-docs.sh
run: bash build-docs.sh build
- name: Clone gh-pages repository
run: bash build-docs.sh clone
env:
DOCS_KEY: ${{ secrets.DOCS_KEY }}
- name: Push changes
run: bash build-docs.sh push

View file

@ -20,11 +20,14 @@ jobs:
deploy:
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
@ -34,8 +37,4 @@ jobs:
- name: Build package
run: hatch build
- name: Publish package
env:
HATCH_INDEX_USER: __token__
HATCH_INDEX_AUTH: ${{ secrets.PYPI_API_TOKEN }}
run: |
hatch publish
uses: pypa/gh-action-pypi-publish@release/v1

View file

@ -9,13 +9,13 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
@ -31,4 +31,4 @@ jobs:
- name: Run tests
run: |
tox
tox

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

@ -9,7 +9,7 @@
Homepage
</a>
<a href="https://pyrofork.mayuri.my.id">
<a href="https://pyrofork.wulan17.dev">
Documentation
</a>
@ -44,7 +44,7 @@ async def hello(client, message):
app.run()
```
**Pyrofork** is a modern, elegant and asynchronous [MTProto API](https://pyrofork.mayuri.my.id/main/topics/mtproto-vs-botapi)
**Pyrofork** is a modern, elegant and asynchronous [MTProto API](https://pyrofork.wulan17.dev/main/topics/mtproto-vs-botapi)
framework. It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot
identity (bot API alternative) using Python.
@ -72,6 +72,6 @@ pip3 install pyrofork
### Resources
- Check out the docs at https://pyrofork.mayuri.my.id to learn more about Pyrofork, get started right
- Check out the docs at https://pyrofork.wulan17.dev to learn more about Pyrofork, get started right
away and discover more in-depth material for building your client applications.
- Join the official group at https://t.me/MayuriChan_Chat and stay tuned for news, updates and announcements.

View file

@ -1,42 +1,87 @@
#!/bin/bash
export DOCS_KEY
VENV="$(pwd)"/venv
export VENV
if [[ "$(echo "$GITHUB_REF" | cut -d '/' -f "1 2")" == "refs/tags" ]]; then
branch="main"
elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then
branch="staging"
else
b="$(echo "$GITHUB_REF" | cut -d '/' -f '3 4')"
if [[ $(echo "$b" | cut -d '/' -f 1 ) == "dev" ]]; then
b="$(echo "$b" | cut -d '/' -f 2)"
if [[ "$b" =~ ^[0-9]\.[0-9]\.x ]]; then
branch="$b"
# Check if config.sh exists
if [ -f config.sh ]; then
source config.sh
fi
function parse_parameters() {
while (($#)); do
case $1 in
all | configure | cleanup | virtualenv | build | clone | push ) action=$1 ;;
*) exit 33 ;;
esac
shift
done
}
function do_configure() {
echo "#!/bin/bash" > config.sh
echo "export VENV=\"$(pwd)/venv\"" >> config.sh
if [[ "$(echo "$GITHUB_REF" | cut -d '/' -f "1 2")" == "refs/tags" ]]; then
echo "export BRANCH=\"main\"" >> config.sh
elif [[ "$GITHUB_REF" == "refs/heads/staging" ]]; then
echo "export BRANCH=\"staging\"" >> config.sh
else
b="$(echo "$GITHUB_REF" | cut -d '/' -f '3 4')"
if [[ $(echo "$b" | cut -d '/' -f 1 ) == "dev" ]]; then
b="$(echo "$b" | cut -d '/' -f 2)"
if [[ "$b" =~ ^[0-9]\.[0-9]\.x ]]; then
echo "export BRANCH=\"$b\"" >> config.sh
else
exit 0
fi
else
exit 0
fi
else
exit 0
fi
fi
chmod +x config.sh
}
make clean
make clean-docs
make venv
make api
"$VENV"/bin/pip install -e '.[docs]'
cd compiler/docs || exit 1 && "$VENV"/bin/python compiler.py
cd ../.. || exit 1
"$VENV"/bin/sphinx-build -b html "docs/source" "docs/build/html" -j auto
git clone https://wulan17:"$DOCS_KEY"@github.com/Mayuri-Chan/pyrofork-docs.git
cd pyrofork-docs || exit 1
mkdir -p "$branch"
cd "$branch" || exit 1
rm -rf _includes api genindex.html intro py-modindex.html sitemap.xml support.html topics _static faq index.html objects.inv searchindex.js start telegram
cp -r ../../docs/build/html/* .
git config --local user.name "Mayuri-Chan"
git config --local user.email "mayuri@mayuri.my.id"
git add --all
git commit -a -m "docs: $branch: Update docs $(date '+%Y-%m-%d | %H:%m:%S %p %Z')" --signoff
git push -u origin --all
function do_cleanup() {
make clean
make clean-docs
}
function do_virtualenv() {
make venv
make api
"$VENV"/bin/pip install -e '.[docs]'
}
function do_build() {
cd compiler/docs || exit 1 && "$VENV"/bin/python compiler.py
cd ../.. || exit 1
"$VENV"/bin/sphinx-build -b html "docs/source" "docs/build/html" -j auto
}
function do_clone() {
git clone https://wulan17:"$DOCS_KEY"@github.com/Mayuri-Chan/pyrofork-docs.git
}
function do_push() {
cd pyrofork-docs || exit 1
mkdir -p "$BRANCH"
cd "$BRANCH" || exit 1
rm -rf _includes api genindex.html intro py-modindex.html sitemap.xml support.html topics _static faq index.html objects.inv searchindex.js start telegram
cp -r ../../docs/build/html/* .
git config --local user.name "Mayuri-Chan"
git config --local user.email "mayuri@mayuri.my.id"
git add --all
git commit -a -m "docs: $BRANCH: Update docs $(date '+%Y-%m-%d | %H:%m:%S %p %Z')" --signoff
git push -u origin --all
}
function do_all() {
do_configure
source config.sh
do_cleanup
do_virtualenv
do_build
do_clone
do_push
}
parse_parameters "$@"
do_"${action:=all}"

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 "

File diff suppressed because it is too large Load diff

View file

@ -20,4 +20,4 @@ class {name}: # type: ignore
raise TypeError("Base types can only be used for type checking purposes: "
"you tried to use a base type instance as argument, "
"but you need to instantiate one of its constructors instead. "
"More info: https://pyrofork.mayuri.my.id/telegram/base/{doc_name}")
"More info: https://pyrofork.wulan17.dev/telegram/base/{doc_name}")

View file

@ -146,6 +146,7 @@ def pyrogram_api():
stop_transmission
export_session_string
set_parse_mode
ping
""",
conversation="""
Conversation
@ -164,7 +165,9 @@ def pyrogram_api():
""",
messages="""
Messages
add_task_to_todo
send_message
forward_media_group
forward_messages
copy_message
copy_media_group
@ -172,6 +175,7 @@ def pyrogram_api():
send_audio
send_document
send_sticker
send_todo
send_video
send_animation
send_voice
@ -183,6 +187,7 @@ def pyrogram_api():
send_contact
send_cached_media
send_reaction
set_todo_tasks_completion
edit_message_text
edit_message_caption
edit_message_media
@ -196,6 +201,7 @@ def pyrogram_api():
delete_scheduled_messages
get_available_effects
get_messages
get_message_read_participants
get_scheduled_messages
get_media_group
get_chat_history
@ -218,6 +224,10 @@ def pyrogram_api():
get_discussion_replies
get_discussion_replies_count
get_custom_emoji_stickers
transcribe_audio
translate_message_text
start_bot
delete_chat_history
""",
chats="""
Chats
@ -248,8 +258,8 @@ def pyrogram_api():
get_folders
get_forum_topics
get_forum_topics_by_id
get_forum_topics_count
set_chat_username
get_nearby_chats
archive_chats
unarchive_chats
add_chat_members
@ -275,6 +285,7 @@ def pyrogram_api():
hide_general_topic
reopen_forum_topic
reopen_general_topic
transfer_chat_ownership
unhide_general_topic
update_color
update_folder
@ -343,6 +354,39 @@ def pyrogram_api():
get_contacts
get_contacts_count
""",
payments="""
Payments
apply_gift_code
check_gift_code
convert_gift
create_invoice_link
get_payment_form
get_stars_transactions
get_stars_transactions_by_id
get_available_gifts
get_upgraded_gift
get_chat_gifts_count
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
@ -370,18 +414,18 @@ def pyrogram_api():
get_bot_info
set_bot_info
get_collectible_item_info
get_owned_bots
get_similar_bots
""",
business="""
Telegram Business
answer_pre_checkout_query
answer_shipping_query
create_invoice_link
delete_business_messages
get_business_connection
get_stars_transactions
get_stars_transactions_by_id
refund_star_payment
send_invoice
send_paid_media
get_business_account_gifts
get_business_account_star_balance
transfer_business_account_stars
""",
authorization="""
Authorization
@ -393,12 +437,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
""",
@ -422,7 +465,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:
@ -456,6 +499,7 @@ def pyrogram_api():
BusinessWeeklyOpen
BusinessWorkingHours
User
Username
Chat
ChatPreview
ChatPhoto
@ -474,24 +518,39 @@ def pyrogram_api():
Folder
Restriction
EmojiStatus
ExportedFolderLink
ForumTopic
PeerUser
PeerChannel
BotInfo
GroupCallMember
ChatColor
CollectibleItemInfo
BotVerification
""",
messages_media="""
Messages & Media
Message
MessageEntity
MessageOriginChannel
MessageOriginChat
MessageOriginHiddenUser
MessageOriginImport
MessageOriginUser
MessageOrigin
Photo
Thumbnail
TodoList
TodoTask
TodoTasksAdded
TodoTasksCompleted
TodoTasksIncompleted
Audio
AvailableEffect
Document
ExternalReplyInfo
AlternativeVideo
Animation
LabeledPrice
Video
Voice
VideoNote
@ -501,7 +560,8 @@ def pyrogram_api():
Sticker
StickerSet
Game
GiftedPremium
Gift
GiftAttribute
Giveaway
GiveawayLaunched
GiveawayResult
@ -509,6 +569,9 @@ def pyrogram_api():
WebPage
WebPageEmpty
WebPagePreview
TranscribedAudio
TranslatedText
TextQuote
Poll
PollOption
Dice
@ -519,18 +582,26 @@ def pyrogram_api():
VideoChatMembersInvited
WebAppData
MessageReactions
MessageReactor
ChatReactions
ForumTopicCreated
ForumTopicEdited
ForumTopicClosed
ForumTopicDeleted
ForumTopicReopened
GeneralTopicHidden
GeneralTopicUnhidden
Reaction
ReactionCount
ReactionType
MessageReactionUpdated
MessageReactionCountUpdated
ExportedStoryLink
ChatTheme
ChatWallpaper
ContactRegistered
ReadParticipant
ScreenshotTaken
Wallpaper
WallpaperSettings
""",
stories="""
Stories
@ -546,6 +617,25 @@ def pyrogram_api():
InputMediaArea
InputMediaAreaChannelPost
""",
payment="""
Payment
CheckedGiftCode
ExtendedMediaPreview
GiftCode
GiftedPremium
InputStarsTransaction
Invoice
LabeledPrice
PaidMedia
PaidMessagePriceChanged
PaymentForm
PaymentInfo
PaymentRefunded
PurchasedPaidMedia
StarsStatus
StarsTransaction
SuccessfulPayment
""",
pyromod="""
Pyromod
Identifier
@ -582,7 +672,6 @@ def pyrogram_api():
MenuButtonWebApp
MenuButtonDefault
SentWebAppMessage
PreCheckoutQuery
""",
bot_commands="""
Bot commands
@ -598,18 +687,10 @@ def pyrogram_api():
""",
business="""
Telegram Business
ExtendedMediaPreview
InputStarsTransaction
Invoice
PaidMedia
PaymentInfo
PaymentRefunded
PreCheckoutQuery
ShippingAddress
ShippingOption
ShippingQuery
StarsStatus
StarsTransaction
SuccessfulPayment
""",
input_media="""
Input Media
@ -656,17 +737,20 @@ def pyrogram_api():
InputMessageContent
InputMessageContent
InputReplyToMessage
InputReplyToMonoforum
InputReplyToStory
InputTextMessageContent
InputLocationMessageContent
InputVenueMessageContent
InputContactMessageContent
InputInvoiceMessageContent
InputTodoTask
""",
authorization="""
Authorization
ActiveSession
ActiveSessions
LoginToken
SentCode
TermsOfService
"""
@ -684,7 +768,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)})
@ -738,6 +822,8 @@ def pyrogram_api():
Message.reply_web_page
Message.get_media_group
Message.react
Message.transcribe
Message.translate
Message.wait_for_click
""",
chat="""
@ -796,6 +882,26 @@ def pyrogram_api():
Story.reply_video_note
Story.reply_voice
""",
folder="""
Folder
Folder.delete
Folder.update
Folder.include_chat
Folder.exclude_chat
Folder.update_color
Folder.pin_chat
Folder.remove_chat
Folder.export_link
""",
gift="""
Gift
Gift.show
Gift.hide
Gift.convert
Gift.upgrade
Gift.transfer
Gift.wear
""",
callback_query="""
Callback Query
CallbackQuery.answer

View file

@ -140,3 +140,28 @@ ChatJoinRequest
{chat_join_request_toctree}
Folder
---------------
.. hlist::
:columns: 2
{folder_hlist}
.. toctree::
:hidden:
{folder_toctree}
Gift
---------------
.. hlist::
:columns: 2
{gift_hlist}
.. toctree::
:hidden:
{gift_toctree}

View file

@ -190,6 +190,19 @@ Bots
{bots}
Payments
----
.. autosummary::
:nosignatures:
{payments}
.. toctree::
:hidden:
{payments}
Authorization
-------------
@ -217,4 +230,4 @@ Learn more about how to use the raw API at :doc:`Advanced Usage <../../topics/ad
.. toctree::
:hidden:
{advanced}
{advanced}

View file

@ -164,6 +164,45 @@ InputMessageContent
{input_message_content}
ShippingQuery
-------------------
.. autosummary::
:nosignatures:
{shipping_query}
.. toctree::
:hidden:
{shipping_query}
PreCheckoutQuery
-------------------
.. autosummary::
:nosignatures:
{pre_checkout_query}
.. toctree::
:hidden:
{pre_checkout_query}
Payment
-------------------
.. autosummary::
:nosignatures:
{payment}
.. toctree::
:hidden:
{payment}
Authorization
-------------
@ -175,4 +214,4 @@ Authorization
.. toctree::
:hidden:
{authorization}
{authorization}

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

@ -2,10 +2,12 @@ id message
ABOUT_TOO_LONG The provided about/bio text is too long
ACCESS_TOKEN_EXPIRED The bot token has expired
ACCESS_TOKEN_INVALID The bot access token is invalid
ADDRESS_INVALID The specified geopoint address is invalid.
ADMINS_TOO_MUCH The chat has too many administrators
ADMIN_ID_INVALID The specified admin ID is invalid
ADMIN_RANK_EMOJI_NOT_ALLOWED Emoji are not allowed in custom administrator titles
ADMIN_RANK_INVALID The custom administrator title is invalid or too long
ADMIN_RIGHTS_EMPTY The chatAdminRights constructor passed in keyboardButtonRequestPeer.peer_type.user_admin_rights has no rights set (i.e. flags is 0).
ALBUM_PHOTOS_TOO_MANY Too many photos were included in the album
API_ID_INVALID The api_id/api_hash combination is invalid
API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side because it was published somewhere
@ -23,6 +25,7 @@ AUTOARCHIVE_NOT_AVAILABLE This feature is not yet enabled for your account due t
BANK_CARD_NUMBER_INVALID The credit card number is invalid
BANNED_RIGHTS_INVALID You provided a set of restrictions that is invalid
BASE_PORT_LOC_INVALID The base port location is invalid
BIRTHDAY_INVALID The age should be less than 150 year old in Telegram
BOTS_TOO_MUCH The chat has too many bots
BOT_CHANNELS_NA Bots can't edit admin privileges
BOT_COMMAND_DESCRIPTION_INVALID The command description was empty, too long or had invalid characters
@ -32,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
@ -43,7 +47,9 @@ 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
BUTTON_TYPE_INVALID The type of one of the buttons you provided is invalid
BUTTON_URL_INVALID The button url is invalid
@ -58,13 +64,15 @@ CHANNELS_ADMIN_PUBLIC_TOO_MUCH You are an administrator of too many public chann
CHANNELS_TOO_MUCH You have joined too many channels or supergroups, leave some and try again
CHANNEL_ADD_INVALID Internal error.
CHANNEL_BANNED The channel is banned
CHANNEL_ID_INVALID The specified supergroup ID is invalid.
CHANNEL_INVALID The channel parameter is invalid
CHANNEL_PARICIPANT_MISSING The current user is not in the channel
CHANNEL_PRIVATE The channel/supergroup is not accessible
CHANNEL_TOO_BIG The channel too big
CHANNEL_TOO_LARGE The channel is too large
CHANNEL_TOO_LARGE "Channel is too large to be deleted; this error is issued when trying to delete channels with more than 1000 members (subject to change)."
CHARGE_ALREADY_REFUNDED The charge id was already used for a refund.
CHARGE_NOT_FOUND The charge id was not found.
CHATLIST_EXCLUDE_INVALID The specified `exclude_peers` are invalid.
CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content
CHAT_ABOUT_TOO_LONG The chat about text is too long
CHAT_ADMIN_REQUIRED The method requires chat admin privileges
@ -95,6 +103,7 @@ CONNECTION_SYSTEM_EMPTY The connection to the system is empty
CONNECTION_SYSTEM_LANG_CODE_EMPTY The system language code is empty
CONTACT_ADD_MISSING Contact to add is missing
CONTACT_ID_INVALID The provided contact id is invalid
CONTACT_MISSING The specified user is not a contact.
CONTACT_NAME_EMPTY The provided contact name is empty
CONTACT_REQ_MISSING Missing contact request
CREATE_CALL_FAILED An error occurred while creating the call
@ -109,10 +118,12 @@ DOCUMENT_INVALID The document is invalid
EMAIL_HASH_EXPIRED The email hash expired and cannot be used to verify it
EMAIL_INVALID The email provided is invalid
EMAIL_NOT_ALLOWED This email is not allowed
EMAIL_NOT_SETUP In order to change the login email with emailVerifyPurposeLoginChange, an existing login email must already be set using emailVerifyPurposeLoginSetup.
EMAIL_UNCONFIRMED Email unconfirmed
EMAIL_UNCONFIRMED_X The provided email isn't confirmed, {value} is the length of the verification code that was just sent to the email
EMAIL_VERIFY_EXPIRED The verification email has expired
EMOJI_INVALID The specified theme emoji is valid
EMOJI_MARKUP_INVALID The specified `video_emoji_markup` was invalid.
EMOJI_NOT_MODIFIED The theme wasn't changed
EMOTICON_EMPTY The emoticon parameter is empty
EMOTICON_INVALID The emoticon parameter is invalid
@ -129,6 +140,9 @@ ERROR_TEXT_EMPTY The provided error message is empty
EXPIRE_DATE_INVALID The expiration date is invalid
EXPIRE_FORBIDDEN Expire forbidden
EXPORT_CARD_INVALID The provided card is invalid
EXTENDED_MEDIA_AMOUNT_INVALID The maximum amount of `star_count` should be less than the `stars_paid_post_amount_max`
EXTENDED_MEDIA_PEER_INVALID The specified chat type is invalid.
EXTENDED_MEDIA_TYPE_INVALID The specified extended media type is unsupported.
EXTERNAL_URL_INVALID The external media URL is invalid
FIELD_NAME_EMPTY The field with the name FIELD_NAME is missing
FIELD_NAME_INVALID The field with the name FIELD_NAME is invalid
@ -157,13 +171,16 @@ FIRSTNAME_INVALID The first name is invalid
FOLDER_ID_EMPTY The folder you tried to delete was already empty
FOLDER_ID_INVALID The folder id is invalid
FORM_ID_EXPIRED The specified id has expired.
FORUM_ENABLED You can't execute the specified action because the group is a [forum](https://core.telegram.org/api/forum), disable forum functionality to continue.
FRESH_CHANGE_ADMINS_FORBIDDEN You can't change administrator settings in this chat because your session was logged-in recently
FROM_MESSAGE_BOT_DISABLED Bots can't use fromMessage min constructors
FROM_PEER_INVALID The from peer value is invalid
GAME_BOT_INVALID You cannot send that game with the current bot
GENERAL_MODIFY_ICON_FORBIDDEN You can't modify the icon of the General topic.
GEO_POINT_INVALID Invalid geo point provided
GIF_CONTENT_TYPE_INVALID GIF content-type invalid
GIF_ID_INVALID The provided gif/animation id is invalid
GIFT_SLUG_INVALID The specified slug is invalid.
GIFT_SLUG_EXPIRED The gift slug is expired
GRAPH_EXPIRED_RELOAD This graph has expired, please obtain a new graph token
GRAPH_INVALID_RELOAD Invalid graph token provided, please reload the stats and provide the updated token
@ -190,7 +207,9 @@ INPUT_LAYER_INVALID The provided layer is invalid
INPUT_METHOD_INVALID The method invoked is invalid in the current schema
INPUT_REQUEST_TOO_LONG The input request is too long
INPUT_TEXT_EMPTY The specified text is empty
INPUT_TEXT_TOO_LONG The specified text is too long.
INPUT_USER_DEACTIVATED The target user has been deleted/deactivated
INVITES_TOO_MUCH The maximum number of per-folder invites specified by the `chatlist_invites_limit_default`/`chatlist_invites_limit_premium` was reached.
INVITE_FORBIDDEN_WITH_JOINAS If the user has anonymously joined a group call as a channel, they can't invite other users to the group call because that would cause deanonymization, because the invite would be sent using the original user ID, not the anonymized channel ID
INVITE_HASH_EMPTY The invite hash is empty
INVITE_HASH_EXPIRED The chat invite link is no longer valid
@ -241,6 +260,7 @@ MULTI_MEDIA_TOO_LONG The album/media group contains too many items
NEW_SALT_INVALID The new salt is invalid
NEW_SETTINGS_EMPTY No password is set on the current account, and no new password was specified in `new_settings`
NEW_SETTINGS_INVALID The new settings are invalid
NOGENERAL_HIDE_FORBIDDEN The hidden parameter is only valid for the General topic message_thread_id=1
NEXT_OFFSET_INVALID The next offset value is invalid
OFFSET_INVALID The offset parameter is invalid
OFFSET_PEER_ID_INVALID The provided offset peer is invalid
@ -292,6 +312,7 @@ PHOTO_SAVE_FILE_INVALID The photo you tried to send cannot be saved by Telegram
PHOTO_THUMB_URL_EMPTY The photo thumb URL is empty
PHOTO_THUMB_URL_INVALID The photo thumb URL is invalid
PINNED_DIALOGS_TOO_MUCH Too many pinned dialogs
PINNED_TOPIC_NOT_MODIFIED The pinned topic was not modified.
PIN_RESTRICTED You can't pin messages in private chats with other people
POLL_ANSWERS_INVALID The poll answers are invalid
POLL_ANSWER_INVALID One of the poll answers is not acceptable
@ -301,6 +322,8 @@ POLL_QUESTION_INVALID The poll question is invalid
POLL_UNSUPPORTED This layer does not support polls in the invoked method
POLL_VOTE_REQUIRED Cast a vote in the poll before calling this method
PREMIUM_ACCOUNT_REQUIRED The method requires a premium user account
PREMIUM_GIFTCODE_WAS_REFUNDED This gift code can't be redeemed because the giveaway organizer requested a refund
PRICING_CHAT_INVALID This chat chat doesn't support subscription link.
PRIVACY_KEY_INVALID The privacy key is invalid
PRIVACY_TOO_LONG Your privacy exception list has exceeded the maximum capacity
PRIVACY_VALUE_INVALID The privacy value is invalid
@ -357,6 +380,9 @@ SLOWMODE_MULTI_MSGS_DISABLED Slowmode is enabled, you cannot forward multiple me
SMS_CODE_CREATE_FAILED An error occurred while creating the SMS code
SRP_ID_INVALID Invalid SRP ID provided
SRP_PASSWORD_CHANGED The password has changed
STARGIFT_ALREADY_CONVERTED The provided star gift already converted to stars
STARGIFT_ALREADY_UPGRADED This star gift was already upgraded before
STARGIFT_USAGE_LIMITED The star gift usage is limited
START_PARAM_EMPTY The start parameter is empty
START_PARAM_INVALID The start parameter is invalid
START_PARAM_TOO_LONG The start parameter is too long
@ -380,8 +406,15 @@ STICKER_THUMB_PNG_NOPNG A png sticker thumbnail file was expected, but something
STICKER_VIDEO_BIG The specified video sticker is too big
STICKER_VIDEO_NODOC You must send the video sticker as a document
STICKER_VIDEO_NOWEBM A webm video file was expected, but something else was provided
STORY_ID_EMPTY You specified no story IDs.
STORY_ID_INVALID The specified story ID is invalid.
STORY_NOT_MODIFIED The new story information you passed is equal to the previous story information, thus it wasn't modified.
STORY_PERIOD_INVALID The specified story period is invalid for this account.
STORIES_TOO_MUCH Too many stories in the current account
STORY_SEND_FLOOD_WEEKLY_X You've hit the weekly story limit, wait for the specified number of seconds before posting a new story.
STORY_SEND_FLOOD_MONTHLY_X You've hit the monthly story limit, wait for the specified number of seconds before posting a new story.
STORY_PERIOD_INVALID The story period is invalid
SUBSCRIPTION_PERIOD_INVALID The subscription period is invalid.
SWITCH_PM_TEXT_EMPTY The switch_pm.text field was empty
TAKEOUT_INVALID The takeout id is invalid
TAKEOUT_REQUIRED The method must be invoked inside a takeout session
@ -398,8 +431,11 @@ TMP_PASSWORD_INVALID The temporary password is invalid
TOKEN_INVALID The provided token is invalid
TOPIC_CLOSED The topic was closed
TOPIC_DELETED The topic was deleted
TOPIC_CLOSE_SEPARATELY The close flag cannot be provided together with any of the other flags.
TOPIC_HIDE_SEPARATELY The hide flag cannot be provided together with any of the other flags.
TOPIC_ID_INVALID The provided topic ID is invalid
TOPIC_NOT_MODIFIED The topic was not modified
TOPIC_TITLE_EMPTY The specified topic title is empty.
TO_LANG_INVALID The specified destination language is invalid
TRANSCRIPTION_FAILED Telegram is having internal problems. Please try again later to transcribe the audio.
TTL_DAYS_INVALID The provided TTL days is invalid
@ -440,11 +476,12 @@ USER_VOLUME_INVALID The specified user volume is invalid
VIDEO_CONTENT_TYPE_INVALID The video content type is invalid (i.e.: not streamable)
VIDEO_FILE_INVALID The video file is invalid
VIDEO_TITLE_EMPTY The specified video title is empty
VOICE_MESSAGES_FORBIDDEN Voice messages are restricted
VOICE_MESSAGES_FORBIDDEN This user's privacy settings forbid you from sending voice messages
VOLUME_LOC_NOT_FOUND The volume location can't be found
WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper
WALLPAPER_INVALID The input wallpaper was not valid
WALLPAPER_MIME_INVALID The wallpaper mime type is invalid
WALLPAPER_NOT_FOUND The specified wallpaper could not be found.
WC_CONVERT_URL_INVALID WC convert URL invalid
WEBDOCUMENT_INVALID The web document is invalid
WEBDOCUMENT_MIME_INVALID The web document mime type is invalid
@ -463,5 +500,9 @@ STORIES_NEVER_CREATED You have never created any stories
MEDIA_FILE_INVALID The provided media file is invalid
CHANNEL_FORUM_MISSING The channel forum is missing
TTL_PERIOD_INVALID The provided TTL period is invalid
BOOSTS_REQUIRED Channel required more boost to upload a story
BOOSTS_EMPTY Boosts empty
BOOSTS_REQUIRED The specified channel must first be boosted by its users in order to perform this action
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
2 ABOUT_TOO_LONG The provided about/bio text is too long
3 ACCESS_TOKEN_EXPIRED The bot token has expired
4 ACCESS_TOKEN_INVALID The bot access token is invalid
5 ADDRESS_INVALID The specified geopoint address is invalid.
6 ADMINS_TOO_MUCH The chat has too many administrators
7 ADMIN_ID_INVALID The specified admin ID is invalid
8 ADMIN_RANK_EMOJI_NOT_ALLOWED Emoji are not allowed in custom administrator titles
9 ADMIN_RANK_INVALID The custom administrator title is invalid or too long
10 ADMIN_RIGHTS_EMPTY The chatAdminRights constructor passed in keyboardButtonRequestPeer.peer_type.user_admin_rights has no rights set (i.e. flags is 0).
11 ALBUM_PHOTOS_TOO_MANY Too many photos were included in the album
12 API_ID_INVALID The api_id/api_hash combination is invalid
13 API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side because it was published somewhere
25 BANK_CARD_NUMBER_INVALID The credit card number is invalid
26 BANNED_RIGHTS_INVALID You provided a set of restrictions that is invalid
27 BASE_PORT_LOC_INVALID The base port location is invalid
28 BIRTHDAY_INVALID The age should be less than 150 year old in Telegram
29 BOTS_TOO_MUCH The chat has too many bots
30 BOT_CHANNELS_NA Bots can't edit admin privileges
31 BOT_COMMAND_DESCRIPTION_INVALID The command description was empty, too long or had invalid characters
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
54 BUTTON_TYPE_INVALID The type of one of the buttons you provided is invalid
55 BUTTON_URL_INVALID The button url is invalid
64 CHANNELS_TOO_MUCH You have joined too many channels or supergroups, leave some and try again
65 CHANNEL_ADD_INVALID Internal error.
66 CHANNEL_BANNED The channel is banned
67 CHANNEL_ID_INVALID The specified supergroup ID is invalid.
68 CHANNEL_INVALID The channel parameter is invalid
69 CHANNEL_PARICIPANT_MISSING The current user is not in the channel
70 CHANNEL_PRIVATE The channel/supergroup is not accessible
71 CHANNEL_TOO_BIG The channel too big
72 CHANNEL_TOO_LARGE The channel is too large Channel is too large to be deleted; this error is issued when trying to delete channels with more than 1000 members (subject to change).
73 CHARGE_ALREADY_REFUNDED The charge id was already used for a refund.
74 CHARGE_NOT_FOUND The charge id was not found.
75 CHATLIST_EXCLUDE_INVALID The specified `exclude_peers` are invalid.
76 CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content
77 CHAT_ABOUT_TOO_LONG The chat about text is too long
78 CHAT_ADMIN_REQUIRED The method requires chat admin privileges
103 CONNECTION_SYSTEM_LANG_CODE_EMPTY The system language code is empty
104 CONTACT_ADD_MISSING Contact to add is missing
105 CONTACT_ID_INVALID The provided contact id is invalid
106 CONTACT_MISSING The specified user is not a contact.
107 CONTACT_NAME_EMPTY The provided contact name is empty
108 CONTACT_REQ_MISSING Missing contact request
109 CREATE_CALL_FAILED An error occurred while creating the call
118 EMAIL_HASH_EXPIRED The email hash expired and cannot be used to verify it
119 EMAIL_INVALID The email provided is invalid
120 EMAIL_NOT_ALLOWED This email is not allowed
121 EMAIL_NOT_SETUP In order to change the login email with emailVerifyPurposeLoginChange, an existing login email must already be set using emailVerifyPurposeLoginSetup.
122 EMAIL_UNCONFIRMED Email unconfirmed
123 EMAIL_UNCONFIRMED_X The provided email isn't confirmed, {value} is the length of the verification code that was just sent to the email
124 EMAIL_VERIFY_EXPIRED The verification email has expired
125 EMOJI_INVALID The specified theme emoji is valid
126 EMOJI_MARKUP_INVALID The specified `video_emoji_markup` was invalid.
127 EMOJI_NOT_MODIFIED The theme wasn't changed
128 EMOTICON_EMPTY The emoticon parameter is empty
129 EMOTICON_INVALID The emoticon parameter is invalid
140 EXPIRE_DATE_INVALID The expiration date is invalid
141 EXPIRE_FORBIDDEN Expire forbidden
142 EXPORT_CARD_INVALID The provided card is invalid
143 EXTENDED_MEDIA_AMOUNT_INVALID The maximum amount of `star_count` should be less than the `stars_paid_post_amount_max`
144 EXTENDED_MEDIA_PEER_INVALID The specified chat type is invalid.
145 EXTENDED_MEDIA_TYPE_INVALID The specified extended media type is unsupported.
146 EXTERNAL_URL_INVALID The external media URL is invalid
147 FIELD_NAME_EMPTY The field with the name FIELD_NAME is missing
148 FIELD_NAME_INVALID The field with the name FIELD_NAME is invalid
171 FOLDER_ID_EMPTY The folder you tried to delete was already empty
172 FOLDER_ID_INVALID The folder id is invalid
173 FORM_ID_EXPIRED The specified id has expired.
174 FORUM_ENABLED You can't execute the specified action because the group is a [forum](https://core.telegram.org/api/forum), disable forum functionality to continue.
175 FRESH_CHANGE_ADMINS_FORBIDDEN You can't change administrator settings in this chat because your session was logged-in recently
176 FROM_MESSAGE_BOT_DISABLED Bots can't use fromMessage min constructors
177 FROM_PEER_INVALID The from peer value is invalid
178 GAME_BOT_INVALID You cannot send that game with the current bot
179 GENERAL_MODIFY_ICON_FORBIDDEN You can't modify the icon of the General topic.
180 GEO_POINT_INVALID Invalid geo point provided
181 GIF_CONTENT_TYPE_INVALID GIF content-type invalid
182 GIF_ID_INVALID The provided gif/animation id is invalid
183 GIFT_SLUG_INVALID The specified slug is invalid.
184 GIFT_SLUG_EXPIRED The gift slug is expired
185 GRAPH_EXPIRED_RELOAD This graph has expired, please obtain a new graph token
186 GRAPH_INVALID_RELOAD Invalid graph token provided, please reload the stats and provide the updated token
207 INPUT_METHOD_INVALID The method invoked is invalid in the current schema
208 INPUT_REQUEST_TOO_LONG The input request is too long
209 INPUT_TEXT_EMPTY The specified text is empty
210 INPUT_TEXT_TOO_LONG The specified text is too long.
211 INPUT_USER_DEACTIVATED The target user has been deleted/deactivated
212 INVITES_TOO_MUCH The maximum number of per-folder invites specified by the `chatlist_invites_limit_default`/`chatlist_invites_limit_premium` was reached.
213 INVITE_FORBIDDEN_WITH_JOINAS If the user has anonymously joined a group call as a channel, they can't invite other users to the group call because that would cause deanonymization, because the invite would be sent using the original user ID, not the anonymized channel ID
214 INVITE_HASH_EMPTY The invite hash is empty
215 INVITE_HASH_EXPIRED The chat invite link is no longer valid
260 NEW_SALT_INVALID The new salt is invalid
261 NEW_SETTINGS_EMPTY No password is set on the current account, and no new password was specified in `new_settings`
262 NEW_SETTINGS_INVALID The new settings are invalid
263 NOGENERAL_HIDE_FORBIDDEN The hidden parameter is only valid for the General topic message_thread_id=1
264 NEXT_OFFSET_INVALID The next offset value is invalid
265 OFFSET_INVALID The offset parameter is invalid
266 OFFSET_PEER_ID_INVALID The provided offset peer is invalid
312 PHOTO_THUMB_URL_EMPTY The photo thumb URL is empty
313 PHOTO_THUMB_URL_INVALID The photo thumb URL is invalid
314 PINNED_DIALOGS_TOO_MUCH Too many pinned dialogs
315 PINNED_TOPIC_NOT_MODIFIED The pinned topic was not modified.
316 PIN_RESTRICTED You can't pin messages in private chats with other people
317 POLL_ANSWERS_INVALID The poll answers are invalid
318 POLL_ANSWER_INVALID One of the poll answers is not acceptable
322 POLL_UNSUPPORTED This layer does not support polls in the invoked method
323 POLL_VOTE_REQUIRED Cast a vote in the poll before calling this method
324 PREMIUM_ACCOUNT_REQUIRED The method requires a premium user account
325 PREMIUM_GIFTCODE_WAS_REFUNDED This gift code can't be redeemed because the giveaway organizer requested a refund
326 PRICING_CHAT_INVALID This chat chat doesn't support subscription link.
327 PRIVACY_KEY_INVALID The privacy key is invalid
328 PRIVACY_TOO_LONG Your privacy exception list has exceeded the maximum capacity
329 PRIVACY_VALUE_INVALID The privacy value is invalid
380 SMS_CODE_CREATE_FAILED An error occurred while creating the SMS code
381 SRP_ID_INVALID Invalid SRP ID provided
382 SRP_PASSWORD_CHANGED The password has changed
383 STARGIFT_ALREADY_CONVERTED The provided star gift already converted to stars
384 STARGIFT_ALREADY_UPGRADED This star gift was already upgraded before
385 STARGIFT_USAGE_LIMITED The star gift usage is limited
386 START_PARAM_EMPTY The start parameter is empty
387 START_PARAM_INVALID The start parameter is invalid
388 START_PARAM_TOO_LONG The start parameter is too long
406 STICKER_VIDEO_BIG The specified video sticker is too big
407 STICKER_VIDEO_NODOC You must send the video sticker as a document
408 STICKER_VIDEO_NOWEBM A webm video file was expected, but something else was provided
409 STORY_ID_EMPTY You specified no story IDs.
410 STORY_ID_INVALID The specified story ID is invalid.
411 STORY_NOT_MODIFIED The new story information you passed is equal to the previous story information, thus it wasn't modified.
412 STORY_PERIOD_INVALID The specified story period is invalid for this account.
413 STORIES_TOO_MUCH Too many stories in the current account
414 STORY_SEND_FLOOD_WEEKLY_X You've hit the weekly story limit, wait for the specified number of seconds before posting a new story.
415 STORY_SEND_FLOOD_MONTHLY_X You've hit the monthly story limit, wait for the specified number of seconds before posting a new story.
416 STORY_PERIOD_INVALID The story period is invalid
417 SUBSCRIPTION_PERIOD_INVALID The subscription period is invalid.
418 SWITCH_PM_TEXT_EMPTY The switch_pm.text field was empty
419 TAKEOUT_INVALID The takeout id is invalid
420 TAKEOUT_REQUIRED The method must be invoked inside a takeout session
431 TOKEN_INVALID The provided token is invalid
432 TOPIC_CLOSED The topic was closed
433 TOPIC_DELETED The topic was deleted
434 TOPIC_CLOSE_SEPARATELY The close flag cannot be provided together with any of the other flags.
435 TOPIC_HIDE_SEPARATELY The hide flag cannot be provided together with any of the other flags.
436 TOPIC_ID_INVALID The provided topic ID is invalid
437 TOPIC_NOT_MODIFIED The topic was not modified
438 TOPIC_TITLE_EMPTY The specified topic title is empty.
439 TO_LANG_INVALID The specified destination language is invalid
440 TRANSCRIPTION_FAILED Telegram is having internal problems. Please try again later to transcribe the audio.
441 TTL_DAYS_INVALID The provided TTL days is invalid
476 VIDEO_CONTENT_TYPE_INVALID The video content type is invalid (i.e.: not streamable)
477 VIDEO_FILE_INVALID The video file is invalid
478 VIDEO_TITLE_EMPTY The specified video title is empty
479 VOICE_MESSAGES_FORBIDDEN Voice messages are restricted This user's privacy settings forbid you from sending voice messages
480 VOLUME_LOC_NOT_FOUND The volume location can't be found
481 WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper
482 WALLPAPER_INVALID The input wallpaper was not valid
483 WALLPAPER_MIME_INVALID The wallpaper mime type is invalid
484 WALLPAPER_NOT_FOUND The specified wallpaper could not be found.
485 WC_CONVERT_URL_INVALID WC convert URL invalid
486 WEBDOCUMENT_INVALID The web document is invalid
487 WEBDOCUMENT_MIME_INVALID The web document mime type is invalid
500 MEDIA_FILE_INVALID The provided media file is invalid
501 CHANNEL_FORUM_MISSING The channel forum is missing
502 TTL_PERIOD_INVALID The provided TTL period is invalid
503 BOOSTS_REQUIRED Channel required more boost to upload a story The specified channel must first be boosted by its users in order to perform this action
504 BOOSTS_EMPTY Boosts empty You can't modify the icon of the General topic.
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

@ -14,9 +14,10 @@ PHONE_PASSWORD_FLOOD You have tried to log-in too many times
PREMIUM_CURRENTLY_UNAVAILABLE Premium currently unavailable
PREVIOUS_CHAT_IMPORT_ACTIVE_WAIT_XMIN Similar to a flood wait, must wait {value} minutes
SEND_CODE_UNAVAILABLE Returned when all available options for this type of number were already used (e.g. flash-call, then SMS, then this error might be returned to trigger a second resend)
PREMIUM_GIFTCODE_WAS_REFUNDED This gift code can't be redeemed because the giveaway organizer requested a refund
STICKERSET_INVALID The sticker set is invalid
STICKERSET_OWNER_ANONYMOUS This sticker set can't be used as the group's sticker set because it was created by one of its anonymous admins
UPDATE_APP_TO_LOGIN Update app to login
USERPIC_PRIVACY_REQUIRED You need to disable privacy settings for your profile picture in order to make your geolocation public
USERPIC_UPLOAD_REQUIRED You must have a profile picture to publish your geolocation
USER_RESTRICTED You are limited/restricted. You can't perform this action
USER_RESTRICTED You are limited/restricted. You can't perform this action

1 id message
14 PREMIUM_CURRENTLY_UNAVAILABLE Premium currently unavailable
15 PREVIOUS_CHAT_IMPORT_ACTIVE_WAIT_XMIN Similar to a flood wait, must wait {value} minutes
16 SEND_CODE_UNAVAILABLE Returned when all available options for this type of number were already used (e.g. flash-call, then SMS, then this error might be returned to trigger a second resend)
17 PREMIUM_GIFTCODE_WAS_REFUNDED This gift code can't be redeemed because the giveaway organizer requested a refund
18 STICKERSET_INVALID The sticker set is invalid
19 STICKERSET_OWNER_ANONYMOUS This sticker set can't be used as the group's sticker set because it was created by one of its anonymous admins
20 UPDATE_APP_TO_LOGIN Update app to login
21 USERPIC_PRIVACY_REQUIRED You need to disable privacy settings for your profile picture in order to make your geolocation public
22 USERPIC_UPLOAD_REQUIRED You must have a profile picture to publish your geolocation
23 USER_RESTRICTED You are limited/restricted. You can't perform this action

View file

@ -41,6 +41,8 @@ Index
- :meth:`~Client.on_edited_message`
- :meth:`~Client.on_edited_bot_business_message`
- :meth:`~Client.on_callback_query`
- :meth:`~Client.on_shipping_query`
- :meth:`~Client.on_pre_checkout_query`
- :meth:`~Client.on_message_reaction_updated`
- :meth:`~Client.on_message_reaction_count_updated`
- :meth:`~Client.on_inline_query`
@ -48,12 +50,13 @@ Index
- :meth:`~Client.on_chat_member_updated`
- :meth:`~Client.on_chat_join_request`
- :meth:`~Client.on_deleted_messages`
- :meth:`~Client.on_edited_bot_business_message`
- :meth:`~Client.on_deleted_bot_business_message`
- :meth:`~Client.on_user_status`
- :meth:`~Client.on_story`
- :meth:`~Client.on_poll`
- :meth:`~Client.on_disconnect`
- :meth:`~Client.on_raw_update`
- :meth:`~Client.on_error`
-----
@ -76,9 +79,10 @@ Details
.. autodecorator:: pyrogram.Client.on_chat_member_updated()
.. autodecorator:: pyrogram.Client.on_chat_join_request()
.. autodecorator:: pyrogram.Client.on_deleted_messages()
.. autodecorator:: pyrogram.Client.on_edited_bot_business_message()
.. autodecorator:: pyrogram.Client.on_deleted_bot_business_message()
.. autodecorator:: pyrogram.Client.on_user_status()
.. autodecorator:: pyrogram.Client.on_story()
.. autodecorator:: pyrogram.Client.on_poll()
.. autodecorator:: pyrogram.Client.on_disconnect()
.. autodecorator:: pyrogram.Client.on_raw_update()
.. autodecorator:: pyrogram.Client.on_error()

View file

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

View file

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

View file

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

View file

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

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

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

View file

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

View file

@ -16,10 +16,13 @@ to apply only a valid value among the expected ones.
BusinessSchedule
ChatAction
ChatEventAction
ChatJoinType
ChatMemberStatus
ChatMembersFilter
ChatType
ClientPlatform
FolderColor
GiftAttributeType
ListenerTypes
MessageEntityType
MessageMediaType
@ -27,22 +30,28 @@ to apply only a valid value among the expected ones.
MessagesFilter
ParseMode
PollType
ProfileColor
SentCodeType
NextCodeType
UserStatus
ReactionType
ReplyColor
StoriesPrivacyRules
StoryPrivacy
.. toctree::
:hidden:
BusinessSchedule
ChatAction
ChatEventAction
ChatJoinType
ChatMemberStatus
ChatMembersFilter
ChatType
ClientPlatform
FolderColor
GiftAttributeType
ListenerTypes
MessageEntityType
MessageMediaType
@ -50,9 +59,11 @@ to apply only a valid value among the expected ones.
MessagesFilter
ParseMode
PollType
ProfileColor
SentCodeType
NextCodeType
UserStatus
ReactionType
ReplyColor
StoriesPrivacyRules
StoryPrivacy

View file

@ -43,6 +43,8 @@ Index
- :class:`DeletedMessagesHandler`
- :class:`DeletedBotBusinessMessagesHandler`
- :class:`CallbackQueryHandler`
- :class:`PreCheckoutQueryHandler`
- :class:`ShippingQueryHandler`
- :class:`MessageReactionUpdatedHandler`
- :class:`MessageReactionCountUpdatedHandler`
- :class:`InlineQueryHandler`
@ -53,6 +55,7 @@ Index
- :class:`PollHandler`
- :class:`DisconnectHandler`
- :class:`RawUpdateHandler`
- :class:`ErrorHandler`
-----
@ -80,3 +83,4 @@ Details
.. autoclass:: PollHandler()
.. autoclass:: DisconnectHandler()
.. autoclass:: RawUpdateHandler()
.. autoclass:: ErrorHandler()

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])
@ -73,7 +73,7 @@ html_theme_options = {
"repo": "fontawesome/brands/github",
"edit": "material/file-edit-outline",
},
"site_url": "https://pyrofork.mayuri.my.id/",
"site_url": "https://pyrofork.wulan17.dev/",
"repo_url": "https://github.com/Mayuri-Chan/pyrofork/",
"repo_name": "pyrofork",
"globaltoc_collapse": True,

View file

@ -47,7 +47,7 @@ like send_audio(), send_document(), send_location(), etc...
),
InlineKeyboardButton( # Opens a web URL
"URL",
url="https://pyrofork.mayuri.my.id"
url="https://pyrofork.wulan17.dev"
),
],
[ # Second row

View file

@ -24,13 +24,13 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
input_message_content=InputTextMessageContent(
"Here's how to install **Pyrofork**"
),
url="https://pyrofork.mayuri.my.id/intro/install",
url="https://pyrofork.wulan17.dev/intro/install",
description="How to install Pyrofork",
reply_markup=InlineKeyboardMarkup(
[
[InlineKeyboardButton(
"Open website",
url="https://pyrofork.mayuri.my.id/intro/install"
url="https://pyrofork.wulan17.dev/intro/install"
)]
]
)
@ -40,13 +40,13 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
input_message_content=InputTextMessageContent(
"Here's how to use **Pyrofork**"
),
url="https://pyrofork.mayuri.my.id/start/invoking",
url="https://pyrofork.wulan17.dev/start/invoking",
description="How to use Pyrofork",
reply_markup=InlineKeyboardMarkup(
[
[InlineKeyboardButton(
"Open website",
url="https://pyrofork.mayuri.my.id/start/invoking"
url="https://pyrofork.wulan17.dev/start/invoking"
)]
]
)

View file

@ -11,7 +11,7 @@ to make it only work for specific messages in a specific chat.
# Target chat. Can also be a list of multiple chat ids/usernames
TARGET = -100123456789
# Welcome message template
MESSAGE = "{} Welcome to [Pyrofork](https://pyrofork.mayuri.my.id/)'s group chat {}!"
MESSAGE = "{} Welcome to [Pyrofork](https://pyrofork.wulan17.dev/)'s group chat {}!"
app = Client("my_account")

View file

@ -80,7 +80,20 @@ Using async_pymongo (Recommended for python3.9+):
print(await app.get_me())
Using motor:
Using official mongodb driver:
.. code-block:: python
from pymongo import AsyncMongoClient
from pyrogram import Client
conn = AsyncMongoClient("mongodb://...")
async with Client("my_account", mongodb=dict(connection=conn, remove_peers=False)) as app:
print(await app.get_me())
Using motor (Deprecated, but still works):
.. code-block:: python

View file

@ -37,68 +37,16 @@ list of the basic styles currently supported by Pyrofork.
- spoiler
- `text URL <https://pyrogram.org>`_
- `user text mention <tg://user?id=123456789>`_
- :emoji:`🔥`
- ``inline fixed-width code``
- .. code-block:: text
pre-formatted
fixed-width
code block
- > Quoted text
Markdown Style
--------------
To strictly use this mode, pass :obj:`~pyrogram.enums.ParseMode.MARKDOWN` to the *parse_mode* parameter when using
:meth:`~pyrogram.Client.send_message`. Use the following syntax in your message:
.. code-block:: text
**bold**
__italic__
--underline--
~~strike~~
||spoiler||
[text URL](https://pyrogram.org/)
[text user mention](tg://user?id=123456789)
`inline fixed-width code`
```
pre-formatted
fixed-width
code block
```
> Quoted text
**Example**:
.. code-block:: python
from pyrogram import enums
await app.send_message(
"me",
(
"**bold**, "
"__italic__, "
"--underline--, "
"~~strike~~, "
"||spoiler||, "
"[URL](https://pyrogram.org), "
"`code`, "
"```"
"for i in range(10):\n"
" print(i)"
"```"
),
parse_mode=enums.ParseMode.MARKDOWN
)
- > Quoted text with collapse/expand button
HTML Style
----------
@ -122,10 +70,10 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.HTML` to the *parse_mode*
<a href="tg://user?id=123456789">inline mention</a>
<code>inline fixed-width code</code>
<emoji id="12345678901234567890">🔥</emoji>
<code>inline fixed-width code</code>
<pre>
pre-formatted
fixed-width
@ -134,6 +82,8 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.HTML` to the *parse_mode*
<blockquote>Quoted text</blockquote>
<blockquote expandable>Quoted text with collapse/expand button</blockquote>
**Example**:
.. code-block:: python
@ -178,6 +128,72 @@ To strictly use this mode, pass :obj:`~pyrogram.enums.HTML` to the *parse_mode*
&lt;my text&gt;
Markdown Style
--------------
.. warning::
The Markdown style is not recommended for complex text formatting.
If you want to use complex text formatting such as nested entities, overlapping entities use the HTML style instead.
To strictly use this mode, pass :obj:`~pyrogram.enums.ParseMode.MARKDOWN` to the *parse_mode* parameter when using
:meth:`~pyrogram.Client.send_message`. Use the following syntax in your message:
.. code-block:: text
**bold**
__italic__
--underline--
~~strike~~
||spoiler||
[text URL](https://pyrogram.org/)
[text user mention](tg://user?id=123456789)
![🔥](tg://emoji?id=12345678901234567890)
`inline fixed-width code`
```
pre-formatted
fixed-width
code block
```
> Quoted text
**> Quoted text with collapse/expand button
**Example**:
.. code-block:: python
from pyrogram import enums
await app.send_message(
"me",
(
"**bold**, "
"__italic__, "
"--underline--, "
"~~strike~~, "
"||spoiler||, "
"[URL](https://pyrogram.org), "
"`code`, "
"```"
"for i in range(10):\n"
" print(i)"
"```"
),
parse_mode=enums.ParseMode.MARKDOWN
)
Different Styles
----------------
@ -230,18 +246,18 @@ strike` styles, and you can still combine both Markdown and HTML together.
Here there are some example texts you can try sending:
**Markdown**:
- ``**bold, --underline--**``
- ``**bold __italic --underline ~~strike~~--__**``
- ``**bold __and** italic__``
**HTML**:
- ``<b>bold, <u>underline</u></b>``
- ``<b>bold <i>italic <u>underline <s>strike</s></u></i></b>``
- ``<b>bold <i>and</b> italic</i>``
**Markdown (Not Recommended)**:
- ``**bold, --underline--**``
- ``**bold __italic --underline ~~strike~~--__**``
- ``**bold __and** italic__``
**Combined**:
- ``--you can combine <i>HTML</i> with **Markdown**--``

View file

@ -6,7 +6,7 @@ authors = [{ name = "wulan17", email = "mayuri@mayuri.my.id" }]
dependencies = ["pyaes==1.6.1", "pysocks==1.7.1", "pymediainfo-pyrofork>=6.0.1,<7.0.0"]
readme = "README.md"
license = "LGPL-3.0-or-later"
requires-python = "~=3.8"
requires-python = "~=3.10"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
@ -15,11 +15,11 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: Implementation",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
@ -43,7 +43,7 @@ Homepage = "https://github.com/Mayuri-Chan"
Tracker = "https://github.com/Mayuri-Chan/pyrofork/issues"
Community = "https://t.me/MayuriChan_Chat"
Source = "https://github.com/Mayuri-Chan/pyrofork"
Documentation = "https://pyrofork.mayuri.my.id"
Documentation = "https://pyrofork.wulan17.dev"
[build-system]
requires = ["hatchling"]
@ -60,7 +60,7 @@ dev = [
docs = [
"sphinx",
"sphinx-immaterial==0.12.2",
"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.40"
__version__ = "2.3.69"
__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,42 +33,45 @@ 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
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
from pyrogram.errors import (
SessionPasswordNeeded,
VolumeLocNotFound, ChannelPrivate,
BadRequest
BadRequest, ChannelInvalid, PersistentTimestampInvalid, PersistentTimestampOutdated
)
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
@ -221,10 +227,13 @@ class Client(Methods):
SYSTEM_VERSION = f"{platform.system()} {platform.release()}"
LANG_CODE = "en"
LANG_PACK = ""
SYSTEM_LANG_CODE = "en-US"
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
@ -245,13 +254,16 @@ class Client(Methods):
app_version: str = APP_VERSION,
device_model: str = DEVICE_MODEL,
system_version: str = SYSTEM_VERSION,
system_lang_code: str = SYSTEM_LANG_CODE,
lang_code: str = LANG_CODE,
lang_pack: str = LANG_PACK,
ipv6: Optional[bool] = False,
alt_port: Optional[bool] = False,
proxy: Optional[dict] = None,
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 +278,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,
@ -280,13 +292,16 @@ class Client(Methods):
self.app_version = app_version
self.device_model = device_model
self.system_version = system_version
self.system_lang_code = system_lang_code.lower()
self.lang_code = lang_code.lower()
self.lang_pack = lang_pack.lower()
self.ipv6 = ipv6
self.alt_port = alt_port
self.proxy = proxy
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 +331,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 +410,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 +426,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
if not self.use_qrcode:
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
if not self.use_qrcode:
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 +518,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.
@ -576,7 +591,7 @@ class Client(Methods):
)
if peer.usernames is not None and len(peer.usernames) > 1:
for uname in peer.usernames:
usernames.append((peer.id, uname.username.lower()))
usernames.append((peer_id, uname.username.lower()))
phone_number = peer.phone
peer_type = "bot" if peer.bot else "user"
elif isinstance(peer, (raw.types.Chat, raw.types.ChatForbidden)):
@ -593,7 +608,7 @@ class Client(Methods):
)
if peer.usernames is not None and len(peer.usernames) > 1:
for uname in peer.usernames:
usernames.append((peer.id, uname.username.lower()))
usernames.append((peer_id, uname.username.lower()))
peer_type = "channel" if peer.broadcast else "supergroup"
elif isinstance(peer, raw.types.ChannelForbidden):
peer_id = utils.get_channel_id(peer.id)
@ -662,10 +677,11 @@ class Client(Methods):
)]
),
pts=pts - pts_count,
limit=pts
limit=pts,
force=False
)
)
except ChannelPrivate:
except (ChannelPrivate, PersistentTimestampOutdated, PersistentTimestampInvalid):
pass
else:
if not isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
@ -710,6 +726,92 @@ class Client(Methods):
elif isinstance(updates, raw.types.UpdatesTooLong):
log.info(updates)
async def recover_gaps(self) -> Tuple[int, int]:
states = await self.storage.update_state()
message_updates_counter = 0
other_updates_counter = 0
if not states:
log.info("No states found, skipping recovery.")
return (message_updates_counter, other_updates_counter)
for state in states:
id, local_pts, _, local_date, _ = state
prev_pts = 0
while True:
try:
diff = await self.invoke(
raw.functions.updates.GetChannelDifference(
channel=await self.resolve_peer(id),
filter=raw.types.ChannelMessagesFilterEmpty(),
pts=local_pts,
limit=10000,
force=False
) if id < 0 else
raw.functions.updates.GetDifference(
pts=local_pts,
date=local_date,
qts=0
)
)
except (ChannelPrivate, ChannelInvalid, PersistentTimestampOutdated, PersistentTimestampInvalid):
break
if isinstance(diff, raw.types.updates.DifferenceEmpty):
break
elif isinstance(diff, raw.types.updates.DifferenceTooLong):
break
elif isinstance(diff, raw.types.updates.Difference):
local_pts = diff.state.pts
elif isinstance(diff, raw.types.updates.DifferenceSlice):
local_pts = diff.intermediate_state.pts
local_date = diff.intermediate_state.date
if prev_pts == local_pts:
break
prev_pts = local_pts
elif isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
break
elif isinstance(diff, raw.types.updates.ChannelDifferenceTooLong):
break
elif isinstance(diff, raw.types.updates.ChannelDifference):
local_pts = diff.pts
users = {i.id: i for i in diff.users}
chats = {i.id: i for i in diff.chats}
for message in diff.new_messages:
message_updates_counter += 1
self.dispatcher.updates_queue.put_nowait(
(
raw.types.UpdateNewMessage(
message=message,
pts=local_pts,
pts_count=-1
),
users,
chats
)
)
for update in diff.other_updates:
other_updates_counter += 1
self.dispatcher.updates_queue.put_nowait(
(update, users, chats)
)
if isinstance(diff, (raw.types.updates.Difference, raw.types.updates.ChannelDifference)):
break
await self.storage.update_state(id)
log.info("Recovered %s messages and %s updates.", message_updates_counter, other_updates_counter)
return (message_updates_counter, other_updates_counter)
async def load_session(self):
await self.storage.open()
@ -723,7 +825,7 @@ class Client(Methods):
if session_empty:
if not self.api_id or not self.api_hash:
raise AttributeError("The API key is required for new authorizations. "
"More info: https://pyrofork.mayuri.my.id/main/start/auth")
"More info: https://pyrofork.wulan17.dev/main/start/auth")
await self.storage.api_id(self.api_id)
@ -761,6 +863,12 @@ class Client(Methods):
except Exception as e:
print(e)
def is_excluded(self, exclude, module):
for e in exclude:
if module == e or module.startswith(e + '.'):
return True
return False
def load_plugins(self):
if self.plugins:
plugins = self.plugins.copy()
@ -779,40 +887,178 @@ class Client(Methods):
include = plugins.get("include", [])
exclude = plugins.get("exclude", [])
exclude_plugins = []
exclude_handlers = {}
if exclude:
for path, handler in exclude:
module_path = os.path.join(
root.replace(".", "/"), path.replace(".", "/")
)
if handler is None:
exclude_plugins.append(module_path.replace("/", ".").replace("\\", "."))
else:
exclude_handlers[module_path.replace("/", ".").replace("\\", ".")] = handler
count = 0
if not include:
for path in sorted(Path(root.replace(".", "/")).rglob("*.py")):
module_path = '.'.join(path.parent.parts + (path.stem,))
module = import_module(module_path)
for current_root, _, filenames in os.walk(root.replace(".", "/")):
namespace = current_root.replace("/", ".").replace("\\", ".")
if "__pycache__" in namespace:
continue
if namespace in exclude_plugins:
log.warning(
'[%s] [LOAD] Ignoring namespace "%s"', self.name, namespace
)
continue
else:
for filename in filenames:
if filename.endswith(".py"):
module_path = namespace + "." + filename[:-3]
if module_path in exclude_plugins:
log.warning(
'[%s] [LOAD] Ignoring namespace "%s"',
self.name,
module_path,
)
continue
else:
module = import_module(module_path)
for name in vars(module).keys():
# noinspection PyBroadException
try:
for handler, group in getattr(module, name).handlers:
if isinstance(handler, Handler) and isinstance(group, int):
self.add_handler(handler, group)
for name in vars(module).keys():
log.info('[{}] [LOAD] {}("{}") in group {} from "{}"'.format(
self.name, type(handler).__name__, name, group, module_path))
# noinspection PyBroadException
try:
for handler, group in getattr(
module, name
).handlers:
if isinstance(
handler, Handler
) and isinstance(group, int):
count += 1
except Exception:
pass
if (
module_path in exclude_handlers
and name
in exclude_handlers[module_path]
):
exclude_handlers[
module_path
].remove(name)
log.warning(
'[{}] [LOAD] Ignoring function "{}" from group {} in "{}"'.format(
self.name,
name,
group,
module_path,
)
)
continue
self.add_handler(handler, group)
log.info(
'[{}] [LOAD] {}("{}") in group {} from "{}"'.format(
self.name,
type(handler).__name__,
name,
group,
module_path,
)
)
count += 1
except Exception:
pass
else:
for path, handlers in include:
module_path = root + "." + path
module_path = root.replace("/", ".").replace("\\", ".") + "." + path
if self.is_excluded(exclude_plugins, module_path):
log.warning(
'[%s] [LOAD] Ignoring namespace "%s"', self.name, module_path
)
continue
warn_non_existent_functions = True
try:
module = import_module(module_path)
except ImportError:
log.warning('[%s] [LOAD] Ignoring non-existent module "%s"', self.name, module_path)
log.warning(
'[%s] [LOAD] Ignoring non-existent module "%s"',
self.name,
module_path,
)
continue
if "__path__" in dir(module):
log.warning('[%s] [LOAD] Ignoring namespace "%s"', self.name, module_path)
continue
for current_root, _, filenames in os.walk(module_path.replace(".", "/")):
namespace = current_root.replace("/", ".").replace("\\", ".")
if "__pycache__" in namespace:
continue
if namespace in exclude_plugins:
log.warning(
'[%s] [LOAD] Ignoring namespace "%s"', self.name, namespace
)
continue
else:
for filename in filenames:
if filename.endswith(".py"):
module_path = namespace + "." + filename[:-3]
if module_path in exclude_plugins:
log.warning(
'[%s] [LOAD] Ignoring namespace "%s"',
self.name,
module_path,
)
continue
else:
module = import_module(module_path)
for name in vars(module).keys():
# noinspection PyBroadException
try:
for handler, group in getattr(
module, name
).handlers:
if isinstance(
handler, Handler
) and isinstance(group, int):
if (
module_path in exclude_handlers
and name
in exclude_handlers[module_path]
):
exclude_handlers[
module_path
].remove(name)
log.warning(
'[{}] [LOAD] Ignoring function "{}" from group {} in "{}"'.format(
self.name,
name,
group,
module_path,
)
)
continue
self.add_handler(handler, group)
log.info(
'[{}] [LOAD] {}("{}") in group {} from "{}"'.format(
self.name,
type(handler).__name__,
name,
group,
module_path,
)
)
count += 1
except Exception:
pass
if handlers is None:
handlers = vars(module).keys()
@ -823,62 +1069,59 @@ class Client(Methods):
try:
for handler, group in getattr(module, name).handlers:
if isinstance(handler, Handler) and isinstance(group, int):
if (
module_path in exclude_handlers
and name in exclude_handlers[module_path]
):
exclude_handlers[module_path].remove(name)
log.warning(
'[{}] [LOAD] Ignoring function "{}" from group {} in "{}"'.format(
self.name, name, group, module_path
)
)
continue
self.add_handler(handler, group)
log.info('[{}] [LOAD] {}("{}") in group {} from "{}"'.format(
self.name, type(handler).__name__, name, group, module_path))
log.info(
'[{}] [LOAD] {}("{}") in group {} from "{}"'.format(
self.name,
type(handler).__name__,
name,
group,
module_path,
)
)
count += 1
except Exception:
if warn_non_existent_functions:
log.warning('[{}] [LOAD] Ignoring non-existent function "{}" from "{}"'.format(
self.name, name, module_path))
log.warning(
'[{}] [LOAD] Ignoring non-existent function "{}" from "{}"'.format(
self.name, name, module_path
)
)
if exclude:
for path, handlers in exclude:
module_path = root + "." + path
warn_non_existent_functions = True
try:
module = import_module(module_path)
except ImportError:
log.warning('[%s] [UNLOAD] Ignoring non-existent module "%s"', self.name, module_path)
continue
if "__path__" in dir(module):
log.warning('[%s] [UNLOAD] Ignoring namespace "%s"', self.name, module_path)
continue
if handlers is None:
handlers = vars(module).keys()
warn_non_existent_functions = False
for name in handlers:
# noinspection PyBroadException
try:
for handler, group in getattr(module, name).handlers:
if isinstance(handler, Handler) and isinstance(group, int):
self.remove_handler(handler, group)
log.info('[{}] [UNLOAD] {}("{}") from group {} in "{}"'.format(
self.name, type(handler).__name__, name, group, module_path))
count -= 1
except Exception:
if warn_non_existent_functions:
log.warning('[{}] [UNLOAD] Ignoring non-existent function "{}" from "{}"'.format(
self.name, name, module_path))
for module in exclude_handlers:
for handler in exclude_handlers[module]:
log.warning(
'[{}] [LOAD] Ignoring non-existent function "{}" from "{}"'.format(
self.name, handler, module
)
)
if count > 0:
log.info('[{}] Successfully loaded {} plugin{} from "{}"'.format(
self.name, count, "s" if count > 1 else "", root))
log.info(
'[{}] Successfully loaded {} plugin{} from "{}"'.format(
self.name, count, "s" if count > 1 else "", root
)
)
else:
log.warning('[%s] No plugin loaded from "%s"', self.name, root)
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

@ -55,7 +55,7 @@ except ImportError:
log.warning(
"TgCrypto is missing! "
"Pyrogram will work the same, but at a much slower speed. "
"More info: https://pyrofork.mayuri.my.id/main/topics/speedups"
"More info: https://pyrofork.wulan17.dev/main/topics/speedups"
)

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,11 +21,11 @@ import asyncio
import inspect
import logging
from collections import OrderedDict
from typing import Any
import pyrogram
from pyrogram import errors
from pyrogram import utils
from pyrogram import raw
from pyrogram import raw, types, utils
from pyrogram.handlers.handler import Handler
from pyrogram.handlers import (
BotBusinessConnectHandler,
BotBusinessMessageHandler,
@ -33,6 +33,7 @@ from pyrogram.handlers import (
MessageHandler,
EditedMessageHandler,
EditedBotBusinessMessageHandler,
ErrorHandler,
DeletedMessagesHandler,
DeletedBotBusinessMessagesHandler,
MessageReactionUpdatedHandler,
@ -47,7 +48,8 @@ from pyrogram.handlers import (
ChosenInlineResultHandler,
ChatMemberUpdatedHandler,
ChatJoinRequestHandler,
StoryHandler
StoryHandler,
PurchasedPaidMediaHandler
)
from pyrogram.raw.types import (
UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
@ -62,7 +64,8 @@ from pyrogram.raw.types import (
UpdateBotMessageReaction,
UpdateBotMessageReactions,
UpdateBotShippingQuery,
UpdateBusinessBotCallbackQuery
UpdateBusinessBotCallbackQuery,
UpdateBotPurchasedPaidMedia
)
log = logging.getLogger(__name__)
@ -88,13 +91,20 @@ class Dispatcher:
BOT_BUSSINESS_CONNECT_UPDATES = (UpdateBotBusinessConnect,)
PRE_CHECKOUT_QUERY_UPDATES = (UpdateBotPrecheckoutQuery,)
SHIPPING_QUERY_UPDATES = (UpdateBotShippingQuery,)
PURCHASED_PAID_MEDIA_UPDATES = (UpdateBotPurchasedPaidMedia,)
def __init__(self, client: "pyrogram.Client"):
self.client = client
self.loop = asyncio.get_event_loop()
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
self.loop = loop
self.handler_worker_tasks = []
self.locks_list = []
self.error_handlers = []
self.updates_queue = asyncio.Queue()
self.groups = OrderedDict()
@ -229,6 +239,12 @@ class Dispatcher:
BotBusinessConnectHandler
)
async def purchased_paid_media_parser(update, users, chats):
return (
pyrogram.types.PurchasedPaidMedia._parse(self.client, update, users),
PurchasedPaidMediaHandler
)
self.update_parsers = {
Dispatcher.NEW_MESSAGE_UPDATES: message_parser,
Dispatcher.NEW_BOT_BUSINESS_MESSAGE_UPDATES: bot_business_message_parser,
@ -248,14 +264,15 @@ class Dispatcher:
Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser,
Dispatcher.MESSAGE_BOT_NA_REACTION_UPDATES: message_bot_na_reaction_parser,
Dispatcher.MESSAGE_BOT_A_REACTION_UPDATES: message_bot_a_reaction_parser,
Dispatcher.BOT_BUSSINESS_CONNECT_UPDATES: bot_business_connect_parser
Dispatcher.BOT_BUSSINESS_CONNECT_UPDATES: bot_business_connect_parser,
Dispatcher.PURCHASED_PAID_MEDIA_UPDATES: purchased_paid_media_parser
}
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}
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(
@ -265,93 +282,7 @@ class Dispatcher:
log.info("Started %s HandlerTasks", self.client.workers)
if not self.client.skip_updates:
states = await self.client.storage.update_state()
if not states:
log.info("No states found, skipping recovery.")
return
message_updates_counter = 0
other_updates_counter = 0
for state in states:
id, local_pts, _, local_date, _ = state
prev_pts = 0
while True:
try:
diff = await self.client.invoke(
raw.functions.updates.GetChannelDifference(
channel=await self.client.resolve_peer(id),
filter=raw.types.ChannelMessagesFilterEmpty(),
pts=local_pts,
limit=10000
) if id < 0 else
raw.functions.updates.GetDifference(
pts=local_pts,
date=local_date,
qts=0
)
)
except (errors.ChannelPrivate, errors.ChannelInvalid):
break
if isinstance(diff, raw.types.updates.DifferenceEmpty):
break
elif isinstance(diff, raw.types.updates.DifferenceTooLong):
break
elif isinstance(diff, raw.types.updates.Difference):
local_pts = diff.state.pts
elif isinstance(diff, raw.types.updates.DifferenceSlice):
local_pts = diff.intermediate_state.pts
local_date = diff.intermediate_state.date
if prev_pts == local_pts:
break
prev_pts = local_pts
elif isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
break
elif isinstance(diff, raw.types.updates.ChannelDifferenceTooLong):
break
elif isinstance(diff, raw.types.updates.ChannelDifference):
local_pts = diff.pts
users = {i.id: i for i in diff.users}
chats = {i.id: i for i in diff.chats}
for message in diff.new_messages:
message_updates_counter += 1
self.updates_queue.put_nowait(
(
raw.types.UpdateNewMessage(
message=message,
pts=local_pts,
pts_count=-1
) if id == self.client.me.id else
raw.types.UpdateNewChannelMessage(
message=message,
pts=local_pts,
pts_count=-1
),
users,
chats
)
)
for update in diff.other_updates:
other_updates_counter += 1
self.updates_queue.put_nowait(
(update, users, chats)
)
if isinstance(diff, (raw.types.updates.Difference, raw.types.updates.ChannelDifference)):
break
await self.client.storage.update_state(id)
log.info("Recovered %s messages and %s updates.", message_updates_counter, other_updates_counter)
await self.client.recover_gaps()
async def stop(self):
if not self.client.no_updates:
@ -363,6 +294,7 @@ class Dispatcher:
self.handler_worker_tasks.clear()
self.groups.clear()
self.error_handlers.clear()
log.info("Stopped %s HandlerTasks", self.client.workers)
@ -372,11 +304,14 @@ class Dispatcher:
await lock.acquire()
try:
if group not in self.groups:
self.groups[group] = []
self.groups = OrderedDict(sorted(self.groups.items()))
self.groups[group].append(handler)
if isinstance(handler, ErrorHandler):
if handler not in self.error_handlers:
self.error_handlers.append(handler)
else:
if group not in self.groups:
self.groups[group] = []
self.groups = OrderedDict(sorted(self.groups.items()))
self.groups[group].append(handler)
finally:
for lock in self.locks_list:
lock.release()
@ -389,17 +324,23 @@ class Dispatcher:
await lock.acquire()
try:
if group not in self.groups:
raise ValueError(f"Group {group} does not exist. Handler was not removed.")
self.groups[group].remove(handler)
if isinstance(handler, ErrorHandler):
if handler not in self.error_handlers:
raise ValueError(
f"Error handler {handler} does not exist. Handler was not removed."
)
self.error_handlers.remove(handler)
else:
if group not in self.groups:
raise ValueError(f"Group {group} does not exist. Handler was not removed.")
self.groups[group].remove(handler)
finally:
for lock in self.locks_list:
lock.release()
self.loop.create_task(fn())
async def handler_worker(self, lock):
async def handler_worker(self, lock: asyncio.Lock):
while True:
packet = await self.updates_queue.get()
@ -407,53 +348,91 @@ class Dispatcher:
break
try:
update, users, chats = packet
parser = self.update_parsers.get(type(update), None)
parsed_update, handler_type = (
await parser(update, users, chats)
if parser is not None
else (None, type(None))
)
async with lock:
for group in self.groups.values():
for handler in group:
args = None
if isinstance(handler, handler_type):
try:
if await handler.check(self.client, parsed_update):
args = (parsed_update,)
except Exception as e:
log.exception(e)
continue
elif isinstance(handler, RawUpdateHandler):
args = (update, users, chats)
if args is None:
continue
try:
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
)
except pyrogram.StopPropagation:
raise
except pyrogram.ContinuePropagation:
continue
except Exception as e:
log.exception(e)
break
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:
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)
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,
):
handled_error = True
break
except pyrogram.StopPropagation:
raise
except pyrogram.ContinuePropagation:
continue
except Exception as inner_exception:
log.exception("Error in error handler: %s", inner_exception)
if not handled_error:
log.exception("Unhandled exception: %s", exception)

View file

@ -20,14 +20,18 @@
from .business_schedule import BusinessSchedule
from .chat_action import ChatAction
from .chat_event_action import ChatEventAction
from .chat_join_type import ChatJoinType
from .chat_member_status import ChatMemberStatus
from .chat_members_filter import ChatMembersFilter
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
@ -45,14 +49,18 @@ __all__ = [
'BusinessSchedule',
'ChatAction',
'ChatEventAction',
'ChatJoinType',
'ChatMemberStatus',
'ChatMembersFilter',
'ChatType',
'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

@ -0,0 +1,34 @@
# 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 enum import auto
from .auto_name import AutoName
class ChatJoinType(AutoName):
"""How the service message :obj:`~pyrogram.enums.MessageServiceType.NEW_CHAT_MEMBERS` was used for the member to join the chat."""
BY_ADD = auto()
"A new member joined the chat via an invite link"
BY_LINK = auto()
"A new member joined the chat via an invite link"
BY_REQUEST = auto()
"A new member was accepted to the chat by an administrator"

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

@ -0,0 +1,36 @@
# 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 pyrogram import raw
from .auto_name import AutoName
class GiftAttributeType(AutoName):
"""Star gift attribute type enumeration used in :obj:`~pyrogram.types.GiftAttribute`."""
MODEL = raw.types.StarGiftAttributeModel
"Model attribute"
SYMBOL = raw.types.StarGiftAttributePattern
"Symbol attribute"
BACKDROP = raw.types.StarGiftAttributeBackdrop
"Backdrop attribute"
ORIGINAL_DETAILS = raw.types.StarGiftAttributeOriginalDetails
"Original details attribute"

View file

@ -0,0 +1,35 @@
# 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 enum import auto
from .auto_name import AutoName
class GiftForResaleOrder(AutoName):
"""Describes order in which upgraded gifts for resale will be sorted. Used in :meth:`~pyrogram.Client.search_gifts_for_resale`."""
PRICE = auto()
"The gifts will be sorted by their price from the lowest to the highest"
CHANGE_DATE = auto()
"The gifts will be sorted by the last date when their price was changed from the newest to the oldest"
NUMBER = auto()
"The gifts will be sorted by their number from the smallest to the largest"

View file

@ -84,3 +84,6 @@ class MessageMediaType(AutoName):
PAID_MEDIA = auto()
"Paid media"
TODO = auto()
"To-Do list media"

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

@ -28,9 +28,6 @@ class MessageServiceType(AutoName):
NEW_CHAT_MEMBERS = auto()
"New members join"
CHAT_JOINED_BY_REQUEST = auto()
"a member chat join request approved by admin."
LEFT_CHAT_MEMBERS = auto()
"Left chat members"
@ -61,7 +58,7 @@ class MessageServiceType(AutoName):
GAME_HIGH_SCORE = auto()
"Game high score"
ChatShared = auto()
CHAT_SHARED = auto()
"a shared chat/channel/user"
FORUM_TOPIC_CREATED = auto()
@ -116,4 +113,31 @@ class MessageServiceType(AutoName):
"Payment refunded"
BOT_ALLOWED = auto()
"Bot allowed"
"Bot allowed"
CHAT_THEME_UPDATED = auto()
"Chat theme updated"
CHAT_WALLPAPER_UPDATED = auto()
"Chat wallpaper updated"
CONTACT_REGISTERED = auto()
"Contact registered"
GIFT_CODE = auto()
"Gift code"
GIFT = auto()
"Star gift"
SCREENSHOT_TAKEN = auto()
"Screenshot taken"
PAID_MESSAGE_PRICE_CHANGED = auto()
"Paid message price changed"
TODO_TASKS_ADDED = auto()
"To-Do tasks added"
TODO_TASKS_COMPLETION = auto()
"To-Do tasks completion/incompletion"

View file

@ -27,3 +27,6 @@ class ReactionType(AutoName):
CUSTOM_EMOJI = auto()
"""Custom emoji reaction type."""
PAID = auto()
"""Paid reaction type."""

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)
@ -337,6 +338,34 @@ game = create(game_filter)
# endregion
# region giveaway_filter
async def giveaway_filter(_, __, m: Message):
return bool(m.giveaway)
giveaway = create(giveaway_filter)
"""Filter messages that contain :obj:`~pyrogram.types.Giveaway` objects."""
# endregion
# region giveaway_result_filter
async def giveaway_result_filter(_, __, m: Message):
return bool(m.giveaway_winners or m.giveaway_completed)
giveaway_result = create(giveaway_result_filter)
"""Filter messages that contain :obj:`~pyrogram.types.GiveawayWinners` or :obj:`~pyrogram.types.GiveawayCompleted` objects."""
# endregion
# region gift_code_filter
async def gift_code_filter(_, __, m: Message):
return bool(m.gift_code)
gift_code = create(gift_code_filter)
"""Filter messages that contain :obj:`~pyrogram.types.GiftCode` objects."""
# endregion
# region star_gift_filter
async def star_gift_filter(_, __, m: Message):
return bool(m.gift)
star_gift = create(star_gift_filter)
"""Filter messages that contain :obj:`~pyrogram.types.Gift` objects."""
# endregion
# region video_filter
async def video_filter(_, __, m: Message):
return bool(m.video)
@ -767,7 +796,7 @@ from_scheduled = create(from_scheduled_filter)
# region linked_channel_filter
async def linked_channel_filter(_, __, m: Message):
return bool(m.forward_from_chat and not m.from_user)
return bool((m.forward_origin and m.forward_origin.chat) and not m.from_user)
linked_channel = create(linked_channel_filter)
@ -861,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
@ -875,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
@ -982,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
@ -1015,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 (
@ -1033,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
@ -1042,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
@ -1053,6 +1136,7 @@ class topic(Filter, set):
Parameters:
topics (``int`` | ``list``):
Pass one or more topic ids to filter messages in specific topics.
Pass 1 for general topic.
Defaults to None (no topics).
"""
@ -1064,4 +1148,6 @@ class topic(Filter, set):
)
async def __call__(self, _, message: Message):
if message.is_topic_message and not message.topic:
return 1 in self
return message.topic and message.topic.id in self

View file

@ -29,10 +29,11 @@ from .deleted_bot_business_messages_handler import DeletedBotBusinessMessagesHan
from .disconnect_handler import DisconnectHandler
from .edited_message_handler import EditedMessageHandler
from .edited_bot_business_message_handler import EditedBotBusinessMessageHandler
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
from .story_handler import StoryHandler
@ -40,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

@ -0,0 +1,79 @@
# 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 __future__ import annotations
from collections.abc import Iterable
from typing import Callable
from .handler import Handler
import pyrogram
from pyrogram.types import Update
class ErrorHandler(Handler):
"""The Error handler class. Used to handle errors.
It is intended to be used with :meth:`~pyrogram.Client.add_handler`
For a nicer way to register this handler, have a look at the
:meth:`~pyrogram.Client.on_error` decorator.
Parameters:
callback (``Callable``):
Pass a function that will be called when a new Error arrives. It takes *(client, error)*
as positional arguments (look at the section below for a detailed description).
exceptions (``Exception`` | Iterable of ``Exception``, *optional*):
Pass one or more exception classes to allow only a subset of errors to be passed
in your callback function.
Other parameters:
client (:obj:`~pyrogram.Client`):
The Client itself, useful when you want to call other API methods inside the error handler.
update (:obj:`~pyrogram.Update`):
The update that caused the error.
error (``Exception``):
The error that was raised.
"""
def __init__(
self,
callback: Callable,
exceptions: type[Exception] | Iterable[type[Exception]] | None = None,
):
self.exceptions = (
tuple(exceptions)
if isinstance(exceptions, Iterable)
else (exceptions,)
if exceptions
else (Exception,)
)
super().__init__(callback)
async def check(self, client: pyrogram.Client, update: Update, exception: Exception) -> bool:
if isinstance(exception, self.exceptions):
await self.callback(client, update, exception)
return True
return False
def check_remove(self, error: type[Exception] | Iterable[type[Exception]]) -> bool:
return isinstance(error, self.exceptions)

View file

@ -0,0 +1,49 @@
# 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 Callable
from .handler import Handler
class PurchasedPaidMediaHandler(Handler):
"""The PurchasedPaidMedia handler class. Used to handle purchased paid medias.
It is intended to be used with :meth:`~pyrogram.Client.add_handler`
For a nicer way to register this handler, have a look at the
:meth:`~pyrogram.Client.on_purchased_paid_media` decorator.
Parameters:
callback (``Callable``):
Pass a function that will be called when a paid media purchased. It takes *(client, update)*
as positional arguments (look at the section below for a detailed description).
filters (:obj:`Filters`):
Pass one or more filters to allow only a subset of updates to be passed
in your callback function.
Other parameters:
client (:obj:`~pyrogram.Client`):
The Client itself, useful when you want to call other API methods inside the handler.
update (:obj:`~pyrogram.types.PurchasedPaidMedia`):
Information about who bought paid media.
"""
def __init__(self, callback: Callable, filters=None):
super().__init__(callback, filters)

View file

@ -35,6 +35,10 @@ class RawUpdateHandler(Handler):
*(client, update, users, chats)* as positional arguments (look at the section below for
a detailed description).
filters (:obj:`Filters`):
Pass one or more filters to allow only a subset of callback queries to be passed
in your callback function.
Other Parameters:
client (:obj:`~pyrogram.Client`):
The Client itself, useful when you want to call other API methods inside the update handler.
@ -64,5 +68,5 @@ class RawUpdateHandler(Handler):
- :obj:`~pyrogram.raw.types.ChannelForbidden`
"""
def __init__(self, callback: Callable):
super().__init__(callback)
def __init__(self, callback: Callable, filters=None):
super().__init__(callback, filters)

View file

@ -13,4 +13,15 @@ GNU General Public License for more details.
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
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

@ -23,11 +23,14 @@ from .bots import Bots
from .chats import Chats
from .contacts import Contacts
from .decorators import Decorators
from .forums import Forums
from .invite_links import InviteLinks
from .messages import Messages
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
@ -40,7 +43,10 @@ class Methods(
Contacts,
Password,
Pyromod,
Payments,
Phone,
Chats,
Forums,
Stickers,
Users,
Messages,

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

@ -36,6 +36,8 @@ from .set_bot_default_privileges import SetBotDefaultPrivileges
from .set_bot_info import SetBotInfo
from .set_chat_menu_button import SetChatMenuButton
from .set_game_score import SetGameScore
from .get_owned_bots import GetOwnedBots
from .get_similar_bots import GetSimilarBots
class Bots(
@ -57,6 +59,8 @@ class Bots(
SetChatMenuButton,
GetChatMenuButton,
AnswerWebAppQuery,
GetCollectibleItemInfo
GetCollectibleItemInfo,
GetOwnedBots,
GetSimilarBots,
):
pass

View file

@ -28,17 +28,24 @@ class GetCollectibleItemInfo:
phone_number: str = None
) -> "types.CollectibleInfo":
"""Returns information about a given collectible item that was purchased at https://fragment.com
.. include:: /_includes/usable-by/users.rst
You must use exactly one of ``username`` OR ``phone_number``.
Parameters:
username (``str``, *optional*):
Describes a collectible username that can be purchased at https://fragment.com
phone_number (``str``, *optional*):
Describes a collectible phone number that can be purchased at https://fragment.com
Returns:
:obj:`~pyrogram.types.CollectibleInfo`: On success, a collectible info is returned.
Example:
.. code-block:: python
username = await app.get_collectible_item_info(username="nerd")
print(username)
"""

View file

@ -0,0 +1,46 @@
# 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 List
import pyrogram
from pyrogram import raw, types
class GetOwnedBots:
async def get_owned_bots(
self: "pyrogram.Client",
) -> List["types.User"]:
"""Returns the list of bots owned by the current user.
.. include:: /_includes/usable-by/users.rst
Returns:
List of :obj:`~pyrogram.types.User`: On success.
Example:
.. code-block:: python
bots = await app.get_owned_bots()
"""
bots = await self.invoke(raw.functions.bots.GetAdminedBots())
return types.List([
types.User._parse(self, b)
for b in bots
])

View file

@ -0,0 +1,46 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# 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, Union
import pyrogram
from pyrogram import raw
class GetSimilarBots:
async def get_similar_bots(
self: "pyrogram.Client",
bot: Union[int, str]
) -> List["pyrogram.types.User"]:
"""Get a list of bots similar to the target bot.
.. include:: /_includes/usable-by/users.rst
Parameters:
bot (``int`` | ``str``):
Unique identifier (int) or username (str) of the target bot.
Returns:
List of :obj:`~pyrogram.types.User`: On success.
"""
peer = await self.resolve_peer(bot)
r = await self.invoke(raw.functions.bots.GetBotRecommendations(bot=peer))
return pyrogram.types.List([
pyrogram.types.User._parse(self, u)
for u in r.users
])

View file

@ -34,6 +34,7 @@ class SendGame:
business_connection_id: str = None,
reply_to_message_id: int = None,
protect_content: bool = None,
allow_paid_broadcast: bool = None,
message_effect_id: int = None,
reply_markup: Union[
"types.InlineKeyboardMarkup",
@ -74,6 +75,9 @@ class SendGame:
protect_content (``bool``, *optional*):
Protects the contents of the sent message from forwarding and saving.
allow_paid_broadcast (``bool``, *optional*):
Pass True to allow the message to ignore regular broadcast limits for a small fee; for bots only
message_effect_id (``int`` ``64-bit``, *optional*):
Unique identifier of the message effect to be added to the message; for private chats only.
@ -109,6 +113,7 @@ class SendGame:
reply_to=reply_to,
random_id=self.rnd_id(),
noforwards=protect_content,
allow_paid_floodskip=allow_paid_broadcast,
effect=message_effect_id,
reply_markup=await reply_markup.write(self) if reply_markup else None
)

View file

@ -17,10 +17,11 @@
# 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, Union, Optional
from datetime import datetime
from typing import Union, List, Optional
import pyrogram
from pyrogram import enums, raw, types, utils
from pyrogram import raw, enums, types, utils
class SendInlineBotResult:
@ -29,13 +30,17 @@ class SendInlineBotResult:
chat_id: Union[int, str],
query_id: int,
result_id: str,
disable_notification: bool = None,
message_thread_id: int = None,
reply_to_message_id: int = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None
) -> "raw.base.Updates":
disable_notification: Optional[bool] = None,
message_thread_id: Optional[int] = None,
reply_to_message_id: Optional[int] = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_story_id: Optional[int] = None,
quote_text: Optional[str] = None,
parse_mode: Optional["enums.ParseMode"] = None,
quote_entities: Optional[List["types.MessageEntity"]] = None,
quote_offset: Optional[int] = None,
schedule_date: datetime = None,
) -> "types.Message":
"""Send an inline bot result.
Bot results can be retrieved using :meth:`~pyrogram.Client.get_inline_bot_results`
@ -60,50 +65,74 @@ class SendInlineBotResult:
message_thread_id (``int``, *optional*):
Unique identifier of a message thread to which the message belongs.
for supergroups only
For supergroups only.
reply_to_message_id (``bool``, *optional*):
If the message is a reply, ID of the original message.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
reply_to_chat_id (``int``, *optional*):
If the message is a reply, ID of the original chat.
quote_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
List of special entities that appear in quote_text, which can be specified instead of *parse_mode*.
for reply_to_message only.
reply_to_story_id (``int``, *optional*):
If the message is a reply, ID of the target story.
quote_text (``str``, *optional*):
Text of the quote to be sent.
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
By default, quote_text are parsed using both Markdown and HTML styles.
By default, texts are parsed using both Markdown and HTML styles.
You can combine both syntaxes together.
For quote_text.
quote_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*):
List of special entities that appear in quote text, which can be specified instead of *parse_mode*.
quote_offset (``int``, *optional*):
Offset for quote in original message.
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
Date when the message will be automatically sent.
Returns:
:obj:`~pyrogram.raw.base.Updates`: Currently, on success, a raw result is returned.
:obj:`~pyrogram.types.Message`: On success, the sent message is returned or False if no message was sent.
Example:
.. code-block:: python
await app.send_inline_bot_result(chat_id, query_id, result_id)
"""
quote_text, quote_entities = (await utils.parse_text_entities(self, quote_text, parse_mode, quote_entities)).values()
reply_to = await utils.get_reply_to(
client=self,
chat_id=chat_id,
reply_to_message_id=reply_to_message_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode
quote_offset=quote_offset,
parse_mode=parse_mode,
)
return await self.invoke(
r = await self.invoke(
raw.functions.messages.SendInlineBotResult(
peer=await self.resolve_peer(chat_id),
query_id=query_id,
id=result_id,
random_id=self.rnd_id(),
silent=disable_notification or None,
reply_to=reply_to
reply_to=reply_to,
schedule_date=utils.datetime_to_timestamp(schedule_date),
)
)
for i in r.updates:
if isinstance(i, (raw.types.UpdateNewMessage,
raw.types.UpdateNewChannelMessage,
raw.types.UpdateNewScheduledMessage)):
return await types.Message._parse(
self, i.message,
{i.id: i for i in r.users},
{i.id: i for i in r.chats},
is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage),
business_connection_id=getattr(i, "connection_id", None)
)

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.
#
@ -17,23 +18,21 @@
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .create_invoice_link import CreateInvoiceLink
from .answer_shipping_query import AnswerShippingQuery
from .delete_business_messages import DeleteBusinessMessages
from .get_business_connection import GetBusinessConnection
from .get_stars_transactions import GetStarsTransactions
from .get_stars_transactions_by_id import GetStarsTransactionsById
from .refund_stars_payment import RefundStarPayment
from .send_invoice import SendInvoice
from .send_paid_media import SendPaidMedia
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,
CreateInvoiceLink,
AnswerShippingQuery,
DeleteBusinessMessages,
GetBusinessConnection,
GetStarsTransactions,
GetStarsTransactionsById,
RefundStarPayment,
SendInvoice,
SendPaidMedia
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

@ -21,24 +21,14 @@ from .add_chat_members import AddChatMembers
from .archive_chats import ArchiveChats
from .ban_chat_member import BanChatMember
from .create_channel import CreateChannel
from .create_forum_topic import CreateForumTopic
from .create_group import CreateGroup
from .create_supergroup import CreateSupergroup
from .close_forum_topic import CloseForumTopic
from .close_general_topic import CloseGeneralTopic
from .delete_channel import DeleteChannel
from .delete_chat_photo import DeleteChatPhoto
from .delete_folder import DeleteFolder
from .delete_forum_topic import DeleteForumTopic
from .delete_supergroup import DeleteSupergroup
from .delete_user_history import DeleteUserHistory
from .edit_forum_topic import EditForumTopic
from .edit_general_topic import EditGeneralTopic
from .export_folder_link import ExportFolderLink
from .reopen_forum_topic import ReopenForumTopic
from .reopen_general_topic import ReopenGeneralTopic
from .hide_general_topic import HideGeneralTopic
from .unhide_general_topic import UnhideGeneralTopic
from .get_chat import GetChat
from .get_chat_event_log import GetChatEventLog
from .get_chat_member import GetChatMember
@ -48,9 +38,6 @@ from .get_chat_online_count import GetChatOnlineCount
from .get_dialogs import GetDialogs
from .get_dialogs_count import GetDialogsCount
from .get_folders import GetFolders
from .get_forum_topics import GetForumTopics
from .get_forum_topics_by_id import GetForumTopicsByID
from .get_nearby_chats import GetNearbyChats
from .get_send_as_chats import GetSendAsChats
from .join_chat import JoinChat
from .leave_chat import LeaveChat
@ -67,6 +54,7 @@ from .set_chat_title import SetChatTitle
from .set_chat_username import SetChatUsername
from .set_send_as_chat import SetSendAsChat
from .set_slow_mode import SetSlowMode
from .transfer_chat_ownership import TransferChatOwnership
from .unarchive_chats import UnarchiveChats
from .unban_chat_member import UnbanChatMember
from .unpin_all_chat_messages import UnpinAllChatMessages
@ -97,29 +85,16 @@ class Chats(
SetChatPermissions,
GetDialogsCount,
GetFolders,
GetForumTopics,
GetForumTopicsByID,
ArchiveChats,
UnarchiveChats,
CreateGroup,
CreateSupergroup,
CreateChannel,
CreateForumTopic,
CloseForumTopic,
CloseGeneralTopic,
AddChatMembers,
DeleteChannel,
DeleteFolder,
DeleteForumTopic,
DeleteSupergroup,
EditForumTopic,
EditGeneralTopic,
ExportFolderLink,
ReopenForumTopic,
ReopenGeneralTopic,
HideGeneralTopic,
UnhideGeneralTopic,
GetNearbyChats,
SetAdministratorTitle,
SetSlowMode,
DeleteUserHistory,
@ -130,6 +105,7 @@ class Chats(
GetSendAsChats,
SetSendAsChat,
SetChatProtectedContent,
TransferChatOwnership,
UpdateColor,
UpdateFolder
):

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

@ -25,7 +25,7 @@ class ExportFolderLink:
async def export_folder_link(
self: "pyrogram.Client",
folder_id: int
) -> str:
) -> "pyrogram.types.ExportedFolderLink":
"""Export link to a user's folder.
.. include:: /_includes/usable-by/users.rst
@ -35,7 +35,7 @@ class ExportFolderLink:
Unique identifier (int) of the target folder.
Returns:
``str``: On success, a link to the folder as string is returned.
:obj:`~pyrogram.types.ExportedFolderLink` objects.
Example:
.. code-block:: python
@ -67,4 +67,4 @@ class ExportFolderLink:
)
)
return r.invite.url
return types.ExportedFolderLink._parse(r)

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

@ -21,7 +21,7 @@ from typing import AsyncGenerator, Optional
import pyrogram
from pyrogram import types, raw, utils
from pyrogram.errors import ChannelPrivate
from pyrogram.errors import ChannelPrivate, PeerIdInvalid
class GetDialogs:
@ -80,7 +80,7 @@ class GetDialogs:
chat_id = utils.get_peer_id(message.peer_id)
try:
messages[chat_id] = await types.Message._parse(self, message, users, chats)
except ChannelPrivate:
except (ChannelPrivate, PeerIdInvalid):
continue
dialogs = []

View file

@ -81,7 +81,7 @@ class GetFolders:
users.update({i.id: i for i in r.users})
chats.update({i.id: i for i in r.chats})
folders = types.List(types.Folder._parse(self, folder, users, chats) for folder in raw_folders)
folders = types.List([types.Folder._parse(self, folder, users, chats) for folder in raw_folders])
if not folders:
return None

View file

@ -1,79 +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/>.
from typing import List
import pyrogram
from pyrogram import raw
from pyrogram import types
from pyrogram import utils
class GetNearbyChats:
async def get_nearby_chats(
self: "pyrogram.Client",
latitude: float,
longitude: float
) -> List["types.Chat"]:
"""Get nearby chats.
.. include:: /_includes/usable-by/users.rst
Parameters:
latitude (``float``):
Latitude of the location.
longitude (``float``):
Longitude of the location.
Returns:
List of :obj:`~pyrogram.types.Chat`: On success, a list of nearby chats is returned.
Example:
.. code-block:: python
chats = await app.get_nearby_chats(latitude, longitude)
print(chats)
"""
r = await self.invoke(
raw.functions.contacts.GetLocated(
geo_point=raw.types.InputGeoPoint(
lat=latitude,
long=longitude
)
)
)
if not r.updates:
return []
chats = types.List([types.Chat._parse_chat(self, chat) for chat in r.chats])
peers = r.updates[0].peers
for peer in peers:
if isinstance(peer.peer, raw.types.PeerChannel):
chat_id = utils.get_channel_id(peer.peer.channel_id)
for chat in chats:
if chat.id == chat_id:
chat.distance = peer.distance
break
return chats

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