Merge branch 'develop' into session_storage
# Conflicts: # pyrogram/client/client.py # pyrogram/client/ext/base_client.py # pyrogram/client/ext/syncer.py # pyrogram/client/methods/contacts/get_contacts.py
This commit is contained in:
commit
142d5ab335
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
76
.github/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
# 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
Normal file
1
.github/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1 @@
|
||||
# How to Contribute
|
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
github: delivrance
|
||||
custom: https://docs.pyrogram.org/support-pyrogram
|
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
21
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a bug report affecting the library
|
||||
labels: "bug"
|
||||
---
|
||||
|
||||
<!-- WARNING: Ignoring this template could lead to the issue being closed as incomplete -->
|
||||
|
||||
## 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/develop.zip` and reproduced the issue using the latest development version.
|
||||
|
||||
## Description
|
||||
A clear and concise description of the problem.
|
||||
|
||||
## Steps to Reproduce
|
||||
[A minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
|
||||
## Traceback
|
||||
The full traceback (if applicable).
|
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest ideas, new features or enhancements
|
||||
labels: "enhancement"
|
||||
---
|
||||
|
||||
<!-- WARNING: Ignoring this template could lead to the issue being closed as incomplete -->
|
||||
|
||||
## 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.
|
15
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
15
.github/ISSUE_TEMPLATE/question.md
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
name: Ask Question
|
||||
about: Ask a Pyrogram related question
|
||||
title: For Q&A purposes, please read this template body
|
||||
labels: "question"
|
||||
---
|
||||
|
||||
<!-- WARNING: Ignoring this template could lead to the issue being closed as incomplete -->
|
||||
|
||||
# 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.
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,7 +3,7 @@
|
||||
config.ini
|
||||
|
||||
# Pyrogram generated code
|
||||
pyrogram/api/errors/exceptions/
|
||||
pyrogram/errors/exceptions/
|
||||
pyrogram/api/functions/
|
||||
pyrogram/api/types/
|
||||
pyrogram/api/all.py
|
||||
|
@ -1,6 +1,7 @@
|
||||
## Include
|
||||
include COPYING COPYING.lesser NOTICE requirements.txt
|
||||
include README.md COPYING COPYING.lesser NOTICE requirements.txt
|
||||
recursive-include compiler *.py *.tl *.tsv *.txt
|
||||
recursive-include pyrogram mime.types
|
||||
|
||||
## Exclude
|
||||
prune pyrogram/api/errors/exceptions
|
||||
|
85
README.md
Normal file
85
README.md
Normal file
@ -0,0 +1,85 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
<img src="https://i.imgur.com/BOgY9ai.png" alt="Pyrogram">
|
||||
</a>
|
||||
<br>
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
<br>
|
||||
<a href="https://docs.pyrogram.org">
|
||||
Documentation
|
||||
</a>
|
||||
•
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Releases
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/Pyrogram">
|
||||
Community
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Pyrogram
|
||||
|
||||
``` python
|
||||
from pyrogram import Client, Filters
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def hello(client, message):
|
||||
message.reply("Hello {}".format(message.from_user.first_name))
|
||||
|
||||
|
||||
app.run()
|
||||
```
|
||||
|
||||
**Pyrogram** is an elegant, easy-to-use [Telegram](https://telegram.org/) client library and framework written from the
|
||||
ground up in Python and C. It enables you to easily create custom apps for both user and bot identities (bot API alternative) via the [MTProto API](https://core.telegram.org/api#telegram-api).
|
||||
|
||||
> [Pyrogram in fully-asynchronous mode is also available »](https://github.com/pyrogram/pyrogram/issues/181)
|
||||
>
|
||||
> [Working PoC of Telegram voice calls using Pyrogram »](https://github.com/bakatrouble/pytgvoip)
|
||||
|
||||
### Features
|
||||
|
||||
- **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](https://github.com/pyrogram/tgcrypto), a high-performance library
|
||||
written in pure C.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **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 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.4 or higher.
|
||||
- A [Telegram API key](https://docs.pyrogram.org/intro/setup#api-keys).
|
||||
|
||||
### Installing
|
||||
|
||||
``` bash
|
||||
pip3 install pyrogram
|
||||
```
|
||||
|
||||
### Resources
|
||||
|
||||
- The Docs contain lots of resources to help you getting started with Pyrogram: https://docs.pyrogram.org.
|
||||
- Reading [Examples in this repository](https://github.com/pyrogram/pyrogram/tree/master/examples) is also a good way
|
||||
for learning how Pyrogram works.
|
||||
- Seeking extra help? Don't be shy, come join and ask our [Community](https://t.me/PyrogramChat)!
|
||||
- For other requests you can send an [Email](mailto:dan@pyrogram.org) or a [Message](https://t.me/haskell).
|
||||
|
||||
### Contributing
|
||||
|
||||
Pyrogram is brand new, and **you are welcome to try it and help make it even better** by either submitting pull
|
||||
requests or reporting issues/bugs as well as suggesting best practices, ideas, enhancements on both code
|
||||
and documentation. Any help is appreciated!
|
||||
|
||||
### Copyright & License
|
||||
|
||||
- Copyright (C) 2017-2019 Dan Tès <<https://github.com/delivrance>>
|
||||
- Licensed under the terms of the [GNU Lesser General Public License v3 or later (LGPLv3+)](COPYING.lesser)
|
131
README.rst
131
README.rst
@ -1,131 +0,0 @@
|
||||
|header|
|
||||
|
||||
Pyrogram
|
||||
========
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, Filters
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message(Filters.private)
|
||||
def hello(client, message):
|
||||
message.reply("Hello {}".format(message.from_user.first_name))
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
**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 apps using both user and bot identities (bot API alternative) via the `MTProto API`_.
|
||||
|
||||
`Pyrogram in fully-asynchronous mode is also available » <https://github.com/pyrogram/pyrogram/issues/181>`_
|
||||
|
||||
`Working PoC of Telegram voice calls using Pyrogram » <https://github.com/bakatrouble/pytgvoip>`_
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- **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.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **Updated**, to the latest Telegram API version, currently Layer 97 on top of `MTProto 2.0`_.
|
||||
- **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.4 or higher.
|
||||
- A `Telegram API key`_.
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
.. code:: shell
|
||||
|
||||
pip3 install pyrogram
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
- The Docs contain lots of resources to help you getting started with Pyrogram: https://docs.pyrogram.ml.
|
||||
- Reading `Examples in this repository`_ is also a good way for learning how Pyrogram works.
|
||||
- Seeking extra help? Don't be shy, come join and ask our Community_!
|
||||
- For other requests you can send an Email_ or a Message_.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Pyrogram is brand new, and **you are welcome to try it and help make it even better** by either submitting pull
|
||||
requests or reporting issues/bugs as well as suggesting best practices, ideas, enhancements on both code
|
||||
and documentation. Any help is appreciated!
|
||||
|
||||
Copyright & License
|
||||
-------------------
|
||||
|
||||
- Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
- Licensed under the terms of the `GNU Lesser General Public License v3 or later (LGPLv3+)`_
|
||||
|
||||
.. _`Telegram`: https://telegram.org/
|
||||
.. _`MTProto API`: https://core.telegram.org/api#telegram-api
|
||||
.. _`Telegram API key`: https://docs.pyrogram.ml/start/ProjectSetup#api-keys
|
||||
.. _`Community`: https://t.me/PyrogramChat
|
||||
.. _`Examples in this repository`: https://github.com/pyrogram/pyrogram/tree/master/examples
|
||||
.. _`GitHub`: https://github.com/pyrogram/pyrogram/issues
|
||||
.. _`Email`: admin@pyrogram.ml
|
||||
.. _`Message`: https://t.me/haskell
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
.. _`MTProto 2.0`: https://core.telegram.org/mtproto
|
||||
.. _`GNU Lesser General Public License v3 or later (LGPLv3+)`: COPYING.lesser
|
||||
|
||||
.. |header| raw:: html
|
||||
|
||||
<h1 align="center">
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
<div><img src="https://raw.githubusercontent.com/pyrogram/logos/master/logos/pyrogram_logo2.png" alt="Pyrogram Logo"></div>
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
|
||||
<br>
|
||||
<a href="https://docs.pyrogram.ml">
|
||||
Documentation
|
||||
</a>
|
||||
•
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Changelog
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/PyrogramChat">
|
||||
Community
|
||||
</a>
|
||||
<br>
|
||||
<a href="compiler/api/source/main_api.tl">
|
||||
<img src="https://img.shields.io/badge/schema-layer%2097-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="Schema Layer">
|
||||
</a>
|
||||
<a href="https://github.com/pyrogram/tgcrypto">
|
||||
<img src="https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="TgCrypto Version">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
.. |logo| image:: https://raw.githubusercontent.com/pyrogram/logos/master/logos/pyrogram_logo2.png
|
||||
:target: https://pyrogram.ml
|
||||
:alt: Pyrogram
|
||||
|
||||
.. |description| replace:: **Telegram MTProto API Framework for Python**
|
||||
|
||||
.. |schema| image:: https://img.shields.io/badge/schema-layer%2097-eda738.svg?longCache=true&colorA=262b30
|
||||
:target: compiler/api/source/main_api.tl
|
||||
:alt: Schema Layer
|
||||
|
||||
.. |tgcrypto| image:: https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30
|
||||
:target: https://github.com/pyrogram/tgcrypto
|
||||
:alt: TgCrypto Version
|
@ -53,10 +53,10 @@ def get_docstring_arg_type(t: str, is_list: bool = False, is_pyrogram_type: bool
|
||||
return "``{}``".format(t.lower())
|
||||
elif t == "true":
|
||||
return "``bool``"
|
||||
elif t == "Object" or t == "X":
|
||||
return "Any object from :obj:`pyrogram.api.types`"
|
||||
elif t == "TLObject" or t == "X":
|
||||
return "Any object from :obj:`~pyrogram.api.types`"
|
||||
elif t == "!X":
|
||||
return "Any method from :obj:`pyrogram.api.functions`"
|
||||
return "Any method from :obj:`~pyrogram.api.functions`"
|
||||
elif t.startswith("Vector"):
|
||||
return "List of " + get_docstring_arg_type(t.split("<", 1)[1][:-1], True, is_pyrogram_type)
|
||||
else:
|
||||
@ -288,9 +288,9 @@ def start():
|
||||
sorted_args = sort_args(c.args)
|
||||
|
||||
arguments = (
|
||||
", "
|
||||
+ ("*, " if c.args else "")
|
||||
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
|
||||
", "
|
||||
+ ("*, " if c.args else "")
|
||||
+ (", ".join([get_argument_type(i) for i in sorted_args if i != ("flags", "#")]) if c.args else "")
|
||||
)
|
||||
|
||||
fields = "\n ".join(
|
||||
@ -328,15 +328,16 @@ def start():
|
||||
)
|
||||
|
||||
if docstring_args:
|
||||
docstring_args = "Args:\n " + "\n ".join(docstring_args)
|
||||
docstring_args = "Parameters:\n " + "\n ".join(docstring_args)
|
||||
else:
|
||||
docstring_args = "No parameters required."
|
||||
|
||||
docstring_args = "Attributes:\n ID: ``{}``\n\n ".format(c.id) + docstring_args
|
||||
docstring_args = "Attributes:\n LAYER: ``{}``\n\n ".format(layer) + docstring_args
|
||||
|
||||
if c.section == "functions":
|
||||
docstring_args += "\n\n Raises:\n :obj:`RPCError <pyrogram.RPCError>`"
|
||||
docstring_args += "\n\n Returns:\n " + get_docstring_arg_type(c.return_type)
|
||||
|
||||
else:
|
||||
references = get_references(".".join(filter(None, [c.namespace, c.name])))
|
||||
|
||||
@ -393,7 +394,7 @@ def start():
|
||||
)
|
||||
|
||||
read_types += "\n "
|
||||
read_types += "{} = Object.read(b{}) if flags & (1 << {}) else []\n ".format(
|
||||
read_types += "{} = TLObject.read(b{}) if flags & (1 << {}) else []\n ".format(
|
||||
arg_name, ", {}".format(sub_type.title()) if sub_type in core_types else "", index
|
||||
)
|
||||
else:
|
||||
@ -402,7 +403,7 @@ def start():
|
||||
write_types += "b.write(self.{}.write())\n ".format(arg_name)
|
||||
|
||||
read_types += "\n "
|
||||
read_types += "{} = Object.read(b) if flags & (1 << {}) else None\n ".format(
|
||||
read_types += "{} = TLObject.read(b) if flags & (1 << {}) else None\n ".format(
|
||||
arg_name, index
|
||||
)
|
||||
else:
|
||||
@ -421,7 +422,7 @@ def start():
|
||||
)
|
||||
|
||||
read_types += "\n "
|
||||
read_types += "{} = Object.read(b{})\n ".format(
|
||||
read_types += "{} = TLObject.read(b{})\n ".format(
|
||||
arg_name, ", {}".format(sub_type.title()) if sub_type in core_types else ""
|
||||
)
|
||||
else:
|
||||
@ -429,7 +430,7 @@ def start():
|
||||
write_types += "b.write(self.{}.write())\n ".format(arg_name)
|
||||
|
||||
read_types += "\n "
|
||||
read_types += "{} = Object.read(b)\n ".format(arg_name)
|
||||
read_types += "{} = TLObject.read(b)\n ".format(arg_name)
|
||||
|
||||
if c.docs:
|
||||
description = c.docs.split("|")[0].split("§")[1]
|
||||
@ -462,7 +463,7 @@ def start():
|
||||
["{0}={0}".format(i[0]) for i in sorted_args if i != ("flags", "#")]
|
||||
),
|
||||
slots=", ".join(['"{}"'.format(i[0]) for i in sorted_args if i != ("flags", "#")]),
|
||||
qualname="{}{}".format("{}.".format(c.namespace) if c.namespace else "", c.name)
|
||||
qualname="{}.{}{}".format(c.section, "{}.".format(c.namespace) if c.namespace else "", c.name)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -22,10 +22,13 @@ inputPeerSelf#7da07ec9 = InputPeer;
|
||||
inputPeerChat#179be863 chat_id:int = InputPeer;
|
||||
inputPeerUser#7b8e7de6 user_id:int access_hash:long = InputPeer;
|
||||
inputPeerChannel#20adaef8 channel_id:int access_hash:long = InputPeer;
|
||||
inputPeerUserFromMessage#17bae2e6 peer:InputPeer msg_id:int user_id:int = InputPeer;
|
||||
inputPeerChannelFromMessage#9c95f7bb peer:InputPeer msg_id:int channel_id:int = InputPeer;
|
||||
|
||||
inputUserEmpty#b98886cf = InputUser;
|
||||
inputUserSelf#f7c1b13f = InputUser;
|
||||
inputUser#d8292816 user_id:int access_hash:long = InputUser;
|
||||
inputUserFromMessage#2d117597 peer:InputPeer msg_id:int user_id:int = InputUser;
|
||||
|
||||
inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact;
|
||||
|
||||
@ -60,9 +63,12 @@ inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
|
||||
|
||||
inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation;
|
||||
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
|
||||
inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes = InputFileLocation;
|
||||
inputDocumentFileLocation#bad07584 id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
|
||||
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
|
||||
inputTakeoutFileLocation#29be5899 = InputFileLocation;
|
||||
inputPhotoFileLocation#40181ffe id:long access_hash:long file_reference:bytes thumb_size:string = InputFileLocation;
|
||||
inputPeerPhotoFileLocation#27d69997 flags:# big:flags.0?true peer:InputPeer volume_id:long local_id:int = InputFileLocation;
|
||||
inputStickerSetThumb#dbaeae9 stickerset:InputStickerSet volume_id:long local_id:int = InputFileLocation;
|
||||
|
||||
peerUser#9db1bc6d user_id:int = Peer;
|
||||
peerChat#bad0e5bb chat_id:int = Peer;
|
||||
@ -79,14 +85,11 @@ storage.fileMov#4b09ebbc = storage.FileType;
|
||||
storage.fileMp4#b3cea0e4 = storage.FileType;
|
||||
storage.fileWebp#1081464c = storage.FileType;
|
||||
|
||||
fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileLocation;
|
||||
fileLocation#91d11eb dc_id:int volume_id:long local_id:int secret:long file_reference:bytes = FileLocation;
|
||||
|
||||
userEmpty#200250ba id:int = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
user#2e13f4c3 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?string bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
|
||||
|
||||
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
|
||||
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
|
||||
userProfilePhoto#ecd75d8c photo_id:long photo_small:FileLocation photo_big:FileLocation dc_id:int = UserProfilePhoto;
|
||||
|
||||
userStatusEmpty#9d05049 = UserStatus;
|
||||
userStatusOnline#edb93949 expires:int = UserStatus;
|
||||
@ -98,11 +101,11 @@ userStatusLastMonth#77ebc742 = UserStatus;
|
||||
chatEmpty#9ba2d800 id:int = Chat;
|
||||
chat#3bda1bde flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true id:int title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#7328bdb id:int title:string = Chat;
|
||||
channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#4df30834 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true id:int access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int version:int restriction_reason:flags.9?string admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#289da732 flags:# broadcast:flags.5?true megagroup:flags.8?true id:int access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#22a235da flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int = ChatFull;
|
||||
channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
|
||||
chatFull#1b7c9db3 flags:# can_set_username:flags.7?true id:int about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int = ChatFull;
|
||||
channelFull#9882e516 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.13?int pts:int = ChatFull;
|
||||
|
||||
chatParticipant#c8d7493e user_id:int inviter_id:int date:int = ChatParticipant;
|
||||
chatParticipantCreator#da13538a user_id:int = ChatParticipant;
|
||||
@ -112,11 +115,11 @@ chatParticipantsForbidden#fc900c2b flags:# chat_id:int self_participant:flags.0?
|
||||
chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
|
||||
|
||||
chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
chatPhoto#475cdbd5 photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
|
||||
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
|
||||
@ -147,7 +150,7 @@ messageActionHistoryClear#9fbab604 = MessageAction;
|
||||
messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
|
||||
messageActionPaymentSentMe#8f31b327 flags:# currency:string total_amount:long payload:bytes info:flags.0?PaymentRequestedInfo shipping_option_id:flags.1?string charge:PaymentCharge = MessageAction;
|
||||
messageActionPaymentSent#40699cd0 currency:string total_amount:long = MessageAction;
|
||||
messageActionPhoneCall#80e11a7f flags:# call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||
messageActionPhoneCall#80e11a7f flags:# video:flags.2?true call_id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = MessageAction;
|
||||
messageActionScreenshotTaken#4792929b = MessageAction;
|
||||
messageActionCustomAction#fae69f56 message:string = MessageAction;
|
||||
messageActionBotAllowed#abe9affe domain:string = MessageAction;
|
||||
@ -155,10 +158,11 @@ messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:
|
||||
messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType> = MessageAction;
|
||||
messageActionContactSignUp#f3f25f76 = MessageAction;
|
||||
|
||||
dialog#e4def5db flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage = Dialog;
|
||||
dialog#2c171f72 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = Dialog;
|
||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||
|
||||
photoEmpty#2331b22d id:long = Photo;
|
||||
photo#9c477dd8 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> = Photo;
|
||||
photo#d07504a5 flags:# has_stickers:flags.0?true id:long access_hash:long file_reference:bytes date:int sizes:Vector<PhotoSize> dc_id:int = Photo;
|
||||
|
||||
photoSizeEmpty#e17e23c type:string = PhotoSize;
|
||||
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
|
||||
@ -196,7 +200,7 @@ inputReportReasonChildAbuse#adf44ee3 = ReportReason;
|
||||
inputReportReasonOther#e1746d0a text:string = ReportReason;
|
||||
inputReportReasonCopyright#9b89f93a = ReportReason;
|
||||
|
||||
userFull#8ea4a881 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int = UserFull;
|
||||
userFull#745559cc flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true user:User about:flags.1?string link:contacts.Link profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int = UserFull;
|
||||
|
||||
contact#f911c994 user_id:int mutual:Bool = Contact;
|
||||
|
||||
@ -221,7 +225,7 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.dialogsNotModified#f0e3e596 count:int = messages.Dialogs;
|
||||
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#a6c47aaa flags:# inexact:flags.1?true count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#c8edce1e flags:# inexact:flags.1?true count:int next_rate:flags.0?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.channelMessages#99262e37 flags:# inexact:flags.1?true pts:int count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesNotModified#74535f21 count:int = messages.Messages;
|
||||
|
||||
@ -271,14 +275,14 @@ updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings
|
||||
updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update;
|
||||
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
|
||||
updateUserPhone#12b9417b user_id:int phone:string = Update;
|
||||
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
|
||||
updateReadHistoryInbox#9c974fdf flags:# folder_id:flags.0?int peer:Peer max_id:int still_unread_count:int pts:int pts_count:int = Update;
|
||||
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
|
||||
updateWebPage#7f891213 webpage:WebPage pts:int pts_count:int = Update;
|
||||
updateReadMessagesContents#68c13933 messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateChannelTooLong#eb0467fb flags:# channel_id:int pts:flags.0?int = Update;
|
||||
updateChannel#b6d45656 channel_id:int = Update;
|
||||
updateNewChannelMessage#62ba04d9 message:Message pts:int pts_count:int = Update;
|
||||
updateReadChannelInbox#4214f37f channel_id:int max_id:int = Update;
|
||||
updateReadChannelInbox#330b5424 flags:# folder_id:flags.0?int channel_id:int max_id:int still_unread_count:int pts:int = Update;
|
||||
updateDeleteChannelMessages#c37521c9 channel_id:int messages:Vector<int> pts:int pts_count:int = Update;
|
||||
updateChannelMessageViews#98a12b4b channel_id:int id:int views:int = Update;
|
||||
updateChatParticipantAdmin#b6901959 chat_id:int user_id:int is_admin:Bool version:int = Update;
|
||||
@ -300,8 +304,8 @@ updateRecentStickers#9a422c20 = Update;
|
||||
updateConfig#a229dd06 = Update;
|
||||
updatePtsChanged#3354678f = Update;
|
||||
updateChannelWebPage#40771900 channel_id:int webpage:WebPage pts:int pts_count:int = Update;
|
||||
updateDialogPinned#19d27f3c flags:# pinned:flags.0?true peer:DialogPeer = Update;
|
||||
updatePinnedDialogs#ea4cb65b flags:# order:flags.0?Vector<DialogPeer> = Update;
|
||||
updateDialogPinned#6e6fe51c flags:# pinned:flags.0?true folder_id:flags.1?int peer:DialogPeer = Update;
|
||||
updatePinnedDialogs#fa0f3ca2 flags:# folder_id:flags.1?int order:flags.0?Vector<DialogPeer> = Update;
|
||||
updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
|
||||
updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
|
||||
updateBotShippingQuery#e0cdc940 query_id:long user_id:int payload:bytes shipping_address:PostAddress = Update;
|
||||
@ -318,6 +322,7 @@ updateUserPinnedMessage#4c43da18 user_id:int id:int = Update;
|
||||
updateChatPinnedMessage#e10db349 chat_id:int id:int version:int = Update;
|
||||
updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update;
|
||||
updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update;
|
||||
updateFolderPeers#19360dc0 folder_peers:Vector<FolderPeer> pts:int pts_count:int = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -344,7 +349,7 @@ upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes
|
||||
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
|
||||
config#e6ca25f6 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
config#330b4067 flags:# phonecalls_enabled:flags.1?true default_p2p_contacts:flags.3?true preload_featured_stickers:flags.4?true ignore_phone_entities:flags.5?true revoke_pm_inbox:flags.6?true blocked_mode:flags.8?true pfs_enabled:flags.13?true date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> dc_txt_domain_name:string chat_size_max:int megagroup_size_max:int forwarded_count_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int push_chat_period_ms:int push_chat_limit:int saved_gifs_limit:int edit_time_limit:int revoke_time_limit:int revoke_pm_time_limit:int rating_e_decay:int stickers_recent_limit:int stickers_faved_limit:int channels_read_media_period:int tmp_sessions:flags.0?int pinned_dialogs_count_max:int pinned_infolder_count_max:int call_receive_timeout_ms:int call_ring_timeout_ms:int call_connect_timeout_ms:int call_packet_timeout_ms:int me_url_prefix:string autoupdate_url_prefix:flags.7?string gif_search_username:flags.9?string venue_search_username:flags.10?string img_search_username:flags.11?string static_maps_provider:flags.12?string caption_length_max:int message_length_max:int webfile_dc_id:int suggested_lang_code:flags.2?string lang_pack_version:flags.2?int base_lang_pack_version:flags.2?int = Config;
|
||||
|
||||
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
|
||||
|
||||
@ -413,6 +418,7 @@ inputPrivacyKeyPhoneCall#fabadc5f = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneP2P#db9e70d2 = InputPrivacyKey;
|
||||
inputPrivacyKeyForwards#a4dd4c08 = InputPrivacyKey;
|
||||
inputPrivacyKeyProfilePhoto#5719bacc = InputPrivacyKey;
|
||||
inputPrivacyKeyPhoneNumber#352dafa = InputPrivacyKey;
|
||||
|
||||
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
||||
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
||||
@ -420,6 +426,7 @@ privacyKeyPhoneCall#3d662b7b = PrivacyKey;
|
||||
privacyKeyPhoneP2P#39491cc8 = PrivacyKey;
|
||||
privacyKeyForwards#69ec56a3 = PrivacyKey;
|
||||
privacyKeyProfilePhoto#96151fed = PrivacyKey;
|
||||
privacyKeyPhoneNumber#d19ae46d = PrivacyKey;
|
||||
|
||||
inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule;
|
||||
inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule;
|
||||
@ -427,6 +434,8 @@ inputPrivacyValueAllowUsers#131cc67f users:Vector<InputUser> = InputPrivacyRule;
|
||||
inputPrivacyValueDisallowContacts#ba52007 = InputPrivacyRule;
|
||||
inputPrivacyValueDisallowAll#d66b66c9 = InputPrivacyRule;
|
||||
inputPrivacyValueDisallowUsers#90110467 users:Vector<InputUser> = InputPrivacyRule;
|
||||
inputPrivacyValueAllowChatParticipants#4c81c1ba chats:Vector<int> = InputPrivacyRule;
|
||||
inputPrivacyValueDisallowChatParticipants#d82363af chats:Vector<int> = InputPrivacyRule;
|
||||
|
||||
privacyValueAllowContacts#fffe1bac = PrivacyRule;
|
||||
privacyValueAllowAll#65427b82 = PrivacyRule;
|
||||
@ -434,8 +443,10 @@ privacyValueAllowUsers#4d5bbe0c users:Vector<int> = PrivacyRule;
|
||||
privacyValueDisallowContacts#f888fa1a = PrivacyRule;
|
||||
privacyValueDisallowAll#8b73e763 = PrivacyRule;
|
||||
privacyValueDisallowUsers#c7f49b7 users:Vector<int> = PrivacyRule;
|
||||
privacyValueAllowChatParticipants#18be796b chats:Vector<int> = PrivacyRule;
|
||||
privacyValueDisallowChatParticipants#acae0690 chats:Vector<int> = PrivacyRule;
|
||||
|
||||
account.privacyRules#554abb6f rules:Vector<PrivacyRule> users:Vector<User> = account.PrivacyRules;
|
||||
account.privacyRules#50a04e45 rules:Vector<PrivacyRule> chats:Vector<Chat> users:Vector<User> = account.PrivacyRules;
|
||||
|
||||
accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
|
||||
|
||||
@ -459,7 +470,6 @@ messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMess
|
||||
|
||||
contactLinkUnknown#5f4f9247 = ContactLink;
|
||||
contactLinkNone#feedd3ad = ContactLink;
|
||||
contactLinkHasPhone#268f3f59 = ContactLink;
|
||||
contactLinkContact#d502c2d0 = ContactLink;
|
||||
|
||||
webPageEmpty#eb1477e8 id:long = WebPage;
|
||||
@ -485,13 +495,13 @@ chatInviteEmpty#69df3769 = ExportedChatInvite;
|
||||
chatInviteExported#fc2e05bc link:string = ExportedChatInvite;
|
||||
|
||||
chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
|
||||
chatInvite#db74f558 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:ChatPhoto participants_count:int participants:flags.4?Vector<User> = ChatInvite;
|
||||
chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector<User> = ChatInvite;
|
||||
|
||||
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
|
||||
stickerSet#6a90bcb7 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize count:int hash:int = StickerSet;
|
||||
stickerSet#eeb46f27 flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumb:flags.4?PhotoSize thumb_dc_id:flags.4?int count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
|
||||
@ -507,6 +517,8 @@ keyboardButtonRequestGeoLocation#fc796b3f text:string = KeyboardButton;
|
||||
keyboardButtonSwitchInline#568a748 flags:# same_peer:flags.0?true text:string query:string = KeyboardButton;
|
||||
keyboardButtonGame#50f41ccf text:string = KeyboardButton;
|
||||
keyboardButtonBuy#afd93fbb text:string = KeyboardButton;
|
||||
keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton;
|
||||
inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton;
|
||||
|
||||
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||
|
||||
@ -533,13 +545,14 @@ messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#afeb712e channel_id:int access_hash:long = InputChannel;
|
||||
inputChannelFromMessage#2a286531 peer:InputPeer msg_id:int channel_id:int = InputChannel;
|
||||
|
||||
contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;
|
||||
|
||||
messageRange#ae30253 min_id:int max_id:int = MessageRange;
|
||||
|
||||
updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int = updates.ChannelDifference;
|
||||
updates.channelDifferenceTooLong#6a9d7b35 flags:# final:flags.0?true pts:int timeout:flags.1?int top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
|
||||
updates.channelDifferenceTooLong#a4bcc6fe flags:# final:flags.0?true timeout:flags.1?int dialog:Dialog messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
|
||||
updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:flags.1?int new_messages:Vector<Message> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> = updates.ChannelDifference;
|
||||
|
||||
channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter;
|
||||
@ -628,6 +641,8 @@ topPeerCategoryCorrespondents#637b7ed = TopPeerCategory;
|
||||
topPeerCategoryGroups#bd17a14a = TopPeerCategory;
|
||||
topPeerCategoryChannels#161d9628 = TopPeerCategory;
|
||||
topPeerCategoryPhoneCalls#1e76a78c = TopPeerCategory;
|
||||
topPeerCategoryForwardUsers#a8406ca9 = TopPeerCategory;
|
||||
topPeerCategoryForwardChats#fbeec0f0 = TopPeerCategory;
|
||||
|
||||
topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector<TopPeer> = TopPeerCategoryPeers;
|
||||
|
||||
@ -767,11 +782,11 @@ inputStickerSetItem#ffa0a496 flags:# document:InputDocument emoji:string mask_co
|
||||
inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall;
|
||||
|
||||
phoneCallEmpty#5366c915 id:long = PhoneCall;
|
||||
phoneCallWaiting#1b8f4ad1 flags:# id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
|
||||
phoneCallRequested#83761ce4 id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCallAccepted#6d003d3f id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCall#e6f9ddf3 flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connection:PhoneConnection alternative_connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
|
||||
phoneCallWaiting#1b8f4ad1 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
|
||||
phoneCallRequested#87eabb53 flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCallAccepted#997c454a flags:# video:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
|
||||
phoneCall#8742ae7f flags:# p2p_allowed:flags.5?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int = PhoneCall;
|
||||
phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.5?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
|
||||
|
||||
phoneConnection#9d4c17c0 id:long ip:string ipv6:string port:int peer_tag:bytes = PhoneConnection;
|
||||
|
||||
@ -797,7 +812,7 @@ langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:fl
|
||||
channelAdminLogEventActionChangeTitle#e6dfb825 prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAbout#55188a2e prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeUsername#6a4afc38 prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangePhoto#b82f55c3 prev_photo:ChatPhoto new_photo:ChatPhoto = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangePhoto#434bd2af prev_photo:Photo new_photo:Photo = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleInvites#1b7907ae new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleSignatures#26ae0971 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionUpdatePinned#e9e82c18 message:Message = ChannelAdminLogEventAction;
|
||||
@ -812,6 +827,7 @@ channelAdminLogEventActionChangeStickerSet#b1c3caa7 prev_stickerset:InputSticker
|
||||
channelAdminLogEventActionTogglePreHistoryHidden#5f5c95f1 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionDefaultBannedRights#2df5fc0a prev_banned_rights:ChatBannedRights new_banned_rights:ChatBannedRights = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionStopPoll#8f079643 message:Message = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeLinkedChat#a26f881b prev_value:int new_value:int = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#3b5a3e40 id:long date:int user_id:int action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
@ -843,8 +859,10 @@ inputMessageReplyTo#bad88395 id:int = InputMessage;
|
||||
inputMessagePinned#86872538 = InputMessage;
|
||||
|
||||
inputDialogPeer#fcaafeb7 peer:InputPeer = InputDialogPeer;
|
||||
inputDialogPeerFolder#64600527 folder_id:int = InputDialogPeer;
|
||||
|
||||
dialogPeer#e56dbf05 peer:Peer = DialogPeer;
|
||||
dialogPeerFolder#514519e2 folder_id:int = DialogPeer;
|
||||
|
||||
messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
|
||||
messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
|
||||
@ -1000,6 +1018,22 @@ emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int k
|
||||
|
||||
emojiURL#a575739d url:string = EmojiURL;
|
||||
|
||||
emojiLanguage#b3fb5361 lang_code:string = EmojiLanguage;
|
||||
|
||||
fileLocationToBeDeprecated#bc7fc6cd volume_id:long local_id:int = FileLocation;
|
||||
|
||||
folder#ff544e65 flags:# autofill_new_broadcasts:flags.0?true autofill_public_groups:flags.1?true autofill_new_correspondents:flags.2?true id:int title:string photo:flags.3?ChatPhoto = Folder;
|
||||
|
||||
inputFolderPeer#fbd2c296 peer:InputPeer folder_id:int = InputFolderPeer;
|
||||
|
||||
folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer;
|
||||
|
||||
messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter;
|
||||
|
||||
urlAuthResultRequest#92d33a0e flags:# request_write_access:flags.0?true bot:User domain:string = UrlAuthResult;
|
||||
urlAuthResultAccepted#8f8c0e4e url:string = UrlAuthResult;
|
||||
urlAuthResultDefault#a9d6db1f = UrlAuthResult;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -1098,14 +1132,14 @@ contacts.unblock#e54100bd id:InputUser = Bool;
|
||||
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
|
||||
contacts.search#11f812d8 q:string limit:int = contacts.Found;
|
||||
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
|
||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||
contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:int = contacts.TopPeers;
|
||||
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
|
||||
contacts.resetSaved#879537f1 = Bool;
|
||||
contacts.getSaved#82f1e39f = Vector<SavedContact>;
|
||||
contacts.toggleTopPeers#8514bdda enabled:Bool = Bool;
|
||||
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#b098aee6 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
||||
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
@ -1152,7 +1186,7 @@ messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_par
|
||||
messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>;
|
||||
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
|
||||
messages.migrateChat#15a3b8e3 chat_id:int = Updates;
|
||||
messages.searchGlobal#9e3cacb0 q:string offset_date:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
messages.searchGlobal#f79c611 q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool;
|
||||
messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document;
|
||||
messages.searchGifs#bf9a776b q:string offset:int = messages.FoundGifs;
|
||||
@ -1185,8 +1219,8 @@ messages.getCommonChats#d0a48c4 user_id:InputUser max_id:int limit:int = message
|
||||
messages.getAllChats#eba80ff0 except_ids:Vector<int> = messages.Chats;
|
||||
messages.getWebPage#32ca8f91 url:string hash:int = WebPage;
|
||||
messages.toggleDialogPin#a731e257 flags:# pinned:flags.0?true peer:InputDialogPeer = Bool;
|
||||
messages.reorderPinnedDialogs#5b51d63f flags:# force:flags.0?true order:Vector<InputDialogPeer> = Bool;
|
||||
messages.getPinnedDialogs#e254d64e = messages.PeerDialogs;
|
||||
messages.reorderPinnedDialogs#3b1adf37 flags:# force:flags.0?true folder_id:int order:Vector<InputDialogPeer> = Bool;
|
||||
messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs;
|
||||
messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector<ShippingOption> = Bool;
|
||||
messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool;
|
||||
messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
|
||||
@ -1212,7 +1246,11 @@ messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
||||
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||
messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
|
||||
messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
|
||||
messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector<string> = Vector<EmojiLanguage>;
|
||||
messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL;
|
||||
messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
|
||||
messages.requestUrlAuth#e33f5613 peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
|
||||
messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1281,6 +1319,9 @@ channels.readMessageContents#eab5dc38 channel:InputChannel id:Vector<int> = Bool
|
||||
channels.deleteHistory#af369d42 channel:InputChannel max_id:int = Bool;
|
||||
channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
|
||||
channels.getLeftChannels#8341ecc0 offset:int = messages.Chats;
|
||||
channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
|
||||
channels.getBroadcastsForDiscussion#1a87f304 = messages.Chats;
|
||||
channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
@ -1298,11 +1339,11 @@ stickers.changeStickerPosition#ffb6d4ca sticker:InputDocument position:int = mes
|
||||
stickers.addStickerToSet#8653febe stickerset:InputStickerSet sticker:InputStickerSetItem = messages.StickerSet;
|
||||
|
||||
phone.getCallConfig#55451fa9 = DataJSON;
|
||||
phone.requestCall#5b95b3d4 user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.requestCall#42ff96ed flags:# video:flags.0?true user_id:InputUser random_id:int g_a_hash:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.acceptCall#3bd2b4a0 peer:InputPhoneCall g_b:bytes protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.confirmCall#2efe1722 peer:InputPhoneCall g_a:bytes key_fingerprint:long protocol:PhoneCallProtocol = phone.PhoneCall;
|
||||
phone.receivedCall#17d54f61 peer:InputPhoneCall = Bool;
|
||||
phone.discardCall#78d413a6 peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
|
||||
phone.discardCall#b2cbc1c0 flags:# video:flags.0?true peer:InputPhoneCall duration:int reason:PhoneCallDiscardReason connection_id:long = Updates;
|
||||
phone.setCallRating#59ead627 flags:# user_initiative:flags.0?true peer:InputPhoneCall rating:int comment:string = Updates;
|
||||
phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
|
||||
|
||||
@ -1312,4 +1353,10 @@ langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:i
|
||||
langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
|
||||
langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
|
||||
|
||||
// LAYER 97
|
||||
folders.editPeerFolders#6847d0ab folder_peers:Vector<InputFolderPeer> = Updates;
|
||||
folders.deleteFolder#1c295881 folder_id:int = Updates;
|
||||
|
||||
// LAYER 100
|
||||
|
||||
// Ports
|
||||
channels.exportInvite#c7560885 channel:InputChannel = ExportedChatInvite;
|
@ -5,7 +5,7 @@ from io import BytesIO
|
||||
from pyrogram.api.core import *
|
||||
|
||||
|
||||
class {class_name}(Object):
|
||||
class {class_name}(TLObject):
|
||||
"""{docstring_args}
|
||||
"""
|
||||
|
||||
|
@ -18,10 +18,11 @@
|
||||
|
||||
import ast
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
HOME = "compiler/docs"
|
||||
DESTINATION = "docs/source"
|
||||
DESTINATION = "docs/source/telegram"
|
||||
|
||||
FUNCTIONS_PATH = "pyrogram/api/functions"
|
||||
TYPES_PATH = "pyrogram/api/types"
|
||||
@ -29,8 +30,10 @@ TYPES_PATH = "pyrogram/api/types"
|
||||
FUNCTIONS_BASE = "functions"
|
||||
TYPES_BASE = "types"
|
||||
|
||||
shutil.rmtree(TYPES_BASE, ignore_errors=True)
|
||||
shutil.rmtree(FUNCTIONS_BASE, ignore_errors=True)
|
||||
|
||||
def snek(s: str):
|
||||
s = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", s)
|
||||
return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s).lower()
|
||||
|
||||
|
||||
def generate(source_path, base):
|
||||
@ -50,9 +53,11 @@ def generate(source_path, base):
|
||||
for node in ast.walk(p):
|
||||
if isinstance(node, ast.ClassDef):
|
||||
name = node.name
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
# name = "".join([str(j.title()) for j in os.path.splitext(i)[0].split("_")])
|
||||
full_path = os.path.basename(path) + "/" + name + ".rst"
|
||||
full_path = os.path.basename(path) + "/" + snek(name).replace("_", "-") + ".rst"
|
||||
|
||||
if level:
|
||||
full_path = base + "/" + full_path
|
||||
@ -65,7 +70,7 @@ def generate(source_path, base):
|
||||
title=name,
|
||||
title_markup="=" * len(name),
|
||||
full_class_path="pyrogram.api.{}".format(
|
||||
os.path.splitext(full_path)[0].replace("/", ".")
|
||||
".".join(full_path.split("/")[:-1]) + "." + name
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -82,7 +87,7 @@ def generate(source_path, base):
|
||||
entities = []
|
||||
|
||||
for i in v:
|
||||
entities.append(i)
|
||||
entities.append(snek(i).replace("_", "-"))
|
||||
|
||||
if k != base:
|
||||
inner_path = base + "/" + k + "/index" + ".rst"
|
||||
@ -98,6 +103,7 @@ def generate(source_path, base):
|
||||
with open(DESTINATION + "/" + inner_path, "w", encoding="utf-8") as f:
|
||||
if k == base:
|
||||
f.write(":tocdepth: 1\n\n")
|
||||
k = "Raw " + k
|
||||
|
||||
f.write(
|
||||
toctree.format(
|
||||
@ -115,6 +121,8 @@ def start():
|
||||
global page_template
|
||||
global toctree
|
||||
|
||||
shutil.rmtree(DESTINATION, ignore_errors=True)
|
||||
|
||||
with open(HOME + "/template/page.txt", encoding="utf-8") as f:
|
||||
page_template = f.read()
|
||||
|
||||
@ -129,6 +137,6 @@ if "__main__" == __name__:
|
||||
FUNCTIONS_PATH = "../../pyrogram/api/functions"
|
||||
TYPES_PATH = "../../pyrogram/api/types"
|
||||
HOME = "."
|
||||
DESTINATION = "../../docs/source"
|
||||
DESTINATION = "../../docs/source/telegram"
|
||||
|
||||
start()
|
||||
|
2
compiler/docs/template/page.txt
vendored
2
compiler/docs/template/page.txt
vendored
@ -1,5 +1,5 @@
|
||||
{title}
|
||||
{title_markup}
|
||||
|
||||
.. autoclass:: {full_class_path}
|
||||
.. autoclass:: {full_class_path}()
|
||||
:members:
|
||||
|
@ -96,4 +96,13 @@ EXTERNAL_URL_INVALID The external media URL is invalid
|
||||
CHAT_NOT_MODIFIED The chat settings were not modified
|
||||
RESULTS_TOO_MUCH The result contains too many items
|
||||
RESULT_ID_DUPLICATE The result contains items with duplicated identifiers
|
||||
ACCESS_TOKEN_INVALID The bot access token is invalid
|
||||
ACCESS_TOKEN_INVALID The bot access token is invalid
|
||||
INVITE_HASH_EXPIRED The chat invite link is no longer valid
|
||||
USER_BANNED_IN_CHANNEL You are limited, check @SpamBot for details
|
||||
MESSAGE_EDIT_TIME_EXPIRED You can no longer edit this message
|
||||
FOLDER_ID_INVALID The folder id is invalid
|
||||
MEGAGROUP_PREHISTORY_HIDDEN The action failed because the supergroup has the pre-history hidden
|
||||
CHAT_LINK_EXISTS The action failed because the supergroup is linked to a channel
|
||||
LINK_NOT_MODIFIED The chat link was not modified because you tried to link to the same target
|
||||
BROADCAST_ID_INVALID The channel is invalid
|
||||
MEGAGROUP_ID_INVALID The supergroup is invalid
|
|
@ -2,6 +2,7 @@ id message
|
||||
AUTH_KEY_UNREGISTERED The key is not registered in the system
|
||||
AUTH_KEY_INVALID The key is invalid
|
||||
USER_DEACTIVATED The user has been deleted/deactivated
|
||||
USER_DEACTIVATED_BAN The user has been deleted/deactivated
|
||||
SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions
|
||||
SESSION_EXPIRED The authorization has expired
|
||||
ACTIVE_USER_REQUIRED The method is only available to already activated users
|
||||
|
|
@ -2,4 +2,6 @@ id message
|
||||
CHAT_WRITE_FORBIDDEN You don't have rights to send messages in this chat
|
||||
RIGHT_FORBIDDEN One or more admin rights can't be applied to this kind of chat (channel/supergroup)
|
||||
CHAT_ADMIN_INVITE_REQUIRED You don't have rights to invite other users
|
||||
MESSAGE_DELETE_FORBIDDEN You don't have rights to delete messages in this chat
|
||||
MESSAGE_DELETE_FORBIDDEN You don't have rights to delete messages in this chat
|
||||
CHAT_SEND_MEDIA_FORBIDDEN You can't send media messages in this chat
|
||||
MESSAGE_AUTHOR_REQUIRED You are not the author of this message
|
|
@ -5,4 +5,8 @@ RPC_MCGET_FAIL Telegram is having internal problems. Please try again later
|
||||
PERSISTENT_TIMESTAMP_OUTDATED Telegram is having internal problems. Please try again later
|
||||
HISTORY_GET_FAILED Telegram is having internal problems. Please try again later
|
||||
REG_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later
|
||||
RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later
|
||||
RANDOM_ID_DUPLICATE Telegram is having internal problems. Please try again later
|
||||
WORKER_BUSY_TOO_LONG_RETRY Telegram is having internal problems. Please try again later
|
||||
INTERDC_X_CALL_ERROR Telegram is having internal problems at DC{x}. Please try again later
|
||||
INTERDC_X_CALL_RICH_ERROR Telegram is having internal problems at DC{x}. Please try again later
|
||||
FOLDER_DEAC_AUTOFIX_ALL Telegram is having internal problems. Please try again later
|
|
85
docs/releases.py
Normal file
85
docs/releases.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2019 Dan Tès <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.
|
||||
|
||||
Releases
|
||||
--------
|
||||
|
||||
""".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))
|
8
docs/robots.txt
Normal file
8
docs/robots.txt
Normal file
@ -0,0 +1,8 @@
|
||||
User-agent: *
|
||||
|
||||
Allow: /
|
||||
|
||||
Disallow: /dev/*
|
||||
Disallow: /old/*
|
||||
|
||||
Sitemap: https://docs.pyrogram.org/sitemap.xml
|
@ -18,17 +18,17 @@
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
|
||||
canonical = "https://docs.pyrogram.ml"
|
||||
canonical = "https://docs.pyrogram.org/"
|
||||
|
||||
dirs = {
|
||||
".": ("weekly", 1.0),
|
||||
"intro": ("weekly", 0.9),
|
||||
"start": ("weekly", 0.9),
|
||||
"resources": ("weekly", 0.8),
|
||||
"pyrogram": ("weekly", 0.8),
|
||||
"functions": ("monthly", 0.7),
|
||||
"types": ("monthly", 0.7),
|
||||
"errors": ("weekly", 0.6)
|
||||
"api": ("weekly", 0.8),
|
||||
"topics": ("weekly", 0.8),
|
||||
"releases": ("weekly", 0.8),
|
||||
"telegram": ("weekly", 0.6)
|
||||
}
|
||||
|
||||
|
||||
@ -37,10 +37,10 @@ def now():
|
||||
|
||||
|
||||
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")
|
||||
f.write('<?xml version="1.0" encoding="utf-8"?>\n')
|
||||
f.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n')
|
||||
|
||||
urls = [(canonical, now(), "weekly", 1.0)]
|
||||
urls = []
|
||||
|
||||
|
||||
def search(path):
|
||||
@ -48,14 +48,27 @@ with open("sitemap.xml", "w") as f:
|
||||
for j in os.listdir(path):
|
||||
search("{}/{}".format(path, j))
|
||||
except NotADirectoryError:
|
||||
d = path.split("/")[0]
|
||||
path = "{}/{}".format(canonical, path.split(".")[0])
|
||||
path = re.sub("^(.+)/index$", "\g<1>", path)
|
||||
urls.append((path, now(), dirs[d][0], dirs[d][1]))
|
||||
if not path.endswith(".rst"):
|
||||
return
|
||||
|
||||
path = path.split("/")[1:]
|
||||
|
||||
if path[0].endswith(".rst"):
|
||||
folder = "."
|
||||
else:
|
||||
folder = path[0]
|
||||
|
||||
path = "{}{}".format(canonical, "/".join(path))[:-len(".rst")]
|
||||
|
||||
if path.endswith("index"):
|
||||
path = path[:-len("index")]
|
||||
|
||||
urls.append((path, now(), *dirs[folder]))
|
||||
|
||||
|
||||
for i in dirs.keys():
|
||||
search(i)
|
||||
search("source")
|
||||
|
||||
urls.sort(key=lambda x: x[3], reverse=True)
|
||||
|
||||
for i in urls:
|
||||
f.write(" <url>\n")
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
BIN
docs/source/_images/pyrogram.png
Normal file
BIN
docs/source/_images/pyrogram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
150
docs/source/api/bound-methods.rst
Normal file
150
docs/source/api/bound-methods.rst
Normal file
@ -0,0 +1,150 @@
|
||||
Bound Methods
|
||||
=============
|
||||
|
||||
Some Pyrogram types define what are called bound methods. Bound methods are functions attached to a class which are
|
||||
accessed via an instance of that class. They make it even easier to call specific methods by automatically inferring
|
||||
some of the required arguments.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 8
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message()
|
||||
def hello(client, message)
|
||||
message.reply("hi")
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
Message
|
||||
^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Message.click`
|
||||
- :meth:`~Message.delete`
|
||||
- :meth:`~Message.download`
|
||||
- :meth:`~Message.forward`
|
||||
- :meth:`~Message.pin`
|
||||
- :meth:`~Message.edit_text`
|
||||
- :meth:`~Message.edit_caption`
|
||||
- :meth:`~Message.edit_media`
|
||||
- :meth:`~Message.edit_reply_markup`
|
||||
- :meth:`~Message.reply_text`
|
||||
- :meth:`~Message.reply_animation`
|
||||
- :meth:`~Message.reply_audio`
|
||||
- :meth:`~Message.reply_cached_media`
|
||||
- :meth:`~Message.reply_chat_action`
|
||||
- :meth:`~Message.reply_contact`
|
||||
- :meth:`~Message.reply_document`
|
||||
- :meth:`~Message.reply_game`
|
||||
- :meth:`~Message.reply_inline_bot_result`
|
||||
- :meth:`~Message.reply_location`
|
||||
- :meth:`~Message.reply_media_group`
|
||||
- :meth:`~Message.reply_photo`
|
||||
- :meth:`~Message.reply_poll`
|
||||
- :meth:`~Message.reply_sticker`
|
||||
- :meth:`~Message.reply_venue`
|
||||
- :meth:`~Message.reply_video`
|
||||
- :meth:`~Message.reply_video_note`
|
||||
- :meth:`~Message.reply_voice`
|
||||
|
||||
Chat
|
||||
^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :meth:`~Chat.archive`
|
||||
- :meth:`~Chat.unarchive`
|
||||
|
||||
User
|
||||
^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :meth:`~User.archive`
|
||||
- :meth:`~User.unarchive`
|
||||
|
||||
CallbackQuery
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
- :meth:`~CallbackQuery.answer`
|
||||
- :meth:`~CallbackQuery.edit_text`
|
||||
- :meth:`~CallbackQuery.edit_caption`
|
||||
- :meth:`~CallbackQuery.edit_media`
|
||||
- :meth:`~CallbackQuery.edit_reply_markup`
|
||||
|
||||
InlineQuery
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :meth:`~InlineQuery.answer`
|
||||
|
||||
-----
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. Message
|
||||
.. automethod:: Message.click()
|
||||
.. automethod:: Message.delete()
|
||||
.. automethod:: Message.download()
|
||||
.. automethod:: Message.forward()
|
||||
.. automethod:: Message.pin()
|
||||
.. automethod:: Message.edit_text()
|
||||
.. automethod:: Message.edit_caption()
|
||||
.. automethod:: Message.edit_media()
|
||||
.. automethod:: Message.edit_reply_markup()
|
||||
.. automethod:: Message.reply_text()
|
||||
.. automethod:: Message.reply_animation()
|
||||
.. automethod:: Message.reply_audio()
|
||||
.. automethod:: Message.reply_cached_media()
|
||||
.. automethod:: Message.reply_chat_action()
|
||||
.. automethod:: Message.reply_contact()
|
||||
.. automethod:: Message.reply_document()
|
||||
.. automethod:: Message.reply_game()
|
||||
.. automethod:: Message.reply_inline_bot_result()
|
||||
.. automethod:: Message.reply_location()
|
||||
.. automethod:: Message.reply_media_group()
|
||||
.. automethod:: Message.reply_photo()
|
||||
.. automethod:: Message.reply_poll()
|
||||
.. automethod:: Message.reply_sticker()
|
||||
.. automethod:: Message.reply_venue()
|
||||
.. automethod:: Message.reply_video()
|
||||
.. automethod:: Message.reply_video_note()
|
||||
.. automethod:: Message.reply_voice()
|
||||
|
||||
.. Chat
|
||||
.. automethod:: Chat.archive()
|
||||
.. automethod:: Chat.unarchive()
|
||||
|
||||
.. User
|
||||
.. automethod:: User.archive()
|
||||
.. automethod:: User.unarchive()
|
||||
|
||||
.. CallbackQuery
|
||||
.. automethod:: CallbackQuery.answer()
|
||||
.. automethod:: CallbackQuery.edit_text()
|
||||
.. automethod:: CallbackQuery.edit_caption()
|
||||
.. automethod:: CallbackQuery.edit_media()
|
||||
.. automethod:: CallbackQuery.edit_reply_markup()
|
||||
|
||||
.. InlineQuery
|
||||
.. automethod:: InlineQuery.answer()
|
19
docs/source/api/client.rst
Normal file
19
docs/source/api/client.rst
Normal file
@ -0,0 +1,19 @@
|
||||
Pyrogram Client
|
||||
===============
|
||||
|
||||
This is the Client class. It exposes high-level methods for an easy access to the API.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1-3
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. autoclass:: pyrogram.Client()
|
57
docs/source/api/decorators.rst
Normal file
57
docs/source/api/decorators.rst
Normal file
@ -0,0 +1,57 @@
|
||||
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
|
||||
: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
|
||||
functions.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 6
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message()
|
||||
def log(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.on_message`
|
||||
- :meth:`~Client.on_callback_query`
|
||||
- :meth:`~Client.on_inline_query`
|
||||
- :meth:`~Client.on_deleted_messages`
|
||||
- :meth:`~Client.on_user_status`
|
||||
- :meth:`~Client.on_poll`
|
||||
- :meth:`~Client.on_disconnect`
|
||||
- :meth:`~Client.on_raw_update`
|
||||
|
||||
-----
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. Decorators
|
||||
.. autodecorator:: pyrogram.Client.on_message()
|
||||
.. autodecorator:: pyrogram.Client.on_callback_query()
|
||||
.. autodecorator:: pyrogram.Client.on_inline_query()
|
||||
.. autodecorator:: pyrogram.Client.on_deleted_messages()
|
||||
.. autodecorator:: pyrogram.Client.on_user_status()
|
||||
.. autodecorator:: pyrogram.Client.on_poll()
|
||||
.. autodecorator:: pyrogram.Client.on_disconnect()
|
||||
.. autodecorator:: pyrogram.Client.on_raw_update()
|
72
docs/source/api/errors.rst
Normal file
72
docs/source/api/errors.rst
Normal file
@ -0,0 +1,72 @@
|
||||
RPC Errors
|
||||
==========
|
||||
|
||||
All Pyrogram API errors live inside the ``errors`` sub-package: ``pyrogram.errors``.
|
||||
The errors ids listed here are shown as *UPPER_SNAKE_CASE*, but the actual exception names to import from Pyrogram
|
||||
follow the usual *PascalCase* convention.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1, 5
|
||||
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
try:
|
||||
...
|
||||
except FloodWait as e:
|
||||
...
|
||||
|
||||
303 - SeeOther
|
||||
--------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/303_SEE_OTHER.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
400 - BadRequest
|
||||
----------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/400_BAD_REQUEST.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
401 - Unauthorized
|
||||
------------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/401_UNAUTHORIZED.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
403 - Forbidden
|
||||
---------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/403_FORBIDDEN.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
406 - NotAcceptable
|
||||
-------------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/406_NOT_ACCEPTABLE.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
420 - Flood
|
||||
-----------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/420_FLOOD.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
||||
|
||||
500 - InternalServerError
|
||||
-------------------------
|
||||
|
||||
.. csv-table::
|
||||
:file: ../../../compiler/error/source/500_INTERNAL_SERVER_ERROR.tsv
|
||||
:delim: tab
|
||||
:header-rows: 1
|
@ -1,5 +1,8 @@
|
||||
Filters
|
||||
=======
|
||||
Update Filters
|
||||
==============
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. autoclass:: pyrogram.Filters
|
||||
:members:
|
56
docs/source/api/handlers.rst
Normal file
56
docs/source/api/handlers.rst
Normal file
@ -0,0 +1,56 @@
|
||||
Update Handlers
|
||||
===============
|
||||
|
||||
Handlers are used to instruct Pyrogram about which kind of updates you'd like to handle with your callback functions.
|
||||
|
||||
For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead.
|
||||
In case you decided to manually create a handler, use :class:`~pyrogram.Client.add_handler` to register
|
||||
it.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1, 10
|
||||
|
||||
from pyrogram import Client, MessageHandler
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
def dump(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(dump))
|
||||
|
||||
app.run()
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :class:`MessageHandler`
|
||||
- :class:`DeletedMessagesHandler`
|
||||
- :class:`CallbackQueryHandler`
|
||||
- :class:`InlineQueryHandler`
|
||||
- :class:`UserStatusHandler`
|
||||
- :class:`PollHandler`
|
||||
- :class:`DisconnectHandler`
|
||||
- :class:`RawUpdateHandler`
|
||||
|
||||
-----
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. Handlers
|
||||
.. autoclass:: MessageHandler()
|
||||
.. autoclass:: DeletedMessagesHandler()
|
||||
.. autoclass:: CallbackQueryHandler()
|
||||
.. autoclass:: InlineQueryHandler()
|
||||
.. autoclass:: UserStatusHandler()
|
||||
.. autoclass:: PollHandler()
|
||||
.. autoclass:: DisconnectHandler()
|
||||
.. autoclass:: RawUpdateHandler()
|
290
docs/source/api/methods.rst
Normal file
290
docs/source/api/methods.rst
Normal file
@ -0,0 +1,290 @@
|
||||
Available Methods
|
||||
=================
|
||||
|
||||
All Pyrogram methods listed here are bound to a :class:`~pyrogram.Client` instance.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 6
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
app.send_message("haskell", "hi")
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
Utilities
|
||||
^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
- :meth:`~Client.start`
|
||||
- :meth:`~Client.stop`
|
||||
- :meth:`~Client.restart`
|
||||
- :meth:`~Client.idle`
|
||||
- :meth:`~Client.run`
|
||||
- :meth:`~Client.add_handler`
|
||||
- :meth:`~Client.remove_handler`
|
||||
- :meth:`~Client.stop_transmission`
|
||||
|
||||
Messages
|
||||
^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.send_message`
|
||||
- :meth:`~Client.forward_messages`
|
||||
- :meth:`~Client.send_photo`
|
||||
- :meth:`~Client.send_audio`
|
||||
- :meth:`~Client.send_document`
|
||||
- :meth:`~Client.send_sticker`
|
||||
- :meth:`~Client.send_animated_sticker`
|
||||
- :meth:`~Client.send_video`
|
||||
- :meth:`~Client.send_animation`
|
||||
- :meth:`~Client.send_voice`
|
||||
- :meth:`~Client.send_video_note`
|
||||
- :meth:`~Client.send_media_group`
|
||||
- :meth:`~Client.send_location`
|
||||
- :meth:`~Client.send_venue`
|
||||
- :meth:`~Client.send_contact`
|
||||
- :meth:`~Client.send_cached_media`
|
||||
- :meth:`~Client.edit_message_text`
|
||||
- :meth:`~Client.edit_message_caption`
|
||||
- :meth:`~Client.edit_message_media`
|
||||
- :meth:`~Client.edit_message_reply_markup`
|
||||
- :meth:`~Client.edit_inline_text`
|
||||
- :meth:`~Client.edit_inline_caption`
|
||||
- :meth:`~Client.edit_inline_media`
|
||||
- :meth:`~Client.edit_inline_reply_markup`
|
||||
- :meth:`~Client.send_chat_action`
|
||||
- :meth:`~Client.delete_messages`
|
||||
- :meth:`~Client.get_messages`
|
||||
- :meth:`~Client.get_history`
|
||||
- :meth:`~Client.get_history_count`
|
||||
- :meth:`~Client.read_history`
|
||||
- :meth:`~Client.iter_history`
|
||||
- :meth:`~Client.send_poll`
|
||||
- :meth:`~Client.vote_poll`
|
||||
- :meth:`~Client.stop_poll`
|
||||
- :meth:`~Client.retract_vote`
|
||||
- :meth:`~Client.download_media`
|
||||
|
||||
Chats
|
||||
^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.join_chat`
|
||||
- :meth:`~Client.leave_chat`
|
||||
- :meth:`~Client.kick_chat_member`
|
||||
- :meth:`~Client.unban_chat_member`
|
||||
- :meth:`~Client.restrict_chat_member`
|
||||
- :meth:`~Client.promote_chat_member`
|
||||
- :meth:`~Client.export_chat_invite_link`
|
||||
- :meth:`~Client.set_chat_photo`
|
||||
- :meth:`~Client.delete_chat_photo`
|
||||
- :meth:`~Client.set_chat_title`
|
||||
- :meth:`~Client.set_chat_description`
|
||||
- :meth:`~Client.pin_chat_message`
|
||||
- :meth:`~Client.unpin_chat_message`
|
||||
- :meth:`~Client.get_chat`
|
||||
- :meth:`~Client.get_chat_member`
|
||||
- :meth:`~Client.get_chat_members`
|
||||
- :meth:`~Client.get_chat_members_count`
|
||||
- :meth:`~Client.iter_chat_members`
|
||||
- :meth:`~Client.get_dialogs`
|
||||
- :meth:`~Client.iter_dialogs`
|
||||
- :meth:`~Client.get_dialogs_count`
|
||||
- :meth:`~Client.restrict_chat`
|
||||
- :meth:`~Client.update_chat_username`
|
||||
- :meth:`~Client.archive_chats`
|
||||
- :meth:`~Client.unarchive_chats`
|
||||
|
||||
Users
|
||||
^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.get_me`
|
||||
- :meth:`~Client.get_users`
|
||||
- :meth:`~Client.get_profile_photos`
|
||||
- :meth:`~Client.get_profile_photos_count`
|
||||
- :meth:`~Client.iter_profile_photos`
|
||||
- :meth:`~Client.set_profile_photo`
|
||||
- :meth:`~Client.delete_profile_photos`
|
||||
- :meth:`~Client.update_username`
|
||||
- :meth:`~Client.get_user_dc`
|
||||
|
||||
Contacts
|
||||
^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.add_contacts`
|
||||
- :meth:`~Client.get_contacts`
|
||||
- :meth:`~Client.get_contacts_count`
|
||||
- :meth:`~Client.delete_contacts`
|
||||
|
||||
Password
|
||||
^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.enable_cloud_password`
|
||||
- :meth:`~Client.change_cloud_password`
|
||||
- :meth:`~Client.remove_cloud_password`
|
||||
|
||||
Bots
|
||||
^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :meth:`~Client.get_inline_bot_results`
|
||||
- :meth:`~Client.send_inline_bot_result`
|
||||
- :meth:`~Client.answer_callback_query`
|
||||
- :meth:`~Client.answer_inline_query`
|
||||
- :meth:`~Client.request_callback_answer`
|
||||
- :meth:`~Client.send_game`
|
||||
- :meth:`~Client.set_game_score`
|
||||
- :meth:`~Client.get_game_high_scores`
|
||||
|
||||
Advanced Usage (Raw API)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Learn more about these methods at :doc:`Advanced Usage <../topics/advanced-usage>`.
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
- :meth:`~Client.send`
|
||||
- :meth:`~Client.resolve_peer`
|
||||
- :meth:`~Client.save_file`
|
||||
|
||||
-----
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. Utilities
|
||||
.. automethod:: Client.start()
|
||||
.. automethod:: Client.stop()
|
||||
.. automethod:: Client.restart()
|
||||
.. automethod:: Client.idle()
|
||||
.. automethod:: Client.run()
|
||||
.. automethod:: Client.add_handler()
|
||||
.. automethod:: Client.remove_handler()
|
||||
.. automethod:: Client.stop_transmission()
|
||||
|
||||
.. Messages
|
||||
.. automethod:: Client.send_message()
|
||||
.. automethod:: Client.forward_messages()
|
||||
.. automethod:: Client.send_photo()
|
||||
.. automethod:: Client.send_audio()
|
||||
.. automethod:: Client.send_document()
|
||||
.. automethod:: Client.send_sticker()
|
||||
.. automethod:: Client.send_animated_sticker()
|
||||
.. automethod:: Client.send_video()
|
||||
.. automethod:: Client.send_animation()
|
||||
.. automethod:: Client.send_voice()
|
||||
.. automethod:: Client.send_video_note()
|
||||
.. automethod:: Client.send_media_group()
|
||||
.. automethod:: Client.send_location()
|
||||
.. automethod:: Client.send_venue()
|
||||
.. automethod:: Client.send_contact()
|
||||
.. automethod:: Client.send_cached_media()
|
||||
.. automethod:: Client.send_chat_action()
|
||||
.. automethod:: Client.edit_message_text()
|
||||
.. automethod:: Client.edit_message_caption()
|
||||
.. automethod:: Client.edit_message_media()
|
||||
.. automethod:: Client.edit_message_reply_markup()
|
||||
.. automethod:: Client.edit_inline_text()
|
||||
.. automethod:: Client.edit_inline_caption()
|
||||
.. automethod:: Client.edit_inline_media()
|
||||
.. automethod:: Client.edit_inline_reply_markup()
|
||||
.. automethod:: Client.delete_messages()
|
||||
.. automethod:: Client.get_messages()
|
||||
.. automethod:: Client.get_history()
|
||||
.. automethod:: Client.get_history_count()
|
||||
.. automethod:: Client.read_history()
|
||||
.. automethod:: Client.iter_history()
|
||||
.. automethod:: Client.send_poll()
|
||||
.. automethod:: Client.vote_poll()
|
||||
.. automethod:: Client.stop_poll()
|
||||
.. automethod:: Client.retract_vote()
|
||||
.. automethod:: Client.download_media()
|
||||
|
||||
.. Chats
|
||||
.. automethod:: Client.join_chat()
|
||||
.. automethod:: Client.leave_chat()
|
||||
.. automethod:: Client.kick_chat_member()
|
||||
.. automethod:: Client.unban_chat_member()
|
||||
.. automethod:: Client.restrict_chat_member()
|
||||
.. automethod:: Client.promote_chat_member()
|
||||
.. automethod:: Client.export_chat_invite_link()
|
||||
.. automethod:: Client.set_chat_photo()
|
||||
.. automethod:: Client.delete_chat_photo()
|
||||
.. automethod:: Client.set_chat_title()
|
||||
.. automethod:: Client.set_chat_description()
|
||||
.. automethod:: Client.pin_chat_message()
|
||||
.. automethod:: Client.unpin_chat_message()
|
||||
.. automethod:: Client.get_chat()
|
||||
.. automethod:: Client.get_chat_member()
|
||||
.. automethod:: Client.get_chat_members()
|
||||
.. automethod:: Client.get_chat_members_count()
|
||||
.. automethod:: Client.iter_chat_members()
|
||||
.. automethod:: Client.get_dialogs()
|
||||
.. automethod:: Client.iter_dialogs()
|
||||
.. automethod:: Client.get_dialogs_count()
|
||||
.. automethod:: Client.restrict_chat()
|
||||
.. automethod:: Client.update_chat_username()
|
||||
.. automethod:: Client.archive_chats()
|
||||
.. automethod:: Client.unarchive_chats()
|
||||
|
||||
.. Users
|
||||
.. automethod:: Client.get_me()
|
||||
.. automethod:: Client.get_users()
|
||||
.. automethod:: Client.get_profile_photos()
|
||||
.. automethod:: Client.get_profile_photos_count()
|
||||
.. automethod:: Client.iter_profile_photos()
|
||||
.. automethod:: Client.set_profile_photo()
|
||||
.. automethod:: Client.delete_profile_photos()
|
||||
.. automethod:: Client.update_username()
|
||||
.. automethod:: Client.get_user_dc()
|
||||
|
||||
.. Contacts
|
||||
.. automethod:: Client.add_contacts()
|
||||
.. automethod:: Client.get_contacts()
|
||||
.. automethod:: Client.get_contacts_count()
|
||||
.. automethod:: Client.delete_contacts()
|
||||
|
||||
.. Password
|
||||
.. automethod:: Client.enable_cloud_password()
|
||||
.. automethod:: Client.change_cloud_password()
|
||||
.. automethod:: Client.remove_cloud_password()
|
||||
|
||||
.. Bots
|
||||
.. automethod:: Client.get_inline_bot_results()
|
||||
.. automethod:: Client.send_inline_bot_result()
|
||||
.. automethod:: Client.answer_callback_query()
|
||||
.. automethod:: Client.answer_inline_query()
|
||||
.. automethod:: Client.request_callback_answer()
|
||||
.. automethod:: Client.send_game()
|
||||
.. automethod:: Client.set_game_score()
|
||||
.. automethod:: Client.get_game_high_scores()
|
||||
|
||||
.. Advanced Usage
|
||||
.. automethod:: Client.send()
|
||||
.. automethod:: Client.resolve_peer()
|
||||
.. automethod:: Client.save_file()
|
170
docs/source/api/types.rst
Normal file
170
docs/source/api/types.rst
Normal file
@ -0,0 +1,170 @@
|
||||
Available Types
|
||||
===============
|
||||
|
||||
All Pyrogram types listed here are accessible through the main package directly.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1
|
||||
|
||||
from pyrogram import User, Message, ...
|
||||
|
||||
.. note::
|
||||
|
||||
**Optional** fields may not exist when irrelevant -- i.e.: they will contain the value of ``None`` and aren't shown
|
||||
when, for example, using ``print()``.
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Index
|
||||
-----
|
||||
|
||||
Users & Chats
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 5
|
||||
|
||||
- :class:`User`
|
||||
- :class:`UserStatus`
|
||||
- :class:`Chat`
|
||||
- :class:`ChatPreview`
|
||||
- :class:`ChatPhoto`
|
||||
- :class:`ChatMember`
|
||||
- :class:`ChatPermissions`
|
||||
- :class:`Dialog`
|
||||
|
||||
Messages & Media
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 5
|
||||
|
||||
- :class:`Message`
|
||||
- :class:`MessageEntity`
|
||||
- :class:`Photo`
|
||||
- :class:`Thumbnail`
|
||||
- :class:`Audio`
|
||||
- :class:`Document`
|
||||
- :class:`Animation`
|
||||
- :class:`Video`
|
||||
- :class:`Voice`
|
||||
- :class:`VideoNote`
|
||||
- :class:`Contact`
|
||||
- :class:`Location`
|
||||
- :class:`Venue`
|
||||
- :class:`Sticker`
|
||||
- :class:`Game`
|
||||
- :class:`Poll`
|
||||
- :class:`PollOption`
|
||||
|
||||
Bots & Keyboards
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
- :class:`ReplyKeyboardMarkup`
|
||||
- :class:`KeyboardButton`
|
||||
- :class:`ReplyKeyboardRemove`
|
||||
- :class:`InlineKeyboardMarkup`
|
||||
- :class:`InlineKeyboardButton`
|
||||
- :class:`ForceReply`
|
||||
- :class:`CallbackQuery`
|
||||
- :class:`GameHighScore`
|
||||
- :class:`CallbackGame`
|
||||
|
||||
Input Media
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
- :class:`InputMedia`
|
||||
- :class:`InputMediaPhoto`
|
||||
- :class:`InputMediaVideo`
|
||||
- :class:`InputMediaAudio`
|
||||
- :class:`InputMediaAnimation`
|
||||
- :class:`InputMediaDocument`
|
||||
- :class:`InputPhoneContact`
|
||||
|
||||
Inline Mode
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :class:`InlineQuery`
|
||||
- :class:`InlineQueryResult`
|
||||
- :class:`InlineQueryResultArticle`
|
||||
|
||||
InputMessageContent
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 3
|
||||
|
||||
- :class:`InputMessageContent`
|
||||
- :class:`InputTextMessageContent`
|
||||
|
||||
-----
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
.. User & Chats
|
||||
.. autoclass:: User()
|
||||
.. autoclass:: UserStatus()
|
||||
.. autoclass:: Chat()
|
||||
.. autoclass:: ChatPreview()
|
||||
.. autoclass:: ChatPhoto()
|
||||
.. autoclass:: ChatMember()
|
||||
.. autoclass:: ChatPermissions()
|
||||
.. autoclass:: Dialog()
|
||||
|
||||
.. Messages & Media
|
||||
.. autoclass:: Message()
|
||||
.. autoclass:: MessageEntity()
|
||||
.. autoclass:: Photo()
|
||||
.. autoclass:: Thumbnail()
|
||||
.. autoclass:: Audio()
|
||||
.. autoclass:: Document()
|
||||
.. autoclass:: Animation()
|
||||
.. autoclass:: Video()
|
||||
.. autoclass:: Voice()
|
||||
.. autoclass:: VideoNote()
|
||||
.. autoclass:: Contact()
|
||||
.. autoclass:: Location()
|
||||
.. autoclass:: Venue()
|
||||
.. autoclass:: Sticker()
|
||||
.. autoclass:: Game()
|
||||
.. autoclass:: Poll()
|
||||
.. autoclass:: PollOption()
|
||||
|
||||
.. Bots & Keyboards
|
||||
.. autoclass:: ReplyKeyboardMarkup()
|
||||
.. autoclass:: KeyboardButton()
|
||||
.. autoclass:: ReplyKeyboardRemove()
|
||||
.. autoclass:: InlineKeyboardMarkup()
|
||||
.. autoclass:: InlineKeyboardButton()
|
||||
.. autoclass:: ForceReply()
|
||||
.. autoclass:: CallbackQuery()
|
||||
.. autoclass:: GameHighScore()
|
||||
.. autoclass:: CallbackGame()
|
||||
|
||||
.. Input Media
|
||||
.. autoclass:: InputMedia()
|
||||
.. autoclass:: InputMediaPhoto()
|
||||
.. autoclass:: InputMediaVideo()
|
||||
.. autoclass:: InputMediaAudio()
|
||||
.. autoclass:: InputMediaAnimation()
|
||||
.. autoclass:: InputMediaDocument()
|
||||
.. autoclass:: InputPhoneContact()
|
||||
|
||||
.. Inline Mode
|
||||
.. autoclass:: InlineQuery()
|
||||
.. autoclass:: InlineQueryResult()
|
||||
.. autoclass:: InlineQueryResultArticle()
|
||||
|
||||
.. InputMessageContent
|
||||
.. autoclass:: InputMessageContent()
|
||||
.. autoclass:: InputTextMessageContent()
|
@ -1,198 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>
|
||||
#
|
||||
# Pyrogram documentation build configuration file, created by
|
||||
# sphinx-quickstart on Fri Dec 29 11:35:55 2017.
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
# 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.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
# 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.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
sys.path.insert(0, os.path.abspath("../.."))
|
||||
|
||||
# Import after sys.path.insert() to avoid issues
|
||||
from pyrogram import __version__
|
||||
|
||||
from pygments.styles.friendly import FriendlyStyle
|
||||
|
||||
FriendlyStyle.background_color = "#f3f2f1"
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
project = "Pyrogram"
|
||||
copyright = "2017-2019, Dan"
|
||||
author = "Dan"
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinx.ext.autosummary'
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.autosummary"
|
||||
]
|
||||
|
||||
# Don't show source files on docs
|
||||
html_show_sourcelink = True
|
||||
master_doc = "index"
|
||||
source_suffix = ".rst"
|
||||
autodoc_member_order = "bysource"
|
||||
|
||||
# Order by source, not alphabetically
|
||||
autodoc_member_order = 'bysource'
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
#
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Pyrogram'
|
||||
copyright = '2017-2019, Dan Tès'
|
||||
author = 'Dan Tès'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = "version " + __version__
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
version = __version__
|
||||
release = version
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This patterns also effect to html_static_path and html_extra_path
|
||||
exclude_patterns = []
|
||||
napoleon_use_rtype = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'friendly'
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
pygments_style = "friendly"
|
||||
|
||||
html_title = "Pyrogram Documentation"
|
||||
|
||||
# Overridden by template
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_static_path = ["_static"]
|
||||
html_show_sourcelink = True
|
||||
html_show_copyright = False
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
html_theme_options = {
|
||||
'canonical_url': "https://docs.pyrogram.ml/",
|
||||
'collapse_navigation': False,
|
||||
'sticky_navigation': False,
|
||||
'logo_only': True,
|
||||
'display_version': True
|
||||
"canonical_url": "https://docs.pyrogram.org/",
|
||||
"collapse_navigation": True,
|
||||
"sticky_navigation": True,
|
||||
"logo_only": True,
|
||||
"display_version": True,
|
||||
"style_external_links": True
|
||||
}
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
html_logo = '_images/logo.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = '_images/favicon.ico'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# This is required for the alabaster theme
|
||||
# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
|
||||
html_sidebars = {
|
||||
'**': [
|
||||
'relations.html', # needs 'show_related': True theme option to display
|
||||
'searchbox.html',
|
||||
]
|
||||
}
|
||||
|
||||
# -- Options for HTMLHelp output ------------------------------------------
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Pyrogramdoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
# 'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
# 'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
# 'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'Pyrogram.tex', 'Pyrogram Documentation',
|
||||
'Dan Tès', 'manual'),
|
||||
]
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'pyrogram', 'Pyrogram Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Pyrogram', 'Pyrogram Documentation',
|
||||
author, 'Pyrogram', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
html_logo = "_images/pyrogram.png"
|
||||
html_favicon = "_images/favicon.ico"
|
||||
|
@ -1,7 +0,0 @@
|
||||
400 - Bad Request
|
||||
=================
|
||||
|
||||
.. module:: pyrogram.errors.BadRequest
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.bad_request_400
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
420 - Flood
|
||||
===========
|
||||
|
||||
.. module:: pyrogram.errors.Flood
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.flood_420
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
403 - Forbidden
|
||||
===============
|
||||
|
||||
.. module:: pyrogram.errors.Forbidden
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.forbidden_403
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
500 - Internal Server Error
|
||||
===========================
|
||||
|
||||
.. module:: pyrogram.errors.InternalServerError
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.internal_server_error_500
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
406 - Not Acceptable
|
||||
====================
|
||||
|
||||
.. module:: pyrogram.errors.NotAcceptable
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.not_acceptable_406
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
303 - See Other
|
||||
===============
|
||||
|
||||
.. module:: pyrogram.errors.SeeOther
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.see_other_303
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
401 - Unauthorized
|
||||
==================
|
||||
|
||||
.. module:: pyrogram.errors.Unauthorized
|
||||
|
||||
.. automodule:: pyrogram.errors.exceptions.unauthorized_401
|
||||
:members:
|
@ -1,7 +0,0 @@
|
||||
520 - Unknown Error
|
||||
===================
|
||||
|
||||
.. module:: pyrogram.errors.UnknownError
|
||||
|
||||
.. autoexception:: pyrogram.errors.rpc_error.UnknownError
|
||||
:members:
|
273
docs/source/faq.rst
Normal file
273
docs/source/faq.rst
Normal file
@ -0,0 +1,273 @@
|
||||
Pyrogram FAQ
|
||||
============
|
||||
|
||||
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
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
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 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.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **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
|
||||
|
||||
How stable and reliable is Pyrogram?
|
||||
------------------------------------
|
||||
|
||||
So far, since its first public release, Pyrogram has always shown itself to be quite reliable in handling client-server
|
||||
interconnections and just as stable when keeping long running applications online. The only annoying issues faced are
|
||||
actually coming from Telegram servers internal errors and down times, from which Pyrogram is able to recover itself
|
||||
automatically.
|
||||
|
||||
To challenge the framework, the creator is constantly keeping a public
|
||||
`welcome bot <https://github.com/pyrogram/pyrogram/blob/develop/examples/welcomebot.py>`_ online 24/7 on his own,
|
||||
relatively-busy account for well over a year now.
|
||||
|
||||
In addition to that, about six months ago, one of the most popular Telegram bot has been rewritten
|
||||
:doc:`using Pyrogram <powered-by>` and is serving more than 200,000 Monthly Active Users since
|
||||
then, uninterruptedly and without any need for restarting it.
|
||||
|
||||
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/C108qkX.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 the same file_id across different accounts?
|
||||
-----------------------------------------------------
|
||||
|
||||
No, Telegram doesn't allow this.
|
||||
|
||||
File ids are personal and bound to a specific user/bot -- and 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_ids in Pyrogram?
|
||||
-----------------------------------------
|
||||
|
||||
Definitely! All file ids you might have taken from the Bot API are 100% compatible and re-usable in Pyrogram...
|
||||
|
||||
...at least for now.
|
||||
|
||||
Telegram is slowly changing some server's internals and it's doing it in such a way that file ids are going to break
|
||||
inevitably. Not only this, but it seems that the new, hypothetical, file ids could also possibly expire at anytime, thus
|
||||
losing the *persistence* feature.
|
||||
|
||||
This change will most likely affect the official :doc:`Bot API <topics/mtproto-vs-botapi>` too (unless Telegram
|
||||
implements some workarounds server-side to keep backwards compatibility, which Pyrogram could in turn make use of) and
|
||||
we can expect a proper notice from Telegram.
|
||||
|
||||
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 ended 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.
|
||||
|
||||
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 (each of which can work
|
||||
independently) spread in 5 different locations. However, some of the less busy DCs have been lately dismissed and their
|
||||
IP addresses are now kept as aliases.
|
||||
|
||||
.. csv-table:: Production Environment
|
||||
:header: ID, Location, IPv4, IPv6
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
DC1, "MIA, Miami FL, USA", ``149.154.175.50``, ``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.149``, ``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``
|
||||
|
||||
***** Alias DC
|
||||
|
||||
More info about the Test Environment can be found :doc:`here <topics/test-servers>`.
|
||||
|
||||
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.
|
||||
|
||||
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 refers to a user you have't seen yet (from contacts, groups in common, forwarded messages or private
|
||||
chats).
|
||||
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
|
||||
|
||||
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 one.
|
||||
|
||||
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``.
|
||||
|
||||
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 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>
|
||||
|
||||
.. centered:: Join the discussion at `@Pyrogram <https://t.me/pyrogram>`_
|
||||
|
||||
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
|
79
docs/source/glossary.rst
Normal file
79
docs/source/glossary.rst
Normal file
@ -0,0 +1,79 @@
|
||||
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`_.
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Session
|
||||
Also known as *login session*, is a strictly personal piece of information 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
|
@ -4,8 +4,8 @@ Welcome to Pyrogram
|
||||
.. raw:: html
|
||||
|
||||
<div align="center">
|
||||
<a href="https://docs.pyrogram.ml">
|
||||
<div><img src="_static/logo.png" alt="Pyrogram Logo"></div>
|
||||
<a href="/">
|
||||
<div><img src="_static/pyrogram.png" alt="Pyrogram Logo" width="420"></div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -13,26 +13,17 @@ Welcome to Pyrogram
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
|
||||
<br>
|
||||
<a href="https://docs.pyrogram.ml">
|
||||
Documentation
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
Source Code
|
||||
</a>
|
||||
•
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Changelog
|
||||
Releases
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/PyrogramChat">
|
||||
<a href="https://t.me/Pyrogram">
|
||||
Community
|
||||
</a>
|
||||
<br>
|
||||
<a href="compiler/api/source/main_api.tl">
|
||||
<img src="https://img.shields.io/badge/schema-layer%2097-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="Schema Layer">
|
||||
</a>
|
||||
<a href="https://github.com/pyrogram/tgcrypto">
|
||||
<img src="https://img.shields.io/badge/tgcrypto-v1.1.1-eda738.svg?longCache=true&colorA=262b30"
|
||||
alt="TgCrypto Version">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
.. code-block:: python
|
||||
@ -49,73 +40,122 @@ Welcome to Pyrogram
|
||||
|
||||
app.run()
|
||||
|
||||
Welcome to Pyrogram's Documentation! Here you can find resources for learning how to use the framework.
|
||||
Contents are organized into self-contained topics and can be accessed from the sidebar, or by following them in order
|
||||
using the Next button at the end of each page. But first, here's a brief overview of what is this all about.
|
||||
**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 apps for both user and bot identities (bot API alternative) via the
|
||||
:doc:`MTProto API <topics/mtproto-vs-botapi>`.
|
||||
|
||||
About
|
||||
-----
|
||||
.. _Telegram: https://telegram.org
|
||||
|
||||
**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 apps using both user and bot identities (bot API alternative) via the `MTProto API`_.
|
||||
How the Documentation is Organized
|
||||
----------------------------------
|
||||
|
||||
Features
|
||||
--------
|
||||
Contents are organized into self-contained topics and can be all accessed from the sidebar, or by 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.
|
||||
|
||||
- **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.
|
||||
- **Documented**: Pyrogram API methods, types and public interfaces are well documented.
|
||||
- **Type-hinted**: Exposed Pyrogram types and method parameters are all type-hinted.
|
||||
- **Updated**, to the latest Telegram API version, currently Layer 97 on top of `MTProto 2.0`_.
|
||||
- **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.
|
||||
First Steps
|
||||
-----------
|
||||
|
||||
To get started, press the Next button.
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly.
|
||||
- :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods.
|
||||
- :doc:`Handling Updates <start/updates>`: How to handle Telegram updates.
|
||||
- :doc:`Error Handling <start/errors>`: How to handle API errors correctly.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Pyrogram Client <api/client>`: Reference details about the Client class.
|
||||
- :doc:`Available Methods <api/methods>`: List of available high-level methods.
|
||||
- :doc:`Available Types <api/types>`: List of available high-level types.
|
||||
- :doc:`Bound Methods <api/bound-methods>`: List of convenient bound methods.
|
||||
|
||||
Meta
|
||||
----
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Pyrogram FAQ <faq>`: Answers to common Pyrogram questions.
|
||||
- :doc:`Pyrogram Glossary <glossary>`: List of words with brief explanations.
|
||||
- :doc:`Powered by Pyrogram <powered-by>`: Collection of Pyrogram Projects.
|
||||
- :doc:`Support Pyrogram <support-pyrogram>`: 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.
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Quick Start
|
||||
:caption: Introduction
|
||||
|
||||
start/Installation
|
||||
start/Setup
|
||||
start/Usage
|
||||
intro/quickstart
|
||||
intro/install
|
||||
intro/setup
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Resources
|
||||
:caption: Getting Started
|
||||
|
||||
resources/UpdateHandling
|
||||
resources/UsingFilters
|
||||
resources/MoreOnUpdates
|
||||
resources/ConfigurationFile
|
||||
resources/SmartPlugins
|
||||
resources/AutoAuthorization
|
||||
resources/CustomizeSessions
|
||||
resources/TgCrypto
|
||||
resources/TextFormatting
|
||||
resources/SOCKS5Proxy
|
||||
resources/BotsInteraction
|
||||
resources/ErrorHandling
|
||||
resources/TestServers
|
||||
resources/AdvancedUsage
|
||||
resources/VoiceCalls
|
||||
resources/Changelog
|
||||
start/auth
|
||||
start/invoking
|
||||
start/updates
|
||||
start/errors
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Main Package
|
||||
:caption: API Reference
|
||||
|
||||
pyrogram/index
|
||||
api/client
|
||||
api/methods
|
||||
api/types
|
||||
api/bound-methods
|
||||
api/handlers
|
||||
api/decorators
|
||||
api/filters
|
||||
api/errors
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Topic Guides
|
||||
|
||||
topics/use-filters
|
||||
topics/create-filters
|
||||
topics/more-on-updates
|
||||
topics/config-file
|
||||
topics/smart-plugins
|
||||
topics/auto-auth
|
||||
topics/session-settings
|
||||
topics/tgcrypto
|
||||
topics/text-formatting
|
||||
topics/serialize
|
||||
topics/proxy
|
||||
topics/bots-interaction
|
||||
topics/mtproto-vs-botapi
|
||||
topics/debugging
|
||||
topics/test-servers
|
||||
topics/advanced-usage
|
||||
topics/voice-calls
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Meta
|
||||
|
||||
faq
|
||||
glossary
|
||||
powered-by
|
||||
support-pyrogram
|
||||
license
|
||||
releases/index
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Telegram API
|
||||
|
||||
functions/index
|
||||
types/index
|
||||
telegram/functions/index
|
||||
telegram/types/index
|
||||
|
||||
.. _`Telegram`: https://telegram.org
|
||||
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
|
||||
.. _`MTProto API`: https://core.telegram.org/api#telegram-api
|
||||
.. _`MTProto 2.0`: https://core.telegram.org/mtproto
|
||||
Last updated on |today|
|
@ -1,8 +1,8 @@
|
||||
Installation
|
||||
============
|
||||
Install Guide
|
||||
=============
|
||||
|
||||
Being a Python library, **Pyrogram** requires Python to be installed in your system.
|
||||
We recommend using the latest version of 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/.
|
||||
@ -20,7 +20,7 @@ Install Pyrogram
|
||||
|
||||
$ pip3 install -U pyrogram
|
||||
|
||||
- or, with TgCrypto_ as extra requirement (recommended):
|
||||
- or, with :doc:`TgCrypto <../topics/tgcrypto>` as extra requirement (recommended):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -29,12 +29,12 @@ Install Pyrogram
|
||||
Bleeding Edge
|
||||
-------------
|
||||
|
||||
Things are constantly evolving in Pyrogram, although new releases are published only when enough changes are added,
|
||||
but this doesn't mean you can't try new features right now!
|
||||
Pyrogram is always evolving, although new releases on PyPI are published only when enough changes are added, but this
|
||||
doesn't mean you can't try new features right now!
|
||||
|
||||
In case you would like to try out the latest Pyrogram features and additions, the `GitHub repo`_ is always kept updated
|
||||
with new changes; you can install the development version straight from the ``develop`` branch using this command
|
||||
(note "develop.zip" in the link):
|
||||
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 ``develop`` branch using this command (note "develop.zip" in
|
||||
the link):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -44,7 +44,8 @@ Asynchronous
|
||||
------------
|
||||
|
||||
Pyrogram heavily depends on IO-bound network code (it's a cloud-based messaging framework after all), and here's
|
||||
where asyncio shines the most by providing extra performance while running on a single OS-level thread only.
|
||||
where asyncio shines the most by providing extra performance and efficiency while running on a single OS-level thread
|
||||
only.
|
||||
|
||||
**A fully asynchronous variant of Pyrogram is therefore available** (Python 3.5.3+ required).
|
||||
Use this command to install (note "asyncio.zip" in the link):
|
||||
@ -54,7 +55,7 @@ Use this command to install (note "asyncio.zip" in the link):
|
||||
$ pip3 install -U https://github.com/pyrogram/pyrogram/archive/asyncio.zip
|
||||
|
||||
|
||||
Pyrogram API remains the same and features are kept up to date from the non-async, default develop branch, but you
|
||||
Pyrogram's API remains the same and features are kept up to date from the non-async, default develop branch, but you
|
||||
are obviously required Python asyncio knowledge in order to take full advantage of it.
|
||||
|
||||
|
||||
@ -82,11 +83,10 @@ Verifying
|
||||
To verify that Pyrogram is correctly installed, open a Python shell and import it.
|
||||
If no error shows up you are good to go.
|
||||
|
||||
.. code-block:: python
|
||||
.. parsed-literal::
|
||||
|
||||
>>> import pyrogram
|
||||
>>> pyrogram.__version__
|
||||
'0.12.0'
|
||||
'|version|'
|
||||
|
||||
.. _TgCrypto: https://docs.pyrogram.ml/resources/TgCrypto
|
||||
.. _`Github repo`: http://github.com/pyrogram/pyrogram
|
49
docs/source/intro/quickstart.rst
Normal file
49
docs/source/intro/quickstart.rst
Normal file
@ -0,0 +1,49 @@
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
The next few steps serve as a quick start for all new Pyrogrammers that want to get something done as fast as possible.
|
||||
Let's go!
|
||||
|
||||
Get Pyrogram Real Fast
|
||||
----------------------
|
||||
|
||||
1. Install Pyrogram with ``pip3 install -U pyrogram``.
|
||||
|
||||
2. Get your own Telegram API key from https://my.telegram.org/apps.
|
||||
|
||||
3. Open your best text editor and paste the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
api_id = 12345
|
||||
api_hash = "0123456789abcdef0123456789abcdef"
|
||||
|
||||
with Client("my_account", api_id, api_hash) as app:
|
||||
app.send_message("me", "Greetings from **Pyrogram**!")
|
||||
|
||||
4. Replace *api_id* and *api_hash* values with your own.
|
||||
|
||||
5. Save the file as ``pyro.py``.
|
||||
|
||||
6. Run the script with ``python3 pyro.py``
|
||||
|
||||
7. Follow the instructions on your terminal to login.
|
||||
|
||||
8. Watch Pyrogram send a message to yourself.
|
||||
|
||||
9. Join our `community`_.
|
||||
|
||||
10. Say, "hi!".
|
||||
|
||||
Enjoy the API
|
||||
-------------
|
||||
|
||||
That was just a quick overview that barely scratched the surface!
|
||||
In the next few pages of the introduction, we'll take a much more in-depth look of what 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
|
||||
learn some more details.
|
||||
|
||||
.. _community: //t.me/Pyrogram
|
59
docs/source/intro/setup.rst
Normal file
59
docs/source/intro/setup.rst
Normal file
@ -0,0 +1,59 @@
|
||||
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
|
||||
project with the library. Let's see how it's done.
|
||||
|
||||
API Keys
|
||||
--------
|
||||
|
||||
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.
|
||||
#. Fill out the form to register a new Telegram application.
|
||||
#. Done! The API key consists of two parts: **api_id** and **api_hash**.
|
||||
|
||||
.. important::
|
||||
|
||||
The API key is personal and must be kept secret.
|
||||
|
||||
.. note::
|
||||
|
||||
The API key is unique for each user, but defines a token for a Telegram *application* you are going to build. This
|
||||
means that you are able to authorize multiple users (and bots too) to access the Telegram database through the
|
||||
MTProto API by a single API key.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
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:
|
||||
|
||||
- First option (recommended): create a new ``config.ini`` file at the root of your working directory, 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 keep your credentials out of your code without having to deal with how to load them:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pyrogram]
|
||||
api_id = 12345
|
||||
api_hash = 0123456789abcdef0123456789abcdef
|
||||
|
||||
- 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
|
||||
credentials from the environment variables and directly pass the values into Pyrogram):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id=12345,
|
||||
api_hash="0123456789abcdef0123456789abcdef"
|
||||
)
|
||||
|
||||
.. note::
|
||||
|
||||
To keep code snippets clean and concise, from now on it is assumed you are making use of the ``config.ini`` file,
|
||||
thus, the *api_id* and *api_hash* parameters usage won't be shown anymore.
|
15
docs/source/license.rst
Normal file
15
docs/source/license.rst
Normal file
@ -0,0 +1,15 @@
|
||||
About the License
|
||||
=================
|
||||
|
||||
.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png
|
||||
:align: right
|
||||
|
||||
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
|
69
docs/source/powered-by.rst
Normal file
69
docs/source/powered-by.rst
Normal file
@ -0,0 +1,69 @@
|
||||
Powered by Pyrogram
|
||||
===================
|
||||
|
||||
This is a collection of remarkable projects made with Pyrogram.
|
||||
|
||||
.. A collection of Pyrojects :^)
|
||||
|
||||
.. tip::
|
||||
|
||||
If you'd like to propose a project that's worth being listed here, feel free to open a `Feature Request`_.
|
||||
|
||||
Projects Showcase
|
||||
-----------------
|
||||
|
||||
`YTAudioBot <https://t.me/ytaudio>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| **A YouTube audio downloader on Telegram, serving over 200k MAU.**
|
||||
| --- by `Dan <https://t.me/haskell>`_
|
||||
|
||||
- Main: https://t.me/ytaudiobot
|
||||
- Mirror: https://t.me/ytaudio_bot
|
||||
- Website: https://ytaudiobot.ml
|
||||
|
||||
-----
|
||||
|
||||
`Pyrogram Assistant <https://github.com/pyrogram/assistant>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| **The assistant bot that helps people with Pyrogram directly on Telegram**
|
||||
| --- by `Dan <https://t.me/haskell>`_
|
||||
|
||||
- Bot: https://t.me/pyrogrambot
|
||||
- Source Code: https://github.com/pyrogram/assistant
|
||||
|
||||
-----
|
||||
|
||||
`PyroBot <https://git.colinshark.de/PyroBot/PyroBot>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| **A Telegram userbot based on Pyrogram**
|
||||
| --- by `Colin <https://t.me/ColinShark>`_
|
||||
|
||||
- Source Code: https://git.colinshark.de/PyroBot/PyroBot
|
||||
|
||||
-----
|
||||
|
||||
`TgIntegration <https://github.com/JosXa/tgintegration>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| **Integration Test Library for Telegram Messenger Bots in Python**
|
||||
| --- by `JosXa <https://t.me/JosXa>`_
|
||||
|
||||
- Source Code: https://github.com/JosXa/tgintegration
|
||||
|
||||
-----
|
||||
|
||||
`BotListBot <https://t.me/botlist>`_
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
| **A bot which partly uses Pyrogram to check if other bots are still alive**
|
||||
| --- by `JosXa <https://t.me/JosXa>`_
|
||||
|
||||
- Source Code: https://github.com/JosXa/BotListBot
|
||||
|
||||
-----
|
||||
|
||||
.. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md
|
||||
|
@ -1,5 +0,0 @@
|
||||
ChatAction
|
||||
==========
|
||||
|
||||
.. autoclass:: pyrogram.ChatAction
|
||||
:members:
|
@ -1,158 +0,0 @@
|
||||
Client
|
||||
======
|
||||
|
||||
.. currentmodule:: pyrogram.Client
|
||||
|
||||
.. autoclass:: pyrogram.Client
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
start
|
||||
stop
|
||||
restart
|
||||
idle
|
||||
run
|
||||
add_handler
|
||||
remove_handler
|
||||
send
|
||||
resolve_peer
|
||||
save_file
|
||||
stop_transmission
|
||||
|
||||
Decorators
|
||||
----------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
on_message
|
||||
on_callback_query
|
||||
on_inline_query
|
||||
on_deleted_messages
|
||||
on_user_status
|
||||
on_disconnect
|
||||
on_raw_update
|
||||
|
||||
Messages
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
send_message
|
||||
forward_messages
|
||||
send_photo
|
||||
send_audio
|
||||
send_document
|
||||
send_sticker
|
||||
send_video
|
||||
send_animation
|
||||
send_voice
|
||||
send_video_note
|
||||
send_media_group
|
||||
send_location
|
||||
send_venue
|
||||
send_contact
|
||||
send_cached_media
|
||||
send_chat_action
|
||||
edit_message_text
|
||||
edit_message_caption
|
||||
edit_message_reply_markup
|
||||
edit_message_media
|
||||
delete_messages
|
||||
get_messages
|
||||
get_history
|
||||
iter_history
|
||||
send_poll
|
||||
vote_poll
|
||||
close_poll
|
||||
retract_vote
|
||||
download_media
|
||||
|
||||
Chats
|
||||
-----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
join_chat
|
||||
leave_chat
|
||||
kick_chat_member
|
||||
unban_chat_member
|
||||
restrict_chat_member
|
||||
promote_chat_member
|
||||
export_chat_invite_link
|
||||
set_chat_photo
|
||||
delete_chat_photo
|
||||
set_chat_title
|
||||
set_chat_description
|
||||
pin_chat_message
|
||||
unpin_chat_message
|
||||
get_chat
|
||||
get_chat_preview
|
||||
get_chat_member
|
||||
get_chat_members
|
||||
get_chat_members_count
|
||||
iter_chat_members
|
||||
get_dialogs
|
||||
iter_dialogs
|
||||
restrict_chat
|
||||
update_chat_username
|
||||
|
||||
Users
|
||||
-----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
get_me
|
||||
get_users
|
||||
get_user_profile_photos
|
||||
set_user_profile_photo
|
||||
delete_user_profile_photos
|
||||
update_username
|
||||
|
||||
Contacts
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
add_contacts
|
||||
get_contacts
|
||||
delete_contacts
|
||||
|
||||
Password
|
||||
--------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
enable_cloud_password
|
||||
change_cloud_password
|
||||
remove_cloud_password
|
||||
|
||||
Bots
|
||||
----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
get_inline_bot_results
|
||||
send_inline_bot_result
|
||||
answer_callback_query
|
||||
answer_inline_query
|
||||
request_callback_answer
|
||||
send_game
|
||||
set_game_score
|
||||
get_game_high_scores
|
||||
answer_inline_query
|
||||
|
||||
|
||||
.. autoclass:: pyrogram.Client
|
||||
:inherited-members:
|
||||
:members:
|
@ -1,37 +0,0 @@
|
||||
Handlers
|
||||
========
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
MessageHandler
|
||||
DeletedMessagesHandler
|
||||
CallbackQueryHandler
|
||||
InlineQueryHandler
|
||||
UserStatusHandler
|
||||
DisconnectHandler
|
||||
RawUpdateHandler
|
||||
|
||||
.. autoclass:: MessageHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: DeletedMessagesHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: CallbackQueryHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineQueryHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: UserStatusHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: DisconnectHandler
|
||||
:members:
|
||||
|
||||
.. autoclass:: RawUpdateHandler
|
||||
:members:
|
||||
|
@ -1,6 +0,0 @@
|
||||
ParseMode
|
||||
=========
|
||||
|
||||
.. autoclass:: pyrogram.ParseMode
|
||||
:members:
|
||||
:undoc-members:
|
@ -1,15 +0,0 @@
|
||||
RPCError
|
||||
========
|
||||
|
||||
.. autoexception:: pyrogram.RPCError
|
||||
:members:
|
||||
|
||||
.. toctree::
|
||||
../errors/SeeOther
|
||||
../errors/BadRequest
|
||||
../errors/Unauthorized
|
||||
../errors/Forbidden
|
||||
../errors/NotAcceptable
|
||||
../errors/Flood
|
||||
../errors/InternalServerError
|
||||
../errors/UnknownError
|
@ -1,263 +0,0 @@
|
||||
Types
|
||||
=====
|
||||
|
||||
.. currentmodule:: pyrogram
|
||||
|
||||
Users & Chats
|
||||
-------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
User
|
||||
UserStatus
|
||||
Chat
|
||||
ChatPreview
|
||||
ChatPhoto
|
||||
ChatMember
|
||||
ChatMembers
|
||||
ChatPermissions
|
||||
Dialog
|
||||
Dialogs
|
||||
|
||||
Messages & Media
|
||||
----------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
Message
|
||||
Messages
|
||||
MessageEntity
|
||||
Photo
|
||||
PhotoSize
|
||||
UserProfilePhotos
|
||||
Audio
|
||||
Document
|
||||
Animation
|
||||
Video
|
||||
Voice
|
||||
VideoNote
|
||||
Contact
|
||||
Location
|
||||
Venue
|
||||
Sticker
|
||||
Poll
|
||||
PollOption
|
||||
|
||||
Bots
|
||||
----
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
ReplyKeyboardMarkup
|
||||
KeyboardButton
|
||||
ReplyKeyboardRemove
|
||||
InlineKeyboardMarkup
|
||||
InlineKeyboardButton
|
||||
ForceReply
|
||||
CallbackQuery
|
||||
Game
|
||||
|
||||
Input Media
|
||||
-----------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
InputMedia
|
||||
InputMediaPhoto
|
||||
InputMediaVideo
|
||||
InputMediaAudio
|
||||
InputMediaAnimation
|
||||
InputMediaDocument
|
||||
InputPhoneContact
|
||||
|
||||
Inline Mode
|
||||
------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
InlineQuery
|
||||
InlineQueryResult
|
||||
InlineQueryResultArticle
|
||||
|
||||
InputMessageContent
|
||||
-------------------
|
||||
|
||||
.. autosummary::
|
||||
:nosignatures:
|
||||
|
||||
InputMessageContent
|
||||
InputTextMessageContent
|
||||
|
||||
.. User & Chats
|
||||
------------
|
||||
|
||||
.. autoclass:: User
|
||||
:members:
|
||||
|
||||
.. autoclass:: UserStatus
|
||||
:members:
|
||||
|
||||
.. autoclass:: Chat
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPreview
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPhoto
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatMember
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatMembers
|
||||
:members:
|
||||
|
||||
.. autoclass:: ChatPermissions
|
||||
:members:
|
||||
|
||||
.. autoclass:: Dialog
|
||||
:members:
|
||||
|
||||
.. autoclass:: Dialogs
|
||||
:members:
|
||||
|
||||
.. Messages & Media
|
||||
----------------
|
||||
|
||||
.. autoclass:: Message
|
||||
:members:
|
||||
|
||||
.. autoclass:: Messages
|
||||
:members:
|
||||
|
||||
.. autoclass:: MessageEntity
|
||||
:members:
|
||||
|
||||
.. autoclass:: Photo
|
||||
:members:
|
||||
|
||||
.. autoclass:: PhotoSize
|
||||
:members:
|
||||
|
||||
.. autoclass:: UserProfilePhotos
|
||||
:members:
|
||||
|
||||
.. autoclass:: Audio
|
||||
:members:
|
||||
|
||||
.. autoclass:: Document
|
||||
:members:
|
||||
|
||||
.. autoclass:: Animation
|
||||
:members:
|
||||
|
||||
.. autoclass:: Video
|
||||
:members:
|
||||
|
||||
.. autoclass:: Voice
|
||||
:members:
|
||||
|
||||
.. autoclass:: VideoNote
|
||||
:members:
|
||||
|
||||
.. autoclass:: Contact
|
||||
:members:
|
||||
|
||||
.. autoclass:: Location
|
||||
:members:
|
||||
|
||||
.. autoclass:: Venue
|
||||
:members:
|
||||
|
||||
.. autoclass:: Sticker
|
||||
:members:
|
||||
|
||||
.. autoclass:: Poll
|
||||
:members:
|
||||
|
||||
.. autoclass:: PollOption
|
||||
:members:
|
||||
|
||||
.. Bots
|
||||
----
|
||||
|
||||
.. autoclass:: ReplyKeyboardMarkup
|
||||
:members:
|
||||
|
||||
.. autoclass:: KeyboardButton
|
||||
:members:
|
||||
|
||||
.. autoclass:: ReplyKeyboardRemove
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineKeyboardMarkup
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineKeyboardButton
|
||||
:members:
|
||||
|
||||
.. autoclass:: ForceReply
|
||||
:members:
|
||||
|
||||
.. autoclass:: CallbackQuery
|
||||
:members:
|
||||
|
||||
.. autoclass:: Game
|
||||
:members:
|
||||
|
||||
.. autoclass:: GameHighScore
|
||||
:members:
|
||||
|
||||
.. autoclass:: GameHighScores
|
||||
:members:
|
||||
|
||||
.. Input Media
|
||||
-----------
|
||||
|
||||
.. autoclass:: InputMedia
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaPhoto
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaVideo
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaAudio
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaAnimation
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputMediaDocument
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputPhoneContact
|
||||
:members:
|
||||
|
||||
|
||||
.. Inline Mode
|
||||
-----------
|
||||
|
||||
.. autoclass:: InlineQuery
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineQueryResult
|
||||
:members:
|
||||
|
||||
.. autoclass:: InlineQueryResultArticle
|
||||
:members:
|
||||
|
||||
.. InputMessageContent
|
||||
-------------------
|
||||
|
||||
.. autoclass:: InputMessageContent
|
||||
:members:
|
||||
|
||||
.. autoclass:: InputTextMessageContent
|
||||
:members:
|
@ -1,20 +0,0 @@
|
||||
Pyrogram
|
||||
========
|
||||
|
||||
In this section you can find a detailed description of the Pyrogram package and its API.
|
||||
|
||||
:class:`Client <pyrogram.Client>` is the main class. It exposes easy-to-use methods that are named
|
||||
after the well established `Telegram Bot API`_ methods, thus offering a familiar look to Bot developers.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
Client
|
||||
Types
|
||||
Handlers
|
||||
Filters
|
||||
ChatAction
|
||||
ParseMode
|
||||
RPCError
|
||||
|
||||
.. _Telegram Bot API: https://core.telegram.org/bots/api#available-methods
|
@ -1,11 +0,0 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
Currently, all Pyrogram release notes live inside the GitHub repository web page:
|
||||
https://github.com/pyrogram/pyrogram/releases
|
||||
|
||||
(You will be automatically redirected in 10 seconds.)
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<meta http-equiv="refresh" content="10; URL=https://github.com/pyrogram/pyrogram/releases"/>
|
@ -1,59 +0,0 @@
|
||||
Error Handling
|
||||
==============
|
||||
|
||||
Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks.
|
||||
|
||||
There are many errors that Telegram could return, but they all fall in one of these categories
|
||||
(which are in turn children of the :obj:`RPCError <pyrogram.RPCError>` superclass):
|
||||
|
||||
- :obj:`303 - See Other <pyrogram.errors.SeeOther>`
|
||||
- :obj:`400 - Bad Request <pyrogram.errors.BadRequest>`
|
||||
- :obj:`401 - Unauthorized <pyrogram.errors.Unauthorized>`
|
||||
- :obj:`403 - Forbidden <pyrogram.errors.Forbidden>`
|
||||
- :obj:`406 - Not Acceptable <pyrogram.errors.NotAcceptable>`
|
||||
- :obj:`420 - Flood <pyrogram.errors.Flood>`
|
||||
- :obj:`500 - Internal Server Error <pyrogram.errors.InternalServerError>`
|
||||
|
||||
As stated above, there are really many (too many) errors, and in case Pyrogram does not know anything yet about a
|
||||
specific one, it raises a special :obj:`520 Unknown Error <pyrogram.errors.UnknownError>` exception and logs it
|
||||
in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors; in later versions of Pyrogram
|
||||
some kind of automatic error reporting module might be implemented.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram.errors import (
|
||||
BadRequest, Flood, InternalServerError,
|
||||
SeeOther, Unauthorized, UnknownError
|
||||
)
|
||||
|
||||
try:
|
||||
...
|
||||
except BadRequest:
|
||||
pass
|
||||
except Flood:
|
||||
pass
|
||||
except InternalServerError:
|
||||
pass
|
||||
except SeeOther:
|
||||
pass
|
||||
except Unauthorized:
|
||||
pass
|
||||
except UnknownError:
|
||||
pass
|
||||
|
||||
Exception objects may also contain some informative values.
|
||||
E.g.: :obj:`FloodWait <pyrogram.errors.exceptions.flood_420.FloodWait>` holds the amount of seconds you have to wait
|
||||
before you can try again. The value is always stored in the ``x`` field of the returned exception object:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import time
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
try:
|
||||
...
|
||||
except FloodWait as e:
|
||||
time.sleep(e.x)
|
@ -1,72 +0,0 @@
|
||||
Update Handling
|
||||
===============
|
||||
|
||||
Let's now dive right into the core of the framework.
|
||||
|
||||
Updates are events that happen in your Telegram account (incoming messages, new channel posts, new members join, ...)
|
||||
and are handled by registering one or more callback functions in your app using `Handlers <../pyrogram/Handlers.html>`_.
|
||||
|
||||
Each handler deals with a specific event and once a matching update arrives from Telegram, your registered callback
|
||||
function will be called.
|
||||
|
||||
Registering an Handler
|
||||
----------------------
|
||||
|
||||
To explain how handlers work let's have a look at the most used one, the
|
||||
:obj:`MessageHandler <pyrogram.MessageHandler>`, which will be in charge for handling :obj:`Message <pyrogram.Message>`
|
||||
updates coming from all around your chats. Every other handler shares the same setup logic; you should not have troubles
|
||||
settings them up once you learn from this section.
|
||||
|
||||
Using add_handler()
|
||||
-------------------
|
||||
|
||||
The :meth:`add_handler() <pyrogram.Client.add_handler>` method takes any handler instance that wraps around your defined
|
||||
callback function and registers it in your Client. Here's a full example that prints out the content of a message as
|
||||
soon as it arrives:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, MessageHandler
|
||||
|
||||
|
||||
def my_function(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
app.add_handler(my_handler)
|
||||
|
||||
app.run()
|
||||
|
||||
Using Decorators
|
||||
----------------
|
||||
|
||||
A much nicer way to register a MessageHandler is by decorating your callback function with the
|
||||
:meth:`on_message() <pyrogram.Client.on_message>` decorator, which will still make use of add_handler() under the hood.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message()
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Due to how these decorators work in Pyrogram, they will wrap your defined callback function in a tuple consisting of
|
||||
``(handler, group)``; this will be the value held by your function identifier (e.g.: *my_function* from the example
|
||||
above).
|
||||
|
||||
In case, for some reason, you want to get your own function back after it has been decorated, you need to access
|
||||
``my_function[0].callback``, that is, the *callback* field of the *handler* object which is the first element in the
|
||||
tuple.
|
@ -1,194 +0,0 @@
|
||||
Using Filters
|
||||
=============
|
||||
|
||||
So far we've seen how to register a callback function that executes every time a specific update comes from the server,
|
||||
but there's much more than that to come.
|
||||
|
||||
Here we'll discuss about :class:`Filters <pyrogram.Filters>`. Filters enable a fine-grain control over what kind of
|
||||
updates are allowed or not to be passed in your callback functions, based on their inner details.
|
||||
|
||||
Let's start right away with a simple example:
|
||||
|
||||
- This example will show you how to **only** handle messages containing an :obj:`Audio <pyrogram.Audio>` object and
|
||||
ignore any other message. Filters are passed as the first argument of the decorator:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4
|
||||
|
||||
from pyrogram import Filters
|
||||
|
||||
|
||||
@app.on_message(Filters.audio)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- or, without decorators. Here filters are passed as the second argument of the handler constructor:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 8
|
||||
|
||||
from pyrogram import Filters, MessageHandler
|
||||
|
||||
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(my_handler, Filters.audio))
|
||||
|
||||
Combining Filters
|
||||
-----------------
|
||||
|
||||
Filters can also be used in a more advanced way by inverting and combining more filters together using bitwise
|
||||
operators ``~``, ``&`` and ``|``:
|
||||
|
||||
- Use ``~`` to invert a filter (behaves like the ``not`` operator).
|
||||
- Use ``&`` and ``|`` to merge two filters (behave like ``and``, ``or`` operators respectively).
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- Message is a **text** message **and** is **not edited**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text & ~Filters.edited)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **sticker** **and** is coming from a **channel or** a **private** chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.sticker & (Filters.channel | Filters.private))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
Advanced Filters
|
||||
----------------
|
||||
|
||||
Some filters, like :meth:`command() <pyrogram.Filters.command>` or :meth:`regex() <pyrogram.Filters.regex>`
|
||||
can also accept arguments:
|
||||
|
||||
- Message is either a */start* or */help* **command**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command(["start", "help"]))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **text** message or a media **caption** matching the given **regex** pattern.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.regex("pyrogram"))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
More handlers using different filters can also live together.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command("start"))
|
||||
def start_command(client, message):
|
||||
print("This is the /start command")
|
||||
|
||||
|
||||
@app.on_message(Filters.command("help"))
|
||||
def help_command(client, message):
|
||||
print("This is the /help command")
|
||||
|
||||
|
||||
@app.on_message(Filters.chat("PyrogramChat"))
|
||||
def from_pyrogramchat(client, message):
|
||||
print("New message in @PyrogramChat")
|
||||
|
||||
Custom Filters
|
||||
--------------
|
||||
|
||||
Pyrogram already provides lots of built-in :class:`Filters <pyrogram.Filters>` to work with, but in case you can't find
|
||||
a specific one for your needs or want to build a custom filter by yourself (to be used in a different kind of handler,
|
||||
for example) you can use :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
.. note::
|
||||
At the moment, the built-in filters are intended to be used with the :obj:`MessageHandler <pyrogram.MessageHandler>`
|
||||
only.
|
||||
|
||||
An example to demonstrate how custom filters work is to show how to create and use one for the
|
||||
:obj:`CallbackQueryHandler <pyrogram.CallbackQueryHandler>`. Note that callback queries updates are only received by
|
||||
bots; create and `authorize your bot <../start/Setup.html#bot-authorization>`_, then send a message with an inline
|
||||
keyboard to yourself. This allows you to test your filter by pressing the inline button:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
app.send_message(
|
||||
"username", # Change this to your username or id
|
||||
"Pyrogram's custom filter test",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[[InlineKeyboardButton("Press me", b"pyrogram")]]
|
||||
)
|
||||
)
|
||||
|
||||
Basic Filters
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
For this basic filter we will be using only the first two parameters of :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries
|
||||
containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data
|
||||
equals to ``b"Pyrogram"``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
static_data = Filters.create(
|
||||
name="StaticdData",
|
||||
func=lambda flt, callback_query: callback_query.data == b"Pyrogram"
|
||||
)
|
||||
|
||||
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same
|
||||
could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def func(flt, callback_query):
|
||||
return callback_query.data == b"Pyrogram"
|
||||
|
||||
static_data = Filters.create(
|
||||
name="StaticData",
|
||||
func=func
|
||||
)
|
||||
|
||||
The filter usage remains the same:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(static_data)
|
||||
def pyrogram_data(client, callback_query):
|
||||
client.answer_callback_query(callback_query.id, "it works!")
|
||||
|
||||
Filters with Arguments
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
A much cooler filter would be one that accepts "Pyrogram" or any other data as argument at usage time.
|
||||
A dynamic filter like this will make use of the third parameter of :meth:`Filters.create() <pyrogram.Filters.create>`.
|
||||
|
||||
This is how a dynamic custom filter looks like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def dynamic_data(data):
|
||||
return Filters.create(
|
||||
name="DynamicData",
|
||||
func=lambda flt, callback_query: flt.data == callback_query.data,
|
||||
data=data # "data" kwarg is accessed with "filter.data"
|
||||
)
|
||||
|
||||
And its usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(dynamic_data(b"Pyrogram"))
|
||||
def pyrogram_data(client, callback_query):
|
||||
client.answer_callback_query(callback_query.id, "it works!")
|
@ -1,120 +0,0 @@
|
||||
Setup
|
||||
=====
|
||||
|
||||
Once you successfully `installed Pyrogram`_, you will still have to follow a few steps before you can actually use
|
||||
the library to make API calls. This section provides all the information you need in order to set up a project
|
||||
with Pyrogram.
|
||||
|
||||
API Keys
|
||||
--------
|
||||
|
||||
The very first step requires you to obtain a valid Telegram API key (API id/hash pair).
|
||||
If you already have one you can skip this step, otherwise:
|
||||
|
||||
#. Visit https://my.telegram.org/apps and log in with your Telegram Account.
|
||||
#. Fill out the form to register a new Telegram application.
|
||||
#. Done. The API key consists of two parts: **App api_id** and **App api_hash**.
|
||||
|
||||
.. important::
|
||||
|
||||
This API key is personal and must be kept secret.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The API key obtained in the `previous step <#api-keys>`_ defines a token for your application allowing you to access
|
||||
the Telegram database using the MTProto API — **it is therefore required for all authorizations of both users and bots**.
|
||||
|
||||
Having it handy, it's time to configure your Pyrogram project. There are two ways to do so, and you can choose what
|
||||
fits better for you:
|
||||
|
||||
- Create a new ``config.ini`` file at the root of your working directory, 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 keep your
|
||||
credentials out of your code without having to deal with how to load them:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pyrogram]
|
||||
api_id = 12345
|
||||
api_hash = 0123456789abcdef0123456789abcdef
|
||||
|
||||
- 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:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client(
|
||||
"my_account",
|
||||
api_id=12345,
|
||||
api_hash="0123456789abcdef0123456789abcdef"
|
||||
)
|
||||
|
||||
.. note::
|
||||
|
||||
From now on, the code snippets assume you are using the ``config.ini`` file, thus they won't show the *api_id* and
|
||||
*api_hash* parameters usage to keep them as clean as possible.
|
||||
|
||||
User Authorization
|
||||
------------------
|
||||
|
||||
In order to use the API, Telegram requires that users be authorized via their phone numbers.
|
||||
Pyrogram automatically manages this access, all you need to do is create an instance of the
|
||||
:class:`Client <pyrogram.Client>` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call
|
||||
the :meth:`run() <pyrogram.Client.run>` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
app.run()
|
||||
|
||||
This starts an interactive shell asking you to input your **phone number** (including your `Country Code`_)
|
||||
and the **phone code** you will receive:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Enter phone number: +39**********
|
||||
Is "+39**********" correct? (y/n): y
|
||||
Enter phone code: 32768
|
||||
Logged in successfully as Dan
|
||||
|
||||
After successfully authorizing yourself, a new file called ``my_account.session`` will be created allowing Pyrogram
|
||||
executing API calls with your identity. This file will be loaded again when you restart your app, and as long as you
|
||||
keep the session alive, Pyrogram won't ask you again to enter your phone number.
|
||||
|
||||
.. important::
|
||||
|
||||
Your ``*.session`` files are personal and must be kept secret.
|
||||
|
||||
.. note::
|
||||
|
||||
The code above does nothing except asking for credentials and keeping the client online, hit ``CTRL+C`` now to stop
|
||||
your application and keep reading.
|
||||
|
||||
Bot Authorization
|
||||
-----------------
|
||||
|
||||
Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by
|
||||
BotFather_. Bot tokens replace the users' phone numbers only — you still need to
|
||||
`configure a Telegram API key <#configuration>`_ with Pyrogram, even when using bots.
|
||||
|
||||
The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything,
|
||||
usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named
|
||||
after the session name, which will be ``pyrogrambot.session`` for the example below.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client(
|
||||
"pyrogrambot",
|
||||
bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
|
||||
)
|
||||
app.run()
|
||||
|
||||
.. _installed Pyrogram: Installation.html
|
||||
.. _`Country Code`: https://en.wikipedia.org/wiki/List_of_country_calling_codes
|
||||
.. _BotFather: https://t.me/botfather
|
@ -1,51 +0,0 @@
|
||||
Usage
|
||||
=====
|
||||
|
||||
Having your `project set up`_ and your account authorized_, it's time to start playing with the API. Let's start!
|
||||
|
||||
High-level API
|
||||
--------------
|
||||
|
||||
The easiest and recommended way to interact with Telegram is via the high-level Pyrogram methods_ and types_, which are
|
||||
named after the `Telegram Bot API`_.
|
||||
|
||||
Here's a simple example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
app.start()
|
||||
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
|
||||
app.stop()
|
||||
|
||||
You can also use Pyrogram in a context manager with the ``with`` statement. The Client will automatically
|
||||
:meth:`start <pyrogram.Client.start>` and :meth:`stop <pyrogram.Client.stop>` gracefully, even in case of unhandled
|
||||
exceptions in your code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
|
||||
More examples on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_.
|
||||
|
||||
.. _project set up: Setup.html
|
||||
.. _authorized: Setup.html#user-authorization
|
||||
.. _Telegram Bot API: https://core.telegram.org/bots/api
|
||||
.. _methods: ../pyrogram/Client.html#messages
|
||||
.. _types: ../pyrogram/Types.html
|
68
docs/source/start/auth.rst
Normal file
68
docs/source/start/auth.rst
Normal file
@ -0,0 +1,68 @@
|
||||
Authorization
|
||||
=============
|
||||
|
||||
Once a :doc:`project is set up <../intro/setup>`, you will still have to follow a few steps before you can actually use Pyrogram to make
|
||||
API calls. This section provides all the information you need in order to authorize yourself as user or bot.
|
||||
|
||||
User Authorization
|
||||
------------------
|
||||
|
||||
In order to use the API, Telegram requires that users be authorized via their phone numbers.
|
||||
Pyrogram automatically manages this process, all you need to do is create an instance of the
|
||||
:class:`~pyrogram.Client` class by passing to it a ``session_name`` of your choice (e.g.: "my_account") and call
|
||||
the :meth:`~pyrogram.Client.run` method:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
app.run()
|
||||
|
||||
This starts an interactive shell asking you to input your **phone number** (including your `Country Code`_) and the
|
||||
**phone code** you will receive in your devices that are already authorized or via SMS:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Enter phone number: +39**********
|
||||
Is "+39**********" correct? (y/n): y
|
||||
Enter phone code: 32768
|
||||
Logged in successfully as Dan
|
||||
|
||||
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
|
||||
keep the session alive, Pyrogram won't ask you again to enter your phone number.
|
||||
|
||||
.. important::
|
||||
|
||||
Your ``*.session`` files are personal and must be kept secret.
|
||||
|
||||
.. note::
|
||||
|
||||
The code above does nothing except asking for credentials and keeping the client online, hit :guilabel:`CTRL+C` now
|
||||
to stop your application and keep reading.
|
||||
|
||||
Bot Authorization
|
||||
-----------------
|
||||
|
||||
Bots are a special kind of users that are authorized via their tokens (instead of phone numbers), which are created by
|
||||
the `Bot Father`_. Bot tokens replace the users' phone numbers only — you still need to
|
||||
:doc:`configure a Telegram API key <../intro/setup>` with Pyrogram, even when using bots.
|
||||
|
||||
The authorization process is automatically managed. All you need to do is choose a ``session_name`` (can be anything,
|
||||
usually your bot username) and pass your bot token using the ``bot_token`` parameter. The session file will be named
|
||||
after the session name, which will be ``my_bot.session`` for the example below.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client(
|
||||
"my_bot",
|
||||
bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
|
||||
)
|
||||
|
||||
app.run()
|
||||
|
||||
.. _Country Code: https://en.wikipedia.org/wiki/List_of_country_calling_codes
|
||||
.. _Bot Father: https://t.me/botfather
|
91
docs/source/start/errors.rst
Normal file
91
docs/source/start/errors.rst
Normal file
@ -0,0 +1,91 @@
|
||||
Error Handling
|
||||
==============
|
||||
|
||||
Errors are inevitable when working with the API, and they must be correctly handled with ``try..except`` blocks in order
|
||||
to control the behaviour of your application. Pyrogram errors all live inside the ``errors`` package:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import errors
|
||||
|
||||
RPCError
|
||||
--------
|
||||
|
||||
The father of all errors is named ``RPCError``. This error exists in form of a Python exception which is directly
|
||||
subclass-ed from Python's main ``Exception`` and is able to catch all Telegram API related errors. This error is raised
|
||||
every time a method call against Telegram's API was unsuccessful.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram.errors import RPCError
|
||||
|
||||
.. warning::
|
||||
|
||||
It must be noted that catching this error is bad practice, especially when no feedback is given (i.e. by
|
||||
logging/printing the full error traceback), because it makes it impossible to understand what went wrong.
|
||||
|
||||
Error Categories
|
||||
----------------
|
||||
|
||||
The ``RPCError`` packs together all the possible errors Telegram could raise, but to make things tidier, Pyrogram
|
||||
provides categories of errors, which are named after the common HTTP errors and subclass-ed from the RPCError:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram.errors import BadRequest, Forbidden, ...
|
||||
|
||||
- `303 - SeeOther <../api/errors#seeother>`_
|
||||
- `400 - BadRequest <../api/errors#badrequest>`_
|
||||
- `401 - Unauthorized <../api/errors#unauthorized>`_
|
||||
- `403 - Forbidden <../api/errors#forbidden>`_
|
||||
- `406 - NotAcceptable <../api/errors#notacceptable>`_
|
||||
- `420 - Flood <../api/errors#flood>`_
|
||||
- `500 - InternalServerError <../api/errors#internalservererror>`_
|
||||
|
||||
Single Errors
|
||||
-------------
|
||||
|
||||
For a fine-grained control over every single error, Pyrogram does also expose errors that deal each with a specific
|
||||
issue. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
These errors subclass directly from the category of errors they belong to, which in turn subclass from the father
|
||||
RPCError, thus building a class of error hierarchy such as this:
|
||||
|
||||
- RPCError
|
||||
- BadRequest
|
||||
- ``MessageEmpty``
|
||||
- ``UsernameOccupied``
|
||||
- ``...``
|
||||
- InternalServerError
|
||||
- ``RpcCallFail``
|
||||
- ``InterDcCallError``
|
||||
- ``...``
|
||||
- ``...``
|
||||
|
||||
.. _Errors: api/errors
|
||||
|
||||
Unknown Errors
|
||||
--------------
|
||||
|
||||
In case Pyrogram does not know anything yet about a specific error, it raises a special ``520 - UnknownError`` exception
|
||||
and logs it in the ``unknown_errors.txt`` file. Users are invited to report these unknown errors.
|
||||
|
||||
Errors with Values
|
||||
------------------
|
||||
|
||||
Exception objects may also contain some informative values. For example, ``FloodWait`` holds the amount of seconds you
|
||||
have to wait before you can try again. The value is always stored in the ``x`` field of the returned exception object:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import time
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
try:
|
||||
...
|
||||
except FloodWait as e:
|
||||
time.sleep(e.x) # Wait before trying again
|
81
docs/source/start/invoking.rst
Normal file
81
docs/source/start/invoking.rst
Normal file
@ -0,0 +1,81 @@
|
||||
Calling Methods
|
||||
===============
|
||||
|
||||
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!
|
||||
|
||||
Basic Usage
|
||||
-----------
|
||||
|
||||
Making API method calls with Pyrogram is very simple. Here's an example we are going to examine:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
app.start()
|
||||
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi, it's me!")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
|
||||
app.stop()
|
||||
|
||||
#. Let's begin by importing the Client class from the Pyrogram package:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
#. Now instantiate a new Client object, "my_account" is a session name of your choice:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
#. To actually make use of any method, the client has to be started first:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.start()
|
||||
|
||||
#. Now, you can call any method you like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(app.get_me()) # Print information about yourself
|
||||
|
||||
# Send messages to yourself:
|
||||
app.send_message("me", "Hi!") # Text message
|
||||
app.send_location("me", 51.500729, -0.124583) # Location
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI") # Sticker
|
||||
|
||||
#. Finally, when done, simply stop the client:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.stop()
|
||||
|
||||
Context Manager
|
||||
---------------
|
||||
|
||||
You can also use Pyrogram's Client in a context manager with the ``with`` statement. The client will automatically
|
||||
:meth:`~pyrogram.Client.start` and :meth:`~pyrogram.Client.stop` gracefully, even in case of unhandled exceptions in
|
||||
your code. The example above can be therefore rewritten in a much nicer way:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
print(app.get_me())
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
app.send_sticker("me", "CAADBAADyg4AAvLQYAEYD4F7vcZ43AI")
|
||||
|
||||
More examples can be found on `GitHub <https://github.com/pyrogram/pyrogram/tree/develop/examples>`_.
|
109
docs/source/start/updates.rst
Normal file
109
docs/source/start/updates.rst
Normal file
@ -0,0 +1,109 @@
|
||||
Handling Updates
|
||||
================
|
||||
|
||||
Calling :doc:`API methods <invoking>` sequentially is cool, but how to react when, for example, a new message arrives?
|
||||
This page deals with updates and how to handle such events in Pyrogram. Let's have a look at how they work.
|
||||
|
||||
Defining Updates
|
||||
----------------
|
||||
|
||||
First, let's define what are these updates. As hinted already, updates are simply events that happen in your Telegram
|
||||
account (incoming messages, new members join, bot button presses, etc...), which are meant to notify you about a new
|
||||
specific state that has changed. These updates are handled by registering one or more callback functions in your app
|
||||
using :doc:`Handlers <../api/handlers>`.
|
||||
|
||||
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.
|
||||
|
||||
Registering a Handler
|
||||
---------------------
|
||||
|
||||
To explain how handlers work let's have a look at the most used one, the :class:`~pyrogram.MessageHandler`, which will
|
||||
be in charge for handling :class:`~pyrogram.Message` updates coming from all around your chats. Every other handler shares
|
||||
the same setup logic; you should not have troubles settings them up once you learn from this section.
|
||||
|
||||
Using add_handler()
|
||||
-------------------
|
||||
|
||||
The :meth:`~pyrogram.Client.add_handler` method takes any handler instance that wraps around your defined callback
|
||||
function and registers it in your Client. Here's a full example that prints out the content of a message as soon as it
|
||||
arrives:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client, MessageHandler
|
||||
|
||||
|
||||
def my_function(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
app.add_handler(my_handler)
|
||||
|
||||
app.run()
|
||||
|
||||
#. Let's examine these four new pieces. First one: a callback function we defined which accepts two arguments -
|
||||
*(client, message)*. This will be the function that gets executed every time a new message arrives and Pyrogram will
|
||||
call that function by passing the client instance and the new message instance as argument.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def my_function(client, message):
|
||||
print(message)
|
||||
|
||||
#. Second one: the :class:`~pyrogram.MessageHandler`. This object tells Pyrogram the function we defined above must
|
||||
only handle updates that are in form of a :class:`~pyrogram.Message`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
my_handler = MessageHandler(my_function)
|
||||
|
||||
#. Third: the method :meth:`~pyrogram.Client.add_handler`. This method is used to actually register the handler and let
|
||||
Pyrogram know it needs to be taken into consideration when new updates arrive and the internal dispatching phase
|
||||
begins.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.add_handler(my_handler)
|
||||
|
||||
#. Last one, the :meth:`~pyrogram.Client.run` method. What this does is simply call :meth:`~pyrogram.Client.start` and
|
||||
a special method :meth:`~pyrogram.Client.idle` that keeps your main scripts alive until you press ``CTRL+C``; the
|
||||
client will be automatically stopped after that.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.run()
|
||||
|
||||
Using Decorators
|
||||
----------------
|
||||
|
||||
All of the above will become quite verbose, especially in case you have lots of handlers to register. A much nicer way
|
||||
to do so is by decorating your callback function with the :meth:`~pyrogram.Client.on_message` decorator.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message()
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Due to how these decorators work in Pyrogram, they will wrap your defined callback function in a tuple consisting of
|
||||
``(handler, group)``; this will be the value held by your function identifier (e.g.: *my_function* from the example
|
||||
above).
|
||||
|
||||
In case, for some reason, you want to get your own function back after it has been decorated, you need to access
|
||||
``my_function[0].callback``, that is, the *callback* field of the *handler* object which is the first element in the
|
||||
tuple, accessed by bracket notation *[0]*.
|
27
docs/source/support-pyrogram.rst
Normal file
27
docs/source/support-pyrogram.rst
Normal file
@ -0,0 +1,27 @@
|
||||
Support Pyrogram
|
||||
================
|
||||
|
||||
Pyrogram is free and open source software, and thus powered by your love and support! If you like the project and have
|
||||
found it to be useful, give Pyrogram a `Star on GitHub`_. Your appreciation means a lot and helps staying motivated.
|
||||
|
||||
.. 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>
|
||||
<br><br>
|
||||
|
||||
Donate
|
||||
------
|
||||
|
||||
As a developer, you probably understand that "open source" doesn't mean "free work". A lot of time and resources has
|
||||
been put into the project and if you'd like to tip me for Pyrogram -- or any of my `other works`_ -- you can use the
|
||||
PayPal button below. Thank you!
|
||||
|
||||
.. image:: https://i.imgur.com/fasFTzK.png
|
||||
:target: https://paypal.me/delivrance
|
||||
:width: 128
|
||||
|
||||
--- `Dan`_
|
||||
|
||||
.. _Star on GitHub: https://github.com/pyrogram/pyrogram
|
||||
.. _other works: https://github.com/delivrance
|
||||
.. _Dan: https://t.me/haskell
|
@ -1,8 +1,9 @@
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
Pyrogram's API, which consists of well documented convenience methods_ and facade types_, exists to provide a much
|
||||
easier interface to the undocumented and often confusing Telegram API.
|
||||
Pyrogram's API, which consists of well documented convenience :doc:`methods <../api/methods>` and facade
|
||||
:doc:`types <../api/types>`, exists to provide a much easier interface to the undocumented and often confusing Telegram
|
||||
API.
|
||||
|
||||
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.
|
||||
@ -11,7 +12,7 @@ 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
|
||||
Telegram API, you have to use the raw :mod:`functions <pyrogram.api.functions>` and :mod:`types <pyrogram.api.types>`.
|
||||
Telegram API, you have to use the raw :mod:`~pyrogram.api.functions` and :mod:`~pyrogram.api.types`.
|
||||
|
||||
As already hinted, raw functions and types can be really confusing, mainly because people don't realize soon enough they
|
||||
accept *only* the right types and that all required parameters must be filled in. This section will therefore explain
|
||||
@ -21,24 +22,25 @@ some pitfalls to take into consideration when working with the raw API.
|
||||
|
||||
Every available high-level methods 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 `plenty of them`_ are already
|
||||
re-implemented by providing a much simpler and cleaner interface which is very similar to the Bot API (yet much more
|
||||
powerful).
|
||||
Nothing stops you from using the raw functions only, but they are rather complex and
|
||||
:doc:`plenty of them <../api/methods>` 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
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Unlike the methods_ 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.
|
||||
Unlike the :doc:`methods <../api/methods>` 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.
|
||||
|
||||
First of all, both `raw functions`_ and `raw types`_ live in their respective packages (and sub-packages):
|
||||
``pyrogram.api.functions``, ``pyrogram.api.types``. They all exist as Python classes, meaning you need to create an
|
||||
instance of each every time you need them and fill them in with the correct values using named arguments.
|
||||
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.api.functions``, ``pyrogram.api.types``. They all exist as Python
|
||||
classes, meaning you need to create an instance of each every time you need them and fill them in with the correct
|
||||
values using named arguments.
|
||||
|
||||
Next, to actually invoke the raw function you have to use the :meth:`send() <pyrogram.Client.send>` method provided by
|
||||
the Client class and pass the function object you created.
|
||||
Next, to actually invoke the raw function you have to use the :meth:`~pyrogram.Client.send` method provided by the
|
||||
Client class and pass the function object you created.
|
||||
|
||||
Here's some examples:
|
||||
|
||||
@ -101,12 +103,12 @@ sending messages with IDs only thanks to cached access hashes.
|
||||
There are three different InputPeer types, one for each kind of Telegram entity.
|
||||
Whenever an InputPeer is needed you must pass one of these:
|
||||
|
||||
- `InputPeerUser <https://docs.pyrogram.ml/types/InputPeerUser>`_ - Users
|
||||
- `InputPeerChat <https://docs.pyrogram.ml/types/InputPeerChat>`_ - Basic Chats
|
||||
- `InputPeerChannel <https://docs.pyrogram.ml/types/InputPeerChannel>`_ - Either Channels or Supergroups
|
||||
- :class:`~pyrogram.api.types.InputPeerUser` - Users
|
||||
- :class:`~pyrogram.api.types.InputPeerChat` - Basic Chats
|
||||
- :class:`~pyrogram.api.types.InputPeerChannel` - Either Channels or Supergroups
|
||||
|
||||
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
|
||||
:meth:`resolve_peer() <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.
|
||||
|
||||
Another thing to take into consideration about chat IDs is the way they are represented: they are all integers and
|
||||
@ -118,19 +120,11 @@ kind of ID.
|
||||
|
||||
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:
|
||||
|
||||
- ``+ID`` User: *123456789*
|
||||
- ``-ID`` Chat: *-123456789*
|
||||
- ``-100ID`` Channel (and Supergroup): *-100123456789*
|
||||
- ``+ID`` User: *123456789*
|
||||
- ``-ID`` Chat: *-123456789*
|
||||
- ``-100ID`` Channel or Supergroup: *-100123456789*
|
||||
|
||||
So, every time you take a raw ID, make sure to translate it into the correct ID when you want to use it with an
|
||||
high-level method.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _methods: ../pyrogram/Client.html#messages
|
||||
.. _types: ../pyrogram/Types.html
|
||||
.. _plenty of them: ../pyrogram/Client.html#messages
|
||||
.. _raw functions: ../pyrogram/functions
|
||||
.. _raw types: ../pyrogram/types
|
||||
.. _Community: https://t.me/PyrogramChat
|
||||
.. _Community: https://t.me/Pyrogram
|
@ -3,7 +3,7 @@ Auto Authorization
|
||||
|
||||
Manually writing phone number, phone code and password on the terminal every time you want to login can be tedious.
|
||||
Pyrogram is able to automate both **Log In** and **Sign Up** processes, all you need to do is pass the relevant
|
||||
parameters when creating a new :class:`Client <pyrogram.Client>`.
|
||||
parameters when creating a new :class:`~pyrogram.Client`.
|
||||
|
||||
.. note:: If you omit any of the optional parameter required for the authorization, Pyrogram will ask you to
|
||||
manually write it. For instance, if you don't want to set a ``last_name`` when creating a new account you
|
@ -7,8 +7,7 @@ Inline Bots
|
||||
-----------
|
||||
|
||||
- If a bot accepts inline queries, you can call it by using
|
||||
:meth:`get_inline_bot_results() <pyrogram.Client.get_inline_bot_results>` to get the list of its inline results
|
||||
for a query:
|
||||
:meth:`~pyrogram.Client.get_inline_bot_results` to get the list of its inline results for a query:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -24,7 +23,7 @@ Inline Bots
|
||||
results list.
|
||||
|
||||
- After you retrieved the bot results, you can use
|
||||
:meth:`send_inline_bot_result() <pyrogram.Client.send_inline_bot_result>` to send a chosen result to any chat:
|
||||
:meth:`~pyrogram.Client.send_inline_bot_result` to send a chosen result to any chat:
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -1,14 +1,14 @@
|
||||
Configuration File
|
||||
==================
|
||||
|
||||
As already mentioned in previous sections, Pyrogram can be configured by the use of an INI file.
|
||||
This page explains how this file is structured in Pyrogram, how to use it and why.
|
||||
As already mentioned in previous pages, Pyrogram can be configured by the use of an INI file.
|
||||
This page explains how this file is structured, how to use it and why.
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
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 even 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
|
||||
fill in the necessary parts.
|
||||
|
||||
@ -54,7 +54,7 @@ The ``[pyrogram]`` section contains your Telegram API credentials: *api_id* and
|
||||
api_id = 12345
|
||||
api_hash = 0123456789abcdef0123456789abcdef
|
||||
|
||||
`More info about API Key. <../start/Setup.html#configuration>`_
|
||||
`More info about API Key. <../intro/setup#api-keys>`_
|
||||
|
||||
Proxy
|
||||
^^^^^
|
||||
@ -70,7 +70,7 @@ The ``[proxy]`` section contains settings about your SOCKS5 proxy.
|
||||
username = <your_username>
|
||||
password = <your_password>
|
||||
|
||||
`More info about SOCKS5 Proxy. <SOCKS5Proxy.html>`_
|
||||
`More info about SOCKS5 Proxy. <proxy>`_
|
||||
|
||||
Plugins
|
||||
^^^^^^^
|
||||
@ -87,4 +87,4 @@ The ``[plugins]`` section contains settings about Smart Plugins.
|
||||
exclude =
|
||||
module fn2
|
||||
|
||||
`More info about Smart Plugins. <SmartPlugins.html>`_
|
||||
`More info about Smart Plugins. <smart-plugins>`_
|
93
docs/source/topics/create-filters.rst
Normal file
93
docs/source/topics/create-filters.rst
Normal file
@ -0,0 +1,93 @@
|
||||
Creating Filters
|
||||
================
|
||||
|
||||
Pyrogram already provides lots of built-in :class:`~pyrogram.Filters` to work with, but in case you can't find
|
||||
a specific one for your needs or want to build a custom filter by yourself (to be used in a different kind of handler,
|
||||
for example) you can use :meth:`~pyrogram.Filters.create`.
|
||||
|
||||
.. note::
|
||||
|
||||
At the moment, the built-in filters are intended to be used with the :class:`~pyrogram.MessageHandler` only.
|
||||
|
||||
Custom Filters
|
||||
--------------
|
||||
|
||||
An example to demonstrate how custom filters work is to show how to create and use one for the
|
||||
:class:`~pyrogram.CallbackQueryHandler`. Note that callback queries updates are only received by bots as result of a
|
||||
user pressing an inline button attached to the bot's message; create and :doc:`authorize your bot <../start/auth>`,
|
||||
then send a message with an inline keyboard to yourself. This allows you to test your filter by pressing the inline
|
||||
button:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import InlineKeyboardMarkup, InlineKeyboardButton
|
||||
|
||||
app.send_message(
|
||||
"username", # Change this to your username or id
|
||||
"Pyrogram's custom filter test",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[[InlineKeyboardButton("Press me", "pyrogram")]]
|
||||
)
|
||||
)
|
||||
|
||||
Basic Filters
|
||||
-------------
|
||||
|
||||
For this basic filter we will be using only the first two parameters of :meth:`~pyrogram.Filters.create`.
|
||||
|
||||
The code below creates a simple filter for hardcoded, static callback data. This filter will only allow callback queries
|
||||
containing "Pyrogram" as data, that is, the function *func* you pass returns True in case the callback query data
|
||||
equals to ``"Pyrogram"``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
static_data = Filters.create(
|
||||
name="StaticdData",
|
||||
func=lambda flt, query: query.data == "Pyrogram"
|
||||
)
|
||||
|
||||
The ``lambda`` operator in python is used to create small anonymous functions and is perfect for this example, the same
|
||||
could be achieved with a normal function, but we don't really need it as it makes sense only inside the filter's scope:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def func(flt, query):
|
||||
return query.data == "Pyrogram"
|
||||
|
||||
static_data = Filters.create(
|
||||
name="StaticData",
|
||||
func=func
|
||||
)
|
||||
|
||||
The filter usage remains the same:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(static_data)
|
||||
def pyrogram_data(_, query):
|
||||
query.answer("it works!")
|
||||
|
||||
Filters with Arguments
|
||||
----------------------
|
||||
|
||||
A much cooler filter would be one that accepts "Pyrogram" or any other data as argument at usage time.
|
||||
A dynamic filter like this will make use of the third parameter of :meth:`~pyrogram.Filters.create`.
|
||||
|
||||
This is how a dynamic custom filter looks like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def dynamic_data(data):
|
||||
return Filters.create(
|
||||
name="DynamicData",
|
||||
func=lambda flt, query: flt.data == query.data,
|
||||
data=data # "data" kwarg is accessed with "flt.data"
|
||||
)
|
||||
|
||||
And its usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_callback_query(dynamic_data("Pyrogram"))
|
||||
def pyrogram_data(_, query):
|
||||
query.answer("it works!")
|
135
docs/source/topics/debugging.rst
Normal file
135
docs/source/topics/debugging.rst
Normal file
@ -0,0 +1,135 @@
|
||||
Debugging
|
||||
=========
|
||||
|
||||
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.
|
||||
|
||||
Caveman Debugging
|
||||
-----------------
|
||||
|
||||
*The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.*
|
||||
|
||||
-- Brian Kernighan, "Unix for Beginners" (1979)
|
||||
|
||||
Adding ``print()`` statements in crucial parts of your code is by far the most ancient, yet efficient technique for
|
||||
debugging programs, especially considering the concurrent nature of the framework itself. Pyrogram goodness in this
|
||||
respect comes with the fact that any object can be nicely printed just by calling ``print(obj)``, thus giving to you
|
||||
an insight of all its inner details.
|
||||
|
||||
Consider the following code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
dan = app.get_users("haskell")
|
||||
print(dan) # User
|
||||
|
||||
This will show a JSON representation of the object returned by :meth:`~pyrogram.Client.get_users`, which is a
|
||||
:class:`~pyrogram.User` instance, in this case. The output on your terminal will be something similar to this:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"_": "pyrogram.User",
|
||||
"id": 23122162,
|
||||
"is_self": false,
|
||||
"is_contact": false,
|
||||
"is_mutual_contact": false,
|
||||
"is_deleted": false,
|
||||
"is_bot": false,
|
||||
"is_verified": false,
|
||||
"is_restricted": false,
|
||||
"is_support": false,
|
||||
"is_scam": false,
|
||||
"first_name": "Dan",
|
||||
"status": {
|
||||
"_": "pyrogram.UserStatus",
|
||||
"user_id": 23122162,
|
||||
"recently": true
|
||||
},
|
||||
"username": "haskell",
|
||||
"language_code": "en",
|
||||
"photo": {
|
||||
"_": "pyrogram.ChatPhoto",
|
||||
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC",
|
||||
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg"
|
||||
}
|
||||
}
|
||||
|
||||
As you've probably guessed already, Pyrogram objects can be nested. That's how compound data are built, and nesting
|
||||
keeps going until we are left with base data types only, such as ``str``, ``int``, ``bool``, etc.
|
||||
|
||||
Accessing Attributes
|
||||
--------------------
|
||||
|
||||
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 ``.``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
dan_photo = dan.photo
|
||||
print(dan_photo) # ChatPhoto
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"_": "pyrogram.ChatPhoto",
|
||||
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC",
|
||||
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg"
|
||||
}
|
||||
|
||||
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
|
||||
-------------------------
|
||||
|
||||
Another thing worth talking about is how to tell and check for an object's type.
|
||||
|
||||
As you noticed already, when printing an object you'll see the special attribute ``"_"``. This is just a visual thing
|
||||
useful to show humans the object type, but doesn't really exist anywhere; any attempt in accessing it will lead to an
|
||||
error. The correct way to get the object type is by using the built-in function ``type()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
dan_status = dan.status
|
||||
print(type(dan_status))
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
<class 'pyrogram.UserStatus'>
|
||||
|
||||
And to check if an object is an instance of a given class, you use the built-in function ``isinstance()``:
|
||||
|
||||
.. code-block:: python
|
||||
:name: this-py
|
||||
|
||||
from pyrogram import UserStatus
|
||||
|
||||
dan_status = dan.status
|
||||
print(isinstance(dan_status, UserStatus))
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
True
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script>
|
||||
var e = document.querySelector("blockquote p.attribution");
|
||||
var s = e.innerHTML;
|
||||
|
||||
e.innerHTML = s[0] + " " + s.slice(1);
|
||||
</script>
|
@ -1,7 +1,8 @@
|
||||
More on Updates
|
||||
===============
|
||||
|
||||
Here we'll show some advanced usages when working with `update handlers`_ and `filters`_.
|
||||
Here we'll show some advanced usages when working with :doc:`update handlers <../start/updates>` and
|
||||
:doc:`filters <use-filters>`.
|
||||
|
||||
Handler Groups
|
||||
--------------
|
||||
@ -28,7 +29,7 @@ For example, take these two handlers:
|
||||
print("Just Text")
|
||||
|
||||
Here, ``just_text`` is never executed because ``text_or_sticker``, which has been registered first, already handles
|
||||
texts (``Filters.text`` is shared and conflicting). To enable it, register the function using a different group:
|
||||
texts (``Filters.text`` is shared and conflicting). To enable it, register the handler using a different group:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -36,7 +37,7 @@ texts (``Filters.text`` is shared and conflicting). To enable it, register the f
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
||||
Or, if you want ``just_text`` to be executed *before* ``text_or_sticker`` (note ``-1``, which is less than ``0``):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -44,7 +45,7 @@ Or, if you want ``just_text`` to be fired *before* ``text_or_sticker`` (note ``-
|
||||
def just_text(client, message):
|
||||
print("Just Text")
|
||||
|
||||
With :meth:`add_handler() <pyrogram.Client.add_handler>` (without decorators) the same can be achieved with:
|
||||
With :meth:`~pyrogram.Client.add_handler` (without decorators) the same can be achieved with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -151,9 +152,9 @@ Continue Propagation
|
||||
|
||||
As opposed to `stopping the update propagation <#stop-propagation>`_ and also as an alternative to the
|
||||
`handler groups <#handler-groups>`_, you can signal the internal dispatcher to continue the update propagation within
|
||||
**the same group** regardless of the next handler's filters. This allows you to register multiple handlers with
|
||||
overlapping filters in the same group; to let the dispatcher process the next handler you can do *one* of the following
|
||||
in each handler you want to grant permission to continue:
|
||||
**the same group** despite having conflicting filters in the next registered handler. This allows you to register
|
||||
multiple handlers with overlapping filters in the same group; to let the dispatcher process the next handler you can do
|
||||
*one* of the following in each handler you want to grant permission to continue:
|
||||
|
||||
- Call the update's bound-method ``.continue_propagation()`` (preferred way).
|
||||
- Manually ``raise ContinuePropagation`` exception (more suitable for raw updates only).
|
||||
@ -217,6 +218,3 @@ The output of both (equivalent) examples will be:
|
||||
0
|
||||
1
|
||||
2
|
||||
|
||||
.. _`update handlers`: UpdateHandling.html
|
||||
.. _`filters`: UsingFilters.html
|
110
docs/source/topics/mtproto-vs-botapi.rst
Normal file
110
docs/source/topics/mtproto-vs-botapi.rst
Normal file
@ -0,0 +1,110 @@
|
||||
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
|
||||
already superior to, what is usually called, the official Bot API, in many respects. This page will therefore show you
|
||||
why Pyrogram might be a better choice for your project by comparing the two APIs, but first, let's make it clear what
|
||||
actually is the MTProto and the Bot API.
|
||||
|
||||
What is the MTProto API?
|
||||
------------------------
|
||||
|
||||
`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.
|
||||
|
||||
The MTProto **API** on the other hand, is what people, for convenience, call the main Telegram API as a whole. This API
|
||||
is able to authorize both users and bots and is built on top of the MTProto encryption protocol by means of
|
||||
`binary data serialized`_ in a specific way, as described by the `TL language`_, and delivered using UDP, TCP or even
|
||||
HTTP as transport-layer protocol.
|
||||
|
||||
.. _MTProto: https://core.telegram.org/mtproto
|
||||
.. _binary data serialized: https://core.telegram.org/mtproto/serialize
|
||||
.. _TL language: https://core.telegram.org/mtproto/TL
|
||||
|
||||
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
|
||||
accounts that are authorized via tokens instead of phone numbers. The Bot API is built yet again on top of the main
|
||||
Telegram API, but runs on an intermediate server application that in turn communicates with the actual Telegram servers
|
||||
using MTProto.
|
||||
|
||||
.. figure:: https://i.imgur.com/C108qkX.png
|
||||
:align: center
|
||||
|
||||
.. _Bot API: https://core.telegram.org/bots/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
|
||||
HTTP Bot API. Using Pyrogram you can:
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Authorize both user and bot identities**
|
||||
- :guilabel:`--` The Bot API only allows bot accounts
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Upload & download any file, up to 1500 MB each (~1.5 GB)**
|
||||
- :guilabel:`--` The Bot API allows uploads and downloads of files only up to 50 MB / 20 MB in size (respectively).
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Has less overhead due to direct connections to Telegram**
|
||||
- :guilabel:`--` The Bot API uses an intermediate server to handle HTTP requests before they are sent to the actual
|
||||
Telegram servers.
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Run multiple sessions at once, up to 10 per account (either bot or user)**
|
||||
- :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.
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Has much more detailed types and powerful methods**
|
||||
- :guilabel:`--` The Bot API types often miss some useful information about Telegram entities and some of the
|
||||
methods are limited as well.
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Get information about any public chat by usernames, even if not a member**
|
||||
- :guilabel:`--` The Bot API simply doesn't support this
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Obtain information about any message existing in a chat using their ids**
|
||||
- :guilabel:`--` The Bot API simply doesn't support this
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Retrieve the whole chat members list of either public or private chats**
|
||||
- :guilabel:`--` The Bot API simply doesn't support this
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Receive extra updates, such as the one about a user name change**
|
||||
- :guilabel:`--` The Bot API simply doesn't support this
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Has more meaningful errors in case something went wrong**
|
||||
- :guilabel:`--` The Bot API reports less detailed errors
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Get API version updates, and thus new features, sooner**
|
||||
- :guilabel:`--` The Bot API is simply slower in implementing new features
|
52
docs/source/topics/serialize.rst
Normal file
52
docs/source/topics/serialize.rst
Normal file
@ -0,0 +1,52 @@
|
||||
Object Serialization
|
||||
====================
|
||||
|
||||
Serializing means converting a Pyrogram object, which exists as Python class instance, to a text string that can be
|
||||
easily shared and stored anywhere. Pyrogram provides two formats for serializing its objects: one good looking for
|
||||
humans and another more compact for machines that is able to recover the original structures.
|
||||
|
||||
For Humans - str(obj)
|
||||
---------------------
|
||||
|
||||
If you want a nicely formatted, human readable JSON representation of any object in the API -- namely, any object from
|
||||
:doc:`Pyrogram types <../api/types>`, :doc:`raw functions <../telegram/functions/index>` and
|
||||
:doc:`raw types <../telegram/types/index>` -- you can use use ``str(obj)``.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
...
|
||||
|
||||
with app:
|
||||
r = app.get_chat("haskell")
|
||||
|
||||
print(str(r))
|
||||
|
||||
.. tip::
|
||||
|
||||
When using ``print()`` you don't actually need to use ``str()`` on the object because it is called automatically, we
|
||||
have done that above just to show you how to explicitly convert a Pyrogram object to JSON.
|
||||
|
||||
For Machines - repr(obj)
|
||||
------------------------
|
||||
|
||||
If you want to share or store objects for future references in a more compact way, you can use ``repr(obj)``. While
|
||||
still pretty much readable, this format is not intended for humans. The advantage of this format is that once you
|
||||
serialize your object, you can use ``eval()`` to get back the original structure; just make sure to ``import pyrogram``,
|
||||
as the process requires the package to be in scope.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import pyrogram
|
||||
|
||||
...
|
||||
|
||||
with app:
|
||||
r = app.get_chat("haskell")
|
||||
|
||||
print(repr(r))
|
||||
print(eval(repr(r)) == r) # True
|
||||
|
||||
.. note::
|
||||
|
||||
Type definitions are subject to changes between versions. You should make sure to store and load objects using the
|
||||
same Pyrogram version.
|
@ -1,24 +1,23 @@
|
||||
Customize Sessions
|
||||
==================
|
||||
Session Settings
|
||||
================
|
||||
|
||||
As you may probably know, Telegram allows users (and bots) having more than one session (authorizations) registered
|
||||
in the system at the same time.
|
||||
|
||||
Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official
|
||||
app (or by invoking `GetAuthorizations <../functions/account/GetAuthorizations.html>`_ with Pyrogram). They store some
|
||||
useful information such as the client who's using them and from which country and IP address.
|
||||
app (or by invoking :class:`~pyrogram.api.functions.account.GetAuthorizations` with Pyrogram). They
|
||||
store some useful information such as the client who's using them and from which country and IP address.
|
||||
|
||||
|
||||
.. figure:: https://i.imgur.com/lzGPCdZ.png
|
||||
:width: 70%
|
||||
.. figure:: https://i.imgur.com/YaqtMLO.png
|
||||
:width: 600
|
||||
:align: center
|
||||
|
||||
**A Pyrogram session running on Linux, Python 3.6.**
|
||||
**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.7.5**
|
||||
- ``device_model``: **CPython 3.6.5**
|
||||
- ``app_version``: **Pyrogram 0.13.0**
|
||||
- ``device_model``: **CPython 3.7.2**
|
||||
- ``system_version``: **Linux 4.15.0-23-generic**
|
||||
|
||||
Set Custom Values
|
@ -30,7 +30,7 @@ after importing your modules, like this:
|
||||
handlers.py
|
||||
main.py
|
||||
|
||||
- ``handlers.py``
|
||||
- ``handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -41,7 +41,7 @@ after importing your modules, like this:
|
||||
def echo_reversed(client, message):
|
||||
message.reply(message.text[::-1])
|
||||
|
||||
- ``main.py``
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -65,8 +65,8 @@ after importing your modules, like this:
|
||||
app.run()
|
||||
|
||||
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:`add_handler <pyrogram.Client.add_handler>` and manually instantiate each
|
||||
:obj:`MessageHandler <pyrogram.MessageHandler>` object because **you can't use those cool decorators** for your
|
||||
manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each
|
||||
:class:`~pyrogram.MessageHandler` object because **you can't use those cool decorators** for your
|
||||
functions. So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
|
||||
|
||||
Using Smart Plugins
|
||||
@ -80,7 +80,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
|
||||
.. note::
|
||||
|
||||
This is the same example application `as shown above <#introduction>`_, written using the Smart Plugin system.
|
||||
This is the same example application as shown above, written using the Smart Plugin system.
|
||||
|
||||
.. code-block:: text
|
||||
:emphasize-lines: 2, 3
|
||||
@ -91,7 +91,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
config.ini
|
||||
main.py
|
||||
|
||||
- ``plugins/handlers.py``
|
||||
- ``plugins/handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4, 9
|
||||
@ -108,14 +108,14 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
def echo_reversed(client, message):
|
||||
message.reply(message.text[::-1])
|
||||
|
||||
- ``config.ini``
|
||||
- ``config.ini``
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[plugins]
|
||||
root = plugins
|
||||
|
||||
- ``main.py``
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -156,7 +156,7 @@ found inside each module will be, instead, loaded in the order they are defined,
|
||||
.. note::
|
||||
|
||||
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 `More on Updates <MoreOnUpdates.html>`_.
|
||||
filters included a second time will not work. 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
|
||||
exclude) and in which exact order to load plugins. The way to do this is to make use of ``include`` and ``exclude``
|
||||
@ -199,8 +199,8 @@ also organized in subfolders:
|
||||
...
|
||||
...
|
||||
|
||||
- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order
|
||||
(files) and definition order (handlers inside files):
|
||||
- Load every handler from every module, namely *plugins0.py*, *plugins1.py* and *plugins2.py* in alphabetical order
|
||||
(files) and definition order (handlers inside files):
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
@ -217,7 +217,7 @@ also organized in subfolders:
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order:
|
||||
- Load only handlers defined inside *plugins2.py* and *plugins0.py*, in this order:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
@ -243,7 +243,7 @@ also organized in subfolders:
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load everything except the handlers inside *plugins2.py*:
|
||||
- Load everything except the handlers inside *plugins2.py*:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
@ -264,7 +264,7 @@ also organized in subfolders:
|
||||
|
||||
Client("my_account", plugins=plugins).run()
|
||||
|
||||
- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*:
|
||||
- Load only *fn3*, *fn1* and *fn2* (in this order) from *plugins1.py*:
|
||||
|
||||
Using *config.ini* file:
|
||||
|
||||
@ -288,16 +288,15 @@ also organized in subfolders:
|
||||
Load/Unload Plugins at Runtime
|
||||
------------------------------
|
||||
|
||||
In the `previous section <#specifying-the-plugins-to-include>`_ we've explained how to specify which plugins to load and
|
||||
which to ignore before your Client starts. Here we'll show, instead, how to unload and load again a previously
|
||||
registered plugin at runtime.
|
||||
In the previous section we've explained how to specify which plugins to load and which to ignore before your Client
|
||||
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 updates
|
||||
) will be modified in such a way that, when you reference them later on, they will be actually pointing to a tuple of
|
||||
*(handler: Handler, group: int)*. The actual callback function is therefore stored inside the handler's *callback*
|
||||
attribute. Here's an example:
|
||||
|
||||
- ``plugins/handlers.py``
|
||||
- ``plugins/handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 5, 6
|
||||
@ -318,10 +317,10 @@ Unloading
|
||||
^^^^^^^^^
|
||||
|
||||
In order to unload a plugin, or any other handler, all you need to do is obtain a reference to it by importing the
|
||||
relevant module and call :meth:`remove_handler() <pyrogram.Client.remove_handler>` Client's method with your function
|
||||
relevant module and call :meth:`~pyrogram.Client.remove_handler` Client's method with your function
|
||||
name preceded by the star ``*`` operator as argument. Example:
|
||||
|
||||
- ``main.py``
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -343,9 +342,9 @@ Loading
|
||||
^^^^^^^
|
||||
|
||||
Similarly to the unloading process, in order to load again a previously unloaded plugin you do the same, but this time
|
||||
using :meth:`add_handler() <pyrogram.Client.add_handler>` instead. Example:
|
||||
using :meth:`~pyrogram.Client.add_handler` instead. Example:
|
||||
|
||||
- ``main.py``
|
||||
- ``main.py``
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -11,8 +11,8 @@ Beside bold, italic, and pre-formatted code, **Pyrogram does also support inline
|
||||
Markdown Style
|
||||
--------------
|
||||
|
||||
To use this mode, pass :obj:`MARKDOWN <pyrogram.ParseMode.MARKDOWN>` or "markdown" in the *parse_mode* field when using
|
||||
:obj:`send_message() <pyrogram.Client.send_message>`. Use the following syntax in your message:
|
||||
To use this mode, pass "markdown" in the *parse_mode* field when using
|
||||
:meth:`~pyrogram.Client.send_message`. Use the following syntax in your message:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -20,7 +20,7 @@ To use this mode, pass :obj:`MARKDOWN <pyrogram.ParseMode.MARKDOWN>` or "markdow
|
||||
|
||||
__italic text__
|
||||
|
||||
[inline URL](https://docs.pyrogram.ml/)
|
||||
[inline URL](https://docs.pyrogram.org/)
|
||||
|
||||
[inline mention of a user](tg://user?id=23122162)
|
||||
|
||||
@ -34,8 +34,8 @@ To use this mode, pass :obj:`MARKDOWN <pyrogram.ParseMode.MARKDOWN>` or "markdow
|
||||
HTML Style
|
||||
----------
|
||||
|
||||
To use this mode, pass :obj:`HTML <pyrogram.ParseMode.HTML>` or "html" in the *parse_mode* field when using
|
||||
:obj:`send_message() <pyrogram.Client.send_message>`. The following tags are currently supported:
|
||||
To use this mode, pass "html" in the *parse_mode* field when using :meth:`~pyrogram.Client.send_message`.
|
||||
The following tags are currently supported:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -43,7 +43,7 @@ To use this mode, pass :obj:`HTML <pyrogram.ParseMode.HTML>` or "html" in the *p
|
||||
|
||||
<i>italic</i>, <em>italic</em>
|
||||
|
||||
<a href="http://docs.pyrogram.ml/">inline URL</a>
|
||||
<a href="http://docs.pyrogram.org/">inline URL</a>
|
||||
|
||||
<a href="tg://user?id=23122162">inline mention of a user</a>
|
||||
|
||||
@ -66,7 +66,7 @@ Examples
|
||||
"**bold**, "
|
||||
"__italic__, "
|
||||
"[mention](tg://user?id=23122162), "
|
||||
"[URL](https://docs.pyrogram.ml), "
|
||||
"[URL](https://docs.pyrogram.org), "
|
||||
"`code`, "
|
||||
"```"
|
||||
"for i in range(10):\n"
|
||||
@ -84,7 +84,7 @@ Examples
|
||||
"<b>bold</b>, "
|
||||
"<i>italic</i>, "
|
||||
"<a href=\"tg://user?id=23122162\">mention</a>, "
|
||||
"<a href=\"https://pyrogram.ml/\">URL</a>, "
|
||||
"<a href=\"https://pyrogram.org/\">URL</a>, "
|
||||
"<code>code</code>, "
|
||||
"<pre>"
|
||||
"for i in range(10):\n"
|
@ -2,7 +2,7 @@ Fast Crypto
|
||||
===========
|
||||
|
||||
Pyrogram's speed can be *dramatically* boosted up by TgCrypto_, a high-performance, easy-to-install Telegram Crypto
|
||||
Library specifically written in C for Pyrogram [#f1]_ as a Python extension.
|
||||
Library specifically written in C for Pyrogram [1]_ as a Python extension.
|
||||
|
||||
TgCrypto is a replacement for the much slower PyAES and implements the crypto algorithms Telegram requires, namely
|
||||
**AES-IGE 256 bit** (used in MTProto v2.0) and **AES-CTR 256 bit** (used for CDN encrypted files).
|
||||
@ -28,5 +28,5 @@ what you should do next:
|
||||
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
|
||||
.. [#f1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for
|
||||
.. [1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for
|
||||
other Python projects too.
|
108
docs/source/topics/use-filters.rst
Normal file
108
docs/source/topics/use-filters.rst
Normal file
@ -0,0 +1,108 @@
|
||||
Using Filters
|
||||
=============
|
||||
|
||||
So far we've seen how to register a callback function that executes every time a specific update comes from the server,
|
||||
but there's much more than that to come.
|
||||
|
||||
Here we'll discuss about :class:`~pyrogram.Filters`. Filters enable a fine-grain control over what kind of
|
||||
updates are allowed or not to be passed in your callback functions, based on their inner details.
|
||||
|
||||
Single Filters
|
||||
--------------
|
||||
|
||||
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
|
||||
ignore any other message. Filters are passed as the first argument of the decorator:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4
|
||||
|
||||
from pyrogram import Filters
|
||||
|
||||
|
||||
@app.on_message(Filters.audio)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- or, without decorators. Here filters are passed as the second argument of the handler constructor; the first is the
|
||||
callback function itself:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 8
|
||||
|
||||
from pyrogram import Filters, MessageHandler
|
||||
|
||||
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(my_handler, Filters.audio))
|
||||
|
||||
Combining Filters
|
||||
-----------------
|
||||
|
||||
Filters can also be used in a more advanced way by inverting and combining more filters together using bitwise
|
||||
operators ``~``, ``&`` and ``|``:
|
||||
|
||||
- Use ``~`` to invert a filter (behaves like the ``not`` operator).
|
||||
- Use ``&`` and ``|`` to merge two filters (behave like ``and``, ``or`` operators respectively).
|
||||
|
||||
Here are some examples:
|
||||
|
||||
- Message is a **text** message **and** is **not edited**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.text & ~Filters.edited)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **sticker** **and** is coming from a **channel or** a **private** chat.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.sticker & (Filters.channel | Filters.private))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
Advanced Filters
|
||||
----------------
|
||||
|
||||
Some filters, like :meth:`~pyrogram.Filters.command` or :meth:`~pyrogram.Filters.regex`
|
||||
can also accept arguments:
|
||||
|
||||
- Message is either a */start* or */help* **command**.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command(["start", "help"]))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
- Message is a **text** message or a media **caption** matching the given **regex** pattern.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.regex("pyrogram"))
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
More handlers using different filters can also live together.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message(Filters.command("start"))
|
||||
def start_command(client, message):
|
||||
print("This is the /start command")
|
||||
|
||||
|
||||
@app.on_message(Filters.command("help"))
|
||||
def help_command(client, message):
|
||||
print("This is the /help command")
|
||||
|
||||
|
||||
@app.on_message(Filters.chat("PyrogramChat"))
|
||||
def from_pyrogramchat(client, message):
|
||||
print("New message in @PyrogramChat")
|
@ -12,12 +12,12 @@ Example | Description
|
||||
---: | :---
|
||||
[**hello_world**](hello_world.py) | Demonstration of basic API usage
|
||||
[**echobot**](echobot.py) | Echo every private text message
|
||||
[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat)
|
||||
[**history**](history.py) | Get the full message history of a chat
|
||||
[**chat_members**](chat_members.py) | Get all the members of a chat
|
||||
[**dialogs**](dialogs.py) | Get all of your dialog chats
|
||||
[**using_inline_bots**](using_inline_bots.py) | Query an inline bot (as user) and send a result to a chat
|
||||
[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots
|
||||
[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses
|
||||
[**inline_queries**](inline_queries.py) | Handle inline queries
|
||||
[**welcomebot**](welcomebot.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat)
|
||||
[**get_history**](get_history.py) | Get the full message history of a chat
|
||||
[**get_chat_members**](get_chat_members.py) | Get all the members of a chat
|
||||
[**get_dialogs**](get_dialogs.py) | Get all of your dialog chats
|
||||
[**callback_queries**](callback_queries.py) | Handle callback queries (as bot) coming from inline button presses
|
||||
[**inline_queries**](inline_queries.py) | Handle inline queries (as bot) and answer with results
|
||||
[**use_inline_bots**](use_inline_bots.py) | Query an inline bot (as user) and send a result to a chat
|
||||
[**bot_keyboards**](bot_keyboards.py) | Send normal and inline keyboards using regular bots
|
||||
[**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided)
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""This example will show you how to send normal and inline keyboards.
|
||||
"""This example will show you how to send normal and inline keyboards (as bot).
|
||||
|
||||
You must log-in as a regular bot in order to send keyboards (use the token from @BotFather).
|
||||
Any attempt in sending keyboards with a user account will be simply ignored by the server.
|
||||
@ -39,7 +39,7 @@ with app:
|
||||
),
|
||||
InlineKeyboardButton( # Opens a web URL
|
||||
"URL",
|
||||
url="https://docs.pyrogram.ml"
|
||||
url="https://docs.pyrogram.org"
|
||||
),
|
||||
],
|
||||
[ # Second row
|
@ -1,4 +1,4 @@
|
||||
"""This example shows how to get the full dialogs list of a user."""
|
||||
"""This example shows how to get the full dialogs list (as user)."""
|
||||
|
||||
from pyrogram import Client
|
||||
|
@ -22,12 +22,12 @@ def answer(client, inline_query):
|
||||
input_message_content=InputTextMessageContent(
|
||||
"Here's how to install **Pyrogram**"
|
||||
),
|
||||
url="https://docs.pyrogram.ml/start/Installation",
|
||||
url="https://docs.pyrogram.org/intro/install",
|
||||
description="How to install Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Installation")]
|
||||
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.org/intro/install")]
|
||||
]
|
||||
)
|
||||
),
|
||||
@ -37,12 +37,12 @@ def answer(client, inline_query):
|
||||
input_message_content=InputTextMessageContent(
|
||||
"Here's how to use **Pyrogram**"
|
||||
),
|
||||
url="https://docs.pyrogram.ml/start/Usage",
|
||||
url="https://docs.pyrogram.org/start/invoking",
|
||||
description="How to use Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Usage")]
|
||||
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.org/start/invoking")]
|
||||
]
|
||||
)
|
||||
)
|
||||
|
13
examples/use_inline_bots.py
Normal file
13
examples/use_inline_bots.py
Normal file
@ -0,0 +1,13 @@
|
||||
"""This example shows how to query an inline bot (as user)"""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
# Get bot results for "Fuzz Universe" from the inline bot @vid
|
||||
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
|
||||
|
||||
# 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)
|
@ -1,17 +0,0 @@
|
||||
"""This example shows how to query an inline bot"""
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
# Create a new Client
|
||||
app = Client("my_account")
|
||||
|
||||
# Start the Client
|
||||
app.start()
|
||||
|
||||
# Get bot results for "Fuzz Universe" from the inline bot @vid
|
||||
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
|
||||
# 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)
|
||||
|
||||
# Stop the client
|
||||
app.stop()
|
@ -8,7 +8,7 @@ from pyrogram import Client, Emoji, Filters
|
||||
|
||||
TARGET = "PyrogramChat" # Target chat. Can also be a list of multiple chat ids/usernames
|
||||
MENTION = "[{}](tg://user?id={})" # User mention markup
|
||||
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.ml/)'s group chat {}!" # Welcome message
|
||||
MESSAGE = "{} Welcome to [Pyrogram](https://docs.pyrogram.org/)'s group chat {}!" # Welcome message
|
||||
|
||||
app = Client("my_account")
|
||||
|
@ -24,11 +24,9 @@ if sys.version_info[:3] in [(3, 5, 0), (3, 5, 1), (3, 5, 2)]:
|
||||
# Monkey patch the standard "typing" module because Python versions from 3.5.0 to 3.5.2 have a broken one.
|
||||
sys.modules["typing"] = typing
|
||||
|
||||
__version__ = "0.12.0"
|
||||
__version__ = "0.15.0-develop"
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__copyright__ = "Copyright (C) 2017-2019 Dan Tès <https://github.com/delivrance>".replace(
|
||||
"\xe8", "e" if sys.getfilesystemencoding() != "utf-8" else "\xe8"
|
||||
)
|
||||
__copyright__ = "Copyright (C) 2017-2019 Dan <https://github.com/delivrance>"
|
||||
|
||||
from .errors import RPCError
|
||||
from .client import *
|
||||
|
@ -19,8 +19,8 @@
|
||||
from importlib import import_module
|
||||
|
||||
from .all import objects
|
||||
from .core.object import Object
|
||||
from .core.tl_object import TLObject
|
||||
|
||||
for k, v in objects.items():
|
||||
path, name = v.rsplit(".", 1)
|
||||
Object.all[k] = getattr(import_module(path), name)
|
||||
TLObject.all[k] = getattr(import_module(path), name)
|
||||
|
@ -19,10 +19,11 @@
|
||||
from .future_salt import FutureSalt
|
||||
from .future_salts import FutureSalts
|
||||
from .gzip_packed import GzipPacked
|
||||
from .list import List
|
||||
from .message import Message
|
||||
from .msg_container import MsgContainer
|
||||
from .object import Object
|
||||
from .primitives import (
|
||||
Bool, BoolTrue, BoolFalse, Bytes, Double,
|
||||
Int, Long, Int128, Int256, Null, String, Vector
|
||||
)
|
||||
from .tl_object import TLObject
|
||||
|
@ -16,29 +16,28 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
|
||||
from .object import Object
|
||||
from .primitives import Int, Long
|
||||
from .tl_object import TLObject
|
||||
|
||||
|
||||
class FutureSalt(Object):
|
||||
class FutureSalt(TLObject):
|
||||
ID = 0x0949d9dc
|
||||
|
||||
__slots__ = ["valid_since", "valid_until", "salt"]
|
||||
|
||||
QUALNAME = "FutureSalt"
|
||||
|
||||
def __init__(self, valid_since: int or datetime, valid_until: int or datetime, salt: int):
|
||||
def __init__(self, valid_since: int, valid_until: int, salt: int):
|
||||
self.valid_since = valid_since
|
||||
self.valid_until = valid_until
|
||||
self.salt = salt
|
||||
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args) -> "FutureSalt":
|
||||
valid_since = datetime.fromtimestamp(Int.read(b))
|
||||
valid_until = datetime.fromtimestamp(Int.read(b))
|
||||
valid_since = Int.read(b)
|
||||
valid_until = Int.read(b)
|
||||
salt = Long.read(b)
|
||||
|
||||
return FutureSalt(valid_since, valid_until, salt)
|
||||
|
@ -16,22 +16,21 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from datetime import datetime
|
||||
from io import BytesIO
|
||||
|
||||
from . import FutureSalt
|
||||
from .object import Object
|
||||
from .primitives import Int, Long
|
||||
from .tl_object import TLObject
|
||||
|
||||
|
||||
class FutureSalts(Object):
|
||||
class FutureSalts(TLObject):
|
||||
ID = 0xae500895
|
||||
|
||||
__slots__ = ["req_msg_id", "now", "salts"]
|
||||
|
||||
QUALNAME = "FutureSalts"
|
||||
|
||||
def __init__(self, req_msg_id: int, now: int or datetime, salts: list):
|
||||
def __init__(self, req_msg_id: int, now: int, salts: list):
|
||||
self.req_msg_id = req_msg_id
|
||||
self.now = now
|
||||
self.salts = salts
|
||||
@ -39,7 +38,7 @@ class FutureSalts(Object):
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args) -> "FutureSalts":
|
||||
req_msg_id = Long.read(b)
|
||||
now = datetime.fromtimestamp(Int.read(b))
|
||||
now = Int.read(b)
|
||||
|
||||
count = Int.read(b)
|
||||
salts = [FutureSalt.read(b) for _ in range(count)]
|
||||
|
@ -19,24 +19,24 @@
|
||||
from gzip import compress, decompress
|
||||
from io import BytesIO
|
||||
|
||||
from .object import Object
|
||||
from .primitives import Int, Bytes
|
||||
from .tl_object import TLObject
|
||||
|
||||
|
||||
class GzipPacked(Object):
|
||||
class GzipPacked(TLObject):
|
||||
ID = 0x3072cfa1
|
||||
|
||||
__slots__ = ["packed_data"]
|
||||
|
||||
QUALNAME = "GzipPacked"
|
||||
|
||||
def __init__(self, packed_data: Object):
|
||||
def __init__(self, packed_data: TLObject):
|
||||
self.packed_data = packed_data
|
||||
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args) -> "GzipPacked":
|
||||
# Return the Object itself instead of a GzipPacked wrapping it
|
||||
return Object.read(
|
||||
return TLObject.read(
|
||||
BytesIO(
|
||||
decompress(
|
||||
Bytes.read(b)
|
||||
|
@ -16,14 +16,13 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .tl_object import TLObject
|
||||
|
||||
class ParseMode:
|
||||
"""This class provides a convenient access to Parse Modes.
|
||||
Parse Modes are intended to be used with any method that accepts the optional argument **parse_mode**.
|
||||
"""
|
||||
|
||||
HTML = "html"
|
||||
"""Set the parse mode to HTML style"""
|
||||
class List(list, TLObject):
|
||||
__slots__ = []
|
||||
|
||||
MARKDOWN = "markdown"
|
||||
"""Set the parse mode to Markdown style"""
|
||||
def __repr__(self):
|
||||
return "pyrogram.api.core.List([{}])".format(
|
||||
",".join(TLObject.__repr__(i) for i in self)
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user