Compare commits

...

234 Commits

Author SHA1 Message Date
Sam
b472597fbc
Merge branch 'pyrogram:master' into mtpager 2022-02-02 17:41:08 +08:00
Dan
855e69e3f8 Update Pyrogram to v1.4.0 2022-02-01 12:07:30 +01:00
Dan
05bfaa3d87 Add support for video stickers
Add Sticker.is_video attribute
2022-02-01 11:38:58 +01:00
Dan
b676297ca9 Update API schema to Layer 138 2022-02-01 11:36:46 +01:00
Dan
b9424c7455 Add ChatJoinRequest bound methods docs 2022-02-01 11:01:02 +01:00
Dan
aaaa97c77a Document ApiCallError RPC error 2022-01-31 21:28:51 +01:00
Dan
51cf103c15 Update emoji.py 2022-01-31 21:27:58 +01:00
Dan
afad3a7704 Switch from issue templates to issue forms 2022-01-31 21:26:30 +01:00
Dan
084db0cea3 Merge branch 'master' of https://github.com/pyrogram/pyrogram 2022-01-31 20:47:22 +01:00
Dan
a8cc77d903 Update Pyrogram to v1.3.7 2022-01-31 20:46:53 +01:00
Dan
3a911956b0 Update message for automatic sleeps 2022-01-31 20:45:04 +01:00
Dan
6f9e77bc2c Do not handle messages with a pending ack 2022-01-31 20:42:44 +01:00
Sam
2eca3438be
Merge branch 'pyrogram:master' into mtpager 2022-01-31 14:22:43 +08:00
Andrea Princic
c7888437e8
Fixed error while unparsing consecutive entities (#885) 2022-01-29 18:50:51 +01:00
Dan
333d22afca Update API schema to Layer 137 2022-01-29 14:45:35 +01:00
Roj
f1298dfdc6
Add video_start_ts parameter to set_chat_photo (#770)
* Add `video_start_ts` parameter to `set_chat_photo`

* Docstrings update

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2022-01-29 14:08:15 +01:00
Pietro De Nicolao
3e79d7dfce
Add py.typed file for enhanced type hinting (#838)
Fixes #781

* fix: add py.typed file

Comply with PEP 561 and enable type checkers.
Fixes #781.

* chore: add py.typed to package_data in setup.py

* Style fixes

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2022-01-29 13:39:25 +01:00
Dan
b1250e6575 Fix accessing non-existent attribute
Closes #865
2022-01-29 13:02:32 +01:00
Mahesh
149685f9d3
Add placeholder in ForceReply & ReplyKeyboardMarkup (#717)
* Added placeholder

* Fix docs
2022-01-29 11:54:00 +01:00
W4RR10R
244606eed6
Add approve() and decline() bound methods to ChatJoinRequest (#863)
* Bound method approve() and decline()

* Style fixes

Co-authored-by: ArUn Pt <46273006+CW4RR10R@users.noreply.github.com>
Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2022-01-29 11:36:15 +01:00
Shrimadhav U K
4af9e30cfd
Fix caption being "None" when passing None (#879) 2022-01-29 11:13:09 +01:00
Sam
4544782b13
Merge branch 'pyrogram:master' into mtpager 2022-01-21 23:03:10 +08:00
Alisson Lauffer
7d444381c7
Fix spoiler html unparsing (#862)
- The current spoiler implementaion unparses both strikethrough and spoiler tags with <s>, making them indistinguishable
2022-01-21 10:26:52 +01:00
Sam
000e16d1cc
Merge branch 'pyrogram:master' into mtpager 2022-01-20 22:53:05 +08:00
Dan
23b02087c2 Update Pyrogram to v1.3.6 2022-01-20 09:44:21 +01:00
Dan
1162e89f26 Better handling of expiring server salts 2022-01-20 09:43:29 +01:00
Sam
910c6cacb0
Ability to run multiple handlers
🐛 Fix filter type hint
2022-01-20 01:04:13 +08:00
Sam
c1bd82ffdd
🐛 GzipPacked: Fix attr get 2022-01-20 00:03:05 +08:00
Sam
3812c5c584
⏭ Improve import speed
(This is the maximum speed Python can do)
2022-01-19 23:58:07 +08:00
Sam
e318562b16
⏭ Improve import speed
- By doing this can import required module on-the-fly
 Reformatted files
2022-01-19 23:22:43 +08:00
Sam
3c65090c4e
🐛 GzipPacked: Fix attr get 2022-01-19 23:20:26 +08:00
Sam
e413f5682b
🐛 Fix type hint 2022-01-19 22:53:18 +08:00
Sam
12a49e1d31
Crypto-MTProto: Improved pack and unpack function 2022-01-19 22:31:08 +08:00
Sam
053ec738e7
Connection: Improve logging text 2022-01-19 22:28:27 +08:00
Sam
0fa3115d32
🐛 Transport: Fix type hint 2022-01-19 22:27:53 +08:00
Sam
0dfed0b2fa
Transport: Added Padded Intermediate and Obfuscated Padded Intermediate 2022-01-19 22:27:30 +08:00
Sam
2a7b83d668
🐛 TLObject: Fix read return None instead of raise KeyError 2022-01-19 22:21:30 +08:00
Sam
6c078c38d0
Auth: Add type hint for send result 2022-01-19 22:20:54 +08:00
Sam
7178b4b1db
🐛 TCP: Fix exception message 2022-01-19 22:19:02 +08:00
Sam
cafc997df1
🐛 GetChatMembers: Fix unreached code problem 2022-01-19 22:19:02 +08:00
Sam
04b783281e
🆙 TL Schema: Update API schemes to layer 137
 Format compiler.py
2022-01-19 22:19:01 +08:00
Sam
86c81bfff9
Merge branch 'pyrogram:master' into mtpager 2022-01-12 00:28:27 +08:00
Dan
e67fd6efbb Update Pyrogram to v.1.3.5 2022-01-11 17:25:01 +01:00
Dan
a6299f8401 Use a proper condition check when dealing with flag vectors
When reading flag vectors, non-existent vectors are being translated
to [] (empty list). When writing them, the flag condition was
strictly checking for None and an empty list [] would result in an
empty vector being serialized, which should not happen.
Related to #871.
2022-01-11 17:24:17 +01:00
Sam
6d7f409a88
🐛 Remove extra ID added 2022-01-12 00:11:32 +08:00
Sam
4cdd72657e
Merge branch 'pyrogram:master' into mtpager 2022-01-12 00:10:47 +08:00
Dan
db9489b318 Update Pyrogram to v1.3.4 2022-01-11 16:59:08 +01:00
Dan
527ec23c20 Revert reading non-existent flag vectors from None to [] 2022-01-11 16:59:08 +01:00
Sam
52262bcf18
🔰 Add CodeQL scanning 2022-01-11 23:49:53 +08:00
Sam
08ec6528e7
Merge branch 'pyrogram:master' into mtpager 2022-01-11 23:45:20 +08:00
Sam
00454e2f7b
🐛 [fix] Change name back to Pyrogram 2022-01-11 23:44:28 +08:00
Dan
14ae9d314b Update Pyrogram to v1.3.3 2022-01-11 16:44:09 +01:00
Dan
5ec9743a1a
Minor style fix 2022-01-11 16:43:24 +01:00
Danipulok
10c512d39c
Remove unnecessary method call in get_media_group (#860) 2022-01-11 16:42:04 +01:00
Sam
de9705f126
Fix core types and compiler (#871)
- Add missing ID to FutureSalts
- Have vector flags read to None instead of [] for non-existent lists
2022-01-11 16:40:37 +01:00
Sam
0436826f27
Dump version to 1.3.3 2022-01-11 22:36:37 +08:00
Sam
a2ccdb2378
🔄 Sync local code 2022-01-11 22:35:38 +08:00
Sam
ec9e92d6d8
🐛 Fix generate error of vector
🐛 Add missing ID in future_salts.py
2022-01-11 22:05:36 +08:00
Dan
c7da4a8495 Update Pyrogram to v1.3.2 2022-01-10 14:32:10 +01:00
Dan
fbdc6613f2 Fix can_send_other_messages permission being inverted
Fixes #868
2022-01-10 14:31:17 +01:00
Dan
7fb35fbad5 Update Pyrogram to v1.3.1 2022-01-07 17:06:45 +01:00
SUBIN
1d7c57e669
Add missing parameter protect_content (#859) 2022-01-07 17:05:34 +01:00
Lorenzo Delmonte
2ca38d0ee9
Fix typo in OpenCollective link (#856) 2022-01-07 12:31:15 +01:00
Dan
cb6cef37e6 Update copyright year 2022-01-07 12:21:24 +01:00
Dan
44228f2472 Update Pyrogram to v1.3.0 2022-01-07 10:26:55 +01:00
Dan
626a1bd938 Update copyright year 2022-01-07 10:23:45 +01:00
Dan
8c8288412f Various improvements 2022-01-07 10:18:51 +01:00
Dan
80d0966691 Merge branch 'set-chat-protected-content' 2022-01-07 09:51:47 +01:00
Dan
ac3d2b8d7a Rename methods and add proper docs 2022-01-05 12:50:44 +01:00
Fernando Werneck
b283bce262
Add No Forwards chat option (#839)
* Add No Forwards chat option

* Fix chat.py
2022-01-05 12:37:25 +01:00
Dan
0a29890da4 Merge branch 'layer-136' 2022-01-03 11:19:15 +01:00
Dan
ebaf1a23fb Change markdown spoiler delimiter 2022-01-03 11:19:02 +01:00
Dan
f6625192d0 Add parameter protect_content to send_* methods 2022-01-03 11:12:24 +01:00
Dan
fb64e143b6 Add field Message.reactions 2021-12-30 13:46:44 +01:00
Dan
2799011c07 Add type Reaction 2021-12-30 13:46:07 +01:00
Dan
1fa637553d Add method send_reaction 2021-12-30 13:43:44 +01:00
Dan
b0a9d28bda Add field Chat.available_reactions 2021-12-30 13:43:44 +01:00
Dan
46d3d8aaf6 Update REACTION_INVALID error message 2021-12-30 13:39:58 +01:00
SUBIN
00c91120d8
Handle the case when default_send_as is None (#842)
* fix parsing send_as peer.

* Update chat.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-12-30 11:06:37 +01:00
Dan
f7b9137a68 Add support for "spoiler" MessageEntity 2021-12-30 09:14:49 +01:00
Dan
42c690757d Update API schema to Layer 136 2021-12-30 08:57:02 +01:00
Dan
9c67084170 Merge remote-tracking branch 'origin/master' 2021-12-24 16:29:35 +01:00
Dan
a3fab6af4b Merge branch 'mtproto-checks'
# Conflicts:
#	pyrogram/errors/__init__.py
#	pyrogram/session/session.py
2021-12-24 16:28:29 +01:00
Udith Amasura
cc4a850134
Make bot_username optional for LoginUrl (#817)
* make bot username optional

* Update login_url.py

* Update login_url.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-12-23 17:56:22 +01:00
Dan
9a2bc25bc7 Add support for "send_as" chats
- Add methods get_send_as_chats() and set_send_as_chat()
- Add field Chat.send_as_chat
2021-12-23 16:53:03 +01:00
Dan
e8076d1b8a Add method get_discussion_message 2021-12-22 15:00:03 +01:00
Dan
a138b46668 Add Message/Chat.has_protected_content 2021-12-22 14:49:28 +01:00
Dan
2024b3c120 Rename kick(ed) occurrences to ban(ned) 2021-12-22 14:39:52 +01:00
Dan
a909dc12e7 Add support for user profile buttons 2021-12-22 14:36:02 +01:00
Dan
d103ae48fe Add support for ChatJoinRequest events 2021-12-22 14:34:12 +01:00
Dan
8f8c85e8f3 Update ChatInviteLink 2021-12-22 14:13:44 +01:00
Dan
7d917f43e5 Add approve/decline_chat_join_request 2021-12-22 14:12:57 +01:00
Dan
29b4615848 Update create/edit_chat_invite_link 2021-12-22 14:08:24 +01:00
Dan
56e7e11037 Use a specialized exception for handling BadMsgNotification 2021-12-22 14:01:05 +01:00
David Hu
419ecb1af5
Add RPC Error: CHAT_FORWARDS_RESTRICTED (#825)
* Add RPC Error: CHAT_FORWARD_RESTRICTED

* Fix the typo in the previous commit

Sorry, made a typo in the error name

* Update 400_BAD_REQUEST.tsv

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-12-20 20:40:32 +01:00
Robert Schütz
4bb57a4da3
Include tests in sdist (#819) 2021-12-20 20:37:08 +01:00
Sam
fe764e0e2b
Update session string format (#818) 2021-12-20 20:34:57 +01:00
AduchiMergen
ef6125b57a
Fix -503 Timeout errors #664 (#812) 2021-12-20 20:22:56 +01:00
Dan
a917596cb1 Merge branch 'master' of https://github.com/pyrogram/pyrogram 2021-12-17 11:50:14 +01:00
Dan
9b28a120e2 Fix megagroup attribute on ChatForbidden objects 2021-12-17 11:49:53 +01:00
Adek
6fb427fb9a
Add new chat actions (#751)
* Add new chat action

* Update send_chat_action.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-12-17 10:41:39 +01:00
Dan
ea3281b5f6 Raise directly when not checking a boolean expression 2021-12-16 21:39:52 +01:00
Dan
8aa358129c Use specialized exceptions for handling security checks 2021-12-16 21:38:24 +01:00
Dan
a720726479 Remove unneeded assertion 2021-12-16 21:05:01 +01:00
Dan
ed9c7e4694 Simplify the error handling a bit 2021-12-15 19:26:54 +01:00
Dan
c2a29c8c30 Tune stored_msg_ids max size 2021-12-15 16:56:08 +01:00
Dan
2a1af2b8e9 Close and reestablish the TCP connection in case of mismatch 2021-12-15 16:02:39 +01:00
Dan
bc420da0e2 Maintain a sorted list of stored_msg_ids 2021-12-15 15:04:44 +01:00
Dan
cd027b8c1c Implement missing MTProto checks 2021-12-15 13:18:13 +01:00
Abir Hasan
cebecb99c0
Fix renamed raw API function (#810)
`raw.functions.channels.DeleteUserHistory` to `raw.functions.channels.DeleteParticipantHistory`
2021-12-13 13:20:55 +01:00
Dan
bf9e186414 Also fetch peer_id user details 2021-12-09 20:12:13 +01:00
Dan
a73f990667 Improve parsing of Chat 2021-12-08 07:46:41 +01:00
Dan
8a08dcb92a Update UserFull according to the new schema 2021-12-08 07:43:02 +01:00
Dan
439935b401 Fix wrong sender_chat 2021-12-07 22:39:56 +01:00
Dan
e2cce1b1e6 Check empty messages first of all 2021-12-07 20:29:46 +01:00
Dan
8d03850d03 Don't propagate errors when fetching missing user details 2021-12-07 20:22:29 +01:00
Dan
85ee6c3785 Fetch user details in case they are missing 2021-12-07 19:40:06 +01:00
Dan
34b6002c68 Fix joinchat links regex 2021-12-06 14:16:49 +01:00
Dan
f7db103071 Fix missing argument 2021-12-04 18:40:22 +01:00
Dan
2e964b3fa9 Update MAX_USER_ID 2021-12-04 18:39:35 +01:00
Dan
804d00fa0f Update get_me.py 2021-11-26 18:07:28 +01:00
Dan
ca29ea1db4 Update API schema to Layer 135 2021-11-26 18:03:17 +01:00
Dan
a460d12a82 Update API schema to Layer 134 2021-11-10 10:23:10 +01:00
Dan
aba5304fd6
Fix Actions on Python 3.10 2021-10-11 14:34:05 +02:00
Dan
e27f30dade
Enable Actions on Python 3.10 2021-10-11 14:31:00 +02:00
Dan
2265d282f5
Add search_global_count and search_messages_count methods (#768) 2021-10-11 14:27:31 +02:00
Dan
0f204e1d8c
Update requirements.txt 2021-10-06 17:13:30 +02:00
Dan
6efd01937f
Fix issues with Python 3.10 (#766) 2021-10-06 17:12:49 +02:00
Dan
428cbf56a6
Read integers first when size matches 2021-09-25 10:12:12 +02:00
Dan
362441a74a
Update API schema to Layer 133 (patch) 2021-09-25 10:02:19 +02:00
Dan
09c8289259
Update iter_dialogs.py
Closes #749 #750 #756
2021-09-15 17:55:01 +02:00
Alisson Lauffer
02a3969101
Fix Message.command when case is different (#757)
* Fix Message.command when case is different

* Update test_command.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-09-14 18:33:54 +02:00
Davide Galilei
fdbab8cc87
Final fix for reading vectors of bare longs (#754) 2021-09-11 14:52:34 +02:00
Dan
acd92b100b
Actually fix reading vectors of bare longs 2021-09-11 14:32:05 +02:00
Dan
c3953c18ca
Fix reading vectors of bare longs (#752) 2021-09-10 20:57:06 +02:00
Dan
eec7ec3947
Update API schema to Layer 133 2021-09-10 19:46:38 +02:00
Dan
320696b4b2
Update API schema to Layer 132 2021-08-31 21:59:23 +02:00
rking32
bacc7c004b
Improve the async-to-sync wrapper (#744)
* improved async to sync wrapper

* Create a new loop in non-main threads & improve readability

* Do not run_coroutine_threadsafe unless it's outside the loop

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-08-29 12:05:48 +02:00
Md. Hasibul Kabir
e68da74e89
Further improve the session-switching mechanism for inline bots (#739)
* Ability to run multiple bot.

Global session creates a problem for other bot. As that session was generated for another bot can't be used by this bot.

* Use the existing media session lock

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-08-29 10:49:47 +02:00
DatDraggy
aea1ffc46f
Fix old non existing can_send_[sticker...] with can_send_other_messages (#746)
c9d0c5d75a
2021-08-29 08:38:32 +02:00
Gautam Kumar
9e9a944e86
Fix parameter name being in plural (#724) 2021-08-28 14:42:16 +02:00
Jonathan
99e152a67c
Fix accessing non-existent attribute (#747)
This should solve the error `AttributeError: 'ChatParticipantsForbidden' object has no attribute 'participants'` and apply the commit 062a6ce6dd on this file, too.
2021-08-28 14:40:10 +02:00
餅喵
4d933b80f9
Fix TL schema naming conflicts (#690)
* Avoid variable conflicts with Telegram TL schema

* Fix game button with no data attached to button

* Update combinator.txt

* Update compiler.py

* Update tl_object.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-08-28 10:01:12 +02:00
Dan
6745c9d815 Update API schema to Layer 131 2021-07-25 12:46:39 +02:00
Dan
3d6ec570f3 Update API schema to Layer 130 2021-07-10 09:43:14 +02:00
Dan
8845b976ab
Fix docs (#699) (#703)
* Fix docs (#699)

* typo fixing

* Update inline_query_result_video.py

* layer update 129 (commits)

* fixes

* Update main_api.tl

* Update main_api.tl

Co-authored-by: BelgenOp <76117511+BelgenOp@users.noreply.github.com>
2021-06-23 17:01:06 +02:00
Shrimadhav U K
685b9328f8
Add missing parameters in reply_document (#700) 2021-06-22 10:40:13 +02:00
Dan
a65f8e2655 Clearer error message 2021-06-20 08:52:11 +02:00
Dan
3dde55db39 Update API schema to L129 (patch) 2021-06-20 08:48:38 +02:00
Dan
ab63abe6fd Update API schema to Layer 129 2021-06-06 11:52:01 +02:00
Dan
f7713d135e Use a cleaner link 2021-06-01 21:03:17 +02:00
Dan
c90e5a419c Update issue templates 2021-06-01 20:24:10 +02:00
Dan
91e0a08945 Merge branch 'chat-permissions-others' 2021-06-01 13:58:28 +02:00
Dan
0ca8ab29ab Merge branch 'in-memory-media-group' 2021-06-01 13:57:50 +02:00
Dan
523ed3e7cb Add support for in-memory uploads in send_media_group (#519)
* Add support for in-memory uploads for send_media_group

* update input_media_photo docs

* update type hints

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-06-01 13:57:31 +02:00
Dan
c9d0c5d75a Sync chat permissions with official clients 2021-05-31 20:23:32 +02:00
Dan
6cb3e92838 Reword a note 2021-05-22 10:01:46 +02:00
Christy Roys
0d12d8c1bb
Add support for in-memory uploads in send_media_group (#519)
* Add support for in-memory uploads for send_media_group

* update input_media_photo docs

* update type hints

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-22 10:00:23 +02:00
Dan
317685cf54 Further improve the HTML parser
Related to #682
2021-05-15 18:35:57 +02:00
Dan
7c9f1cb8ef Improve the HTML parser
Fixes #682
2021-05-15 18:14:27 +02:00
Ripe
be83f8e25e
Actually fix inline message id invalid (for inline message queries) (#683)
* Fix Inline Message ID Invalid

* Update inline_session.py

* Update inline_session.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-15 07:06:37 +02:00
Dan
aef0cce8d9 Add more RPC errors 2021-05-14 17:31:36 +02:00
Dan
dd32854db4 Squashed commit of the following:
commit d6dcf98d7445cbdc2a036deca57207c14bc354fc
Author: Dan <14043624+delivrance@users.noreply.github.com>
Date:   Wed May 12 09:35:18 2021 +0200

    Rename get_chat_onlines to get_chat_online_count

commit 21ff2a39d856ebc939ce9b15810198c82a9c23c6
Merge: 808c629f 29701a3a
Author: Dan <14043624+delivrance@users.noreply.github.com>
Date:   Wed May 12 09:32:59 2021 +0200

    Merge branch 'master' into get-chat-online-count

commit 808c629f43b185bc0df8337a82f5ecc860bbdb94
Author: Andriel Rodrigues <andrielkogama2@gmail.com>
Date:   Wed May 12 04:28:53 2021 -0300

    Add get_chat_online_count method (todo) (#654)
2021-05-12 09:39:51 +02:00
Dan
29701a3a55 Fix import errors 2021-05-12 09:27:39 +02:00
Gaetano
a4bb2a3fdf
Fix typo in send_video examples (#679) 2021-05-12 09:13:19 +02:00
Dan
e2ef053949 Merge remote-tracking branch 'origin/master' 2021-05-12 09:11:57 +02:00
Dan
5fdb361487 Fixes for InlineQueryResult{Audio,Video} 2021-05-12 09:11:52 +02:00
LёNya
a56b1a3287 add InlineQueryResultVideo 2021-05-12 08:56:44 +02:00
Lorenzo Delmonte
1704420697
Fix wrongly passed positional arguments (#603)
Since CallbackQuery.edit_message_text takes 4 arguments and CallbackQuery.edit_message_caption only 3, the reply_markup ends up to be the disable_web_page_preview one. Resolve this by specifying the argument name
2021-05-12 08:52:28 +02:00
Alisson Lauffer
df4419da8f
Make parse_mode always lowercase (#575)
* Make parse_mode always lowercase

* Update client.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-12 08:49:48 +02:00
Alan
b4bdab1047
Add InlineQueryResultAudio (#539)
* Added audio support for inline query

* mime-type removed

* Update inline_query_result_audio.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-12 08:47:41 +02:00
Dan
0c46b653ec Remove unneeded check 2021-05-12 08:31:08 +02:00
Mahesh
fd04648ea0
Add support for editing inline messages' media using local files (#675)
* Fix edit_inline_media for local files

* Update edit_inline_media.py

* Update edit_inline_media.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-12 08:29:49 +02:00
Leorio Paradinight
56e79c10f8
Fix captions being None when editing media message (#617)
* added missing doc string

* Fix for "None" for default caption
2021-05-12 08:28:21 +02:00
trenoduro
3be981ada1
Improved deleted message handling (#645)
* Tidy up namings of invite link methods

* Improved deleted message handling

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-11 10:45:55 +02:00
Jonathan
293e852afd
Add new method set_bot_commands (#657)
* a new method set_bot_commands

* Delete bot_commands_list.py

* Update set_bot_commands.py

* Update __init__.py

* Update set_bot_commands.py

* Update set_bot_commands.py

* Update bot_command.py

* Update set_bot_commands.py

* Update set_bot_commands.py

* Update compiler.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-11 10:22:17 +02:00
Dan
ed3576e8e6
Enable GitHub Actions on Pull Requests 2021-05-11 10:18:30 +02:00
Danipulok
ecd83c594c
Fixed method Client.get_media_group (#619)
* Fixed method

* Added exception in case message_id is invalid

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-09 12:43:23 +02:00
Danipulok
429b871171
Add method Client.copy_media_group (#592)
* Add method client.copy_media_group

* -updated wrong variable names

* Replace  with

* Update copy_media_group.py

* Update copy_media_group.py

* Update compiler.py

* Update copy_media_group.py

Co-authored-by: Dan <14043624+delivrance@users.noreply.github.com>
2021-05-09 12:39:49 +02:00
Dan
934091d8ea Fix get_me being called for every command
It needs to be called once only
2021-05-07 13:18:00 +02:00
Dan
636ff776d6 Fix duplicated commands in Message.command
Also add more test cases
Related to #676
2021-05-06 19:21:25 +02:00
Dan
4fc4501445 Remove trailing username when adding args to Message.command
Fixes #676
2021-05-06 13:02:26 +02:00
Dan
1d940b96a3 Turn boolean .media and .service fields into strings
This way they can hold more info about the kind of media and service messages.
For example:
- message.media == "document" <-> message.document
- message.service == "new_chat_title" <-> message.new_chat_title
2021-05-05 14:38:29 +02:00
Dan
97bd544333 Fix save_file path argument docs.
Closes #671
2021-05-05 14:18:26 +02:00
Dan
35df2cc1f3 Add filters.command tests 2021-05-05 14:00:25 +02:00
Dan
6cf9dd839e Update configuration for tests 2021-05-05 13:59:24 +02:00
Dan
8515ef1746 Update handling errors example
Use asyncio.sleep instead of time.sleep
2021-05-05 13:58:47 +02:00
Dan
e9e6c30d05 Handle bot commands with trailing usernames
Closes #139, #615
2021-05-05 13:58:03 +02:00
Dan
a3e46b4957 Cleanup connection info logs 2021-05-03 21:07:36 +02:00
Dan
826f815ca3 Merge branch 'master' of https://github.com/pyrogram/pyrogram 2021-05-03 20:59:41 +02:00
Dan
928c8acd01 Fix iter_profile_photos wrong hinted return type 2021-05-03 20:58:37 +02:00
Mario A
2de1606e3d
Fix GameHighScore in the chat with yourself (#669)
Signed-off-by: Mario A <marioanacl22@gmail.com>
2021-04-26 20:45:23 +02:00
Dan
89860a4b4c Add VoiceChatScheduled type and Message.voice_chat_scheduled field 2021-04-26 16:56:10 +02:00
Dan
fa7673e51c Add the field chat_type to the class InlineQuery 2021-04-26 16:20:09 +02:00
Dan
710cfa071d Lower log level for unmatched closing tag 2021-04-26 16:13:36 +02:00
Dan
5e77387919 Fix empty messages don't have a chat id 2021-04-26 16:12:11 +02:00
Dan
e4f99df07c Better error message in case of empty data in buffer 2021-04-26 16:09:39 +02:00
Dan
c13230cb81 Merge branch 'layer-128' 2021-04-26 16:07:56 +02:00
Dan
2eef1d5fcf Accommodate changes to photo file ids 2021-04-26 16:00:21 +02:00
Dan
54350dc943 Merge branch 'handle-503-timeout' 2021-04-26 15:32:07 +02:00
Dan
3c81006b40 Merge branch 'media-servers' 2021-04-26 15:31:08 +02:00
Dan
c5624c639b Cleaner error message 2021-04-15 12:17:25 +02:00
Dan
add492c1be Show the signal name instead of the number 2021-04-15 12:04:43 +02:00
Dan
4f585c156c Update Pyrogram to v1.2.9
- Make less noise at the INFO log level
2021-04-15 09:51:50 +02:00
Dan
0c814e9e5e Add support for media DC IPs 2021-04-13 15:53:53 +02:00
Dan
416c351f6b Update API schema to Layer 128 2021-04-12 21:16:34 +02:00
Dan
9a8bf9d1dc Fix wrongly generated class names 2021-04-12 09:28:58 +02:00
Dan
70ae12eb77 Handle ServiceUnavailable errors
#664
2021-04-12 09:21:20 +02:00
Dan
b6f97ee924 Add support for signed error codes 2021-04-12 09:19:50 +02:00
Dan
0b0bec9e27 Update Pyrogram to v1.2.8 2021-04-07 18:08:03 +02:00
Dan
818aebcc7c Fix memory session's delete() method not being implemented
Closes #660
2021-04-05 18:51:42 +02:00
Dan
aa6b226e64 Update Pyrogram to v1.2.6 2021-03-29 14:15:03 +02:00
Dan
50d1f30ac1 Add missing reply_markup for outgoing bot private messages
Fix #656
2021-03-29 14:14:19 +02:00
Dan
701c1cde07 Update Pyrogram to v1.2.5 2021-03-25 15:35:15 +01:00
Leorio Paradinight
77ab7bffe7
Fix Layer 126 changes [user_id -> participant] (#648) 2021-03-25 15:31:31 +01:00
Dan
a86656aefc Update Pyrogram to 1.2.4
Add missing parameters to chat.promote_member
2021-03-22 17:38:52 +01:00
Dan
97bb996a53 Update Pyrogram to v1.2.3 2021-03-21 22:42:38 +01:00
Dan
da697aec13 Fix messed up method names 2021-03-21 22:42:16 +01:00
Dan
ec1cd15094 Update Pyrogram to v1.2.2 2021-03-21 22:14:32 +01:00
Dan
808346f15b Fix wrong example due to a method rename 2021-03-21 22:13:41 +01:00
Dan
eed331b1b1 Do not copy empty messages 2021-03-21 22:10:33 +01:00
Dan
70efffa896 Remove sphinx tabs extension 2021-03-21 22:08:04 +01:00
Dan
19fab3cc78 Update Pyrogram to v1.2.1 2021-03-21 21:52:37 +01:00
Dan
1d55eaa1ba Fix inline keyboard buttons with empty values 2021-03-21 21:52:37 +01:00
Dan
a47e079fec Update Pyrogram to v1.2.0 2021-03-21 21:52:37 +01:00
Dan
b1dc0315a1 Update API schema to Layer 126 2021-03-21 21:52:37 +01:00
Dan
e01ac7a3d3 Revert changes to the invite link regex pattern
New invite link methods don't need this and this change was
breaking old code (get_chat, join_chat)
2021-03-20 13:16:55 +01:00
Dan
73edcb5e69 Update voice-calls.rst 2021-03-20 11:06:05 +01:00
Dan
f13651af1d Reword the license explanation 2021-03-20 11:05:23 +01:00
Dan
66b1229664 Fix broken hyperlinks 2021-03-20 10:40:38 +01:00
Dan
b39a6cd2d4 Add FAQ about sqlite3.InterfaceError 2021-03-20 10:37:01 +01:00
Dan
c971616808 Add add_contact, improve delete_contacts and import_contacts 2021-03-20 10:13:40 +01:00
Dan
3445507a9a Update types.rst 2021-03-20 07:41:49 +01:00
Dan
2d785acdc7 Add Message.edit and Message.reply to docs 2021-03-19 20:42:48 +01:00
443 changed files with 5892 additions and 3467 deletions

View File

@ -1,76 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at dan@pyrogram.org. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@ -1 +0,0 @@
# How to Contribute

2
.github/FUNDING.yml vendored
View File

@ -1,2 +0,0 @@
github: delivrance
custom: https://docs.pyrogram.org/support-pyrogram

View File

@ -1,20 +0,0 @@
---
name: Bug Report
about: Create a bug report affecting the library
---
<!-- WARNING: Ignoring this template could lead to the issue being closed as invalid -->
## Checklist
- [ ] I am sure the error is coming from Pyrogram's code and not elsewhere.
- [ ] I have searched in the issue tracker for similar bug reports, including closed ones.
- [ ] I ran `pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip` and reproduced the issue using the latest development version.
## Description
A **clear** and **concise** description of the problem. Code snippets must be formatted properly.
## Steps to Reproduce
[A minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example).
## Traceback
The full traceback (if applicable).

51
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: Bug report
description: Report issues affecting the framework or the documentation
body:
- type: checkboxes
attributes:
label: Checklist
options:
- label: I am sure the error is coming from Pyrogram's code and not elsewhere
required: true
- label: I have searched in the issue tracker for similar bug reports, including closed ones
required: true
- label: I ran `pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip` and reproduced the issue using the latest development version
required: true
- type: textarea
attributes:
label: Description
description: Provide a clear and concise description of the issue
placeholder: Description...
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Explain precisely how to reproduce the issue
placeholder: |
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Code example
description: Provide a [minimal, reproducible](https://stackoverflow.com/help/minimal-reproducible-example) and properly formatted example (if applicable)
placeholder: |
from pyrogram import Client
...
render: python
- type: textarea
attributes:
label: Logs
description: Provide the complete traceback (if applicable)
placeholder: |
Traceback (most recent call last):
File "main.py", line 1, in <module>
...
render: shell

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Ask Pyrogram related questions
url: https://stackoverflow.com/questions/tagged/pyrogram
about: This place is only for reporting issues about Pyrogram. You can ask questions at StackOverflow.
- name: Join the Telegram channel
url: https://t.me/pyrogram
about: Join the official channel and stay tuned for news, updates and announcements.

View File

@ -1,14 +0,0 @@
---
name: Feature Request
about: Suggest ideas, new features or enhancements
labels: "enhancement"
---
<!-- WARNING: Ignoring this template could lead to the issue being closed as invalid -->
## Checklist
- [ ] I believe the idea is awesome and would benefit the library.
- [ ] I have searched in the issue tracker for similar requests, including closed ones.
## Description
A detailed description of the request.

View File

@ -0,0 +1,20 @@
name: Feature request
description: Suggest ideas, new features or enhancements
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Checklist
options:
- label: I believe the idea is awesome and would benefit the framework
required: true
- label: I have searched in the issue tracker for similar requests, including closed ones
required: true
- type: textarea
attributes:
label: Description
description: Provide a detailed description of the request
placeholder: Description...
validations:
required: true

View File

@ -1,15 +0,0 @@
---
name: Ask Question
about: Ask a Pyrogram related question
title: For Q&A purposes, please read this template body
labels: "invalid"
---
<!-- WARNING: Ignoring this template could lead to the issue being closed as invalid -->
# Important
This place is for issues about Pyrogram, it's **not a forum**.
If you'd like to post a question, please move to https://stackoverflow.com or join the Telegram community at https://t.me/pyrogram. Useful information on how to ask good questions can be found here: https://stackoverflow.com/help/how-to-ask.
Thanks.

68
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@ -0,0 +1,68 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ mtpager ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ mtpager ]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@ -1,6 +1,6 @@
name: Pyrogram name: Pyrogram
on: [ push ] on: [push, pull_request]
jobs: jobs:
build: build:
@ -8,8 +8,8 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ] os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [ 3.6, 3.7, 3.8, 3.9 ] python-version: [3.7, 3.8, 3.9, "3.10", "pypy-3.7", "pypy-3.8"]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -30,4 +30,4 @@ jobs:
- name: Run tests - name: Run tests
run: | run: |
tox tox

View File

@ -1,10 +1,11 @@
## Include ## Include
include README.md COPYING COPYING.lesser NOTICE requirements.txt include README.md COPYING COPYING.lesser NOTICE requirements.txt
recursive-include compiler *.py *.tl *.tsv *.txt recursive-include compiler *.py *.tl *.tsv *.txt
recursive-include tests *.py
## Exclude ## Exclude
prune pyrogram/errors/exceptions prune pyrogram/errors/exceptions
prune pyrogram/raw/functions prune pyrogram/raw/functions
prune pyrogram/raw/types prune pyrogram/raw/types
prune pyrogram/raw/base prune pyrogram/raw/base
exclude pyrogram/raw/all.py exclude pyrogram/raw/all.py

2
NOTICE
View File

@ -1,5 +1,5 @@
Pyrogram - Telegram MTProto API Client Library for Python Pyrogram - Telegram MTProto API Client Library for Python
Copyright (C) 2017-2021 Dan <https://github.com/delivrance> Copyright (C) 2017-present Dan <https://github.com/delivrance>
This file is part of Pyrogram. This file is part of Pyrogram.

View File

@ -1,6 +1,6 @@
<p align="center"> <p align="center">
<a href="https://github.com/pyrogram/pyrogram"> <a href="https://github.com/pyrogram/pyrogram">
<img src="https://i.imgur.com/BOgY9ai.png" alt="Pyrogram"> <img src="https://docs.pyrogram.org/_static/pyrogram.png" alt="Pyrogram" width="128">
</a> </a>
<br> <br>
<b>Telegram MTProto API Framework for Python</b> <b>Telegram MTProto API Framework for Python</b>
@ -9,17 +9,19 @@
Documentation Documentation
</a> </a>
<a href="https://github.com/pyrogram/pyrogram/releases"> <a href="https://docs.pyrogram.org/releases">
Releases Releases
</a> </a>
<a href="https://t.me/Pyrogram"> <a href="https://t.me/pyrogram">
Community News
</a> </a>
</p> </p>
## Pyrogram ## Pyrogram
> Elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots
``` python ``` python
from pyrogram import Client, filters from pyrogram import Client, filters
@ -28,34 +30,33 @@ app = Client("my_account")
@app.on_message(filters.private) @app.on_message(filters.private)
async def hello(client, message): async def hello(client, message):
await message.reply_text(f"Hello {message.from_user.mention}") await message.reply("Hello from Pyrogram!")
app.run() app.run()
``` ```
**Pyrogram** is a modern, elegant and easy-to-use [Telegram](https://telegram.org/) client library framework written **Pyrogram** is a modern, elegant and asynchronous [MTProto API](https://docs.pyrogram.org/topics/mtproto-vs-botapi)
from the ground up in Python and C. It enables you to easily create custom Telegram client applications for both user framework. It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot
and bot identities (bot API alternative) via the [MTProto API](https://docs.pyrogram.org/topics/mtproto-vs-botapi). identity (bot API alternative) using Python.
### Features ### Support
- **Easy**: You can install Pyrogram with pip and start building your applications right away. If you'd like to support Pyrogram, you can consider:
- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way.
- **Fast**: Crypto parts are boosted up by [TgCrypto](https://github.com/pyrogram/tgcrypto), a high-performance library - [Become a GitHub sponsor](https://github.com/sponsors/delivrance).
written in pure C. - [Become a LiberaPay patron](https://liberapay.com/delivrance).
- **Asynchronous**: Allows both synchronous and asynchronous models to fit all usage needs. - [Become an OpenCollective backer](https://opencollective.com/pyrogram).
- **Documented**: API methods, types and public interfaces are all [well documented](https://docs.pyrogram.org).
### Key Features
- **Ready**: Install Pyrogram with pip and start building your applications right away.
- **Easy**: Makes the Telegram API simple and intuitive, while still allowing advanced usages.
- **Elegant**: Low-level details are abstracted and re-presented in a more convenient way.
- **Fast**: Boosted up by [TgCrypto](https://github.com/pyrogram/tgcrypto), a high-performance crypto library written in pure C.
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support. - **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
- **Updated**, to make use of the latest Telegram API version and features. - **Async**: Fully asynchronous (also usable synchronously if wanted, for convenience).
- **Bot API-like**: Similar to the Bot API in its simplicity, but much more powerful and detailed. - **Powerful**: Full access to Telegram's API to execute any official client action and more.
- **Pluggable**: The Smart Plugin system allows to write components with minimal boilerplate code.
- **Comprehensive**: Execute any advanced action an official client is able to do, and even more.
### Requirements
- Python 3.6 or higher.
- A [Telegram API key](https://docs.pyrogram.org/intro/setup#api-keys).
### Installing ### Installing
@ -65,11 +66,6 @@ pip3 install pyrogram
### Resources ### Resources
- The docs contain lots of resources to help you get started with Pyrogram: https://docs.pyrogram.org. - Check out the docs at https://docs.pyrogram.org to learn more about Pyrogram, get started right
- Seeking extra help? Come join and ask our community: https://t.me/pyrogram. away and discover more in-depth material for building your client applications.
- For other kind of inquiries, you can send a [message](https://t.me/haskell) or an [e-mail](mailto:dan@pyrogram.org). - Join the official channel at https://t.me/pyrogram and stay tuned for news, updates and announcements.
### Copyright & License
- Copyright (C) 2017-2021 Dan <<https://github.com/delivrance>>
- Licensed under the terms of the [GNU Lesser General Public License v3 or later (LGPLv3+)](COPYING.lesser)

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -199,12 +199,12 @@ def start(format: bool = False):
shutil.rmtree(DESTINATION_PATH / "base", ignore_errors=True) shutil.rmtree(DESTINATION_PATH / "base", ignore_errors=True)
with open(HOME_PATH / "source/auth_key.tl") as f1, \ with open(HOME_PATH / "source/auth_key.tl") as f1, \
open(HOME_PATH / "source/sys_msgs.tl") as f2, \ open(HOME_PATH / "source/sys_msgs.tl") as f2, \
open(HOME_PATH / "source/main_api.tl") as f3: open(HOME_PATH / "source/main_api.tl") as f3:
schema = (f1.read() + f2.read() + f3.read()).splitlines() schema = (f1.read() + f2.read() + f3.read()).splitlines()
with open(HOME_PATH / "template/type.txt") as f1, \ with open(HOME_PATH / "template/type.txt") as f1, \
open(HOME_PATH / "template/combinator.txt") as f2: open(HOME_PATH / "template/combinator.txt") as f2:
type_tmpl = f1.read() type_tmpl = f1.read()
combinator_tmpl = f2.read() combinator_tmpl = f2.read()
@ -345,11 +345,11 @@ def start(format: bool = False):
sorted_args = sort_args(c.args) sorted_args = sort_args(c.args)
arguments = ( arguments = (
(", *, " if c.args else "") + (", *, " if c.args else "") +
(", ".join( (", ".join(
[f"{i[0]}: {get_type_hint(i[1])}" [f"{i[0]}: {get_type_hint(i[1])}"
for i in sorted_args] for i in sorted_args]
) if sorted_args else "") ) if sorted_args else "")
) )
fields = "\n ".join( fields = "\n ".join(
@ -408,7 +408,7 @@ def start(format: bool = False):
flag = FLAGS_RE_2.match(i[1]) flag = FLAGS_RE_2.match(i[1])
if flag: if flag:
if flag.group(2) == "true": if flag.group(2) == "true" or flag.group(2).startswith("Vector"):
write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} else 0") write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} else 0")
else: else:
write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} is not None else 0") write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} is not None else 0")
@ -416,11 +416,11 @@ def start(format: bool = False):
write_flags = "\n ".join([ write_flags = "\n ".join([
"flags = 0", "flags = 0",
"\n ".join(write_flags), "\n ".join(write_flags),
"data.write(Int(flags))\n " "b.write(Int(flags))\n "
]) ])
write_types += write_flags write_types += write_flags
read_types += "flags = Int.read(data)\n " read_types += "flags = Int.read(b)\n "
continue continue
@ -433,55 +433,55 @@ def start(format: bool = False):
elif flag_type in CORE_TYPES: elif flag_type in CORE_TYPES:
write_types += "\n " write_types += "\n "
write_types += f"if self.{arg_name} is not None:\n " write_types += f"if self.{arg_name} is not None:\n "
write_types += f"data.write({flag_type.title()}(self.{arg_name}))\n " write_types += f"b.write({flag_type.title()}(self.{arg_name}))\n "
read_types += "\n " read_types += "\n "
read_types += f"{arg_name} = {flag_type.title()}.read(data) if flags & (1 << {index}) else None" read_types += f"{arg_name} = {flag_type.title()}.read(b) if flags & (1 << {index}) else None"
elif "vector" in flag_type.lower(): elif "vector" in flag_type.lower():
sub_type = arg_type.split("<")[1][:-1] sub_type = arg_type.split("<")[1][:-1]
write_types += "\n " write_types += "\n "
write_types += f"if self.{arg_name} is not None:\n " write_types += f"if self.{arg_name}:\n "
write_types += "data.write(Vector(self.{}{}))\n ".format( write_types += "b.write(Vector(self.{}{}))\n ".format(
arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else "" arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else ""
) )
read_types += "\n " read_types += "\n "
read_types += "{} = TLObject.read(data{}) if flags & (1 << {}) else []\n ".format( read_types += "{} = TLObject.read(b{}) if flags & (1 << {}) else []\n ".format(
arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else "", index arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else "", index
) )
else: else:
write_types += "\n " write_types += "\n "
write_types += f"if self.{arg_name} is not None:\n " write_types += f"if self.{arg_name} is not None:\n "
write_types += f"data.write(self.{arg_name}.write())\n " write_types += f"b.write(self.{arg_name}.write())\n "
read_types += "\n " read_types += "\n "
read_types += f"{arg_name} = TLObject.read(data) if flags & (1 << {index}) else None\n " read_types += f"{arg_name} = TLObject.read(b) if flags & (1 << {index}) else None\n "
else: else:
if arg_type in CORE_TYPES: if arg_type in CORE_TYPES:
write_types += "\n " write_types += "\n "
write_types += f"data.write({arg_type.title()}(self.{arg_name}))\n " write_types += f"b.write({arg_type.title()}(self.{arg_name}))\n "
read_types += "\n " read_types += "\n "
read_types += f"{arg_name} = {arg_type.title()}.read(data)\n " read_types += f"{arg_name} = {arg_type.title()}.read(b)\n "
elif "vector" in arg_type.lower(): elif "vector" in arg_type.lower():
sub_type = arg_type.split("<")[1][:-1] sub_type = arg_type.split("<")[1][:-1]
write_types += "\n " write_types += "\n "
write_types += "data.write(Vector(self.{}{}))\n ".format( write_types += "b.write(Vector(self.{}{}))\n ".format(
arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else "" arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else ""
) )
read_types += "\n " read_types += "\n "
read_types += "{} = TLObject.read(data{})\n ".format( read_types += "{} = TLObject.read(b{})\n ".format(
arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else "" arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else ""
) )
else: else:
write_types += "\n " write_types += "\n "
write_types += f"data.write(self.{arg_name}.write())\n " write_types += f"b.write(self.{arg_name}.write())\n "
read_types += "\n " read_types += "\n "
read_types += f"{arg_name} = TLObject.read(data)\n " read_types += f"{arg_name} = TLObject.read(b)\n "
slots = ", ".join([f'"{i[0]}"' for i in sorted_args]) slots = ", ".join([f'"{i[0]}"' for i in sorted_args])
return_arguments = ", ".join([f"{i[0]}={i[0]}" for i in sorted_args]) return_arguments = ", ".join([f"{i[0]}={i[0]}" for i in sorted_args])

File diff suppressed because it is too large Load Diff

View File

@ -23,13 +23,13 @@ class {name}(TLObject): # type: ignore
{fields} {fields}
@staticmethod @staticmethod
def read(data: BytesIO, *args: Any) -> "{name}": def read(b: BytesIO, *args: Any) -> "{name}":
{read_types} {read_types}
return {name}({return_arguments}) return {name}({return_arguments})
def write(self) -> bytes: def write(self) -> bytes:
data = BytesIO() b = BytesIO()
data.write(Int(self.ID, False)) b.write(Int(self.ID, False))
{write_types} {write_types}
return data.getvalue() return b.getvalue()

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -144,6 +144,7 @@ def pyrogram_api():
send_message send_message
forward_messages forward_messages
copy_message copy_message
copy_media_group
send_photo send_photo
send_audio send_audio
send_document send_document
@ -157,6 +158,7 @@ def pyrogram_api():
send_venue send_venue
send_contact send_contact
send_cached_media send_cached_media
send_reaction
edit_message_text edit_message_text
edit_message_caption edit_message_caption
edit_message_media edit_message_media
@ -179,14 +181,17 @@ def pyrogram_api():
retract_vote retract_vote
send_dice send_dice
search_messages search_messages
search_messages_count
search_global search_global
search_global_count
download_media download_media
get_discussion_message
""", """,
chats=""" chats="""
Chats Chats
join_chat join_chat
leave_chat leave_chat
kick_chat_member ban_chat_member
unban_chat_member unban_chat_member
restrict_chat_member restrict_chat_member
promote_chat_member promote_chat_member
@ -221,6 +226,10 @@ def pyrogram_api():
set_slow_mode set_slow_mode
mark_chat_unread mark_chat_unread
get_chat_event_log get_chat_event_log
get_chat_online_count
get_send_as_chats
set_send_as_chat
set_chat_protected_content
""", """,
users=""" users="""
Users Users
@ -239,25 +248,28 @@ def pyrogram_api():
""", """,
invite_links=""" invite_links="""
Invite Links Invite Links
get_chat_invite_link
export_chat_invite_link export_chat_invite_link
create_chat_invite_link create_chat_invite_link
edit_chat_invite_link edit_chat_invite_link
revoke_chat_invite_link revoke_chat_invite_link
delete_chat_invite_link delete_chat_invite_link
delete_all_chat_invite_links
get_chat_invite_link
get_chat_invite_link_members get_chat_invite_link_members
get_chat_invite_link_members_count get_chat_invite_link_members_count
get_chat_invite_links get_chat_admin_invite_links
get_chat_invite_links_count get_chat_admin_invite_links_count
get_chat_admins_with_invite_links get_chat_admins_with_invite_links
delete_chat_admin_invite_links
approve_chat_join_request
decline_chat_join_request
""", """,
contacts=""" contacts="""
Contacts Contacts
add_contacts add_contact
delete_contacts
import_contacts
get_contacts get_contacts
get_contacts_count get_contacts_count
delete_contacts
""", """,
password=""" password="""
Password Password
@ -275,6 +287,7 @@ def pyrogram_api():
send_game send_game
set_game_score set_game_score
get_game_high_scores get_game_high_scores
set_bot_commands
""", """,
authorization=""" authorization="""
Authorization Authorization
@ -351,6 +364,7 @@ def pyrogram_api():
ChatEvent ChatEvent
ChatEventFilter ChatEventFilter
ChatMemberUpdated ChatMemberUpdated
ChatJoinRequest
Dialog Dialog
Restriction Restriction
""", """,
@ -375,6 +389,8 @@ def pyrogram_api():
Poll Poll
PollOption PollOption
Dice Dice
Reaction
VoiceChatScheduled
VoiceChatStarted VoiceChatStarted
VoiceChatEnded VoiceChatEnded
VoiceChatMembersInvited VoiceChatMembersInvited
@ -391,6 +407,7 @@ def pyrogram_api():
CallbackQuery CallbackQuery
GameHighScore GameHighScore
CallbackGame CallbackGame
BotCommand
""", """,
input_media=""" input_media="""
Input Media Input Media
@ -409,6 +426,8 @@ def pyrogram_api():
InlineQueryResultArticle InlineQueryResultArticle
InlineQueryResultPhoto InlineQueryResultPhoto
InlineQueryResultAnimation InlineQueryResultAnimation
InlineQueryResultAudio
InlineQueryResultVideo
ChosenInlineResult ChosenInlineResult
""", """,
input_message_content=""" input_message_content="""
@ -461,10 +480,12 @@ def pyrogram_api():
Message.copy Message.copy
Message.pin Message.pin
Message.unpin Message.unpin
Message.edit
Message.edit_text Message.edit_text
Message.edit_caption Message.edit_caption
Message.edit_media Message.edit_media
Message.edit_reply_markup Message.edit_reply_markup
Message.reply
Message.reply_text Message.reply_text
Message.reply_animation Message.reply_animation
Message.reply_audio Message.reply_audio
@ -492,7 +513,7 @@ def pyrogram_api():
Chat.set_title Chat.set_title
Chat.set_description Chat.set_description
Chat.set_photo Chat.set_photo
Chat.kick_member Chat.ban_member
Chat.unban_member Chat.unban_member
Chat.restrict_member Chat.restrict_member
Chat.promote_member Chat.promote_member
@ -503,6 +524,7 @@ def pyrogram_api():
Chat.join Chat.join
Chat.leave Chat.leave
Chat.mark_unread Chat.mark_unread
Chat.set_protected_content
""", """,
user=""" user="""
User User
@ -522,6 +544,11 @@ def pyrogram_api():
inline_query=""" inline_query="""
InlineQuery InlineQuery
InlineQuery.answer InlineQuery.answer
""",
chat_join_request="""
ChatJoinRequest
ChatJoinRequest.approve
ChatJoinRequest.decline
""" """
) )

View File

@ -1,12 +1,11 @@
Bound Methods Bound Methods
============= =============
Some Pyrogram types define what are called bound methods. Bound methods are functions attached to a class which are Some Pyrogram types define what are called bound methods. Bound methods are functions attached to a type which are
accessed via an instance of that class. They make it even easier to call specific methods by automatically inferring accessed via an instance of that type. They make it even easier to call specific methods by automatically inferring
some of the required arguments. some of the required arguments.
.. code-block:: python .. code-block:: python
:emphasize-lines: 8
from pyrogram import Client from pyrogram import Client
@ -15,7 +14,7 @@ some of the required arguments.
@app.on_message() @app.on_message()
def hello(client, message) def hello(client, message)
message.reply_text("hi") message.reply("hi")
app.run() app.run()
@ -92,3 +91,17 @@ InlineQuery
:hidden: :hidden:
{inline_query_toctree} {inline_query_toctree}
ChatJoinRequest
---------------
.. hlist::
:columns: 2
{chat_join_request_hlist}
.. toctree::
:hidden:
{chat_join_request_toctree}

View File

@ -1,18 +1,17 @@
Available Methods Available Methods
================= =================
This page is about Pyrogram methods. All the methods listed here are bound to a :class:`~pyrogram.Client` instance, This page is about Pyrogram methods. All the methods listed here are bound to a :class:`~pyrogram.Client` instance.
except for :meth:`~pyrogram.idle()`, which is a special function that can be found in the main package directly. Some other utility functions can instead be found in the main package directly.
.. code-block:: python .. code-block:: python
:emphasize-lines: 6
from pyrogram import Client from pyrogram import Client
app = Client("my_account") app = Client("my_account")
with app: with app:
app.send_message("haskell", "hi") app.send_message("me", "hi")
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none

View File

@ -1,17 +1,21 @@
Available Types Available Types
=============== ===============
This page is about Pyrogram types. All types listed here are accessible through ``types`` package. This page is about Pyrogram Types. All types listed here are available through the ``pyrogram.types`` package.
Unless required as argument to a client method, most of the types don't need to be manually instantiated because they
are only returned by other methods. You also don't need to import them, unless you want to type-hint your variables.
.. code-block:: python .. code-block:: python
:emphasize-lines: 1
from pyrogram.types import User, Message, ... from pyrogram.types import User, Message, ...
.. note:: .. note::
**Optional** fields may not exist when irrelevant -- i.e.: they will contain the value of ``None`` and aren't shown Optional fields always exist inside the object, but they could be empty and contain the value of ``None``.
when, for example, using ``print()``. Empty fields aren't shown when, for example, using ``print(message)`` and this means that
``hasattr(message, "photo")`` always returns ``True``.
To tell whether a field is set or not, do a simple boolean check: ``if message.photo: ...``.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -96,6 +96,7 @@ def start():
sub_class = caml(re.sub(r"_X", "_", error_id)) sub_class = caml(re.sub(r"_X", "_", error_id))
sub_class = re.sub(r"^2", "Two", sub_class) sub_class = re.sub(r"^2", "Two", sub_class)
sub_class = re.sub(r" ", "", sub_class)
f_all.write(" \"{}\": \"{}\",\n".format(error_id, sub_class)) f_all.write(" \"{}\": \"{}\",\n".format(error_id, sub_class))

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

View File

@ -52,6 +52,7 @@ CHANNEL_TOO_LARGE The channel is too large to be deleted; this error is issued w
CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content 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_ABOUT_TOO_LONG The chat about text is too long
CHAT_ADMIN_REQUIRED The method requires chat admin privileges CHAT_ADMIN_REQUIRED The method requires chat admin privileges
CHAT_FORWARDS_RESTRICTED The chat restricts forwarding content
CHAT_ID_EMPTY The provided chat id is empty CHAT_ID_EMPTY The provided chat id is empty
CHAT_ID_INVALID The chat id being used is invalid or not known yet. Make sure you see the chat before interacting with it CHAT_ID_INVALID The chat id being used is invalid or not known yet. Make sure you see the chat before interacting with it
CHAT_INVALID The chat is invalid CHAT_INVALID The chat is invalid
@ -61,6 +62,7 @@ CHAT_NOT_MODIFIED The chat settings (title, permissions, photo, etc..) were not
CHAT_RESTRICTED The chat is restricted and cannot be used CHAT_RESTRICTED The chat is restricted and cannot be used
CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat
CHAT_TITLE_EMPTY The chat title is empty CHAT_TITLE_EMPTY The chat title is empty
CHAT_TOO_BIG The chat is too big for this action
CODE_EMPTY The provided code is empty CODE_EMPTY The provided code is empty
CODE_HASH_INVALID The provided code hash invalid CODE_HASH_INVALID The provided code hash invalid
CODE_INVALID The provided code is invalid (i.e. from email) CODE_INVALID The provided code is invalid (i.e. from email)
@ -248,7 +250,7 @@ RANDOM_ID_INVALID The provided random ID is invalid
RANDOM_LENGTH_INVALID The random length is invalid RANDOM_LENGTH_INVALID The random length is invalid
RANGES_INVALID Invalid range provided RANGES_INVALID Invalid range provided
REACTION_EMPTY The reaction provided is empty REACTION_EMPTY The reaction provided is empty
REACTION_INVALID Invalid reaction provided (only emoji are allowed) REACTION_INVALID Invalid reaction provided (only valid emoji are allowed)
REFLECTOR_NOT_AVAILABLE The call reflector is not available REFLECTOR_NOT_AVAILABLE The call reflector is not available
REPLY_MARKUP_BUY_EMPTY Reply markup for buy button empty REPLY_MARKUP_BUY_EMPTY Reply markup for buy button empty
REPLY_MARKUP_GAME_EMPTY The provided reply markup for the game is empty REPLY_MARKUP_GAME_EMPTY The provided reply markup for the game is empty
@ -290,6 +292,8 @@ STICKER_ID_INVALID The provided sticker id is invalid
STICKER_INVALID The provided sticker is invalid STICKER_INVALID The provided sticker is invalid
STICKER_PNG_DIMENSIONS The sticker png dimensions are invalid STICKER_PNG_DIMENSIONS The sticker png dimensions are invalid
STICKER_PNG_NOPNG Stickers must be png files but the provided image was not a png STICKER_PNG_NOPNG Stickers must be png files but the provided image was not a png
STICKER_TGS_NOTGS A tgs sticker file was expected, but something else was provided
STICKER_THUMB_PNG_NOPNG A png sticker thumbnail file was expected, but something else was provided
TAKEOUT_INVALID The takeout id is invalid TAKEOUT_INVALID The takeout id is invalid
TAKEOUT_REQUIRED The method must be invoked inside a takeout session TAKEOUT_REQUIRED The method must be invoked inside a takeout session
TEMP_AUTH_KEY_EMPTY The temporary auth key provided is empty TEMP_AUTH_KEY_EMPTY The temporary auth key provided is empty
@ -298,6 +302,7 @@ THEME_FORMAT_INVALID Invalid theme format provided
THEME_INVALID Invalid theme provided THEME_INVALID Invalid theme provided
THEME_MIME_INVALID You cannot create this theme because the mime-type is invalid THEME_MIME_INVALID You cannot create this theme because the mime-type is invalid
TMP_PASSWORD_DISABLED The temporary password is disabled TMP_PASSWORD_DISABLED The temporary password is disabled
TMP_PASSWORD_INVALID The temporary password is invalid
TOKEN_INVALID The provided token is invalid TOKEN_INVALID The provided token is invalid
TTL_DAYS_INVALID The provided TTL days is invalid TTL_DAYS_INVALID The provided TTL days is invalid
TTL_MEDIA_INVALID The media does not support self-destruction TTL_MEDIA_INVALID The media does not support self-destruction
@ -310,6 +315,7 @@ USERNAME_INVALID The username is invalid
USERNAME_NOT_MODIFIED The username was not modified because you tried to edit it using the same one USERNAME_NOT_MODIFIED The username was not modified because you tried to edit it using the same one
USERNAME_NOT_OCCUPIED The username is not occupied by anyone USERNAME_NOT_OCCUPIED The username is not occupied by anyone
USERNAME_OCCUPIED The username is already in use by someone else USERNAME_OCCUPIED The username is already in use by someone else
USERPIC_UPLOAD_REQUIRED You are required to upload a profile picture for this action
USERS_TOO_FEW Not enough users (to create a chat, for example) USERS_TOO_FEW Not enough users (to create a chat, for example)
USERS_TOO_MUCH The maximum number of users has been exceeded (to create a chat, for example) USERS_TOO_MUCH The maximum number of users has been exceeded (to create a chat, for example)
USER_ADMIN_INVALID The action requires admin privileges. Probably you tried to edit admin privileges on someone you don't have rights to USER_ADMIN_INVALID The action requires admin privileges. Probably you tried to edit admin privileges on someone you don't have rights to
@ -333,6 +339,7 @@ VIDEO_FILE_INVALID The video file is invalid
VOLUME_LOC_NOT_FOUND The volume location can't be found VOLUME_LOC_NOT_FOUND The volume location can't be found
WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper
WALLPAPER_INVALID The input wallpaper was not valid WALLPAPER_INVALID The input wallpaper was not valid
WALLPAPER_MIME_INVALID The wallpaper mime type is invalid
WC_CONVERT_URL_INVALID WC convert URL invalid WC_CONVERT_URL_INVALID WC convert URL invalid
WEBDOCUMENT_INVALID The web document is invalid WEBDOCUMENT_INVALID The web document is invalid
WEBDOCUMENT_MIME_INVALID The web document mime type is invalid WEBDOCUMENT_MIME_INVALID The web document mime type is invalid

1 id message
52 CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content
53 CHAT_ABOUT_TOO_LONG The chat about text is too long
54 CHAT_ADMIN_REQUIRED The method requires chat admin privileges
55 CHAT_FORWARDS_RESTRICTED The chat restricts forwarding content
56 CHAT_ID_EMPTY The provided chat id is empty
57 CHAT_ID_INVALID The chat id being used is invalid or not known yet. Make sure you see the chat before interacting with it
58 CHAT_INVALID The chat is invalid
62 CHAT_RESTRICTED The chat is restricted and cannot be used
63 CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat
64 CHAT_TITLE_EMPTY The chat title is empty
65 CHAT_TOO_BIG The chat is too big for this action
66 CODE_EMPTY The provided code is empty
67 CODE_HASH_INVALID The provided code hash invalid
68 CODE_INVALID The provided code is invalid (i.e. from email)
250 RANDOM_LENGTH_INVALID The random length is invalid
251 RANGES_INVALID Invalid range provided
252 REACTION_EMPTY The reaction provided is empty
253 REACTION_INVALID Invalid reaction provided (only emoji are allowed) Invalid reaction provided (only valid emoji are allowed)
254 REFLECTOR_NOT_AVAILABLE The call reflector is not available
255 REPLY_MARKUP_BUY_EMPTY Reply markup for buy button empty
256 REPLY_MARKUP_GAME_EMPTY The provided reply markup for the game is empty
292 STICKER_INVALID The provided sticker is invalid
293 STICKER_PNG_DIMENSIONS The sticker png dimensions are invalid
294 STICKER_PNG_NOPNG Stickers must be png files but the provided image was not a png
295 STICKER_TGS_NOTGS A tgs sticker file was expected, but something else was provided
296 STICKER_THUMB_PNG_NOPNG A png sticker thumbnail file was expected, but something else was provided
297 TAKEOUT_INVALID The takeout id is invalid
298 TAKEOUT_REQUIRED The method must be invoked inside a takeout session
299 TEMP_AUTH_KEY_EMPTY The temporary auth key provided is empty
302 THEME_INVALID Invalid theme provided
303 THEME_MIME_INVALID You cannot create this theme because the mime-type is invalid
304 TMP_PASSWORD_DISABLED The temporary password is disabled
305 TMP_PASSWORD_INVALID The temporary password is invalid
306 TOKEN_INVALID The provided token is invalid
307 TTL_DAYS_INVALID The provided TTL days is invalid
308 TTL_MEDIA_INVALID The media does not support self-destruction
315 USERNAME_NOT_MODIFIED The username was not modified because you tried to edit it using the same one
316 USERNAME_NOT_OCCUPIED The username is not occupied by anyone
317 USERNAME_OCCUPIED The username is already in use by someone else
318 USERPIC_UPLOAD_REQUIRED You are required to upload a profile picture for this action
319 USERS_TOO_FEW Not enough users (to create a chat, for example)
320 USERS_TOO_MUCH The maximum number of users has been exceeded (to create a chat, for example)
321 USER_ADMIN_INVALID The action requires admin privileges. Probably you tried to edit admin privileges on someone you don't have rights to
339 VOLUME_LOC_NOT_FOUND The volume location can't be found
340 WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper
341 WALLPAPER_INVALID The input wallpaper was not valid
342 WALLPAPER_MIME_INVALID The wallpaper mime type is invalid
343 WC_CONVERT_URL_INVALID WC convert URL invalid
344 WEBDOCUMENT_INVALID The web document is invalid
345 WEBDOCUMENT_MIME_INVALID The web document mime type is invalid

View File

@ -2,7 +2,7 @@ id message
ACTIVE_USER_REQUIRED The method is only available to already activated users ACTIVE_USER_REQUIRED The method is only available to already activated users
AUTH_KEY_INVALID The key is invalid AUTH_KEY_INVALID The key is invalid
AUTH_KEY_PERM_EMPTY The method is unavailable for temporary authorization key, not bound to permanent AUTH_KEY_PERM_EMPTY The method is unavailable for temporary authorization key, not bound to permanent
AUTH_KEY_UNREGISTERED The key is not registered in the system AUTH_KEY_UNREGISTERED The key is not registered in the system. Delete your session file and login again
SESSION_EXPIRED The authorization has expired SESSION_EXPIRED The authorization has expired
SESSION_PASSWORD_NEEDED The two-step verification is enabled and a password is required SESSION_PASSWORD_NEEDED The two-step verification is enabled and a password is required
SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions

1 id message
2 ACTIVE_USER_REQUIRED The method is only available to already activated users
3 AUTH_KEY_INVALID The key is invalid
4 AUTH_KEY_PERM_EMPTY The method is unavailable for temporary authorization key, not bound to permanent
5 AUTH_KEY_UNREGISTERED The key is not registered in the system The key is not registered in the system. Delete your session file and login again
6 SESSION_EXPIRED The authorization has expired
7 SESSION_PASSWORD_NEEDED The two-step verification is enabled and a password is required
8 SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions

View File

@ -9,6 +9,7 @@ CHP_CALL_FAIL Telegram is having internal problems. Please try again later
ENCRYPTION_OCCUPY_ADMIN_FAILED Failed occupying memory for admin info due to Telegram having internal problems. Please try again later ENCRYPTION_OCCUPY_ADMIN_FAILED Failed occupying memory for admin info due to Telegram having internal problems. Please try again later
ENCRYPTION_OCCUPY_FAILED Internal server error while accepting secret chat ENCRYPTION_OCCUPY_FAILED Internal server error while accepting secret chat
FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later
GROUPCALL_ADD_PARTICIPANTS_FAILED Failure while adding voice chat member due to Telegram having internal problems. Please try again later
GROUPED_ID_OCCUPY_FAILED Telegram is having internal problems. Please try again later GROUPED_ID_OCCUPY_FAILED Telegram is having internal problems. Please try again later
HISTORY_GET_FAILED The chat history couldn't be retrieved due to Telegram having internal problems. Please try again later HISTORY_GET_FAILED The chat history couldn't be retrieved due to Telegram having internal problems. Please try again later
IMAGE_ENGINE_DOWN Image engine down due to Telegram having internal problems. Please try again later IMAGE_ENGINE_DOWN Image engine down due to Telegram having internal problems. Please try again later
@ -23,8 +24,10 @@ MSG_RANGE_UNSYNC Message range unsynchronized due to Telegram having internal pr
MT_SEND_QUEUE_TOO_LONG The MTProto send queue has grown too much due to Telegram having internal problems. Please try again later MT_SEND_QUEUE_TOO_LONG The MTProto send queue has grown too much due to Telegram having internal problems. Please try again later
NEED_CHAT_INVALID The provided chat is invalid NEED_CHAT_INVALID The provided chat is invalid
NEED_MEMBER_INVALID The provided member is invalid or does not exist NEED_MEMBER_INVALID The provided member is invalid or does not exist
No workers running The Telegram server is restarting its workers. Try again later.
PARTICIPANT_CALL_FAILED Failure while making call due to Telegram having internal problems. Please try again later PARTICIPANT_CALL_FAILED Failure while making call due to Telegram having internal problems. Please try again later
PERSISTENT_TIMESTAMP_OUTDATED The persistent timestamp is outdated due to Telegram having internal problems. Please try again later PERSISTENT_TIMESTAMP_OUTDATED The persistent timestamp is outdated due to Telegram having internal problems. Please try again later
PHOTO_CREATE_FAILED The creation of the photo failed due to Telegram having internal problems. Please try again later
POSTPONED_TIMEOUT Telegram is having internal problems. Please try again later POSTPONED_TIMEOUT Telegram is having internal problems. Please try again later
PTS_CHANGE_EMPTY No PTS change PTS_CHANGE_EMPTY No PTS change
RANDOM_ID_DUPLICATE You provided a random ID that was already used RANDOM_ID_DUPLICATE You provided a random ID that was already used
@ -39,5 +42,4 @@ UNKNOWN_METHOD The method you tried to call cannot be called on non-CDN DCs
UPLOAD_NO_VOLUME Telegram is having internal problems. Please try again later UPLOAD_NO_VOLUME Telegram is having internal problems. Please try again later
VOLUME_LOC_NOT_FOUND Telegram is having internal problems. Please try again later VOLUME_LOC_NOT_FOUND Telegram is having internal problems. Please try again later
WORKER_BUSY_TOO_LONG_RETRY Server workers are too busy right now due to Telegram having internal problems. Please try again later WORKER_BUSY_TOO_LONG_RETRY Server workers are too busy right now due to Telegram having internal problems. Please try again later
WP_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later WP_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later
GROUPCALL_ADD_PARTICIPANTS_FAILED Failure while adding voice chat member due to Telegram having internal problems. Please try again later
1 id message
9 ENCRYPTION_OCCUPY_ADMIN_FAILED Failed occupying memory for admin info due to Telegram having internal problems. Please try again later
10 ENCRYPTION_OCCUPY_FAILED Internal server error while accepting secret chat
11 FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later
12 GROUPCALL_ADD_PARTICIPANTS_FAILED Failure while adding voice chat member due to Telegram having internal problems. Please try again later
13 GROUPED_ID_OCCUPY_FAILED Telegram is having internal problems. Please try again later
14 HISTORY_GET_FAILED The chat history couldn't be retrieved due to Telegram having internal problems. Please try again later
15 IMAGE_ENGINE_DOWN Image engine down due to Telegram having internal problems. Please try again later
24 MT_SEND_QUEUE_TOO_LONG The MTProto send queue has grown too much due to Telegram having internal problems. Please try again later
25 NEED_CHAT_INVALID The provided chat is invalid
26 NEED_MEMBER_INVALID The provided member is invalid or does not exist
27 No workers running The Telegram server is restarting its workers. Try again later.
28 PARTICIPANT_CALL_FAILED Failure while making call due to Telegram having internal problems. Please try again later
29 PERSISTENT_TIMESTAMP_OUTDATED The persistent timestamp is outdated due to Telegram having internal problems. Please try again later
30 PHOTO_CREATE_FAILED The creation of the photo failed due to Telegram having internal problems. Please try again later
31 POSTPONED_TIMEOUT Telegram is having internal problems. Please try again later
32 PTS_CHANGE_EMPTY No PTS change
33 RANDOM_ID_DUPLICATE You provided a random ID that was already used
42 UPLOAD_NO_VOLUME Telegram is having internal problems. Please try again later
43 VOLUME_LOC_NOT_FOUND Telegram is having internal problems. Please try again later
44 WORKER_BUSY_TOO_LONG_RETRY Server workers are too busy right now due to Telegram having internal problems. Please try again later
45 WP_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later
GROUPCALL_ADD_PARTICIPANTS_FAILED Failure while adding voice chat member due to Telegram having internal problems. Please try again later

View File

@ -0,0 +1,3 @@
id message
Timeout Telegram is having internal problems. Please try again later.
ApiCallError Telegram is having internal problems. Please try again later.
1 id message
2 Timeout Telegram is having internal problems. Please try again later.
3 ApiCallError Telegram is having internal problems. Please try again later.

View File

@ -1,3 +1,5 @@
-r requirements.txt -r requirements.txt
pytest pytest
pytest-asyncio
pytest-cov

View File

@ -1,8 +0,0 @@
# Pyrogram Docs
- Install requirements.
- Install `pandoc` and `latexmk`.
- HTML: `make html`
- PDF: `make latexpdf`
TODO: Explain better

View File

@ -1,7 +1,6 @@
sphinx sphinx
sphinx_rtd_theme sphinx_rtd_theme==1.0.0
sphinx_copybutton sphinx_copybutton
sphinx_tabs
pypandoc pypandoc
requests requests
sphinx-autobuild sphinx-autobuild

View File

@ -1,7 +0,0 @@
User-agent: *
Allow: /
Disallow: /old*
Sitemap: https://docs.pyrogram.org/sitemap.xml

View File

@ -1,84 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 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 shutil
from datetime import datetime
from pathlib import Path
import pypandoc
import requests
URL = "https://api.github.com/repos/pyrogram/pyrogram/releases"
DEST = Path("../source/releases")
INTRO = """
Release Notes
=============
Release notes for Pyrogram releases will describe what's new in each version, and will also make you aware of any
backwards-incompatible changes made in that version.
When upgrading to a new version of Pyrogram, you will need to check all the breaking changes in order to find
incompatible code in your application, but also to take advantage of new features and improvements.
**Contents**
""".lstrip("\n")
shutil.rmtree(DEST, ignore_errors=True)
DEST.mkdir(parents=True)
releases = requests.get(URL).json()
with open(DEST / "index.rst", "w") as index:
index.write(INTRO)
tags = []
for release in releases:
tag = release["tag_name"]
title = release["name"]
name = title.split(" - ")[1]
date = datetime.strptime(
release["published_at"],
"%Y-%m-%dT%H:%M:%SZ"
).strftime("%b %d, %Y")
body = pypandoc.convert_text(
release["body"].replace(r"\r\n", "\n"),
"rst",
format="markdown_github",
extra_args=["--wrap=none"]
)
tarball_url = release["tarball_url"]
zipball_url = release["zipball_url"]
index.write("- :doc:`{} <{}>`\n".format(title, tag))
tags.append(tag)
with open(DEST / "{}.rst".format(tag), "w") as page:
page.write("Pyrogram " + tag + "\n" + "=" * (len(tag) + 9) + "\n\n")
page.write("\t\tReleased on " + str(date) + "\n\n")
page.write("- :download:`Source Code (zip) <{}>`\n".format(zipball_url))
page.write("- :download:`Source Code (tar.gz) <{}>`\n\n".format(tarball_url))
page.write(name + "\n" + "-" * len(name) + "\n\n")
page.write(body + "\n\n")
index.write("\n.. toctree::\n :hidden:\n\n")
index.write("\n".join(" {}".format(tag) for tag in tags))

View File

@ -1,81 +0,0 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 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 datetime
import os
canonical = "https://docs.pyrogram.org/"
dirs = {
".": ("weekly", 1.0),
"intro": ("weekly", 0.9),
"start": ("weekly", 0.9),
"api": ("weekly", 0.8),
"topics": ("weekly", 0.8),
"releases": ("weekly", 0.8),
"telegram": ("weekly", 0.6)
}
def now():
return datetime.datetime.today().strftime("%Y-%m-%d")
with open("sitemap.xml", "w") as f:
f.write('<?xml version="1.0" encoding="utf-8"?>\n')
f.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n')
urls = []
def search(path):
try:
for j in os.listdir(path):
search(f"{path}/{j}")
except NotADirectoryError:
if not path.endswith(".rst"):
return
path = path.split("/")[2:]
if path[0].endswith(".rst"):
folder = "."
else:
folder = path[0]
path = f"{canonical}{'/'.join(path)}"[:-len(".rst")]
if path.endswith("index"):
path = path[:-len("index")]
urls.append((path, now(), *dirs[folder]))
search("../source")
urls.sort(key=lambda x: x[3], reverse=True)
for i in urls:
f.write(f" <url>\n")
f.write(f" <loc>{i[0]}</loc>\n")
f.write(f" <lastmod>{i[1]}</lastmod>\n")
f.write(f" <changefreq>{i[2]}</changefreq>\n")
f.write(f" <priority>{i[3]}</priority>\n")
f.write(f" </url>\n")
f.write("</urlset>")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

View File

@ -8,7 +8,6 @@ found starting from this page.
This page is about the Client class, which exposes high-level methods for an easy access to the API. This page is about the Client class, which exposes high-level methods for an easy access to the API.
.. code-block:: python .. code-block:: python
:emphasize-lines: 1-3
from pyrogram import Client from pyrogram import Client

View File

@ -1,16 +1,12 @@
Decorators Decorators
========== ==========
While still being methods bound to the :class:`~pyrogram.Client` class, decorators are of a special kind and thus
deserve a dedicated page.
Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to Decorators are able to register callback functions for handling updates in a much easier and cleaner way compared to
:doc:`Handlers <handlers>`; they do so by instantiating the correct handler and calling :doc:`Handlers <handlers>`; they do so by instantiating the correct handler and calling
:meth:`~pyrogram.Client.add_handler` automatically. All you need to do is adding the decorators on top of your :meth:`~pyrogram.Client.add_handler` automatically. All you need to do is adding the decorators on top of your
functions. functions.
.. code-block:: python .. code-block:: python
:emphasize-lines: 6
from pyrogram import Client from pyrogram import Client

View File

@ -5,7 +5,6 @@ Handlers are used to instruct Pyrogram about which kind of updates you'd like to
For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead. For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead.
.. code-block:: python .. code-block:: python
:emphasize-lines: 2, 11
from pyrogram import Client from pyrogram import Client
from pyrogram.handlers import MessageHandler from pyrogram.handlers import MessageHandler

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -29,35 +29,37 @@ from pygments.styles.friendly import FriendlyStyle
FriendlyStyle.background_color = "#f3f2f1" FriendlyStyle.background_color = "#f3f2f1"
project = "Pyrogram" project = "Pyrogram"
copyright = f"2017-{datetime.now().year}, Dan" copyright = f"2017-present, Dan"
author = "Dan" author = "Dan"
version = ".".join(__version__.split(".")[:-1])
extensions = [ extensions = [
"sphinx.ext.autodoc", "sphinx.ext.autodoc",
"sphinx.ext.napoleon", "sphinx.ext.napoleon",
"sphinx.ext.autosummary", "sphinx.ext.autosummary",
"sphinx_copybutton", "sphinx_copybutton"
"sphinx_tabs.tabs"
] ]
master_doc = "index" master_doc = "index"
source_suffix = ".rst" source_suffix = ".rst"
autodoc_member_order = "bysource" autodoc_member_order = "bysource"
version = __version__ templates_path = ["_resources/templates"]
release = version html_copy_source = False
templates_path = ["_templates"]
napoleon_use_rtype = False napoleon_use_rtype = False
napoleon_use_param = False
pygments_style = "friendly" pygments_style = "friendly"
copybutton_prompt_text = "$ " copybutton_prompt_text = "$ "
suppress_warnings = ["image.not_readable"]
html_title = "Pyrogram Documentation" html_title = "Pyrogram Documentation"
html_theme = "sphinx_rtd_theme" html_theme = "sphinx_rtd_theme"
html_static_path = ["_static"] html_static_path = ["_resources/static"]
html_show_sourcelink = True html_show_sourcelink = True
html_show_copyright = False html_show_copyright = False
html_theme_options = { html_theme_options = {
@ -65,17 +67,15 @@ html_theme_options = {
"collapse_navigation": True, "collapse_navigation": True,
"sticky_navigation": False, "sticky_navigation": False,
"logo_only": True, "logo_only": True,
"display_version": True, "display_version": False,
"style_external_links": True "style_external_links": True
} }
napoleon_use_param = False html_logo = "_resources/static/img/pyrogram.png"
html_favicon = "_resources/static/img/favicon.ico"
html_logo = "_images/pyrogram.png"
html_favicon = "_images/favicon.ico"
latex_engine = "xelatex" latex_engine = "xelatex"
latex_logo = "_images/pyrogram.png" latex_logo = "_resources/static/img/pyrogram.png"
latex_elements = { latex_elements = {
"pointsize": "12pt", "pointsize": "12pt",

View File

@ -1,404 +0,0 @@
Pyrogram FAQ
============
.. role:: strike
:class: strike
This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general.
.. tip::
If you think something interesting could be added here, feel free to propose it by opening a `Feature Request`_.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
What is Pyrogram?
-----------------
**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and
C. It enables you to easily create custom applications for both user and bot identities (bot API alternative) via the
:doc:`MTProto API <topics/mtproto-vs-botapi>` with the Python programming language.
.. _Telegram: https://telegram.org
Where does the name come from?
------------------------------
The name "Pyrogram" is composed by **pyro**, which comes from the Greek word *πῦρ (pyr)*, meaning fire, and **gram**,
from *Telegram*. The word *pyro* itself is built from *Python*, **py** for short, and the suffix **ro** to come up with
the word *fire*, which also inspired the project logo.
How old is Pyrogram?
--------------------
Pyrogram was first released on December 12, 2017. The actual work on the framework began roughly three months prior to the
initial public release on `GitHub`_.
.. _GitHub: https://github.com/pyrogram/pyrogram
Why Pyrogram?
-------------
- **Easy**: You can install Pyrogram with pip and start building your applications right away.
- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way.
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
- **Asynchronous**: Allows both synchronous and asynchronous models to fit all usage needs.
- **Documented**: API methods, types and public interfaces are all well documented.
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
- **Updated**, to make use of the latest Telegram API version and features.
- **Bot API-like**: Similar to the Bot API in its simplicity, but much more powerful and detailed.
- **Pluggable**: The :doc:`Smart Plugin <topics/smart-plugins>` system allows to write components with minimal
boilerplate code.
- **Comprehensive**: Execute any :doc:`advanced action <topics/advanced-usage>` an official client is able to do, and
even more.
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
Why is Pyrogram defined as both Client Library and Framework?
-------------------------------------------------------------
Simply because it falls in both categories, depending on how you use it.
Pyrogram as a client library makes it easy and intuitive accessing the Telegram API by offering idiomatic Python code
that is generated or hand-written. Low-level details and client-server communication protocols are handled under the
hood. Pyrogram acts as a client library when *you call* its methods and use its types in a batch application that
executes a set of instructions.
Pyrogram as a framework makes it easy to handle live events by allowing you to register event handlers that will be
executed as soon as they arrive from the server side. Pyrogram acts as a framework when it's Pyrogram itself that
*calls your code*, that is, your registered event handlers. Such applications are usually started and left online
indefinitely, until you decide to stop them.
What can MTProto do more than the Bot API?
------------------------------------------
For a detailed answer, please refer to the :doc:`MTProto vs. Bot API <topics/mtproto-vs-botapi>` page.
Why do I need an API key for bots?
----------------------------------
Requests against the official bot API endpoint are made via JSON/HTTP, but are handled by an intermediate server
application that implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always
required, but hidden to the public.
.. figure:: https://i.imgur.com/WvwBoZo.png
:align: center
Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to
identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone
number only.
Can I use Webhooks?
-------------------
Lots of people ask this question because they are used to the bot API, but things are different in Pyrogram!
There is no webhook in Pyrogram, simply because there is no HTTP involved, by default. However, a similar technique is
being used to make receiving updates efficient.
Pyrogram uses persistent connections via TCP sockets to interact with the server and instead of actively asking for
updates every time (polling), Pyrogram will simply sit down and wait for the server to send updates by itself
the very moment they are available (server push).
Can I use the same file_id across different accounts?
-----------------------------------------------------
No, Telegram doesn't allow this.
File ids are personal and bound to a specific account; an attempt in using a foreign file id will result in errors such
as ``[400 MEDIA_EMPTY]``.
The only exception are stickers' file ids; you can use them across different accounts without any problem, like this
one: ``CAADBAADyg4AAvLQYAEYD4F7vcZ43AI``.
Can I use Bot API's file_id values in Pyrogram?
-----------------------------------------------
Yes! All file ids you take or might have taken from the Bot API are 100% compatible and re-usable in Pyrogram.
The opposite is also valid, you can take any file id generated by Pyrogram and re-use in the Bot API.
Can I use multiple clients at once on the same account?
-------------------------------------------------------
Yes, you can. Both user and bot accounts are able to run multiple sessions in parallel (up to 10 per account). However,
you must pay attention and not use the *same* exact session in more than one client at the same time. In other words:
- Avoid copying your session file: even if you rename the file, the copied sessions will still point to a specific one
stored in the server.
- Make sure that only one instance of your script runs, using your session file.
If you -- even accidentally -- fail to do so, all the previous session copies will immediately stop receiving updates
and eventually the server will start throwing the error ``[406 AUTH_KEY_DUPLICATED]``, inviting you to login again.
Why is that so? Because the server has recognized two identical sessions are running in two different locations, and
concludes it could possibly be due to a cloned/stolen device. Having the session terminated in such occasions will
protect the user's privacy.
So, the only correct way to run multiple clients on the same account is authorizing your account (either user or bot)
from the beginning every time, and use one separate session for each parallel client you are going to use.
I started a client and nothing happens!
---------------------------------------
If you are connecting from Russia, China or Iran :doc:`you need a proxy <topics/proxy>`, because Telegram could be
partially or totally blocked in those countries. More information about this block can be found at
`Wikipedia <https://en.wikipedia.org/wiki/Blocking_Telegram_in_Russia>`_.
Another possible cause might be network issues, either yours or Telegram's. To confirm this, add the following code on
the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable network
in a bunch of seconds:
.. code-block:: python
import logging
logging.basicConfig(level=logging.INFO)
Another way to confirm you aren't able to connect to Telegram is by pinging the IP addresses below and see whether ping
fails or not.
What are the IP addresses of Telegram Data Centers?
---------------------------------------------------
The Telegram cloud is currently composed by a decentralized, multi-DC infrastructure (currently 5 DCs, each of which can
work independently) spread in different locations worldwide. However, some of the less busy DCs have been lately
dismissed and their IP addresses are now kept as aliases to the nearest one.
.. csv-table:: Production Environment
:header: ID, Location, IPv4, IPv6
:widths: auto
:align: center
DC1, "MIA, Miami FL, USA", ``149.154.175.53``, ``2001:b28:f23d:f001::a``
DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a``
DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a``
DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a``
DC5, "SIN, Singapore, SG", ``91.108.56.130``, ``2001:b28:f23f:f005::a``
.. csv-table:: Test Environment
:header: ID, Location, IPv4, IPv6
:widths: auto
:align: center
DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e``
DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e``
DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e``
.. centered:: More info about the Test Environment can be found :doc:`here <topics/test-servers>`.
***** Alias DC
Thanks to `@FrayxRulez <https://t.me/tgbetachat/104921>`_ for telling about alias DCs.
I want to migrate my account from DCX to DCY.
---------------------------------------------
This question is often asked by people who find their account(s) always being connected to DC1 - USA (for example), but
are connecting from a place far away (e.g DC4 - Europe), thus resulting in slower interactions when using the API
because of the great physical distance between the user and its associated DC.
When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be created
in, based on the phone number origin.
Even though Telegram `documentations <https://core.telegram.org/api/datacenter#user-migration>`_ state the server might
decide to automatically migrate a user in case of prolonged usages from a distant, unusual location and albeit this
mechanism is also `confirmed <https://twitter.com/telegram/status/427131446655197184>`_ to exist by Telegram itself,
it's currently not possible to have your account migrated, in any way, simply because the feature was once planned but
not yet implemented.
Thanks to `@gabriel <https://t.me/AnotherGroup/217699>`_ for confirming the feature was not implemented yet.
Why is my client reacting slowly in supergroups?
------------------------------------------------
This issue affects only some supergroups or only some members within the same supergroup. Mostly, it affects supergroups
whose creator's account (and thus the supergroup itself) lives inside a **different DC**, far away from yours, but could
also depend on where a member is connecting from.
Because of how Telegram works internally, every single message you receive from and send to other members must pass
through the creator's DC, and in the worst case where you, the creator and another member all belong to three different
DCs, the other member messages have to go through from its DC to the creator's DC and finally to your DC. This process
will inevitably take its time.
To confirm this theory and see it by yourself, you can test in a supergroup where you are sure all parties live
inside the same DC. In this case the responses will be faster.
Another reason that makes responses come slowly is that messages are **dispatched by priority**. Depending on the kind
of member, some users receive messages faster than others and for big and busy supergroups the delay might become
noticeable, especially if you are among the lower end of the priority list:
1. Creator.
2. Administrators.
3. Bots.
4. Mentioned users.
5. Recent online users.
6. Everyone else.
Thanks to `@Manuel15 <https://t.me/PyrogramChat/76990>`_ for the priority list.
I keep getting PEER_ID_INVALID error!
-------------------------------------
The error in question is ``[400 PEER_ID_INVALID]``, and could mean several things:
- The chat id you tried to use is simply wrong, double check it.
- The chat id refers to a group or channel you are not a member of.
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
- The chat id refers to a user or chat your current session hasn't met yet.
About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to
contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching
for usernames, meeting them in a common group, having their phone contacts saved, getting a message mentioning them
(either a forward or a mention in the message text) or obtaining the dialogs list.
Code hangs when I stop, restart, add/remove_handler
---------------------------------------------------
You tried to ``.stop()``, ``.restart()``, ``.add_handler()`` or ``.remove_handler()`` *inside* a running handler, but
that can't be done because the way Pyrogram deals with handlers would make it hang.
When calling one of the methods above inside an event handler, Pyrogram needs to wait for all running handlers to finish
in order to safely continue. In other words, since your handler is blocking the execution by waiting for the called
method to finish and since Pyrogram needs to wait for your handler to finish, you are left with a deadlock.
The solution to this problem is to pass ``block=False`` to such methods so that they return immediately and the actual
code called asynchronously.
UnicodeEncodeError: '<encoding>' codec can't encode …
-----------------------------------------------------
Where ``<encoding>`` might be *ascii*, *cp932*, *charmap* or anything else other than **utf-8**. This error usually
shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to a
better terminal altogether.
Uploading with URLs gives error WEBPAGE_CURL_FAILED
---------------------------------------------------
When uploading media files using an URL, the server automatically tries to download the media and uploads it to the
Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the
media exceeds 20 MB in size. In such cases, your only option is to download the media yourself and upload from your
local machine.
sqlite3.OperationalError: database is locked
--------------------------------------------
This error occurs when more than one process is using the same session file, that is, when you run two or more clients
at the same time using the same session name.
It could also occur when a background script is still running and you forgot about it. In this case, you either restart
your system or find and kill the process that is locking the database. On Unix based systems, you can do the following:
#. ``cd`` into your session file directory.
#. ``fuser my_account.session`` to find the process id.
#. ``kill 1234`` to gracefully stop the process.
#. If the last command doesn't help, use ``kill -9 1234`` instead.
If you want to run multiple clients on the same account, you must authorize your account (either user or bot)
from the beginning every time, and use different session names for each parallel client you are going to use.
sqlite3.OperationalError: unable to open database file
------------------------------------------------------
Stackoverflow to the rescue: https://stackoverflow.com/questions/4636970
FileNotFoundError when using PyInstaller
----------------------------------------
Pyrogram uses two files that are not Python files, which are not included automatically in the PyInstaller bundle:
- ``pyrogram/mime.types``
- ``pyrogram/storage/schema.sql``
To fix the issue, you have to locate your local Pyrogram installation and pass those files to PyInstaller. More info in
their docs https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-files-to-the-bundle.
My verification code expires immediately!
-----------------------------------------
That is because you likely shared it across any of your Telegram chats. Yes, that's right: the server keeps scanning the
messages you send and if an active verification code is found it will immediately expire, automatically.
The reason behind this is to protect unaware users from giving their account access to any potential scammer, but if you
legitimately want to share your account(s) verification codes, consider scrambling them, e.g. ``12345````1-2-3-4-5``.
How can avoid Flood Waits?
--------------------------
Long story short: make less requests, and remember that the API is designed to be used by official apps, by real people;
anything above normal usage could be limited.
This question is being asked quite a lot of times, but the bottom line is that nobody knows the exact limits and it's
unlikely that such information will be ever disclosed, because otherwise people could easily circumvent them and defeat
their whole purpose.
Do also note that Telegram wants to be a safe and reliable place and that limits exist to protect itself from abuses.
Having said that, here's some insights about limits:
- They are tuned by Telegram based on real people usage and can change anytime.
- Some limits are be applied to single sessions, some others apply to the whole account.
- Limits vary based on methods and the arguments passed to methods. For example: log-ins are expensive and thus have
stricter limits; replying to a user command could cause a flood wait in case the user starts flooding, but
such limit will only be applied to that particular chat (i.e.: other users are not affected).
- You can catch Flood Wait exceptions in your code and wait the required seconds before continuing, this way:
.. code-block:: python
import time
from pyrogram.errors import FloodWait
try:
... # Your code
except FloodWait as e:
time.sleep(e.x) # Wait "x" seconds before continuing
More info about error handling can be found `here <start/errors>`_.
My account has been deactivated/limited!
----------------------------------------
First of all, you should understand that Telegram wants to be a safe place for people to stay in, and to pursue this
goal there are automatic protection systems running to prevent flood and spam, as well as a moderation team of humans
who review reports.
.. centered:: Pyrogram is a tool at your commands; it only does what you tell it to do, the rest is up to you.
Having said that, here's a list of what Telegram definitely doesn't like:
- Flood, abusing the API.
- Spam, sending unsolicited messages or adding people to unwanted groups and channels.
- Virtual/VoIP and cheap real numbers, because they are relatively easy to get and likely used for spam/flood.
And thanks to `@koteeq <https://t.me/koteeq>`_, here's a good explanation of how, probably, the system works:
.. raw:: html
<script
async src="https://telegram.org/js/telegram-widget.js?5"
data-telegram-post="PyrogramChat/69424"
data-width="100%">
</script>
<br><br>
However, you might be right, and your account was deactivated/limited without any good reason. This could happen because
of mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at
recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_.
Are there any secret easter eggs?
---------------------------------
Yes. If you found one, `let me know`_!
.. _let me know: https://t.me/pyrogram
.. _@smstelegram: https://twitter.com/smstelegram
.. _this form: https://telegram.org/support
.. _Bug Report: https://github.com/pyrogram/pyrogram/issues/new?labels=bug&template=bug_report.md
.. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md

View File

@ -0,0 +1,11 @@
Client started, but nothing happens
===================================
A possible cause might be network issues, either yours or Telegram's. To check this, add the following code at
the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable
network:
.. code-block:: python
import logging
logging.basicConfig(level=logging.INFO)

View File

@ -0,0 +1,12 @@
Code hangs when calling stop, restart, add/remove_handler
=========================================================
You tried to ``.stop()``, ``.restart()``, ``.add_handler()`` or ``.remove_handler()`` inside a running handler, but
that can't be done because the way Pyrogram deals with handlers would make it hang.
When calling one of the methods above inside an event handler, Pyrogram needs to wait for all running handlers to finish
in order to continue. Since your handler is blocking the execution by waiting for the called method to finish
and since Pyrogram needs to wait for your handler to finish, you are left with a deadlock.
The solution to this problem is to pass ``block=False`` to such methods so that they return immediately and the actual
code called asynchronously.

View File

@ -0,0 +1,23 @@
How to avoid Flood Waits?
=========================
Slow things down and make less requests. Moreover, exact limits are unknown and can change anytime based on normal
usages.
When a flood wait happens the server will tell you how much time to wait before continuing.
The following shows how to catch the exception in your code and wait the required seconds.
.. code-block:: python
import time
from pyrogram.errors import FloodWait
...
try:
... # Your code
except FloodWait as e:
await asyncio.sleep(e.x) # Wait "x" seconds before continuing
...
More info about error handling can be found :doc:`here <../start/errors>`.

View File

@ -0,0 +1,9 @@
How to use webhooks?
====================
There is no webhook in Pyrogram, simply because there is no HTTP involved. However, a similar technique is
being used to make receiving updates efficient.
Pyrogram uses persistent connections via TCP sockets to interact with the server and instead of actively asking for
updates every time (polling), Pyrogram will sit down and wait for the server to send updates by itself the very moment
they are available (server push).

47
docs/source/faq/index.rst Normal file
View File

@ -0,0 +1,47 @@
Frequently Asked Questions
==========================
This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general.
**Contents**
- :doc:`why-is-the-api-key-needed-for-bots`
- :doc:`how-to-use-webhooks`
- :doc:`using-the-same-file-id-across-different-accounts`
- :doc:`using-multiple-clients-at-once-on-the-same-account`
- :doc:`client-started-but-nothing-happens`
- :doc:`what-are-the-ip-addresses-of-telegram-data-centers`
- :doc:`migrating-the-account-to-another-data-center`
- :doc:`why-is-the-client-reacting-slowly-in-supergroups-channels`
- :doc:`peer-id-invalid-error`
- :doc:`code-hangs-when-calling-stop-restart-add-remove-handler`
- :doc:`unicodeencodeerror-codec-cant-encode`
- :doc:`uploading-with-urls-gives-error-webpage-curl-failed`
- :doc:`why-is-the-event-handler-triggered-twice-or-more`
- :doc:`sqlite3-operationalerror-database-is-locked`
- :doc:`sqlite3-interfaceerror-error-binding-parameter`
- :doc:`socket-send-raised-exception-oserror-timeouterror`
- :doc:`how-to-avoid-flood-waits`
- :doc:`the-account-has-been-limited-deactivated`
.. toctree::
:hidden:
why-is-the-api-key-needed-for-bots
how-to-use-webhooks
using-the-same-file-id-across-different-accounts
using-multiple-clients-at-once-on-the-same-account
client-started-but-nothing-happens
what-are-the-ip-addresses-of-telegram-data-centers
migrating-the-account-to-another-data-center
why-is-the-client-reacting-slowly-in-supergroups-channels
peer-id-invalid-error
code-hangs-when-calling-stop-restart-add-remove-handler
unicodeencodeerror-codec-cant-encode
uploading-with-urls-gives-error-webpage-curl-failed
why-is-the-event-handler-triggered-twice-or-more
sqlite3-operationalerror-database-is-locked
sqlite3-interfaceerror-error-binding-parameter
socket-send-raised-exception-oserror-timeouterror
how-to-avoid-flood-waits
the-account-has-been-limited-deactivated

View File

@ -0,0 +1,10 @@
Migrating the account to another data center
============================================
This question is asked by people who find their account always being connected to one DC (data center), but are
connecting from a place far away, thus resulting in slower interactions when using the API because of the greater
physical distance between the user and the associated DC.
When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be
created in. It's also up to the server to decide whether to automatically migrate a user in case of prolonged usages
from a distant location.

View File

@ -0,0 +1,14 @@
PEER_ID_INVALID error
=====================
This error could mean several things:
- The chat id you tried to use is simply wrong, check it again.
- The chat id refers to a group or channel you are not a member of.
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
- The chat id refers to a user or chat your current session hasn't met yet.
About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to
contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching
for usernames, meeting them in a common group, having their phone contacts saved, getting a message mentioning them
or obtaining the dialogs list.

View File

@ -0,0 +1,10 @@
socket.send() raised exception, OSError(), TimeoutError()
=========================================================
If you get this error chances are you are blocking the event loop for too long.
In general, it means you are executing thread-blocking code that prevents the event loop from
running properly. For example:
- You are using ``time.sleep()`` instead of ``asyncio.sleep()``.
- You are running processing loops that take too much time to complete.
- You are reading/writing files to disk that take too much time to complete.

View File

@ -0,0 +1,13 @@
sqlite3.InterfaceError: Error binding parameter
===============================================
This error occurs when you pass a chat id value of the wrong type when trying to call a method. Most likely, you
accidentally passed the whole user or chat object instead of the id or username.
.. code-block:: python
# Wrong. You passed the whole Chat instance
app.send_message(chat, "text")
# Correct
app.send_message(chat.id, "text")

View File

@ -0,0 +1,17 @@
sqlite3.OperationalError: database is locked
============================================
This error occurs when more than one process is using the same session file, that is, when you run two or more clients
at the same time using the same session name or in case another program has accessed the file.
For example, it could occur when a background script is still running and you forgot about it. In this case, you either
restart your system or find and kill the process that is locking the database. On Unix based systems, you can try the
following:
#. ``cd`` into your session file directory.
#. ``fuser my_account.session`` to find the process id.
#. ``kill 1234`` to gracefully stop the process.
#. If the last command doesn't help, use ``kill -9 1234`` instead.
If you want to run multiple clients on the same account, you must authorize your account (either user or bot)
from the beginning every time, and use different session names for each parallel client you are going to use.

View File

@ -0,0 +1,16 @@
The account has been limited/deactivated
========================================
Pyrogram is a framework that interfaces with Telegram; it is at your commands, meaning it only does what you tell it to
do, the rest is up to you and Telegram (see `Telegram's ToS`_).
If you found your account being limited/deactivated, it could be due spam/flood/abuse of the API or the usage of certain
virtual/VoIP numbers.
If you think your account was limited/deactivated by mistake, you can write to recover@telegram.org, contact
`@SpamBot`_ or use `this form`_.
.. _@SpamBot: https://t.me/spambot
.. _this form: https://telegram.org/support
.. _Telegram's ToS: https://telegram.org/tos

View File

@ -0,0 +1,7 @@
UnicodeEncodeError: '...' codec can't encode ...
================================================
Where ``<encoding>`` might be *ascii*, *cp932*, *charmap* or anything else other than *utf-8*. This error usually
shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to
another terminal altogether.

View File

@ -0,0 +1,7 @@
Uploading with URLs gives error WEBPAGE_CURL_FAILED
===================================================
When uploading media files using an URL, the server automatically tries to download the media and uploads it to the
Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the
media file is too large. In such cases, your only option is to download the media yourself and upload it from your
local machine.

View File

@ -0,0 +1,7 @@
Using multiple clients at once on the same account
==================================================
Both user and bot accounts are able to run multiple sessions in parallel. However, you must not use the same session
in more than one client at the same time. The correct way to run multiple clients on the same account is by authorizing
your account (either user or bot) from the beginning each time, and use one separate session for each parallel client.

View File

@ -0,0 +1,6 @@
Using the same file_id across different accounts
================================================
Telegram file_id strings are bound to the account which generated them. An attempt in using a foreign file id will
result in errors such as ``[400 MEDIA_EMPTY]``. The only exception are stickers' file ids; you can use them across
different accounts without any problem.

View File

@ -0,0 +1,30 @@
What are the IP addresses of Telegram Data Centers?
===================================================
Telegram is currently composed by a decentralized, multi-DC infrastructure (currently 5 DCs, each of which can
work independently) spread across different locations worldwide. However, some of the less busy DCs have been lately
dismissed and their IP addresses are now kept as aliases to the nearest one.
.. csv-table:: Production Environment
:header: ID, Location, IPv4, IPv6
:widths: auto
:align: center
DC1, "MIA, Miami FL, USA", ``149.154.175.53``, ``2001:b28:f23d:f001::a``
DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a``
DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a``
DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a``
DC5, "SIN, Singapore, SG", ``91.108.56.130``, ``2001:b28:f23f:f005::a``
.. csv-table:: Test Environment
:header: ID, Location, IPv4, IPv6
:widths: auto
:align: center
DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e``
DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e``
DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e``
.. centered:: More info about the Test Environment can be found :doc:`here <../topics/test-servers>`.
***** Alias DC

View File

@ -0,0 +1,12 @@
Why is the API key needed for bots?
===================================
Requests against the official bot API endpoints are made via JSON/HTTP and are handled by an intermediate server
application that implements the MTProto protocol and uses its own API key to communicate with the MTProto servers.
.. figure:: //_static/img/mtproto-vs-bot-api.png
:align: center
Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to
identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone
number only.

View File

@ -0,0 +1,18 @@
Why is the client reacting slowly in supergroups/channels?
==========================================================
Because of how Telegram works internally, every message you receive and send must pass through the creator's DC, and in
the worst case where you, the creator and another member all belong to three different DCs, the other member messages
have to go through from their DC to the creator's DC and finally to your DC. This is applied to each message and member
of a supergroup/channel and the process will inevitably take its time.
Another reason that makes responses come slowly is that messages are dispatched by priority. Depending on the kind
of member, some users receive messages faster than others and for big and busy supergroups the delay might become
noticeable, especially if you are among the lower end of the priority list:
1. Creator.
2. Administrators.
3. Bots.
4. Mentioned users.
5. Recent online users.
6. Everyone else.

View File

@ -0,0 +1,28 @@
Why is the event handler called twice or more?
==============================================
The event handler is being called twice or more because one or more message edit events have arrived.
By default, Pyrogram listens to both new and edit message events inside ``on_message`` handlers. To prevent edit events
from calling the handler, use the "not edited" filter ``~filters.edited``.
For example:
.. code-block:: python
...
@app.on_message(... & ~filters.edited)
async def handler(client, message):
...
Or, avoid handling any edited message altogether this way:
.. code-block:: python
...
@app.on_message(filters.edited)
async def edited(client, message):
pass
... # other handlers

View File

@ -1,86 +0,0 @@
Pyrogram Glossary
=================
This page contains a list of common words with brief explanations related to Pyrogram and, to some extent, Telegram in
general. Some words may as well link to dedicated articles in case the topic is covered in a more detailed fashion.
.. tip::
If you think something interesting could be added here, feel free to propose it by opening a `Feature Request`_.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
Terms
-----
.. glossary::
:sorted:
API
Application Programming Interface: a set of methods, protocols and tools that make it easier to develop programs
by providing useful building blocks to the developer.
API key
A secret code used to authenticate and/or authorize a specific application to Telegram in order for it to
control how the API is being used, for example, to prevent abuses of the API.
:doc:`More on API keys <intro/setup>`.
DC
Also known as *data center*, is a place where lots of computer systems are housed and used together in order to
achieve high quality and availability for services.
RPC
Acronym for Remote Procedure Call, that is, a function which gets executed at some remote place (i.e. Telegram
server) and not in your local machine.
RPCError
An error caused by an RPC which must be returned in place of the successful result in order to let the caller
know something went wrong. :doc:`More on RPCError <start/errors>`.
MTProto
The name of the custom-made, open and encrypted protocol by Telegram, implemented in Pyrogram.
:doc:`More on MTProto <topics/mtproto-vs-botapi>`.
MTProto API
The Telegram main API Pyrogram makes use of, which is able to connect both users and normal bots to Telegram
using MTProto as application layer protocol and execute any method Telegram provides from its public TL-schema.
:doc:`More on MTProto API <topics/mtproto-vs-botapi>`.
Bot API
The Telegram Bot API that is able to only connect normal bots only to Telegram using HTTP as application layer
protocol and allows to execute a sub-set of the main Telegram API.
:doc:`More on Bot API <topics/mtproto-vs-botapi>`.
Pyrogrammer
A developer that uses Pyrogram to build Telegram applications.
Userbot
Also known as *user bot* or *ubot* for short, is a user logged in by third-party Telegram libraries --- such as
Pyrogram --- to automate some behaviours, like sending messages or reacting to text commands or any other event.
Not to be confused with *bot*, that is, a normal Telegram bot created by `@BotFather <https://t.me/botfather>`_.
Session
Also known as *login session*, is a strictly personal piece of data created and held by both parties
(client and server) which is used to grant permission into a single account without having to start a new
authorization process from scratch.
Callback
Also known as *callback function*, is a user-defined generic function that *can be* registered to and then
called-back by the framework when specific events occurs.
Handler
An object that wraps around a callback function that is *actually meant* to be registered into the framework,
which will then be able to handle a specific kind of events, such as a new incoming message, for example.
:doc:`More on Handlers <start/updates>`.
Decorator
Also known as *function decorator*, in Python, is a callable object that is used to modify another function.
Decorators in Pyrogram are used to automatically register callback functions for handling updates.
:doc:`More on Decorators <start/updates>`.
.. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md

View File

@ -5,7 +5,8 @@ Welcome to Pyrogram
<div align="center"> <div align="center">
<a href="/"> <a href="/">
<div><img src="_static/pyrogram.png" alt="Pyrogram Logo" width="420"></div> <div class="pyrogram-logo-index"><img src="_static/pyrogram.png" alt="Pyrogram"></div>
<div class="pyrogram-text pyrogram-text-index">Pyrogram</div>
</a> </a>
</div> </div>
@ -14,15 +15,15 @@ Welcome to Pyrogram
<br> <br>
<a href="https://github.com/pyrogram/pyrogram"> <a href="https://github.com/pyrogram/pyrogram">
Source Code Development
</a> </a>
<a href="https://github.com/pyrogram/pyrogram/releases"> <a href="https://docs.pyrogram.org/releases">
Releases Releases
</a> </a>
<a href="https://t.me/Pyrogram"> <a href="https://t.me/pyrogram">
Community News
</a> </a>
</p> </p>
@ -35,16 +36,34 @@ Welcome to Pyrogram
@app.on_message(filters.private) @app.on_message(filters.private)
async def hello(client, message): async def hello(client, message):
await message.reply_text(f"Hello {message.from_user.mention}") await message.reply("Hello from Pyrogram!")
app.run() app.run()
**Pyrogram** is a modern, elegant and easy-to-use Telegram_ framework written from the ground up in Python and C. **Pyrogram** is a modern, elegant and asynchronous :doc:`MTProto API <topics/mtproto-vs-botapi>` framework.
It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot identity
:doc:`MTProto API <topics/mtproto-vs-botapi>`. (bot API alternative) using Python.
.. _Telegram: https://telegram.org Support
-------
If you'd like to support Pyrogram, you can consider:
- `Become a GitHub sponsor <https://github.com/sponsors/delivrance>`_.
- `Become a LiberaPay patron <https://liberapay.com/delivrance>`_.
- `Become an OpenCollective backer <https://opencollective.com/pyrogram>`_.
Key Features
------------
- **Ready**: Install Pyrogram with pip and start building your applications right away.
- **Easy**: Makes the Telegram API simple and intuitive, while still allowing advanced usages.
- **Elegant**: Low-level details are abstracted and re-presented in a more convenient way.
- **Fast**: Boosted up by :doc:`TgCrypto <topics/tgcrypto>`, a high-performance crypto library written in pure C.
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
- **Async**: Fully asynchronous (also usable synchronously if wanted, for convenience).
- **Powerful**: Full access to Telegram's API to execute any official client action and more.
How the Documentation is Organized How the Documentation is Organized
---------------------------------- ----------------------------------
@ -53,18 +72,11 @@ Contents are organized into sections composed of self-contained topics which can
following them in order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a following them in order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a
list of the most relevant pages for a quick access. list of the most relevant pages for a quick access.
.. admonition :: Cloud Credits
:class: tip
If you need a cloud server to host your applications, we recommend using **Hetzner Cloud**. Sign up with
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits and help support Pyrogram as
well.
First Steps First Steps
^^^^^^^^^^^ ^^^^^^^^^^^
.. hlist:: .. hlist::
:columns: 2 :columns: 1
- :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly. - :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly.
- :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods. - :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods.
@ -75,7 +87,7 @@ API Reference
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
.. hlist:: .. hlist::
:columns: 2 :columns: 1
- :doc:`Pyrogram Client <api/client>`: Reference details about the Client class. - :doc:`Pyrogram Client <api/client>`: Reference details about the Client class.
- :doc:`Available Methods <api/methods/index>`: List of available high-level methods. - :doc:`Available Methods <api/methods/index>`: List of available high-level methods.
@ -86,16 +98,12 @@ Meta
^^^^ ^^^^
.. hlist:: .. hlist::
:columns: 2 :columns: 1
- :doc:`Pyrogram FAQ <faq>`: Answers to common Pyrogram questions. - :doc:`Pyrogram FAQ <faq/index>`: Answers to common Pyrogram questions.
- :doc:`Pyrogram Glossary <glossary>`: List of words with brief explanations.
- :doc:`Support Pyrogram <support>`: Ways to show your appreciation. - :doc:`Support Pyrogram <support>`: Ways to show your appreciation.
- :doc:`About the License <license>`: Information about the Project license.
- :doc:`Release Notes <releases/index>`: Release notes for Pyrogram releases. - :doc:`Release Notes <releases/index>`: Release notes for Pyrogram releases.
Last updated on |today|
.. toctree:: .. toctree::
:hidden: :hidden:
:caption: Introduction :caption: Introduction
@ -136,14 +144,13 @@ Last updated on |today|
topics/more-on-updates topics/more-on-updates
topics/config-file topics/config-file
topics/smart-plugins topics/smart-plugins
topics/session-settings topics/client-settings
topics/tgcrypto topics/tgcrypto
topics/storage-engines topics/storage-engines
topics/text-formatting topics/text-formatting
topics/serializing topics/serializing
topics/proxy topics/proxy
topics/scheduling topics/scheduling
topics/bots-interaction
topics/mtproto-vs-botapi topics/mtproto-vs-botapi
topics/debugging topics/debugging
topics/test-servers topics/test-servers
@ -154,10 +161,8 @@ Last updated on |today|
:hidden: :hidden:
:caption: Meta :caption: Meta
faq faq/index
glossary
support support
license
releases/index releases/index
.. toctree:: .. toctree::

View File

@ -1,16 +1,9 @@
Install Guide Install Guide
============= =============
Being a modern Python library, **Pyrogram** requires Python 3.6+ to be installed in your system. Being a modern Python framework, Pyrogram requires an up to date version of Python to be installed in your system.
We recommend using the latest versions of both Python 3 and pip. We recommend using the latest versions of both Python 3 and pip.
- Get **Python 3** from https://www.python.org/downloads/ (or with your package manager).
- Get **pip** by following the instructions at https://pip.pypa.io/en/latest/installing/.
.. important::
Pyrogram supports **Python 3** only, starting from version 3.6. **PyPy** is supported too.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
:depth: 1 :depth: 1
@ -36,12 +29,7 @@ Install Pyrogram
Bleeding Edge Bleeding Edge
------------- -------------
Pyrogram is always evolving, although new releases on PyPI are published only when enough changes are added, but this You can install the development version from the git ``master`` branch using this command:
doesn't mean you can't try new features right now!
In case you'd like to try out the latest Pyrogram features, the `GitHub repo`_ is always kept updated with new changes;
you can install the development version straight from the ``master`` branch using this command (note "master.zip" in
the link):
.. code-block:: text .. code-block:: text
@ -57,6 +45,6 @@ If no error shows up you are good to go.
>>> import pyrogram >>> import pyrogram
>>> pyrogram.__version__ >>> pyrogram.__version__
'|version|' 'x.y.z'
.. _`Github repo`: http://github.com/pyrogram/pyrogram .. _`Github repo`: http://github.com/pyrogram/pyrogram

View File

@ -1,49 +1,54 @@
Quick Start Quick Start
=========== ===========
The next few steps serve as a quick start for all new :term:`Pyrogrammers <Pyrogrammer>` that want to see Pyrogram in The next few steps serve as a quick start to see Pyrogram in action as fast as possible.
action as fast as possible. Let's go!
Get Pyrogram Real Fast Get Pyrogram Real Fast
---------------------- ----------------------
.. admonition :: Cloud Credits
:class: tip
If you need a cloud server to host your applications, try Hetzner Cloud. You can sign up with
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits.
1. Install Pyrogram with ``pip3 install -U pyrogram``. 1. Install Pyrogram with ``pip3 install -U pyrogram``.
2. Get your own Telegram API key from https://my.telegram.org/apps. 2. Get your own Telegram API key from https://my.telegram.org/apps.
3. Open your best text editor and paste the following: 3. Open the text editor of your choice and paste the following:
.. code-block:: python .. code-block:: python
import asyncio
from pyrogram import Client from pyrogram import Client
api_id = 12345 api_id = 12345
api_hash = "0123456789abcdef0123456789abcdef" api_hash = "0123456789abcdef0123456789abcdef"
with Client("my_account", api_id, api_hash) as app: async def main():
app.send_message("me", "Greetings from **Pyrogram**!") async with Client("my_account", api_id, api_hash) as app:
await app.send_message("me", "Greetings from **Pyrogram**!")
asyncio.run(main())
4. Replace *api_id* and *api_hash* values with your own. 4. Replace *api_id* and *api_hash* values with your own.
5. Save the file as ``pyro.py``. 5. Save the file as ``hello.py``.
6. Run the script with ``python3 pyro.py`` 6. Run the script with ``python3 hello.py``
7. Follow the instructions on your terminal to login. 7. Follow the instructions on your terminal to login.
8. Watch Pyrogram send a message to yourself. 8. Watch Pyrogram send a message to yourself.
9. Join our `community`_.
10. Say, "hi!".
Enjoy the API Enjoy the API
------------- -------------
That was just a quick overview that barely scratched the surface! That was just a quick overview. In the next few pages of the introduction, we'll take a much more in-depth look of what
In the next few pages of the introduction, we'll take a much more in-depth look of what we have just done above. we have just done above.
Feeling eager to continue? You can take a shortcut to :doc:`Calling Methods <../start/invoking>` and come back later to If you are feeling eager to continue you can take a shortcut to :doc:`Calling Methods <../start/invoking>` and come back
learn some more details. later to learn some more details.
.. _community: https://t.me/Pyrogram .. _community: https://t.me/Pyrogram

View File

@ -2,7 +2,7 @@ Project Setup
============= =============
We have just :doc:`installed Pyrogram <install>`. In this page we'll discuss what you need to do in order to set up a We have just :doc:`installed Pyrogram <install>`. In this page we'll discuss what you need to do in order to set up a
project with the library. Let's see how it's done. project with the framework.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -17,18 +17,13 @@ API Keys
The very first step requires you to obtain a valid Telegram API key (API id/hash pair): The very first step requires you to obtain a valid Telegram API key (API id/hash pair):
#. Visit https://my.telegram.org/apps and log in with your Telegram Account. #. Visit https://my.telegram.org/apps and log in with your Telegram Account.
#. Fill out the form to register a new Telegram application. #. Fill out the form with your details and register a new Telegram application.
#. Done! The API key consists of two parts: **api_id** and **api_hash**. #. Done. The API key consists of two parts: **api_id** and **api_hash**. Keep it secret.
.. important::
The API key is personal and must be kept secret.
.. note:: .. note::
The API key is unique for each user, but defines a token for a Telegram *application* you are going to build. This The API key defines a token for a Telegram *application* you are going to build.
means that you are able to authorize multiple users (and bots too) to access the Telegram database through the This means that you are able to authorize multiple users or bots with a single API key.
MTProto API by a single API key.
Configuration Configuration
------------- -------------
@ -36,9 +31,9 @@ Configuration
Having the API key from the previous step in handy, we can now begin to configure a Pyrogram project. Having the API key from the previous step in handy, we can now begin to configure a Pyrogram project.
There are two ways to do so, and you can choose what fits better for you: There are two ways to do so, and you can choose what fits better for you:
- First option (recommended): create a new ``config.ini`` file next to your main script, copy-paste the following and - First option: create a new ``config.ini`` file next to your main script, copy-paste the following and
replace the **api_id** and **api_hash** values with your own. This is the preferred method because allows you to replace the *api_id* and *api_hash* values with your own. This method allows you to keep your credentials out of
keep your credentials out of your code without having to deal with how to load them: your code without having to deal with how to load them.
.. code-block:: ini .. code-block:: ini
@ -47,8 +42,7 @@ There are two ways to do so, and you can choose what fits better for you:
api_hash = 0123456789abcdef0123456789abcdef api_hash = 0123456789abcdef0123456789abcdef
- Alternatively, you can pass your API key to Pyrogram by simply using the *api_id* and *api_hash* parameters of the - Alternatively, you can pass your API key to Pyrogram by simply using the *api_id* and *api_hash* parameters of the
Client class. This way you can have full control on how to store and load your credentials (e.g., you can load the Client class. This way you can have full control on how to store and load your credentials:
credentials from the environment variables and directly pass the values into Pyrogram):
.. code-block:: python .. code-block:: python

View File

@ -1,15 +0,0 @@
About the License
=================
.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png
:align: left
Pyrogram is free software and is currently licensed under the terms of the
`GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it
provided that modifications are described and licensed for free under LGPLv3+.
In other words: you can use and integrate Pyrogram into your own code --- either open source, under the same or a
different license, or even proprietary --- without being required to release the source code of your own applications.
However, any modifications to the library itself are required to be published for free under the same LGPLv3+ license.
.. _GNU Lesser General Public License v3 or later (LGPLv3+): https://github.com/pyrogram/pyrogram/blob/develop/COPYING.lesser

View File

@ -26,23 +26,20 @@ the :meth:`~pyrogram.Client.run` method:
app = Client("my_account") app = Client("my_account")
app.run() app.run()
This starts an interactive shell asking you to input your **phone number** (including your `Country Code`_) and the This starts an interactive shell asking you to input your **phone number**, including your `Country Code`_ (the plus
**phone code** you will receive in your devices that are already authorized or via SMS: ``+`` and minus ``-`` symbols can be omitted) and the **phone code** you will receive in your devices that are already
authorized or via SMS:
.. code-block:: text .. code-block:: text
Enter phone number: +39********** Enter phone number: +1-123-456-7890
Is "+39**********" correct? (y/n): y Is "+1-123-456-7890" correct? (y/n): y
Enter phone code: 32768 Enter phone code: 12345
Logged in successfully as Dan Logged in successfully
After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram to After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram to
execute API calls with your identity. This file will be loaded again when you restart your app, and as long as you execute API calls with your identity. This file is personal and will be loaded again when you restart your app, and as
keep the session alive, Pyrogram won't ask you again to enter your phone number. long as you keep the session alive, Pyrogram won't ask you again to enter your phone number.
.. important::
Your ``*.session`` file is personal and must be kept secret.
.. note:: .. note::

View File

@ -1,8 +1,8 @@
Error Handling Error Handling
============== ==============
Errors are inevitable when working with the API, and they can be correctly handled with ``try...except`` blocks in order Errors can be correctly handled with ``try...except`` blocks in order to control the behaviour of your application.
to control the behaviour of your application. Pyrogram errors all live inside the ``errors`` package: Pyrogram errors all live inside the ``errors`` package:
.. code-block:: python .. code-block:: python
@ -25,10 +25,10 @@ This error is raised every time a method call against Telegram's API was unsucce
from pyrogram.errors import RPCError from pyrogram.errors import RPCError
.. warning:: .. note::
It must be noted that catching this error is bad practice, especially when no feedback is given (i.e. by Avoid catching this error everywhere, especially when no feedback is given (i.e. by logging/printing the full error
logging/printing the full error traceback), because it makes it impossible to understand what went wrong. traceback), because it makes it impossible to understand what went wrong.
Error Categories Error Categories
---------------- ----------------
@ -84,9 +84,6 @@ whole category of errors and be sure to also handle these unknown errors.
In case a whole class of errors is unknown (that is, an error code that is unknown), Pyrogram will raise a special In case a whole class of errors is unknown (that is, an error code that is unknown), Pyrogram will raise a special
``520 UnknownError`` exception. ``520 UnknownError`` exception.
In both cases, Pyrogram will log them in the ``unknown_errors.txt`` file. Users are invited to report
these unknown errors in the `discussion group <https://t.me/pyrogram>`_.
Errors with Values Errors with Values
------------------ ------------------
@ -96,10 +93,12 @@ The value is stored in the ``x`` attribute of the exception object:
.. code-block:: python .. code-block:: python
import time import asyncio
from pyrogram.errors import FloodWait from pyrogram.errors import FloodWait
try: ...
... # Your code try:
except FloodWait as e: ... # Your code
time.sleep(e.x) # Wait "x" seconds before continuing except FloodWait as e:
await asyncio.sleep(e.x) # Wait "x" seconds before continuing
...

View File

@ -19,7 +19,7 @@ like send_audio(), send_document(), send_location(), etc...
with app: with app:
app.send_message( app.send_message(
"haskell", # Edit this "me", # Edit this
"This is a ReplyKeyboardMarkup example", "This is a ReplyKeyboardMarkup example",
reply_markup=ReplyKeyboardMarkup( reply_markup=ReplyKeyboardMarkup(
[ [
@ -33,7 +33,7 @@ like send_audio(), send_document(), send_location(), etc...
) )
app.send_message( app.send_message(
"haskell", # Edit this "me", # Edit this
"This is a InlineKeyboardMarkup example", "This is a InlineKeyboardMarkup example",
reply_markup=InlineKeyboardMarkup( reply_markup=InlineKeyboardMarkup(
[ [

View File

@ -15,7 +15,7 @@ It uses the ``@on_message`` decorator to register a ``MessageHandler`` and appli
@app.on_message(filters.text & filters.private) @app.on_message(filters.text & filters.private)
def echo(client, message): def echo(client, message):
message.reply_text(message.text) message.reply(message.text)
app.run() # Automatically start() and idle() app.run() # Automatically start() and idle()

View File

@ -13,9 +13,3 @@ This example demonstrates a basic API usage
with app: with app:
# Send a message, Markdown is enabled by default # Send a message, Markdown is enabled by default
app.send_message("me", "Hi there! I'm using **Pyrogram**") app.send_message("me", "Hi there! I'm using **Pyrogram**")
# Send a location
app.send_location("me", 51.500729, -0.124583)
# Send a sticker
app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")

View File

@ -26,7 +26,6 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
), ),
url="https://docs.pyrogram.org/intro/install", url="https://docs.pyrogram.org/intro/install",
description="How to install Pyrogram", description="How to install Pyrogram",
thumb_url="https://i.imgur.com/JyxrStE.png",
reply_markup=InlineKeyboardMarkup( reply_markup=InlineKeyboardMarkup(
[ [
[InlineKeyboardButton( [InlineKeyboardButton(
@ -43,7 +42,6 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
), ),
url="https://docs.pyrogram.org/start/invoking", url="https://docs.pyrogram.org/start/invoking",
description="How to use Pyrogram", description="How to use Pyrogram",
thumb_url="https://i.imgur.com/JyxrStE.png",
reply_markup=InlineKeyboardMarkup( reply_markup=InlineKeyboardMarkup(
[ [
[InlineKeyboardButton( [InlineKeyboardButton(

View File

@ -11,8 +11,8 @@ This example shows how to query an inline bot (as user).
app = Client("my_account") app = Client("my_account")
with app: with app:
# Get bot results for "Fuzz Universe" from the inline bot @vid # Get bot results for "hello" from the inline bot @vid
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe") bot_results = app.get_inline_bot_results("vid", "hello")
# Send the first result (bot_results.results[0]) to your own chat (Saved Messages) # Send the first result (bot_results.results[0]) to your own chat (Saved Messages)
app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id) app.send_inline_bot_result("me", bot_results.query_id, bot_results.results[0].id)

View File

@ -8,7 +8,7 @@ to make it only work for specific messages in a specific chat.
from pyrogram import Client, emoji, filters from pyrogram import Client, emoji, filters
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames TARGET = -100123456789 # Target chat. Can also be a list of multiple chat ids/usernames
MENTION = "[{}](tg://user?id={})" # User mention markup MENTION = "[{}](tg://user?id={})" # User mention markup
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!" # Welcome message MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!" # Welcome message

View File

@ -2,7 +2,7 @@ Calling Methods
=============== ===============
At this point, we have successfully :doc:`installed Pyrogram <../intro/install>` and :doc:`authorized <auth>` our At this point, we have successfully :doc:`installed Pyrogram <../intro/install>` and :doc:`authorized <auth>` our
account; we are now aiming towards the core of the library. It's time to start playing with the API! account; we are now aiming towards the core of the framework.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -22,60 +22,53 @@ Making API method calls with Pyrogram is very simple. Here's a basic example we
app = Client("my_account") app = Client("my_account")
with app: async def main():
app.send_message("me", "Hi!") async with app:
await app.send_message("me", "Hi!")
Basic step-by-step app.run(main())
^^^^^^^^^^^^^^^^^^
#. Let's begin by importing the Client class: Step-by-step
^^^^^^^^^^^^
#. Let's begin by importing the Client class.
.. code-block:: python .. code-block:: python
from pyrogram import Client from pyrogram import Client
#. Now instantiate a new Client object, "my_account" is a session name of your choice: #. Now instantiate a new Client object, "my_account" is a session name of your choice.
.. code-block:: python .. code-block:: python
app = Client("my_account") app = Client("my_account")
#. The ``with`` context manager is a shortcut for starting, executing and stopping the Client: #. Async methods can't be executed at the top level, because they must be inside an async context.
Here we define an async function and put our code inside. Also notice the ``await`` keyword in front of the method
call; this is required for all asynchronous methods.
.. code-block:: python .. code-block:: python
with app: async def main():
async with app:
await app.send_message("me", "Hi!")
#. Now, you can call any method you like: #. Finally, we tell Python to schedule our ``main()`` async function by using Pyrogram's :meth:`~pyrogram.Client.run`
method.
.. code-block:: python .. code-block:: python
app.send_message("me", "Hi!") app.run(main())
Context Manager Context Manager
--------------- ---------------
The ``with`` statement starts a context manager used as a shortcut to automatically call :meth:`~pyrogram.Client.start` The ``async with`` statement starts a context manager, which is used as a shortcut for starting, executing and stopping
and :meth:`~pyrogram.Client.stop`, which are methods required for Pyrogram to work properly. The context manager does the Client, asynchronously. It does so by automatically calling :meth:`~pyrogram.Client.start` and
also gracefully stop the client, even in case of unhandled exceptions in your code. :meth:`~pyrogram.Client.stop` in a more convenient way which also gracefully stops the client, even in case of
unhandled exceptions in your code.
This is how Pyrogram looks without the context manager: Below there's the same example as above, but without the use of the context manager:
.. code-block:: python
from pyrogram import Client
app = Client("my_account")
app.start()
app.send_message("me", "Hi!")
app.stop()
Asynchronous Calls
------------------
In case you want Pyrogram to run asynchronously (e.g.: if you are using third party libraries that require you to call
them with ``await``), use the asynchronous context manager:
.. code-block:: python .. code-block:: python
@ -84,36 +77,48 @@ them with ``await``), use the asynchronous context manager:
app = Client("my_account") app = Client("my_account")
async def main(): async def main():
async with app: await app.start()
await app.send_message("me", "Hi!") await app.send_message("me", "Hi!")
await app.stop()
app.run(main()) app.run(main())
Asynchronous step-by-step Using asyncio.run()
^^^^^^^^^^^^^^^^^^^^^^^^^ -------------------
#. Import the Client class and create an instance: Alternatively to the :meth:`~pyrogram.Client.run` method, you can use Python's ``asyncio.run()`` to execute the main
function, with one little caveat: the Client instance (and possibly other asyncio resources you are going to use) must
be instantiated inside the main function.
.. code-block:: python .. code-block:: python
from pyrogram import Client import asyncio
from pyrogram import Client
async def main():
app = Client("my_account") app = Client("my_account")
#. Async methods can't normally be executed at the top level, because they must be inside an async-defined function; async with app:
here we define one and put our code inside; the context manager is also being used differently in asyncio and await app.send_message("me", "Hi!")
method calls require the await keyword:
.. code-block:: python asyncio.run(main())
async def main(): Synchronous Calls
async with app: ------------------
await app.send_message("me", "Hi!")
#. Finally, we tell Python to schedule our ``main()`` async function, which in turn will execute Pyrogram's methods. Pyrogram is an asynchronous framework, but it also provides a convenience way for calling methods without the need
Using :meth:`~pyrogram.Client.run` this way is a friendly alternative for the much more verbose of async/await keywords and the extra boilerplate. In case you want Pyrogram to run synchronously, simply use the
``asyncio.get_event_loop().run_until_complete(main())``: synchronous context manager:
.. code-block:: python .. code-block:: python
app.run(main()) from pyrogram import Client
app = Client("my_account")
with app:
app.send_message("me", "Hi!")
As you can see, the non-async example becomes less cluttered. Use Pyrogram in this non-asynchronous way only when you
want to write something without the boilerplate or in case you want to combine Pyrogram with other libraries that are
not async.

View File

@ -1,8 +1,8 @@
Handling Updates Handling Updates
================ ================
Calling :doc:`API methods <invoking>` sequentially is cool, but how to react when, for example, a new message arrives? Calling :doc:`API methods <invoking>` sequentially is one way to use Pyrogram, but how to react when, for example, a
This page deals with updates and how to handle such events in Pyrogram. Let's have a look at how they work. new message arrives? This page deals with updates and how to handle such events in Pyrogram.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -14,10 +14,9 @@ This page deals with updates and how to handle such events in Pyrogram. Let's ha
Defining Updates Defining Updates
---------------- ----------------
First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram As hinted already, updates are simply events that happen in your Telegram account (incoming messages, new members join,
account (incoming messages, new members join, bot button presses, etc...), which are meant to notify you about a new bot button presses, etc.), which are meant to notify you about a new specific state that has changed. These updates are
specific state that has changed. These updates are handled by registering one or more callback functions in your app handled by registering one or more callback functions in your app using :doc:`Handlers <../api/handlers>`.
using :doc:`Handlers <../api/handlers>`.
Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback
function will be called back by the framework and its body executed. function will be called back by the framework and its body executed.
@ -40,50 +39,51 @@ The most elegant way to register a message handler is by using the :meth:`~pyrog
app = Client("my_account") app = Client("my_account")
@app.on_message() @app.on_message()
def my_handler(client, message): async def my_handler(client, message):
message.forward("me") await message.forward("me")
app.run() app.run()
The defined function ``my_handler``, which accepts the two arguments *(client, message)*, will be the function that gets The defined function ``my_handler``, which accepts the two arguments *(client, message)*, will be the function that gets
executed every time a new message arrives. executed every time a new message arrives.
Asynchronous handlers In the last line we see again the :meth:`~pyrogram.Client.run` method, this time used without any argument.
Its purpose here is simply to automatically :meth:`~pyrogram.Client.start`, keep the Client online so that it can listen
for updates and :meth:`~pyrogram.Client.stop` it once you hit ``CTRL+C``.
Synchronous handlers
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
You can also have asynchronous handlers; you only need to define the callback function using ``async def`` and call API You can also have synchronous handlers; you only need to define the callback function without using ``async def`` and
methods by placing ``await`` in front of them: call API methods by not placing ``await`` in front of them:
.. code-block:: python .. code-block:: python
@app.on_message() @app.on_message()
async def my_handler(client, message): def my_handler(client, message):
await message.forward("me") message.forward("me")
.. note:: .. note::
You can mix ``def`` and ``async def`` handlers as much as you need, Pyrogram will still work concurrently and You can mix ``def`` and ``async def`` handlers as much as you like, Pyrogram will still work concurrently and
efficiently regardless of what you choose. efficiently regardless of what you choose. However, it is recommended to use Pyrogram in its native, asynchronous
form at all times, unless you want to write something without the boilerplate or in case you want to combine
Pyrogram with other libraries that are not async.
Using add_handler() Using add_handler()
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback
function and registers it in your Client. It is useful in case you want to programmatically add handlers (or in case, function and registers it in your Client. It is useful in case you want to programmatically add handlers.
for some reason, you don't like to use decorators).
.. code-block:: python .. code-block:: python
from pyrogram import Client from pyrogram import Client
from pyrogram.handlers import MessageHandler from pyrogram.handlers import MessageHandler
async def my_function(client, message):
def my_function(client, message): await message.forward("me")
message.forward("me")
app = Client("my_account") app = Client("my_account")
@ -92,12 +92,12 @@ for some reason, you don't like to use decorators).
app.run() app.run()
The same about asynchronous handlers applies for :meth:`~pyrogram.Client.add_handler`: The same about synchronous handlers applies for :meth:`~pyrogram.Client.add_handler`:
.. code-block:: python .. code-block:: python
async def my_function(client, message): def my_function(client, message):
await message.forward("me") message.forward("me")
.. note:: .. note::

View File

@ -1,66 +1,62 @@
Support Pyrogram Support Pyrogram
================ ================
As a developer, you probably understand that "open source" doesn't mean "free work". If you wish to tip me for Pyrogram .. raw:: html
-- or any of my `other works`_ -- you can do so by the ways shown below. Your appreciation means a lot and helps
staying motivated!
--- `Dan`_ <script async defer src="https://buttons.github.io/buttons.js"></script>
<div style="float: right; margin-bottom: 10px">
<a class="github-button"
href="https://github.com/pyrogram/pyrogram/fork"
data-icon="octicon-repo-forked" data-size="large" data-show-count="true"
aria-label="Fork pyrogram/pyrogram on GitHub">Fork</a>
<a class="github-button"
href="https://github.com/pyrogram/pyrogram"
data-icon="octicon-star" data-size="large"
data-show-count="true" aria-label="Star pyrogram/pyrogram on GitHub">Star</a>
</div>
<br style="clear: both"/>
Pyrogram is a free and open source project.
If you enjoy Pyrogram and would like to show your appreciation, consider donating or becoming
a sponsor of the project. You can support Pyrogram via the ways shown below:
----- -----
Star GitHub Sponsor
---- --------------
Pyrogram is free and open source software, and thus powered by your love and support! If you like the project and have `Become a GitHub sponsor <https://github.com/sponsors/delivrance>`_.
found it to be useful, give Pyrogram a `Star on GitHub`_.
.. raw:: html .. raw:: html
<a class="github-button" href="https://github.com/pyrogram/pyrogram" data-size="large" data-show-count="true" aria-label="Star pyrogram/pyrogram on GitHub">Star</a> <a class="github-button"
<br><br> href="https://github.com/sponsors/delivrance"
data-icon="octicon-heart"
data-size="large"
aria-label="Sponsor @delivrance on GitHub">
Sponsor</a>
----- -----
Sponsor LiberaPay Patron
------- ----------------
You can become a GitHub sponsor: `Become a LiberaPay patron <https://liberapay.com/delivrance>`_.
.. raw:: html .. raw:: html
<iframe <script src="https://liberapay.com/delivrance/widgets/button.js"></script>
src="https://github.com/sponsors/delivrance/button"
title="Sponsor delivrance"
height="40" width="120"
style="border: 0px; padding-top: 5px; margin-top: -5px">
</iframe>
----- -----
Donate OpenCollective Backer
------ ---------------------
You can donate via PayPal using the button below: `Become an OpenCollective backer <https://opencollective.com/pyrogram>`_
.. raw:: html .. raw:: html
<form action="https://www.paypal.com/donate" method="post" target="_top"> <script src="https://opencollective.com/pyrogram/banner.js"></script>
<input type="hidden" name="hosted_button_id" value="WMKAVFE47XEML" />
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
<img alt="" border="0" src="https://www.paypal.com/en_IT/i/scr/pixel.gif" width="1" height="1" />
</form>
-----
Cloud Credits
-------------
If you need a cloud server to host your applications, try **Hetzner Cloud**. You can sign up with
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits and help support Pyrogram and
my `other projects`_.
.. _Star on GitHub: https://github.com/pyrogram/pyrogram
.. _other projects: https://github.com/delivrance
.. _other works: https://github.com/delivrance
.. _Dan: https://t.me/haskell

View File

@ -1,9 +1,8 @@
Advanced Usage Advanced Usage
============== ==============
Pyrogram's API, which consists of well documented convenience :doc:`methods <../api/methods/index>` and facade Pyrogram's API -- which consists of well documented :doc:`methods <../api/methods/index>` and
:doc:`types <../api/types/index>`, exists to provide a much easier interface to the undocumented and often confusing :doc:`types <../api/types/index>` -- exists to provide an easier interface to the more complex Telegram API.
Telegram API.
In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main "raw" In this section, you'll be shown the alternative way of communicating with Telegram using Pyrogram: the main "raw"
Telegram API with its functions and types. Telegram API with its functions and types.
@ -21,25 +20,18 @@ Telegram Raw API
If you can't find a high-level method for your needs or if you want complete, low-level access to the whole If you can't find a high-level method for your needs or if you want complete, low-level access to the whole
Telegram API, you have to use the raw :mod:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`. Telegram API, you have to use the raw :mod:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`.
As already hinted, raw functions and types can be really confusing, mainly because people don't realize soon enough they As already hinted, raw functions and types can be less convenient. This section will therefore explain some pitfalls to
accept *only* the right types and that all required parameters must be filled in. This section will therefore explain take into consideration when working with the raw API.
some pitfalls to take into consideration when working with the raw API.
.. hint:: .. tip::
Every available high-level methods in Pyrogram is built on top of these raw functions. Every available high-level method in Pyrogram is built on top of these raw functions.
Nothing stops you from using the raw functions only, but they are rather complex and
:doc:`plenty of them <../api/methods/index>` are already re-implemented by providing a much simpler and cleaner
interface which is very similar to the Bot API (yet much more powerful).
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
Invoking Functions Invoking Functions
^^^^^^^^^^^^^^^^^^ ------------------
Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which can be called in the usual simple way, Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which can be called in the usual simple way,
functions to be invoked from the raw Telegram API have a different way of usage and are more complex. functions to be invoked from the raw Telegram API have a different way of usage.
First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>` First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>`
live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist
@ -61,12 +53,12 @@ Here's some examples:
with Client("my_account") as app: with Client("my_account") as app:
app.send( app.send(
functions.account.UpdateProfile( functions.account.UpdateProfile(
first_name="Dan", last_name="Tès", first_name="First Name", last_name="Last Name",
about="Bio written from Pyrogram" about="New bio text"
) )
) )
- Disable links to your account when someone forwards your messages: - Set online/offline status:
.. code-block:: python .. code-block:: python
@ -74,14 +66,13 @@ Here's some examples:
from pyrogram.raw import functions, types from pyrogram.raw import functions, types
with Client("my_account") as app: with Client("my_account") as app:
app.send( # Set online status
functions.account.SetPrivacy( app.send(functions.account.UpdateStatus(offline=False))
key=types.PrivacyKeyForwards(),
rules=[types.InputPrivacyValueDisallowAll()]
)
)
- Invite users to your channel/supergroup: # Set offline status
app.send(functions.account.UpdateStatus(offline=True))
- Get chat info:
.. code-block:: python .. code-block:: python
@ -89,21 +80,18 @@ Here's some examples:
from pyrogram.raw import functions, types from pyrogram.raw import functions, types
with Client("my_account") as app: with Client("my_account") as app:
app.send( r = app.send(
functions.channels.InviteToChannel( functions.channels.GetFullChannel(
channel=app.resolve_peer(123456789), # ID or Username channel=app.resolve_peer("username")
users=[ # The users you want to invite
app.resolve_peer(23456789), # By ID
app.resolve_peer("username"), # By username
app.resolve_peer("+393281234567"), # By phone number
]
) )
) )
print(r)
Chat IDs Chat IDs
^^^^^^^^ --------
The way Telegram works makes it impossible to directly send a message to a user or a chat by using their IDs only. The way Telegram works makes it not possible to directly send a message to a user or a chat by using their IDs only.
Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed. Pyrogram allows Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed. Pyrogram allows
sending messages with IDs only thanks to cached access hashes. sending messages with IDs only thanks to cached access hashes.
@ -112,18 +100,17 @@ Whenever an InputPeer is needed you must pass one of these:
- :class:`~pyrogram.raw.types.InputPeerUser` - Users - :class:`~pyrogram.raw.types.InputPeerUser` - Users
- :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats - :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats
- :class:`~pyrogram.raw.types.InputPeerChannel` - Either Channels or Supergroups - :class:`~pyrogram.raw.types.InputPeerChannel` - Channels & Supergroups
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides But you don't necessarily have to manually instantiate each object because Pyrogram already provides
:meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer :meth:`~pyrogram.Client.resolve_peer` as a convenience utility method that returns the correct InputPeer
by accepting a peer ID only. by accepting a peer ID only.
Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and
all positive within their respective raw types. all positive within their respective raw types.
Things are different when working with Pyrogram's API because having them in the same space can theoretically lead to Things are different when working with Pyrogram's API because having them in the same space could lead to
collisions, and that's why Pyrogram (as well as the official Bot API) uses a slightly different representation for each collisions, and that's why Pyrogram uses a slightly different representation for each kind of ID.
kind of ID.
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart: For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:

View File

@ -1,50 +0,0 @@
Bots Interaction
================
Users can interact with other bots via plain text messages as well as inline queries.
.. contents:: Contents
:backlinks: none
:depth: 1
:local:
-----
Inline Bots
-----------
- If a bot accepts inline queries, you can call it by using
:meth:`~pyrogram.Client.get_inline_bot_results` to get the list of its inline results for a query:
.. code-block:: python
# Get bot results for "Fuzz Universe" from the inline bot @vid
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
.. figure:: https://i.imgur.com/IAqLs54.png
:width: 90%
:align: center
:figwidth: 60%
``get_inline_bot_results()`` is the equivalent action of writing ``@vid Fuzz Universe`` and getting the
results list.
- After you retrieved the bot results, you can use
:meth:`~pyrogram.Client.send_inline_bot_result` to send a chosen result to any chat:
.. code-block:: python
# Send the first result to your own chat
app.send_inline_bot_result(
"me",
bot_results.query_id,
bot_results.results[0].id
)
.. figure:: https://i.imgur.com/wwxr7B7.png
:width: 90%
:align: center
:figwidth: 60%
``send_inline_bot_result()`` is the equivalent action of choosing a result from the list and sending it
to a chat.

View File

@ -1,24 +1,12 @@
Session Settings Client Settings
================ ===============
As you may probably know, Telegram allows users (and bots) having more than one session (authorizations) registered You can control the way your client appears in the Active Sessions menu of an official client by changing some client
in the system at the same time. settings. By default you will see something like the following:
Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official - Device Model: ``CPython x.y.z``
app (or by invoking :class:`~pyrogram.api.functions.account.GetAuthorizations` with Pyrogram). They - Application: ``Pyrogram x.y.z``
store some useful information such as the client who's using them and from which country and IP address. - System Version: ``Linux x.y.z``
.. figure:: https://i.imgur.com/YaqtMLO.png
:width: 600
:align: center
**A Pyrogram session running on Linux, Python 3.7.**
That's how a session looks like on the Android app, showing the three main pieces of information.
- ``app_version``: **Pyrogram 0.13.0**
- ``device_model``: **CPython 3.7.2**
- ``system_version``: **Linux 4.15.0-23-generic**
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none

View File

@ -15,7 +15,7 @@ Introduction
------------ ------------
The idea behind using a configuration file is to help keeping your code free of private settings information such as The idea behind using a configuration file is to help keeping your code free of private settings information such as
the API Key and Proxy, without having you to even deal with how to load such settings. The configuration file, usually the API Key and Proxy, without having you to deal with how to load such settings. The configuration file, usually
referred as ``config.ini`` file, is automatically loaded from the root of your working directory; all you need to do is referred as ``config.ini`` file, is automatically loaded from the root of your working directory; all you need to do is
fill in the necessary parts. fill in the necessary parts.
@ -23,7 +23,7 @@ fill in the necessary parts.
The configuration file is optional, but recommended. If, for any reason, you prefer not to use it, there's always an The configuration file is optional, but recommended. If, for any reason, you prefer not to use it, there's always an
alternative way to configure Pyrogram via Client's parameters. Doing so, you can have full control on how to store alternative way to configure Pyrogram via Client's parameters. Doing so, you can have full control on how to store
and load your settings (e.g.: from environment variables). and load your settings.
Settings specified via Client's parameter have higher priority and will override any setting stored in the Settings specified via Client's parameter have higher priority and will override any setting stored in the
configuration file. configuration file.

View File

@ -87,7 +87,7 @@ Finally, the filter usage remains the same:
Filters with Arguments Filters with Arguments
---------------------- ----------------------
A much cooler filter would be one that accepts "pyrogram" or any other string as argument at usage time. A more flexible filter would be one that accepts "pyrogram" or any other string as argument at usage time.
A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method and the A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method and the
first argument of the callback function, which is a reference to the filter object itself holding the extra data passed first argument of the callback function, which is a reference to the filter object itself holding the extra data passed
via named arguments. via named arguments.

View File

@ -2,7 +2,7 @@ Debugging
========= =========
When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing
to actually worry about -- that's normal -- and luckily for you, Pyrogram provides some commodities to help you in this. to actually worry about since Pyrogram provides some commodities to help you in this.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -27,8 +27,8 @@ Consider the following code:
.. code-block:: python .. code-block:: python
dan = app.get_users("haskell") me = app.get_users("me")
print(dan) # User print(me) # User
This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a
:class:`~pyrogram.types.User` instance, in this case. The output on your terminal will be something similar to this: :class:`~pyrogram.types.User` instance, in this case. The output on your terminal will be something similar to this:
@ -36,9 +36,9 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
.. code-block:: json .. code-block:: json
{ {
"_": "pyrogram.User", "_": "User",
"id": 23122162, "id": 123456789,
"is_self": false, "is_self": true,
"is_contact": false, "is_contact": false,
"is_mutual_contact": false, "is_mutual_contact": false,
"is_deleted": false, "is_deleted": false,
@ -46,19 +46,13 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
"is_verified": false, "is_verified": false,
"is_restricted": false, "is_restricted": false,
"is_support": false, "is_support": false,
"is_scam": false, "first_name": "Pyrogram",
"first_name": "Dan",
"status": {
"_": "pyrogram.UserStatus",
"user_id": 23122162,
"recently": true
},
"username": "haskell",
"language_code": "en",
"photo": { "photo": {
"_": "pyrogram.ChatPhoto", "_": "ChatPhoto",
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC", "small_file_id": "AbCdE...EdCbA",
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg" "small_photo_unique_id": "VwXyZ...ZyXwV",
"big_file_id": "AbCdE...EdCbA",
"big_photo_unique_id": "VwXyZ...ZyXwV"
} }
} }
@ -69,37 +63,23 @@ Accessing Attributes
-------------------- --------------------
Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are
full-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``: fully-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``:
.. code-block:: python .. code-block:: python
dan_photo = dan.photo photo = me.photo
print(dan_photo) # ChatPhoto print(photo) # ChatPhoto
.. code-block:: json .. code-block:: json
{ {
"_": "pyrogram.ChatPhoto", "_": "ChatPhoto",
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC", "small_file_id": "AbCdE...EdCbA",
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg" "small_photo_unique_id": "VwXyZ...ZyXwV",
"big_file_id": "AbCdE...EdCbA",
"big_photo_unique_id": "VwXyZ...ZyXwV"
} }
However, the bracket notation ``[]`` is also supported, but its usage is discouraged:
.. warning::
Bracket notation in Python is not commonly used for getting/setting object attributes. While it works for Pyrogram
objects, it might not work for anything else and you should not rely on this.
.. code-block:: python
dan_photo_big = dan["photo"]["big_file_id"]
print(dan_photo_big) # str
.. code-block:: text
AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg
Checking an Object's Type Checking an Object's Type
------------------------- -------------------------
@ -111,8 +91,8 @@ error. The correct way to get the object type is by using the built-in function
.. code-block:: python .. code-block:: python
dan_status = dan.status status = me.status
print(type(dan_status)) print(type(status))
.. code-block:: text .. code-block:: text
@ -125,8 +105,8 @@ And to check if an object is an instance of a given class, you use the built-in
from pyrogram.types import UserStatus from pyrogram.types import UserStatus
dan_status = dan.status status = me.status
print(isinstance(dan_status, UserStatus)) print(isinstance(status, UserStatus))
.. code-block:: text .. code-block:: text

View File

@ -24,7 +24,6 @@ group. Dispatching groups hold one or more handlers and are processed sequential
For example, take these two handlers: For example, take these two handlers:
.. code-block:: python .. code-block:: python
:emphasize-lines: 1, 6
@app.on_message(filters.text | filters.sticker) @app.on_message(filters.text | filters.sticker)
def text_or_sticker(client, message): def text_or_sticker(client, message):

View File

@ -1,10 +1,10 @@
MTProto vs. Bot API MTProto vs. Bot API
=================== ===================
Pyrogram is a framework that acts as a fully-fledged Telegram client based on MTProto, and this very feature makes it Pyrogram is a framework written from the ground up that acts as a fully-fledged Telegram client based on the MTProto
already superior to, what is usually called, the official Bot API, in many respects. This page will therefore show you API. This means that Pyrogram is able to execute any official client and bot API action and more. This page will
why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's make it clear what therefore show you why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's
actually is the MTProto and the Bot API. make it clear what actually is the MTProto and the Bot API.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -19,10 +19,11 @@ What is the MTProto API?
`MTProto`_, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram `MTProto`_, took alone, is the name of the custom-made, open and encrypted communication protocol created by Telegram
itself --- it's the only protocol used to exchange information between a client and the actual Telegram servers. itself --- it's the only protocol used to exchange information between a client and the actual Telegram servers.
The MTProto **API** on the other hand, is what people, for convenience, call the main Telegram API as a whole. This API The MTProto API on the other hand, is what people for convenience call the main Telegram API in order to distinguish it
is able to authorize both users and bots and is built on top of the MTProto encryption protocol by means of from the Bot API. The main Telegram API is able to authorize both users and bots and is built on top of the MTProto
`binary data serialized`_ in a specific way, as described by the `TL language`_, and delivered using UDP, TCP or even encryption protocol by means of `binary data serialized`_ in a specific way, as described by the `TL language`_, and
HTTP as transport-layer protocol. delivered using UDP, TCP or even HTTP as transport-layer protocol. Clients that make use of Telegram's main API, such as
Pyrogram, implement all these details.
.. _MTProto: https://core.telegram.org/mtproto .. _MTProto: https://core.telegram.org/mtproto
.. _binary data serialized: https://core.telegram.org/mtproto/serialize .. _binary data serialized: https://core.telegram.org/mtproto/serialize
@ -31,12 +32,12 @@ HTTP as transport-layer protocol.
What is the Bot API? What is the Bot API?
-------------------- --------------------
The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main MTProto API. Bots are special The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main Telegram API. Bots are
accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the main special accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the
Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers main Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram
using MTProto. servers using MTProto.
.. figure:: https://i.imgur.com/WvwBoZo.png .. figure:: //_static/img/mtproto-vs-bot-api.png
:align: center :align: center
.. _Bot API: https://core.telegram.org/bots/api .. _Bot API: https://core.telegram.org/bots/api
@ -44,8 +45,8 @@ using MTProto.
Advantages of the MTProto API Advantages of the MTProto API
----------------------------- -----------------------------
Here is a list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of the official Here is a non-exhaustive list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of
HTTP Bot API. Using Pyrogram you can: the official HTTP Bot API. Using Pyrogram you can:
.. hlist:: .. hlist::
:columns: 1 :columns: 1
@ -69,7 +70,7 @@ HTTP Bot API. Using Pyrogram you can:
.. hlist:: .. hlist::
:columns: 1 :columns: 1
- :guilabel:`+` **Run multiple sessions at once, up to 10 per account (either bot or user)** - :guilabel:`+` **Run multiple sessions at once (for both user and bot identities)**
- :guilabel:`--` The Bot API intermediate server will terminate any other session in case you try to use the same - :guilabel:`--` The Bot API intermediate server will terminate any other session in case you try to use the same
bot again in a parallel connection. bot again in a parallel connection.

View File

@ -14,8 +14,8 @@ non-asynchronous contexts. For more detailed information, you can visit and lear
----- -----
Using ``apscheduler`` Using apscheduler
--------------------- -----------------
- Install with ``pip3 install apscheduler`` - Install with ``pip3 install apscheduler``
- Documentation: https://apscheduler.readthedocs.io - Documentation: https://apscheduler.readthedocs.io

View File

@ -24,8 +24,7 @@ If you want a nicely formatted, human readable JSON representation of any object
... ...
with app: with app:
r = app.get_chat("haskell") r = app.get_chat("me")
print(str(r)) print(str(r))
.. tip:: .. tip::
@ -48,7 +47,7 @@ as the process requires the package to be in scope.
... ...
with app: with app:
r = app.get_chat("haskell") r = app.get_chat("me")
print(repr(r)) print(repr(r))
print(eval(repr(r)) == r) # True print(eval(repr(r)) == r) # True

View File

@ -1,9 +1,9 @@
Smart Plugins Smart Plugins
============= =============
Pyrogram embeds a **smart**, lightweight yet powerful plugin system that is meant to further simplify the organization Pyrogram embeds a smart, lightweight yet powerful plugin system that is meant to further simplify the organization
of large projects and to provide a way for creating pluggable (modular) components that can be **easily shared** across of large projects and to provide a way for creating pluggable (modular) components that can be easily shared across
different Pyrogram applications with **minimal boilerplate code**. different Pyrogram applications with minimal boilerplate code.
.. tip:: .. tip::
@ -74,8 +74,8 @@ after importing your modules, like this:
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each
:class:`~pyrogram.handlers.MessageHandler` object because **you can't use those cool decorators** for your :class:`~pyrogram.handlers.MessageHandler` object because you can't use decorators for your functions.
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
Using Smart Plugins Using Smart Plugins
------------------- -------------------
@ -91,7 +91,6 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
This is the same example application as shown above, written using the Smart Plugin system. This is the same example application as shown above, written using the Smart Plugin system.
.. code-block:: text .. code-block:: text
:emphasize-lines: 2, 3
myproject/ myproject/
plugins/ plugins/
@ -102,7 +101,6 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
- ``plugins/handlers.py`` - ``plugins/handlers.py``
.. code-block:: python .. code-block:: python
:emphasize-lines: 4, 9
from pyrogram import Client, filters from pyrogram import Client, filters
@ -164,7 +162,7 @@ found inside each module will be, instead, loaded in the order they are defined,
.. note:: .. note::
Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping Remember: there can be at most one handler, within a group, dealing with a specific update. Plugins with overlapping
filters included a second time will not work. Learn more at :doc:`More on Updates <more-on-updates>`. filters included a second time will not work, by design. Learn more at :doc:`More on Updates <more-on-updates>`.
This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or This default loading behaviour is usually enough, but sometimes you want to have more control on what to include (or
exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude`` exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude``
@ -300,32 +298,30 @@ In the previous section we've explained how to specify which plugins to load and
starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime. starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime.
Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram
updates) will be modified in such a way that a special ``handler`` attribute pointing to a tuple of updates) will be modified in such a way that a special ``handlers`` attribute pointing to a list of tuples of
*(handler: Handler, group: int)* is attached to the function object itself. *(handler: Handler, group: int)* is attached to the function object itself.
- ``plugins/handlers.py`` - ``plugins/handlers.py``
.. code-block:: python .. code-block:: python
:emphasize-lines: 5, 6
@Client.on_message(filters.text & filters.private) @Client.on_message(filters.text & filters.private)
def echo(client, message): def echo(client, message):
message.reply(message.text) message.reply(message.text)
print(echo) print(echo)
print(echo.handler) print(echo.handlers)
- Printing ``echo`` will show something like ``<function echo at 0x10e3b6598>``. - Printing ``echo`` will show something like ``<function echo at 0x10e3b6598>``.
- Printing ``echo.handler`` will reveal the handler, that is, a tuple containing the actual handler and the group it - Printing ``echo.handlers`` will reveal the handlers, that is, a list of tuples containing the actual handlers and
was registered on ``(<MessageHandler object at 0x10e3abc50>, 0)``. the groups they were registered on ``[(<MessageHandler object at 0x10e3abc50>, 0)]``.
Unloading Unloading
^^^^^^^^^ ^^^^^^^^^
In order to unload a plugin, all you need to do is obtain a reference to it by importing the relevant module and call In order to unload a plugin, all you need to do is obtain a reference to it by importing the relevant module and call
:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* special attribute preceded by the :meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* instance:
star ``*`` operator as argument. Example:
- ``main.py`` - ``main.py``
@ -333,16 +329,19 @@ star ``*`` operator as argument. Example:
from plugins.handlers import echo from plugins.handlers import echo
... handlers = echo.handlers
app.remove_handler(*echo.handler) for h in handlers:
app.remove_handler(*h)
The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive
exactly what is needed. The same could have been achieved with: exactly what is needed. The same could have been achieved with:
.. code-block:: python .. code-block:: python
handler, group = echo.handler handlers = echo.handlers
handler, group = handlers[0]
app.remove_handler(handler, group) app.remove_handler(handler, group)
Loading Loading
@ -359,4 +358,7 @@ using :meth:`~pyrogram.Client.add_handler` instead. Example:
... ...
app.add_handler(*echo.handler) handlers = echo.handlers
for h in handlers:
app.add_handler(*h)

View File

@ -18,28 +18,18 @@ Persisting Sessions
In order to make a client reconnect successfully between restarts, that is, without having to start a new In order to make a client reconnect successfully between restarts, that is, without having to start a new
authorization process from scratch each time, Pyrogram needs to store the generated session data somewhere. authorization process from scratch each time, Pyrogram needs to store the generated session data somewhere.
Other useful data being stored is peers' cache. In short, peers are all those entities you can chat with, such as users
or bots, basic groups, but also channels and supergroups. Because of how Telegram works, a unique pair of **id** and
**access_hash** is needed to contact a peer. This, plus other useful info such as the peer type, is what is stored
inside a session storage.
So, if you ever wondered how is Pyrogram able to contact peers just by asking for their ids, it's because of this very
reason: the peer *id* is looked up in the internal database and the available *access_hash* is retrieved, which is then
used to correctly invoke API methods.
Different Storage Engines Different Storage Engines
------------------------- -------------------------
Let's now talk about how Pyrogram actually stores all the relevant data. Pyrogram offers two different types of storage Pyrogram offers two different types of storage engines: a **File Storage** and a **Memory Storage**.
engines: a **File Storage** and a **Memory Storage**. These engines are well integrated in the library and require a These engines are well integrated in the framework and require a minimal effort to set up. Here's how they work:
minimal effort to set up. Here's how they work:
File Storage File Storage
^^^^^^^^^^^^ ^^^^^^^^^^^^
This is the most common storage engine. It is implemented by using **SQLite**, which will store the session and peers This is the most common storage engine. It is implemented by using **SQLite**, which will store the session details.
details. The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve
peers whenever they are needed. data whenever they are needed.
To use this type of engine, simply pass any name of your choice to the ``session_name`` parameter of the To use this type of engine, simply pass any name of your choice to the ``session_name`` parameter of the
:obj:`~pyrogram.Client` constructor, as usual: :obj:`~pyrogram.Client` constructor, as usual:
@ -68,8 +58,8 @@ session name "**:memory:**" to the ``session_name`` parameter of the :obj:`~pyro
with Client(":memory:") as app: with Client(":memory:") as app:
print(app.get_me()) print(app.get_me())
This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop a This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop
client, the entire database is discarded and the session details used for logging in again will be lost forever. a client, the entire database is discarded and the session details used for logging in again will be lost forever.
Session Strings Session Strings
--------------- ---------------
@ -84,8 +74,8 @@ In case you want to use an in-memory storage, but also want to keep access to th
with Client(":memory:") as app: with Client(":memory:") as app:
print(app.export_session_string()) print(app.export_session_string())
...and save the resulting (quite long) string somewhere. You can use this string as session name the next time you want ...and save the resulting string. You can use this string as session name the next time you want to login
to login using the same session; the storage used will still be completely in-memory: using the same session; the storage used will still be in-memory:
.. code-block:: python .. code-block:: python
@ -96,11 +86,5 @@ to login using the same session; the storage used will still be completely in-me
with Client(session_string) as app: with Client(session_string) as app:
print(app.get_me()) print(app.get_me())
Session strings are useful when you want to run authorized Pyrogram clients on platforms like Session strings are useful when you want to run authorized Pyrogram clients on platforms where their ephemeral
`Heroku <https://www.heroku.com/>`_, where their ephemeral filesystems makes it much harder for a file-based storage filesystems makes it harder for a file-based storage engine to properly work as intended.
engine to properly work as intended.
But, why is the session string so long? Can't it be shorter? No, it can't. The session string already packs the bare
minimum data Pyrogram needs to successfully reconnect to an authorized session, and the 2048-bits auth key is the major
contributor to the overall length. Needless to say that this string, as well as any other session storage, represent
strictly personal data. Keep them safe.

View File

@ -15,8 +15,7 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
.. note:: .. note::
If this is the first time you login into test servers, you will be asked to register your account first. If this is the first time you login into test servers, you will be asked to register your account first.
Don't worry about your contacts and chats, they will be kept untouched inside the production environment; Accounts registered on test servers reside in a different, parallel instance of a Telegram server.
accounts authorized on test servers reside in a different, parallel instance of a Telegram database.
.. contents:: Contents .. contents:: Contents
:backlinks: none :backlinks: none
@ -28,19 +27,15 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
Test Mode in Official Apps Test Mode in Official Apps
-------------------------- --------------------------
You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop: You can also login yourself into test servers using official desktop apps, such as Telegram Web and Telegram Desktop:
- **Webogram**: Login here: https://web.telegram.org/?test=1 - **Telegram Web**: Login here: https://web.telegram.org/?test=1
- **TDesktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server". - **Telegram Desktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
Test Numbers Test Numbers
------------ ------------
Beside normal numbers, the test environment allows you to login with reserved test numbers. Beside normal numbers, the test environment allows you to login with reserved test numbers.
Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random
numbers. Users with such numbers always get ``XXXXX`` as the confirmation code (the DC number, repeated five times). numbers. Users with such numbers always get ``XXXXX`` or ``XXXXXX`` as the confirmation code (the DC number, repeated
five or six times).
.. important::
Do not store any important or private information in such test users' accounts; anyone can make use of the
simplified authorization mechanism and login at any time.

View File

@ -14,7 +14,7 @@ Text Formatting
:class: strike-italic :class: strike-italic
Pyrogram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled Pyrogram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled
texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a great texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a
variety of decorations that can also be nested in order to combine multiple styles together. variety of decorations that can also be nested in order to combine multiple styles together.
.. contents:: Contents .. contents:: Contents
@ -34,8 +34,9 @@ list of the basic styles currently supported by Pyrogram.
- *italic* - *italic*
- :strike:`strike` - :strike:`strike`
- :underline:`underline` - :underline:`underline`
- spoiler
- `text URL <https://pyrogram.org>`_ - `text URL <https://pyrogram.org>`_
- `user text mention <https://t.me/haskell>`_ - `user text mention <tg://user?id=123456789>`_
- ``inline fixed-width code`` - ``inline fixed-width code``
- .. code-block:: text - .. code-block:: text
@ -63,9 +64,11 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
~~strike~~ ~~strike~~
[text URL](https://docs.pyrogram.org/) ||spoiler||
[text user mention](tg://user?id=23122162) [text URL](https://pyrogram.org/)
[text user mention](tg://user?id=123456789)
`inline fixed-width code` `inline fixed-width code`
@ -80,13 +83,13 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
.. code-block:: python .. code-block:: python
app.send_message( app.send_message(
"haskell", "me",
( (
"**bold**, " "**bold**, "
"__italic__, " "__italic__, "
"--underline--, " "--underline--, "
"~~strike~~, " "~~strike~~, "
"[mention](tg://user?id=23122162), " "||spoiler||, "
"[URL](https://pyrogram.org), " "[URL](https://pyrogram.org), "
"`code`, " "`code`, "
"```" "```"
@ -113,9 +116,11 @@ The following tags are currently supported:
<s>strike</s>, <del>strike</del>, <strike>strike</strike> <s>strike</s>, <del>strike</del>, <strike>strike</strike>
<a href="http://docs.pyrogram.org/">text URL</a> <spoiler>spoiler</spoiler>
<a href="tg://user?id=23122162">inline mention</a> <a href="https://pyrogram.org/">text URL</a>
<a href="tg://user?id=123456789">inline mention</a>
<code>inline fixed-width code</code> <code>inline fixed-width code</code>
@ -130,13 +135,13 @@ The following tags are currently supported:
.. code-block:: python .. code-block:: python
app.send_message( app.send_message(
"haskell", "me",
( (
"<b>bold</b>, " "<b>bold</b>, "
"<i>italic</i>, " "<i>italic</i>, "
"<u>underline</u>, " "<u>underline</u>, "
"<s>strike</s>, " "<s>strike</s>, "
"<a href=\"tg://user?id=23122162\">mention</a>, " "<spoiler>spoiler</spoiler>, "
"<a href=\"https://pyrogram.org/\">URL</a>, " "<a href=\"https://pyrogram.org/\">URL</a>, "
"<code>code</code>\n\n" "<code>code</code>\n\n"
"<pre>" "<pre>"
@ -174,7 +179,7 @@ This means you can combine together both syntaxes in the same text:
.. code-block:: python .. code-block:: python
app.send_message("haskell", "**bold**, <i>italic</i>") app.send_message("me", "**bold**, <i>italic</i>")
Result: Result:
@ -185,8 +190,8 @@ If you don't like this behaviour you can always choose to only enable either Mar
.. code-block:: .. code-block::
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="markdown") app.send_message("me", "**bold**, <i>italic</i>", parse_mode="markdown")
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="html") app.send_message("me", "**bold**, <i>italic</i>", parse_mode="html")
Result: Result:
@ -199,7 +204,7 @@ as-is.
.. code-block:: python .. code-block:: python
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode=None) app.send_message("me", "**bold**, <i>italic</i>", parse_mode=None)
Result: Result:

View File

@ -1,11 +1,11 @@
Fast Crypto Fast Crypto
=========== ===========
Pyrogram's speed can be *dramatically* boosted up by TgCrypto_, a high-performance, easy-to-install Telegram Crypto Pyrogram's speed can be boosted up by TgCrypto_, a high-performance, easy-to-install cryptography library specifically
Library specifically written in C for Pyrogram [1]_ as a Python extension. written in C for Pyrogram as a Python extension.
TgCrypto is a replacement for the much slower PyAES and implements the crypto algorithms Telegram requires, namely TgCrypto is a replacement for a slower Python-only alternative and implements the cryptographic algorithms Telegram
**AES-IGE 256 bit** (used in MTProto v2.0) and **AES-CTR 256 bit** (used for CDN encrypted files). requires, namely: AES-256-IGE, AES-256-CTR and AES-256-CBC.
Installation Installation
------------ ------------
@ -14,32 +14,16 @@ Installation
$ pip3 install -U tgcrypto $ pip3 install -U tgcrypto
.. note:: Being a C extension for Python, TgCrypto is an optional but *highly recommended* dependency; when TgCrypto is .. note:: When TgCrypto is not detected in your system, Pyrogram will automatically fall back to a slower Python-only
not detected in your system, Pyrogram will automatically fall back to PyAES and will show you a warning. implementation and will show you a warning.
The reason about being an optional package is that TgCrypto requires some extra system tools in order to be compiled. The reason about being an optional package is that TgCrypto requires extra system tools in order to be compiled.
The errors you receive when trying to install TgCrypto are system dependent, but also descriptive enough to understand The errors you receive when trying to install TgCrypto are system dependent, but also descriptive enough to understand
what you should do next: what you should do next:
.. tabs:: - **Windows**: Install `Visual C++ 2015 Build Tools <https://www.microsoft.com/en-us/download/details.aspx?id=48159>`_.
- **macOS**: A pop-up will automatically ask you to install the command line developer tools.
- **Linux**: Install a proper C compiler (``gcc``, ``clang``) and the Python header files (``python3-dev``).
- **Termux**: Install ``clang`` package.
.. tab:: Windows .. _TgCrypto: https://github.com/pyrogram/tgcrypto
Install `Visual C++ 2015 Build Tools <https://www.microsoft.com/en-us/download/details.aspx?id=48159>`_.
.. tab:: macOS
A pop-up will automatically ask you to install the command line developer tools.
.. tab:: Linux
Install a proper C compiler (``gcc``, ``clang``) and the Python header files (``python3-dev``).
.. tab:: Termux
Install ``clang`` package.
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
.. [1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for
other Python projects too.

View File

@ -19,16 +19,15 @@ Single Filters
Let's start right away with a simple example: Let's start right away with a simple example:
- This example will show you how to **only** handle messages containing an :class:`~pyrogram.Audio` object and - This example will show you how to **only** handle messages containing a :class:`~pyrogram.types.Sticker` object and
ignore any other message. Filters are passed as the first argument of the decorator: ignore any other message. Filters are passed as the first argument of the decorator:
.. code-block:: python .. code-block:: python
:emphasize-lines: 4
from pyrogram import filters from pyrogram import filters
@app.on_message(filters.audio) @app.on_message(filters.sticker)
def my_handler(client, message): def my_handler(client, message):
print(message) print(message)
@ -36,7 +35,6 @@ Let's start right away with a simple example:
callback function itself: callback function itself:
.. code-block:: python .. code-block:: python
:emphasize-lines: 9
from pyrogram import filters from pyrogram import filters
from pyrogram.handlers import MessageHandler from pyrogram.handlers import MessageHandler
@ -46,12 +44,12 @@ Let's start right away with a simple example:
print(message) print(message)
app.add_handler(MessageHandler(my_handler, filters.audio)) app.add_handler(MessageHandler(my_handler, filters.sticker))
Combining Filters Combining Filters
----------------- -----------------
Filters can also be used in a more advanced way by inverting and combining more filters together using bitwise Filters can be used in a more advanced way by inverting and combining more filters together using bitwise
operators ``~``, ``&`` and ``|``: operators ``~``, ``&`` and ``|``:
- Use ``~`` to invert a filter (behaves like the ``not`` operator). - Use ``~`` to invert a filter (behaves like the ``not`` operator).

View File

@ -1,10 +1,19 @@
Voice Calls Voice Calls
=========== ===========
A working proof-of-concept of Telegram voice calls using Pyrogram can be found here: Both private voice calls and group voice calls are currently supported by third-party, external libraries that integrate
https://github.com/bakatrouble/pylibtgvoip. Thanks to `@bakatrouble <https://t.me/bakatrouble>`_. with Pyrogram.
.. note:: Libraries
---------
This page will be updated with more information once voice calls become eventually more usable and more integrated There are currently two main libraries (with very similar names) you can use:
in Pyrogram itself.
1. https://github.com/pytgcalls/pytgcalls
2. https://github.com/MarshalX/tgcalls
Older implementations
---------------------
An older implementation of Telegram voice calls can be found at https://github.com/bakatrouble/pylibtgvoip (currently
outdated due to the deprecation of the Telegram VoIP library used underneath).

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -16,9 +16,9 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>. # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
__version__ = "1.1.13" __version__ = "1.4.0"
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)" __license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
__copyright__ = "Copyright (C) 2017-2021 Dan <https://github.com/delivrance>" __copyright__ = "Copyright (C) 2017-present Dan <https://github.com/delivrance>"
from concurrent.futures.thread import ThreadPoolExecutor from concurrent.futures.thread import ThreadPoolExecutor
@ -35,14 +35,14 @@ class ContinuePropagation(StopAsyncIteration):
pass pass
import asyncio from asyncio import get_event_loop
from . import raw, types, filters, handlers, emoji from . import raw, types, filters, handlers, emoji
from .client import Client from .client import Client
from .sync import idle from .sync import idle
# Save the main thread loop for future references # Save the main thread loop for future references
main_event_loop = asyncio.get_event_loop() main_event_loop = get_event_loop()
CRYPTO_EXECUTOR_SIZE_THRESHOLD = 512 CRYPTO_EXECUTOR_SIZE_THRESHOLD = 512

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #
@ -32,9 +32,11 @@ from pathlib import Path
from typing import Union, List, Optional from typing import Union, List, Optional
import pyrogram import pyrogram
from pyrogram import __version__, __license__
from pyrogram import raw from pyrogram import raw
from pyrogram import utils from pyrogram import utils
from pyrogram.crypto import aes from pyrogram.crypto import aes
from pyrogram.errors import CDNFileHashMismatch
from pyrogram.errors import ( from pyrogram.errors import (
SessionPasswordNeeded, SessionPasswordNeeded,
VolumeLocNotFound, ChannelPrivate, VolumeLocNotFound, ChannelPrivate,
@ -105,6 +107,11 @@ class Client(Methods, Scaffold):
Only applicable for new sessions and will be ignored in case previously created sessions are loaded. Only applicable for new sessions and will be ignored in case previously created sessions are loaded.
Defaults to False. Defaults to False.
mode (``int``, *optional*):
The connection mode to use.
Defaults to Obfuscated TCPAbridged (3),
The list of modes are available at `connection/connection.py`
bot_token (``str``, *optional*): bot_token (``str``, *optional*):
Pass your Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11" Pass your Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
Only applicable for new sessions. Only applicable for new sessions.
@ -186,6 +193,7 @@ class Client(Methods, Scaffold):
ipv6: bool = False, ipv6: bool = False,
proxy: dict = None, proxy: dict = None,
test_mode: bool = False, test_mode: bool = False,
mode: int = 3,
bot_token: str = None, bot_token: str = None,
phone_number: str = None, phone_number: str = None,
phone_code: str = None, phone_code: str = None,
@ -214,6 +222,7 @@ class Client(Methods, Scaffold):
# TODO: Make code consistent, use underscore for private/protected fields # TODO: Make code consistent, use underscore for private/protected fields
self._proxy = proxy self._proxy = proxy
self.test_mode = test_mode self.test_mode = test_mode
self.mode = mode
self.bot_token = bot_token self.bot_token = bot_token
self.phone_number = phone_number self.phone_number = phone_number
self.phone_code = phone_code self.phone_code = phone_code
@ -280,6 +289,10 @@ class Client(Methods, Scaffold):
if self.bot_token: if self.bot_token:
return await self.sign_in_bot(self.bot_token) return await self.sign_in_bot(self.bot_token)
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")
while True: while True:
try: try:
if not self.phone_number: if not self.phone_number:
@ -397,6 +410,9 @@ class Client(Methods, Scaffold):
@parse_mode.setter @parse_mode.setter
def parse_mode(self, parse_mode: Optional[str] = "combined"): def parse_mode(self, parse_mode: Optional[str] = "combined"):
if isinstance(parse_mode, str):
parse_mode = parse_mode.lower()
if parse_mode not in self.PARSE_MODES: if parse_mode not in self.PARSE_MODES:
raise ValueError('parse_mode must be one of {} or None. Not "{}"'.format( raise ValueError('parse_mode must be one of {} or None. Not "{}"'.format(
", ".join(f'"{m}"' for m in self.PARSE_MODES[:-1]), ", ".join(f'"{m}"' for m in self.PARSE_MODES[:-1]),
@ -424,7 +440,6 @@ class Client(Methods, Scaffold):
Example: Example:
.. code-block:: python .. code-block:: python
:emphasize-lines: 10,14,18,22
from pyrogram import Client from pyrogram import Client
@ -432,23 +447,23 @@ class Client(Methods, Scaffold):
with app: with app:
# Default combined mode: Markdown + HTML # Default combined mode: Markdown + HTML
app.send_message("haskell", "1. **markdown** and <i>html</i>") app.send_message("me", "1. **markdown** and <i>html</i>")
# Force Markdown-only, HTML is disabled # Force Markdown-only, HTML is disabled
app.set_parse_mode("markdown") app.set_parse_mode("markdown")
app.send_message("haskell", "2. **markdown** and <i>html</i>") app.send_message("me", "2. **markdown** and <i>html</i>")
# Force HTML-only, Markdown is disabled # Force HTML-only, Markdown is disabled
app.set_parse_mode("html") app.set_parse_mode("html")
app.send_message("haskell", "3. **markdown** and <i>html</i>") app.send_message("me", "3. **markdown** and <i>html</i>")
# Disable the parser completely # Disable the parser completely
app.set_parse_mode(None) app.set_parse_mode(None)
app.send_message("haskell", "4. **markdown** and <i>html</i>") app.send_message("me", "4. **markdown** and <i>html</i>")
# Bring back the default combined mode # Bring back the default combined mode
app.set_parse_mode() app.set_parse_mode()
app.send_message("haskell", "5. **markdown** and <i>html</i>") app.send_message("me", "5. **markdown** and <i>html</i>")
""" """
self.parse_mode = parse_mode self.parse_mode = parse_mode
@ -874,8 +889,7 @@ class Client(Methods, Scaffold):
location = raw.types.InputPeerPhotoFileLocation( location = raw.types.InputPeerPhotoFileLocation(
peer=peer, peer=peer,
volume_id=file_id.volume_id, photo_id=file_id.media_id,
local_id=file_id.local_id,
big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG big=file_id.thumbnail_source == ThumbnailSource.CHAT_PHOTO_BIG
) )
elif file_type == FileType.PHOTO: elif file_type == FileType.PHOTO:
@ -914,9 +928,6 @@ class Client(Methods, Scaffold):
while True: while True:
chunk = r.bytes chunk = r.bytes
if not chunk:
break
f.write(chunk) f.write(chunk)
offset += limit offset += limit
@ -936,6 +947,9 @@ class Client(Methods, Scaffold):
else: else:
await self.loop.run_in_executor(self.executor, func) await self.loop.run_in_executor(self.executor, func)
if len(chunk) < limit:
break
r = await session.send( r = await session.send(
raw.functions.upload.GetFile( raw.functions.upload.GetFile(
location=location, location=location,
@ -1007,7 +1021,7 @@ class Client(Methods, Scaffold):
# https://core.telegram.org/cdn#verifying-files # https://core.telegram.org/cdn#verifying-files
for i, h in enumerate(hashes): for i, h in enumerate(hashes):
cdn_chunk = decrypted_chunk[h.limit * i: h.limit * (i + 1)] cdn_chunk = decrypted_chunk[h.limit * i: h.limit * (i + 1)]
assert h.hash == sha256(cdn_chunk).digest(), f"Invalid CDN hash part {i}" CDNFileHashMismatch.check(h.hash == sha256(cdn_chunk).digest())
f.write(decrypted_chunk) f.write(decrypted_chunk)

View File

@ -1,5 +1,5 @@
# Pyrogram - Telegram MTProto API Client Library for Python # Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance> # Copyright (C) 2017-present Dan <https://github.com/delivrance>
# #
# This file is part of Pyrogram. # This file is part of Pyrogram.
# #

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