Compare commits
234 Commits
notificati
...
mtpager
Author | SHA1 | Date | |
---|---|---|---|
|
b472597fbc | ||
|
855e69e3f8 | ||
|
05bfaa3d87 | ||
|
b676297ca9 | ||
|
b9424c7455 | ||
|
aaaa97c77a | ||
|
51cf103c15 | ||
|
afad3a7704 | ||
|
084db0cea3 | ||
|
a8cc77d903 | ||
|
3a911956b0 | ||
|
6f9e77bc2c | ||
|
2eca3438be | ||
|
c7888437e8 | ||
|
333d22afca | ||
|
f1298dfdc6 | ||
|
3e79d7dfce | ||
|
b1250e6575 | ||
|
149685f9d3 | ||
|
244606eed6 | ||
|
4af9e30cfd | ||
|
4544782b13 | ||
|
7d444381c7 | ||
|
000e16d1cc | ||
|
23b02087c2 | ||
|
1162e89f26 | ||
910c6cacb0 | |||
c1bd82ffdd | |||
3812c5c584 | |||
e318562b16 | |||
3c65090c4e | |||
e413f5682b | |||
12a49e1d31 | |||
053ec738e7 | |||
0fa3115d32 | |||
0dfed0b2fa | |||
2a7b83d668 | |||
6c078c38d0 | |||
7178b4b1db | |||
cafc997df1 | |||
04b783281e | |||
|
86c81bfff9 | ||
|
e67fd6efbb | ||
|
a6299f8401 | ||
|
6d7f409a88 | ||
|
4cdd72657e | ||
|
db9489b318 | ||
|
527ec23c20 | ||
|
52262bcf18 | ||
|
08ec6528e7 | ||
00454e2f7b | |||
|
14ae9d314b | ||
|
5ec9743a1a | ||
|
10c512d39c | ||
|
de9705f126 | ||
0436826f27 | |||
a2ccdb2378 | |||
ec9e92d6d8 | |||
|
c7da4a8495 | ||
|
fbdc6613f2 | ||
|
7fb35fbad5 | ||
|
1d7c57e669 | ||
|
2ca38d0ee9 | ||
|
cb6cef37e6 | ||
|
44228f2472 | ||
|
626a1bd938 | ||
|
8c8288412f | ||
|
80d0966691 | ||
|
ac3d2b8d7a | ||
|
b283bce262 | ||
|
0a29890da4 | ||
|
ebaf1a23fb | ||
|
f6625192d0 | ||
|
fb64e143b6 | ||
|
2799011c07 | ||
|
1fa637553d | ||
|
b0a9d28bda | ||
|
46d3d8aaf6 | ||
|
00c91120d8 | ||
|
f7b9137a68 | ||
|
42c690757d | ||
|
9c67084170 | ||
|
a3fab6af4b | ||
|
cc4a850134 | ||
|
9a2bc25bc7 | ||
|
e8076d1b8a | ||
|
a138b46668 | ||
|
2024b3c120 | ||
|
a909dc12e7 | ||
|
d103ae48fe | ||
|
8f8c85e8f3 | ||
|
7d917f43e5 | ||
|
29b4615848 | ||
|
56e7e11037 | ||
|
419ecb1af5 | ||
|
4bb57a4da3 | ||
fe764e0e2b | |||
|
ef6125b57a | ||
|
a917596cb1 | ||
|
9b28a120e2 | ||
|
6fb427fb9a | ||
|
ea3281b5f6 | ||
|
8aa358129c | ||
|
a720726479 | ||
|
ed9c7e4694 | ||
|
c2a29c8c30 | ||
|
2a1af2b8e9 | ||
|
bc420da0e2 | ||
|
cd027b8c1c | ||
|
cebecb99c0 | ||
|
bf9e186414 | ||
|
a73f990667 | ||
|
8a08dcb92a | ||
|
439935b401 | ||
|
e2cce1b1e6 | ||
|
8d03850d03 | ||
|
85ee6c3785 | ||
|
34b6002c68 | ||
|
f7db103071 | ||
|
2e964b3fa9 | ||
|
804d00fa0f | ||
|
ca29ea1db4 | ||
|
a460d12a82 | ||
|
aba5304fd6 | ||
|
e27f30dade | ||
|
2265d282f5 | ||
|
0f204e1d8c | ||
|
6efd01937f | ||
|
428cbf56a6 | ||
|
362441a74a | ||
|
09c8289259 | ||
|
02a3969101 | ||
|
fdbab8cc87 | ||
|
acd92b100b | ||
|
c3953c18ca | ||
|
eec7ec3947 | ||
|
320696b4b2 | ||
|
bacc7c004b | ||
|
e68da74e89 | ||
|
aea1ffc46f | ||
|
9e9a944e86 | ||
|
99e152a67c | ||
|
4d933b80f9 | ||
|
6745c9d815 | ||
|
3d6ec570f3 | ||
|
8845b976ab | ||
|
685b9328f8 | ||
|
a65f8e2655 | ||
|
3dde55db39 | ||
|
ab63abe6fd | ||
|
f7713d135e | ||
|
c90e5a419c | ||
|
91e0a08945 | ||
|
0ca8ab29ab | ||
|
523ed3e7cb | ||
|
c9d0c5d75a | ||
|
6cb3e92838 | ||
|
0d12d8c1bb | ||
|
317685cf54 | ||
|
7c9f1cb8ef | ||
|
be83f8e25e | ||
|
aef0cce8d9 | ||
|
dd32854db4 | ||
|
29701a3a55 | ||
|
a4bb2a3fdf | ||
|
e2ef053949 | ||
|
5fdb361487 | ||
|
a56b1a3287 | ||
|
1704420697 | ||
|
df4419da8f | ||
|
b4bdab1047 | ||
|
0c46b653ec | ||
|
fd04648ea0 | ||
|
56e79c10f8 | ||
|
3be981ada1 | ||
|
293e852afd | ||
|
ed3576e8e6 | ||
|
ecd83c594c | ||
|
429b871171 | ||
|
934091d8ea | ||
|
636ff776d6 | ||
|
4fc4501445 | ||
|
1d940b96a3 | ||
|
97bd544333 | ||
|
35df2cc1f3 | ||
|
6cf9dd839e | ||
|
8515ef1746 | ||
|
e9e6c30d05 | ||
|
a3e46b4957 | ||
|
826f815ca3 | ||
|
928c8acd01 | ||
|
2de1606e3d | ||
|
89860a4b4c | ||
|
fa7673e51c | ||
|
710cfa071d | ||
|
5e77387919 | ||
|
e4f99df07c | ||
|
c13230cb81 | ||
|
2eef1d5fcf | ||
|
54350dc943 | ||
|
3c81006b40 | ||
|
c5624c639b | ||
|
add492c1be | ||
|
4f585c156c | ||
|
0c814e9e5e | ||
|
416c351f6b | ||
|
9a8bf9d1dc | ||
|
70ae12eb77 | ||
|
b6f97ee924 | ||
|
0b0bec9e27 | ||
|
818aebcc7c | ||
|
aa6b226e64 | ||
|
50d1f30ac1 | ||
|
701c1cde07 | ||
|
77ab7bffe7 | ||
|
a86656aefc | ||
|
97bb996a53 | ||
|
da697aec13 | ||
|
ec1cd15094 | ||
|
808346f15b | ||
|
eed331b1b1 | ||
|
70efffa896 | ||
|
19fab3cc78 | ||
|
1d55eaa1ba | ||
|
a47e079fec | ||
|
b1dc0315a1 | ||
|
e01ac7a3d3 | ||
|
73edcb5e69 | ||
|
f13651af1d | ||
|
66b1229664 | ||
|
b39a6cd2d4 | ||
|
c971616808 | ||
|
3445507a9a | ||
|
2d785acdc7 |
76
.github/CODE_OF_CONDUCT.md
vendored
76
.github/CODE_OF_CONDUCT.md
vendored
@ -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
|
|
1
.github/CONTRIBUTING.md
vendored
1
.github/CONTRIBUTING.md
vendored
@ -1 +0,0 @@
|
|||||||
# How to Contribute
|
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1,2 +0,0 @@
|
|||||||
github: delivrance
|
|
||||||
custom: https://docs.pyrogram.org/support-pyrogram
|
|
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
20
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -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
51
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal 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
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal 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.
|
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -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.
|
|
20
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal 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
|
15
.github/ISSUE_TEMPLATE/question.md
vendored
15
.github/ISSUE_TEMPLATE/question.md
vendored
@ -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
68
.github/workflows/codeql-analysis.yml
vendored
Normal 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
|
8
.github/workflows/python.yml
vendored
8
.github/workflows/python.yml
vendored
@ -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
|
||||||
|
@ -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
2
NOTICE
@ -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.
|
||||||
|
|
||||||
|
60
README.md
60
README.md
@ -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)
|
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
@ -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
@ -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()
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
21
compiler/docs/template/bound-methods.rst
vendored
21
compiler/docs/template/bound-methods.rst
vendored
@ -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}
|
||||||
|
|
||||||
|
7
compiler/docs/template/methods.rst
vendored
7
compiler/docs/template/methods.rst
vendored
@ -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
|
||||||
|
12
compiler/docs/template/types.rst
vendored
12
compiler/docs/template/types.rst
vendored
@ -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
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
@ -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))
|
||||||
|
|
||||||
|
@ -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.
|
||||||
#
|
#
|
||||||
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
|
3
compiler/errors/source/503_SERVICE_UNAVAILABLE.tsv
Normal file
3
compiler/errors/source/503_SERVICE_UNAVAILABLE.tsv
Normal 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,3 +1,5 @@
|
|||||||
-r requirements.txt
|
-r requirements.txt
|
||||||
|
|
||||||
pytest
|
pytest
|
||||||
|
pytest-asyncio
|
||||||
|
pytest-cov
|
@ -1,8 +0,0 @@
|
|||||||
# Pyrogram Docs
|
|
||||||
|
|
||||||
- Install requirements.
|
|
||||||
- Install `pandoc` and `latexmk`.
|
|
||||||
- HTML: `make html`
|
|
||||||
- PDF: `make latexpdf`
|
|
||||||
|
|
||||||
TODO: Explain better
|
|
@ -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
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
User-agent: *
|
|
||||||
|
|
||||||
Allow: /
|
|
||||||
|
|
||||||
Disallow: /old*
|
|
||||||
|
|
||||||
Sitemap: https://docs.pyrogram.org/sitemap.xml
|
|
@ -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))
|
|
@ -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 |
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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",
|
||||||
|
@ -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
|
|
11
docs/source/faq/client-started-but-nothing-happens.rst
Normal file
11
docs/source/faq/client-started-but-nothing-happens.rst
Normal 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)
|
@ -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.
|
23
docs/source/faq/how-to-avoid-flood-waits.rst
Normal file
23
docs/source/faq/how-to-avoid-flood-waits.rst
Normal 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>`.
|
9
docs/source/faq/how-to-use-webhooks.rst
Normal file
9
docs/source/faq/how-to-use-webhooks.rst
Normal 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
47
docs/source/faq/index.rst
Normal 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
|
@ -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.
|
14
docs/source/faq/peer-id-invalid-error.rst
Normal file
14
docs/source/faq/peer-id-invalid-error.rst
Normal 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.
|
@ -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.
|
@ -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")
|
@ -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.
|
16
docs/source/faq/the-account-has-been-limited-deactivated.rst
Normal file
16
docs/source/faq/the-account-has-been-limited-deactivated.rst
Normal 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
|
||||||
|
|
7
docs/source/faq/unicodeencodeerror-codec-cant-encode.rst
Normal file
7
docs/source/faq/unicodeencodeerror-codec-cant-encode.rst
Normal 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.
|
@ -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.
|
@ -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.
|
||||||
|
|
@ -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.
|
@ -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
|
12
docs/source/faq/why-is-the-api-key-needed-for-bots.rst
Normal file
12
docs/source/faq/why-is-the-api-key-needed-for-bots.rst
Normal 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.
|
@ -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.
|
@ -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
|
@ -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
|
|
@ -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::
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
|
@ -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::
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
...
|
@ -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(
|
||||||
[
|
[
|
||||||
|
@ -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()
|
@ -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")
|
|
@ -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(
|
||||||
|
@ -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)
|
@ -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
|
||||||
|
|
||||||
|
@ -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.
|
@ -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::
|
||||||
|
|
||||||
|
@ -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
|
|
@ -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:
|
||||||
|
|
||||||
|
@ -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.
|
|
@ -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
|
@ -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.
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
@ -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.
|
|
||||||
|
@ -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.
|
|
@ -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:
|
||||||
|
|
||||||
|
@ -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.
|
|
@ -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).
|
||||||
|
@ -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).
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user