Compare commits
1 Commits
mtpager
...
fix-vector
Author | SHA1 | Date | |
---|---|---|---|
|
e3f1642797 |
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
|
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Create a bug report affecting the library or the documentation
|
||||
---
|
||||
|
||||
<!-- WARNING: Ignoring or altering this template could lead to the issue being closed as invalid -->
|
||||
|
||||
## Checklist
|
||||
- [ ] I am sure the error is coming from Pyrogram's code and not elsewhere.
|
||||
- [ ] I have searched in the issue tracker for similar bug reports, including closed ones.
|
||||
- [ ] I ran `pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip` and reproduced the issue using the latest development version.
|
||||
|
||||
## Description
|
||||
A **clear** and **concise** description of the problem. Code snippets must be
|
||||
[minimal, reproducible](https://stackoverflow.com/help/minimal-reproducible-example) and properly formatted.
|
||||
|
||||
``` python
|
||||
from pyrogram import Client
|
||||
...
|
||||
```
|
||||
|
||||
## Traceback
|
||||
The full traceback (if applicable).
|
||||
|
||||
```
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1, in <module>
|
||||
```
|
51
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
51
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,51 +0,0 @@
|
||||
name: Bug report
|
||||
description: Report issues affecting the framework or the documentation
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I am sure the error is coming from Pyrogram's code and not elsewhere
|
||||
required: true
|
||||
- label: I have searched in the issue tracker for similar bug reports, including closed ones
|
||||
required: true
|
||||
- label: I ran `pip3 install -U https://github.com/pyrogram/pyrogram/archive/master.zip` and reproduced the issue using the latest development version
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: Provide a clear and concise description of the issue
|
||||
placeholder: Description...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Explain precisely how to reproduce the issue
|
||||
placeholder: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Code example
|
||||
description: Provide a [minimal, reproducible](https://stackoverflow.com/help/minimal-reproducible-example) and properly formatted example (if applicable)
|
||||
placeholder: |
|
||||
from pyrogram import Client
|
||||
...
|
||||
render: python
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Logs
|
||||
description: Provide the complete traceback (if applicable)
|
||||
placeholder: |
|
||||
Traceback (most recent call last):
|
||||
File "main.py", line 1, in <module>
|
||||
...
|
||||
render: shell
|
6
.github/ISSUE_TEMPLATE/config.yml
vendored
6
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -2,7 +2,7 @@ blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask Pyrogram related questions
|
||||
url: https://stackoverflow.com/questions/tagged/pyrogram
|
||||
about: This place is only for reporting issues about Pyrogram. You can ask questions at StackOverflow.
|
||||
- name: Join the Telegram channel
|
||||
about: This place is for issues about Pyrogram. If you'd like to ask a question, please do so at StackOverflow.
|
||||
- name: Join the Telegram community
|
||||
url: https://t.me/pyrogram
|
||||
about: Join the official channel and stay tuned for news, updates and announcements.
|
||||
about: Join the official channel to stay tuned for news and updates.
|
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 or altering this template could lead to the issue being closed as invalid -->
|
||||
|
||||
## Checklist
|
||||
- [ ] I believe the idea is awesome and would benefit the library.
|
||||
- [ ] I have searched in the issue tracker for similar requests, including closed ones.
|
||||
|
||||
## Description
|
||||
A detailed description of the request.
|
20
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
20
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,20 +0,0 @@
|
||||
name: Feature request
|
||||
description: Suggest ideas, new features or enhancements
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I believe the idea is awesome and would benefit the framework
|
||||
required: true
|
||||
- label: I have searched in the issue tracker for similar requests, including closed ones
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: Provide a detailed description of the request
|
||||
placeholder: Description...
|
||||
validations:
|
||||
required: true
|
68
.github/workflows/codeql-analysis.yml
vendored
68
.github/workflows/codeql-analysis.yml
vendored
@ -1,68 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ mtpager ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ mtpager ]
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
6
.github/workflows/python.yml
vendored
6
.github/workflows/python.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: Pyrogram
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -8,8 +8,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
python-version: [3.7, 3.8, 3.9, "3.10", "pypy-3.7", "pypy-3.8"]
|
||||
os: [ ubuntu-latest, macos-latest, windows-latest ]
|
||||
python-version: [ 3.6, 3.7, 3.8, 3.9 ]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -1,11 +1,10 @@
|
||||
## Include
|
||||
include README.md COPYING COPYING.lesser NOTICE requirements.txt
|
||||
recursive-include compiler *.py *.tl *.tsv *.txt
|
||||
recursive-include tests *.py
|
||||
|
||||
## Exclude
|
||||
prune pyrogram/errors/exceptions
|
||||
prune pyrogram/raw/functions
|
||||
prune pyrogram/raw/types
|
||||
prune pyrogram/raw/base
|
||||
exclude pyrogram/raw/all.py
|
||||
exclude pyrogram/raw/all.py
|
2
NOTICE
2
NOTICE
@ -1,5 +1,5 @@
|
||||
Pyrogram - Telegram MTProto API Client Library for Python
|
||||
Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
|
||||
This file is part of Pyrogram.
|
||||
|
||||
|
60
README.md
60
README.md
@ -1,6 +1,6 @@
|
||||
<p align="center">
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
<img src="https://docs.pyrogram.org/_static/pyrogram.png" alt="Pyrogram" width="128">
|
||||
<img src="https://i.imgur.com/BOgY9ai.png" alt="Pyrogram">
|
||||
</a>
|
||||
<br>
|
||||
<b>Telegram MTProto API Framework for Python</b>
|
||||
@ -9,19 +9,17 @@
|
||||
Documentation
|
||||
</a>
|
||||
•
|
||||
<a href="https://docs.pyrogram.org/releases">
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Releases
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/pyrogram">
|
||||
News
|
||||
<a href="https://t.me/Pyrogram">
|
||||
Community
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Pyrogram
|
||||
|
||||
> Elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots
|
||||
|
||||
``` python
|
||||
from pyrogram import Client, filters
|
||||
|
||||
@ -30,33 +28,34 @@ app = Client("my_account")
|
||||
|
||||
@app.on_message(filters.private)
|
||||
async def hello(client, message):
|
||||
await message.reply("Hello from Pyrogram!")
|
||||
await message.reply_text(f"Hello {message.from_user.mention}")
|
||||
|
||||
|
||||
app.run()
|
||||
```
|
||||
|
||||
**Pyrogram** is a modern, elegant and asynchronous [MTProto API](https://docs.pyrogram.org/topics/mtproto-vs-botapi)
|
||||
framework. It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot
|
||||
identity (bot API alternative) using Python.
|
||||
**Pyrogram** is a modern, elegant and easy-to-use [Telegram](https://telegram.org/) client library framework written
|
||||
from the ground up in Python and C. It enables you to easily create custom Telegram client applications for both user
|
||||
and bot identities (bot API alternative) via the [MTProto API](https://docs.pyrogram.org/topics/mtproto-vs-botapi).
|
||||
|
||||
### Support
|
||||
### Features
|
||||
|
||||
If you'd like to support Pyrogram, you can consider:
|
||||
|
||||
- [Become a GitHub sponsor](https://github.com/sponsors/delivrance).
|
||||
- [Become a LiberaPay patron](https://liberapay.com/delivrance).
|
||||
- [Become an OpenCollective backer](https://opencollective.com/pyrogram).
|
||||
|
||||
### Key Features
|
||||
|
||||
- **Ready**: Install Pyrogram with pip and start building your applications right away.
|
||||
- **Easy**: Makes the Telegram API simple and intuitive, while still allowing advanced usages.
|
||||
- **Elegant**: Low-level details are abstracted and re-presented in a more convenient way.
|
||||
- **Fast**: Boosted up by [TgCrypto](https://github.com/pyrogram/tgcrypto), a high-performance crypto library written in pure C.
|
||||
- **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.
|
||||
- **Asynchronous**: Allows both synchronous and asynchronous models to fit all usage needs.
|
||||
- **Documented**: API methods, types and public interfaces are all [well documented](https://docs.pyrogram.org).
|
||||
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
|
||||
- **Async**: Fully asynchronous (also usable synchronously if wanted, for convenience).
|
||||
- **Powerful**: Full access to Telegram's API to execute any official client action and more.
|
||||
- **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.6 or higher.
|
||||
- A [Telegram API key](https://docs.pyrogram.org/intro/setup#api-keys).
|
||||
|
||||
### Installing
|
||||
|
||||
@ -66,6 +65,11 @@ pip3 install pyrogram
|
||||
|
||||
### Resources
|
||||
|
||||
- Check out the docs at https://docs.pyrogram.org to learn more about Pyrogram, get started right
|
||||
away and discover more in-depth material for building your client applications.
|
||||
- Join the official channel at https://t.me/pyrogram and stay tuned for news, updates and announcements.
|
||||
- The docs contain lots of resources to help you get started with Pyrogram: https://docs.pyrogram.org.
|
||||
- Seeking extra help? Come join and ask our community: https://t.me/pyrogram.
|
||||
- For other kind of inquiries, you can send a [message](https://t.me/haskell) or an [e-mail](mailto:dan@pyrogram.org).
|
||||
|
||||
### Copyright & License
|
||||
|
||||
- Copyright (C) 2017-2021 Dan <<https://github.com/delivrance>>
|
||||
- Licensed under the terms of the [GNU Lesser General Public License v3 or later (LGPLv3+)](COPYING.lesser)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -199,12 +199,12 @@ def start(format: bool = False):
|
||||
shutil.rmtree(DESTINATION_PATH / "base", ignore_errors=True)
|
||||
|
||||
with open(HOME_PATH / "source/auth_key.tl") as f1, \
|
||||
open(HOME_PATH / "source/sys_msgs.tl") as f2, \
|
||||
open(HOME_PATH / "source/main_api.tl") as f3:
|
||||
open(HOME_PATH / "source/sys_msgs.tl") as f2, \
|
||||
open(HOME_PATH / "source/main_api.tl") as f3:
|
||||
schema = (f1.read() + f2.read() + f3.read()).splitlines()
|
||||
|
||||
with open(HOME_PATH / "template/type.txt") as f1, \
|
||||
open(HOME_PATH / "template/combinator.txt") as f2:
|
||||
open(HOME_PATH / "template/combinator.txt") as f2:
|
||||
type_tmpl = f1.read()
|
||||
combinator_tmpl = f2.read()
|
||||
|
||||
@ -345,11 +345,11 @@ def start(format: bool = False):
|
||||
sorted_args = sort_args(c.args)
|
||||
|
||||
arguments = (
|
||||
(", *, " if c.args else "") +
|
||||
(", ".join(
|
||||
[f"{i[0]}: {get_type_hint(i[1])}"
|
||||
for i in sorted_args]
|
||||
) if sorted_args else "")
|
||||
(", *, " if c.args else "") +
|
||||
(", ".join(
|
||||
[f"{i[0]}: {get_type_hint(i[1])}"
|
||||
for i in sorted_args]
|
||||
) if sorted_args else "")
|
||||
)
|
||||
|
||||
fields = "\n ".join(
|
||||
@ -408,7 +408,7 @@ def start(format: bool = False):
|
||||
flag = FLAGS_RE_2.match(i[1])
|
||||
|
||||
if flag:
|
||||
if flag.group(2) == "true" or flag.group(2).startswith("Vector"):
|
||||
if flag.group(2) == "true":
|
||||
write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} else 0")
|
||||
else:
|
||||
write_flags.append(f"flags |= (1 << {flag.group(1)}) if self.{i[0]} is not None else 0")
|
||||
@ -441,7 +441,7 @@ def start(format: bool = False):
|
||||
sub_type = arg_type.split("<")[1][:-1]
|
||||
|
||||
write_types += "\n "
|
||||
write_types += f"if self.{arg_name}:\n "
|
||||
write_types += f"if self.{arg_name} is not None:\n "
|
||||
write_types += "b.write(Vector(self.{}{}))\n ".format(
|
||||
arg_name, f", {sub_type.title()}" if sub_type in CORE_TYPES else ""
|
||||
)
|
||||
|
@ -101,13 +101,13 @@ userStatusLastWeek#7bf09fc = UserStatus;
|
||||
userStatusLastMonth#77ebc742 = UserStatus;
|
||||
|
||||
chatEmpty#29562865 id:long = Chat;
|
||||
chat#41cbf256 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chat#41cbf256 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||
channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channel#8261ac61 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int = Chat;
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
|
||||
chatFull#d18ee226 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?Vector<string> = ChatFull;
|
||||
channelFull#e13c3d20 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?Vector<string> = ChatFull;
|
||||
chatFull#4dbdc099 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string = ChatFull;
|
||||
channelFull#e9b27a17 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string = ChatFull;
|
||||
|
||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||
@ -120,7 +120,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto;
|
||||
|
||||
messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message;
|
||||
message#38116ee0 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
message#85d6cbe2 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> ttl_period:flags.25?int = Message;
|
||||
messageService#2b085862 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?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction ttl_period:flags.25?int = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -166,9 +166,8 @@ messageActionInviteToGroupCall#502f92f7 call:InputGroupCall users:Vector<long> =
|
||||
messageActionSetMessagesTTL#aa1afbfd period:int = MessageAction;
|
||||
messageActionGroupCallScheduled#b3a07661 call:InputGroupCall schedule_date:int = MessageAction;
|
||||
messageActionSetChatTheme#aa786345 emoticon:string = MessageAction;
|
||||
messageActionChatJoinedByRequest#ebbca3cb = MessageAction;
|
||||
|
||||
dialog#a8edd0f5 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 unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int = 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;
|
||||
@ -186,7 +185,7 @@ geoPoint#b2a2f663 flags:# long:double lat:double access_hash:long accuracy_radiu
|
||||
|
||||
auth.sentCode#5e002502 flags:# type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode;
|
||||
|
||||
auth.authorization#33fb7bb8 flags:# setup_password_required:flags.1?true otherwise_relogin_days:flags.1?int tmp_sessions:flags.0?int user:User = auth.Authorization;
|
||||
auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization;
|
||||
auth.authorizationSignUpRequired#44747e9a flags:# terms_of_service:flags.0?help.TermsOfService = auth.Authorization;
|
||||
|
||||
auth.exportedAuthorization#b434e2b8 id:long bytes:bytes = auth.ExportedAuthorization;
|
||||
@ -200,7 +199,7 @@ inputPeerNotifySettings#9c3d198e flags:# show_previews:flags.0?Bool silent:flags
|
||||
|
||||
peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
|
||||
|
||||
peerSettings#a518110d flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true request_chat_broadcast:flags.10?true geo_distance:flags.6?int request_chat_title:flags.9?string request_chat_date:flags.9?int = PeerSettings;
|
||||
peerSettings#733f2961 flags:# report_spam:flags.0?true add_contact:flags.1?true block_contact:flags.2?true share_contact:flags.3?true need_contacts_exception:flags.4?true report_geo:flags.5?true autoarchived:flags.7?true invite_members:flags.8?true geo_distance:flags.6?int = PeerSettings;
|
||||
|
||||
wallPaper#a437c3ed id:long flags:# creator:flags.0?true default:flags.1?true pattern:flags.3?true dark:flags.4?true access_hash:long slug:string document:Document settings:flags.2?WallPaperSettings = WallPaper;
|
||||
wallPaperNoFile#e0804116 id:long flags:# default:flags.1?true dark:flags.4?true settings:flags.2?WallPaperSettings = WallPaper;
|
||||
@ -214,7 +213,7 @@ inputReportReasonCopyright#9b89f93a = ReportReason;
|
||||
inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
|
||||
inputReportReasonFake#f5ddd6e7 = ReportReason;
|
||||
|
||||
userFull#cf366521 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true id:long about:flags.1?string settings:PeerSettings 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 ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string = UserFull;
|
||||
userFull#d697ff05 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true user:User about:flags.1?string settings:PeerSettings 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 ttl_period:flags.14?int theme_emoticon:flags.15?string = UserFull;
|
||||
|
||||
contact#145ade0b user_id:long mutual:Bool = Contact;
|
||||
|
||||
@ -357,9 +356,6 @@ updateChannelParticipant#985d3abb flags:# channel_id:long date:int actor_id:long
|
||||
updateBotStopped#c4870a49 user_id:long date:int stopped:Bool qts:int = Update;
|
||||
updateGroupCallConnection#b783982 flags:# presentation:flags.0?true params:DataJSON = Update;
|
||||
updateBotCommands#4d712f2e peer:Peer bot_id:long commands:Vector<BotCommand> = Update;
|
||||
updatePendingJoinRequests#7063c3db peer:Peer requests_pending:int recent_requesters:Vector<long> = Update;
|
||||
updateBotChatInviteRequester#11dfa986 peer:Peer date:int user_id:long about:string invite:ExportedChatInvite qts:int = Update;
|
||||
updateMessageReactions#154798c3 peer:Peer msg_id:int reactions:MessageReactions = Update;
|
||||
|
||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||
|
||||
@ -449,7 +445,7 @@ sendMessageUploadRoundAction#243e1c66 progress:int = SendMessageAction;
|
||||
speakingInGroupCallAction#d92c2285 = SendMessageAction;
|
||||
sendMessageHistoryImportAction#dbda9246 progress:int = SendMessageAction;
|
||||
sendMessageChooseStickerAction#b05ac6b1 = SendMessageAction;
|
||||
sendMessageEmojiInteraction#25972bcb emoticon:string msg_id:int interaction:DataJSON = SendMessageAction;
|
||||
sendMessageEmojiInteraction#6a3233b6 emoticon:string interaction:DataJSON = SendMessageAction;
|
||||
sendMessageEmojiInteractionSeen#b665902e emoticon:string = SendMessageAction;
|
||||
|
||||
contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
|
||||
@ -517,9 +513,9 @@ webPagePending#c586da1c id:long date:int = WebPage;
|
||||
webPage#e89c45b2 flags:# id:long url:string display_url:string hash:int type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document cached_page:flags.10?Page attributes:flags.12?Vector<WebPageAttribute> = WebPage;
|
||||
webPageNotModified#7311ca11 flags:# cached_page_views:flags.0?int = WebPage;
|
||||
|
||||
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true encrypted_requests_disabled:flags.3?true call_requests_disabled:flags.4?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
authorization#ad01d61d flags:# current:flags.0?true official_app:flags.1?true password_pending:flags.2?true hash:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;
|
||||
|
||||
account.authorizations#4bff8ea0 authorization_ttl_days:int authorizations:Vector<Authorization> = account.Authorizations;
|
||||
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
|
||||
|
||||
account.password#185b184f flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes pending_reset_date:flags.5?int = account.Password;
|
||||
|
||||
@ -531,10 +527,10 @@ auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
|
||||
|
||||
receivedNotifyMessage#a384b779 id:int flags:int = ReceivedNotifyMessage;
|
||||
|
||||
chatInviteExported#ab4a819 flags:# revoked:flags.0?true permanent:flags.5?true request_needed:flags.6?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int requested:flags.7?int title:flags.8?string = ExportedChatInvite;
|
||||
chatInviteExported#b18105e8 flags:# revoked:flags.0?true permanent:flags.5?true link:string admin_id:long date:int start_date:flags.4?int expire_date:flags.1?int usage_limit:flags.2?int usage:flags.3?int = ExportedChatInvite;
|
||||
|
||||
chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
|
||||
chatInvite#300c44c1 flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true request_needed:flags.6?true title:string about:flags.5?string photo:Photo 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;
|
||||
chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite;
|
||||
|
||||
inputStickerSetEmpty#ffb62b95 = InputStickerSet;
|
||||
@ -542,12 +538,10 @@ inputStickerSetID#9de7a269 id:long access_hash:long = InputStickerSet;
|
||||
inputStickerSetShortName#861cc8a0 short_name:string = InputStickerSet;
|
||||
inputStickerSetAnimatedEmoji#28703c8 = InputStickerSet;
|
||||
inputStickerSetDice#e67f520e emoticon:string = InputStickerSet;
|
||||
inputStickerSetAnimatedEmojiAnimations#cde3739 = InputStickerSet;
|
||||
|
||||
stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true gifs:flags.6?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int count:int hash:int = StickerSet;
|
||||
stickerSet#d7df217a flags:# archived:flags.1?true official:flags.2?true masks:flags.3?true animated:flags.5?true installed_date:flags.0?int id:long access_hash:long title:string short_name:string thumbs:flags.4?Vector<PhotoSize> thumb_dc_id:flags.4?int thumb_version:flags.4?int count:int hash:int = StickerSet;
|
||||
|
||||
messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
|
||||
messages.stickerSetNotModified#d3f924eb = messages.StickerSet;
|
||||
|
||||
botCommand#c27ac8c7 command:string description:string = BotCommand;
|
||||
|
||||
@ -564,8 +558,6 @@ 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;
|
||||
keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton;
|
||||
inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton;
|
||||
keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton;
|
||||
|
||||
keyboardButtonRow#77608b83 buttons:Vector<KeyboardButton> = KeyboardButtonRow;
|
||||
|
||||
@ -593,7 +585,6 @@ messageEntityUnderline#9c4e7e8b offset:int length:int = MessageEntity;
|
||||
messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity;
|
||||
messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity;
|
||||
messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity;
|
||||
messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity;
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel;
|
||||
@ -611,7 +602,7 @@ channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter;
|
||||
channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector<MessageRange> = ChannelMessagesFilter;
|
||||
|
||||
channelParticipant#c00c07c0 user_id:long date:int = ChannelParticipant;
|
||||
channelParticipantSelf#35a8bfa7 flags:# via_request:flags.0?true user_id:long inviter_id:long date:int = ChannelParticipant;
|
||||
channelParticipantSelf#28a8bc67 user_id:long inviter_id:long date:int = ChannelParticipant;
|
||||
channelParticipantCreator#2fe601d3 flags:# user_id:long admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant;
|
||||
channelParticipantAdmin#34c3bb53 flags:# can_edit:flags.0?true self:flags.1?true user_id:long inviter_id:flags.1?long promoted_by:long date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
|
||||
channelParticipantBanned#6df8014e flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights = ChannelParticipant;
|
||||
@ -668,13 +659,11 @@ messageFwdHeader#5f777dce flags:# imported:flags.7?true from_id:flags.0?Peer fro
|
||||
auth.codeTypeSms#72a3158c = auth.CodeType;
|
||||
auth.codeTypeCall#741cd3e3 = auth.CodeType;
|
||||
auth.codeTypeFlashCall#226ccefb = auth.CodeType;
|
||||
auth.codeTypeMissedCall#d61ad6ee = auth.CodeType;
|
||||
|
||||
auth.sentCodeTypeApp#3dbb5986 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeSms#c000bba2 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
|
||||
auth.sentCodeTypeFlashCall#ab03c6d9 pattern:string = auth.SentCodeType;
|
||||
auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeType;
|
||||
|
||||
messages.botCallbackAnswer#36585ea4 flags:# alert:flags.1?true has_url:flags.3?true native_ui:flags.4?true message:flags.0?string url:flags.2?string cache_time:int = messages.BotCallbackAnswer;
|
||||
|
||||
@ -896,16 +885,13 @@ channelAdminLogEventActionExportedInviteRevoke#410a134e invite:ExportedChatInvit
|
||||
channelAdminLogEventActionExportedInviteEdit#e90ebb59 prev_invite:ExportedChatInvite new_invite:ExportedChatInvite = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionParticipantVolume#3e7f6847 participant:GroupCallParticipant = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeHistoryTTL#6e941a38 prev_value:int new_value:int = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionParticipantJoinByRequest#afb6144a invite:ExportedChatInvite approved_by:long = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeAvailableReactions#9cf7f76a prev_value:Vector<string> new_value:Vector<string> = ChannelAdminLogEventAction;
|
||||
channelAdminLogEventActionChangeTheme#fe69018d prev_value:string new_value:string = ChannelAdminLogEventAction;
|
||||
|
||||
channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent;
|
||||
|
||||
channels.adminLogResults#ed8af74d events:Vector<ChannelAdminLogEvent> chats:Vector<Chat> users:Vector<User> = channels.AdminLogResults;
|
||||
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true = ChannelAdminLogEventsFilter;
|
||||
channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true = ChannelAdminLogEventsFilter;
|
||||
|
||||
popularContact#5ce14175 client_id:long importers:int = PopularContact;
|
||||
|
||||
@ -1074,7 +1060,7 @@ inputWallPaperNoFile#967a462e id:long = InputWallPaper;
|
||||
account.wallPapersNotModified#1c199183 = account.WallPapers;
|
||||
account.wallPapers#cdc3858c hash:long wallpapers:Vector<WallPaper> = account.WallPapers;
|
||||
|
||||
codeSettings#8a6469c2 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true allow_missed_call:flags.5?true logout_tokens:flags.6?Vector<bytes> = CodeSettings;
|
||||
codeSettings#debebe83 flags:# allow_flashcall:flags.0?true current_number:flags.1?true allow_app_hash:flags.4?true = CodeSettings;
|
||||
|
||||
wallPaperSettings#1dc1bca4 flags:# blur:flags.1?true motion:flags.2?true background_color:flags.0?int second_background_color:flags.4?int third_background_color:flags.5?int fourth_background_color:flags.6?int intensity:flags.3?int rotation:flags.4?int = WallPaperSettings;
|
||||
|
||||
@ -1114,7 +1100,7 @@ restrictionReason#d072acb4 platform:string reason:string text:string = Restricti
|
||||
inputTheme#3c5693e9 id:long access_hash:long = InputTheme;
|
||||
inputThemeSlug#f5890df1 slug:string = InputTheme;
|
||||
|
||||
theme#a00e67d6 flags:# creator:flags.0?true default:flags.1?true for_chat:flags.5?true id:long access_hash:long slug:string title:string document:flags.2?Document settings:flags.3?Vector<ThemeSettings> emoticon:flags.6?string installs_count:flags.4?int = Theme;
|
||||
theme#e802b8dc flags:# creator:flags.0?true default:flags.1?true for_chat:flags.5?true id:long access_hash:long slug:string title:string document:flags.2?Document settings:flags.3?ThemeSettings installs_count:flags.4?int = Theme;
|
||||
|
||||
account.themesNotModified#f41eb622 = account.Themes;
|
||||
account.themes#9a3d8c6d hash:long themes:Vector<Theme> = account.Themes;
|
||||
@ -1226,7 +1212,7 @@ messages.historyImportParsed#5e0fb7b9 flags:# pm:flags.0?true group:flags.1?true
|
||||
|
||||
messages.affectedFoundMessages#ef8d3e6c pts:int pts_count:int offset:int messages:Vector<int> = messages.AffectedFoundMessages;
|
||||
|
||||
chatInviteImporter#8c5adfd9 flags:# requested:flags.0?true user_id:long date:int about:flags.2?string approved_by:flags.1?long = ChatInviteImporter;
|
||||
chatInviteImporter#b5cd5f4 user_id:long date:int = ChatInviteImporter;
|
||||
|
||||
messages.exportedChatInvites#bdc62dcc count:int invites:Vector<ExportedChatInvite> users:Vector<User> = messages.ExportedChatInvites;
|
||||
|
||||
@ -1263,42 +1249,15 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR
|
||||
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
|
||||
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
|
||||
|
||||
sponsoredMessage#3a836df8 flags:# random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string message:string entities:flags.1?Vector<MessageEntity> = SponsoredMessage;
|
||||
chatTheme#ed0b5c33 emoticon:string theme:Theme dark_theme:Theme = ChatTheme;
|
||||
|
||||
account.chatThemesNotModified#e011e1c4 = account.ChatThemes;
|
||||
account.chatThemes#fe4cbebd hash:int themes:Vector<ChatTheme> = account.ChatThemes;
|
||||
|
||||
sponsoredMessage#2a3c381f flags:# random_id:bytes from_id:Peer start_param:flags.0?string message:string entities:flags.1?Vector<MessageEntity> = SponsoredMessage;
|
||||
|
||||
messages.sponsoredMessages#65a4c7d5 messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
|
||||
|
||||
searchResultsCalendarPeriod#c9b0539f date:int min_msg_id:int max_msg_id:int count:int = SearchResultsCalendarPeriod;
|
||||
|
||||
messages.searchResultsCalendar#147ee23c flags:# inexact:flags.0?true count:int min_date:int min_msg_id:int offset_id_offset:flags.1?int periods:Vector<SearchResultsCalendarPeriod> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SearchResultsCalendar;
|
||||
|
||||
searchResultPosition#7f648b67 msg_id:int date:int offset:int = SearchResultsPosition;
|
||||
|
||||
messages.searchResultsPositions#53b22baf count:int positions:Vector<SearchResultsPosition> = messages.SearchResultsPositions;
|
||||
|
||||
channels.sendAsPeers#8356cda9 peers:Vector<Peer> chats:Vector<Chat> users:Vector<User> = channels.SendAsPeers;
|
||||
|
||||
users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
||||
|
||||
messages.peerSettings#6880b94d settings:PeerSettings chats:Vector<Chat> users:Vector<User> = messages.PeerSettings;
|
||||
|
||||
auth.loggedOut#c3a2835f flags:# future_auth_token:flags.0?bytes = auth.LoggedOut;
|
||||
|
||||
reactionCount#6fb250d1 flags:# chosen:flags.0?true reaction:string count:int = ReactionCount;
|
||||
|
||||
messageReactions#4f2b9479 flags:# min:flags.0?true can_see_list:flags.2?true results:Vector<ReactionCount> recent_reactions:flags.1?Vector<MessagePeerReaction> = MessageReactions;
|
||||
|
||||
messages.messageReactionsList#31bd492d flags:# count:int reactions:Vector<MessagePeerReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = messages.MessageReactionsList;
|
||||
|
||||
availableReaction#c077ec01 flags:# inactive:flags.0?true reaction:string title:string static_icon:Document appear_animation:Document select_animation:Document activate_animation:Document effect_animation:Document around_animation:flags.1?Document center_icon:flags.1?Document = AvailableReaction;
|
||||
|
||||
messages.availableReactionsNotModified#9f071957 = messages.AvailableReactions;
|
||||
messages.availableReactions#768e3aad hash:int reactions:Vector<AvailableReaction> = messages.AvailableReactions;
|
||||
|
||||
messages.translateNoResult#67ca4737 = messages.TranslatedText;
|
||||
messages.translateResultText#a214f7d0 text:string = messages.TranslatedText;
|
||||
|
||||
messagePeerReaction#51b67eff flags:# big:flags.0?true unread:flags.1?true peer_id:Peer reaction:string = MessagePeerReaction;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -1312,7 +1271,7 @@ invokeWithTakeout#aca9fd2e {X:Type} takeout_id:long query:!X = X;
|
||||
auth.sendCode#a677244f phone_number:string api_id:int api_hash:string settings:CodeSettings = auth.SentCode;
|
||||
auth.signUp#80eee427 phone_number:string phone_code_hash:string first_name:string last_name:string = auth.Authorization;
|
||||
auth.signIn#bcd51581 phone_number:string phone_code_hash:string phone_code:string = auth.Authorization;
|
||||
auth.logOut#3e72ba19 = auth.LoggedOut;
|
||||
auth.logOut#5717da40 = Bool;
|
||||
auth.resetAuthorizations#9fab0d1a = Bool;
|
||||
auth.exportAuthorization#e5bfffcd dc_id:int = auth.ExportedAuthorization;
|
||||
auth.importAuthorization#a57a7dad id:long bytes:bytes = auth.Authorization;
|
||||
@ -1385,10 +1344,10 @@ account.resetWallPapers#bb3b9804 = Bool;
|
||||
account.getAutoDownloadSettings#56da0b3f = account.AutoDownloadSettings;
|
||||
account.saveAutoDownloadSettings#76f36233 flags:# low:flags.0?true high:flags.1?true settings:AutoDownloadSettings = Bool;
|
||||
account.uploadTheme#1c3db333 flags:# file:InputFile thumb:flags.0?InputFile file_name:string mime_type:string = Document;
|
||||
account.createTheme#652e4400 flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?Vector<InputThemeSettings> = Theme;
|
||||
account.updateTheme#2bf40ccc flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?Vector<InputThemeSettings> = Theme;
|
||||
account.createTheme#8432c21f flags:# slug:string title:string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme;
|
||||
account.updateTheme#5cb367d5 flags:# format:string theme:InputTheme slug:flags.0?string title:flags.1?string document:flags.2?InputDocument settings:flags.3?InputThemeSettings = Theme;
|
||||
account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
|
||||
account.installTheme#c727bb3b flags:# dark:flags.0?true theme:flags.1?InputTheme format:flags.2?string base_theme:flags.3?BaseTheme = Bool;
|
||||
account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool;
|
||||
account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme;
|
||||
account.getThemes#7206e458 format:string hash:long = account.Themes;
|
||||
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
|
||||
@ -1399,12 +1358,10 @@ account.setGlobalPrivacySettings#1edaaac2 settings:GlobalPrivacySettings = Globa
|
||||
account.reportProfilePhoto#fa8cc6f5 peer:InputPeer photo_id:InputPhoto reason:ReportReason message:string = Bool;
|
||||
account.resetPassword#9308ce1b = account.ResetPasswordResult;
|
||||
account.declinePasswordReset#4c9409f6 = Bool;
|
||||
account.getChatThemes#d638de89 hash:long = account.Themes;
|
||||
account.setAuthorizationTTL#bf899aa0 authorization_ttl_days:int = Bool;
|
||||
account.changeAuthorizationSettings#40f48462 flags:# hash:long encrypted_requests_disabled:flags.0?Bool call_requests_disabled:flags.1?Bool = Bool;
|
||||
account.getChatThemes#d6d71d7b hash:int = account.ChatThemes;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
users.setSecureValueErrors#90c894b5 id:InputUser errors:Vector<SecureValueError> = Bool;
|
||||
|
||||
contacts.getContactIDs#7adc669d hash:long = Vector<int>;
|
||||
@ -1433,15 +1390,15 @@ messages.getDialogs#a0f4cb4f flags:# exclude_pinned:flags.0?true folder_id:flags
|
||||
messages.getHistory#4423e6c5 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||
messages.search#a0fda762 flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:long = messages.Messages;
|
||||
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
|
||||
messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int min_date:flags.2?int max_date:flags.3?int = messages.AffectedHistory;
|
||||
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
|
||||
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool;
|
||||
messages.sendMessage#d9d75a4 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMedia#e25ff8e0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.forwardMessages#cc30290b flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMessage#520c3870 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
|
||||
messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
|
||||
messages.forwardMessages#d9fee60e flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int = Updates;
|
||||
messages.reportSpam#cf1592db peer:InputPeer = Bool;
|
||||
messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings;
|
||||
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
|
||||
messages.report#8953ab4e peer:InputPeer id:Vector<int> reason:ReportReason message:string = Bool;
|
||||
messages.getChats#49e9528f id:Vector<long> = messages.Chats;
|
||||
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
|
||||
@ -1465,10 +1422,10 @@ messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages
|
||||
messages.getStickers#d5a5d3a1 emoticon:string hash:long = messages.Stickers;
|
||||
messages.getAllStickers#b8a0a1a8 hash:long = messages.AllStickers;
|
||||
messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
|
||||
messages.exportChatInvite#a02ce5d5 flags:# legacy_revoke_permanent:flags.2?true request_needed:flags.3?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int title:flags.4?string = ExportedChatInvite;
|
||||
messages.exportChatInvite#14b9bcd7 flags:# legacy_revoke_permanent:flags.2?true peer:InputPeer expire_date:flags.0?int usage_limit:flags.1?int = ExportedChatInvite;
|
||||
messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
|
||||
messages.importChatInvite#6c50051c hash:string = Updates;
|
||||
messages.getStickerSet#c8a0ec74 stickerset:InputStickerSet hash:int = messages.StickerSet;
|
||||
messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
|
||||
messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = messages.StickerSetInstallResult;
|
||||
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
|
||||
messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
|
||||
@ -1482,7 +1439,7 @@ messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs;
|
||||
messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
|
||||
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
|
||||
messages.setInlineBotResults#eb5ea206 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector<InputBotInlineResult> cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM = Bool;
|
||||
messages.sendInlineBotResult#7aa11297 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendInlineBotResult#220815b0 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int random_id:long query_id:long id:string schedule_date:flags.10?int = Updates;
|
||||
messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData;
|
||||
messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
|
||||
messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Bool;
|
||||
@ -1518,7 +1475,7 @@ messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool;
|
||||
messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readMentions#f0189d3 peer:InputPeer = messages.AffectedHistory;
|
||||
messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages;
|
||||
messages.sendMultiMedia#f803138f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates;
|
||||
messages.sendMultiMedia#cc0110cb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int = Updates;
|
||||
messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile;
|
||||
messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||
messages.getSplitRanges#1cff7e08 = Vector<MessageRange>;
|
||||
@ -1529,6 +1486,7 @@ messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?
|
||||
messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
|
||||
messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates;
|
||||
messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines;
|
||||
messages.getStatsURL#812c2ae6 flags:# dark:flags.0?true peer:InputPeer params:string = StatsURL;
|
||||
messages.editChatAbout#def60797 peer:InputPeer about:string = Bool;
|
||||
messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates;
|
||||
messages.getEmojiKeywords#35a0e062 lang_code:string = EmojiKeywordsDifference;
|
||||
@ -1562,30 +1520,15 @@ messages.uploadImportedMedia#2a862092 peer:InputPeer import_id:long file_name:st
|
||||
messages.startHistoryImport#b43df344 peer:InputPeer import_id:long = Bool;
|
||||
messages.getExportedChatInvites#a2b5a3f6 flags:# revoked:flags.3?true peer:InputPeer admin_id:InputUser offset_date:flags.2?int offset_link:flags.2?string limit:int = messages.ExportedChatInvites;
|
||||
messages.getExportedChatInvite#73746f5c peer:InputPeer link:string = messages.ExportedChatInvite;
|
||||
messages.editExportedChatInvite#bdca2f75 flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int request_needed:flags.3?Bool title:flags.4?string = messages.ExportedChatInvite;
|
||||
messages.editExportedChatInvite#2e4ffbe flags:# revoked:flags.2?true peer:InputPeer link:string expire_date:flags.0?int usage_limit:flags.1?int = messages.ExportedChatInvite;
|
||||
messages.deleteRevokedExportedChatInvites#56987bd5 peer:InputPeer admin_id:InputUser = Bool;
|
||||
messages.deleteExportedChatInvite#d464a42b peer:InputPeer link:string = Bool;
|
||||
messages.getAdminsWithInvites#3920e6ef peer:InputPeer = messages.ChatAdminsWithInvites;
|
||||
messages.getChatInviteImporters#df04dd4e flags:# requested:flags.0?true peer:InputPeer link:flags.1?string q:flags.2?string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters;
|
||||
messages.getChatInviteImporters#26fb7289 peer:InputPeer link:string offset_date:int offset_user:InputUser limit:int = messages.ChatInviteImporters;
|
||||
messages.setHistoryTTL#b80e5fe4 peer:InputPeer period:int = Updates;
|
||||
messages.checkHistoryImportPeer#5dc60f03 peer:InputPeer = messages.CheckedHistoryImportPeer;
|
||||
messages.setChatTheme#e63be13f peer:InputPeer emoticon:string = Updates;
|
||||
messages.getMessageReadParticipants#2c6f97b7 peer:InputPeer msg_id:int = Vector<long>;
|
||||
messages.getSearchResultsCalendar#49f0bde9 peer:InputPeer filter:MessagesFilter offset_id:int offset_date:int = messages.SearchResultsCalendar;
|
||||
messages.getSearchResultsPositions#6e9583a3 peer:InputPeer filter:MessagesFilter offset_id:int limit:int = messages.SearchResultsPositions;
|
||||
messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPeer user_id:InputUser = Updates;
|
||||
messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates;
|
||||
messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates;
|
||||
messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool;
|
||||
messages.sendReaction#25690ce4 flags:# big:flags.1?true peer:InputPeer msg_id:int reaction:flags.0?string = Updates;
|
||||
messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector<int> = Updates;
|
||||
messages.getMessageReactionsList#e0ee6b77 flags:# peer:InputPeer id:int reaction:flags.0?string offset:flags.1?string limit:int = messages.MessageReactionsList;
|
||||
messages.setChatAvailableReactions#14050ea6 peer:InputPeer available_reactions:Vector<string> = Updates;
|
||||
messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions;
|
||||
messages.setDefaultReaction#d960c4d4 reaction:string = Bool;
|
||||
messages.translateText#24ce6dee flags:# peer:flags.0?InputPeer msg_id:flags.0?int text:flags.1?string from_lang:flags.2?string to_lang:string = messages.TranslatedText;
|
||||
messages.getUnreadReactions#e85bae1a peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
messages.readReactions#82e251d7 peer:InputPeer = messages.AffectedHistory;
|
||||
|
||||
updates.getState#edd4882a = updates.State;
|
||||
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
|
||||
@ -1630,7 +1573,8 @@ help.getCountriesList#735787a8 lang_code:string hash:int = help.CountriesList;
|
||||
|
||||
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
channels.reportSpam#f44a8315 channel:InputChannel participant:InputPeer id:Vector<int> = Bool;
|
||||
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
||||
channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
|
||||
channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
|
||||
channels.getParticipants#77ced9d0 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:long = channels.ChannelParticipants;
|
||||
channels.getParticipant#a0ab6cc6 channel:InputChannel participant:InputPeer = channels.ChannelParticipant;
|
||||
@ -1665,8 +1609,6 @@ channels.getInactiveChannels#11e831ee = messages.InactiveChats;
|
||||
channels.convertToGigagroup#b290c69 channel:InputChannel = Updates;
|
||||
channels.viewSponsoredMessage#beaedb94 channel:InputChannel random_id:bytes = Bool;
|
||||
channels.getSponsoredMessages#ec210fbf channel:InputChannel = messages.SponsoredMessages;
|
||||
channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers;
|
||||
channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory;
|
||||
|
||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||
@ -1734,4 +1676,4 @@ stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel
|
||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||
|
||||
// LAYER 138
|
||||
// LAYER 133
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -158,7 +158,6 @@ def pyrogram_api():
|
||||
send_venue
|
||||
send_contact
|
||||
send_cached_media
|
||||
send_reaction
|
||||
edit_message_text
|
||||
edit_message_caption
|
||||
edit_message_media
|
||||
@ -181,17 +180,14 @@ def pyrogram_api():
|
||||
retract_vote
|
||||
send_dice
|
||||
search_messages
|
||||
search_messages_count
|
||||
search_global
|
||||
search_global_count
|
||||
download_media
|
||||
get_discussion_message
|
||||
""",
|
||||
chats="""
|
||||
Chats
|
||||
join_chat
|
||||
leave_chat
|
||||
ban_chat_member
|
||||
kick_chat_member
|
||||
unban_chat_member
|
||||
restrict_chat_member
|
||||
promote_chat_member
|
||||
@ -227,9 +223,6 @@ def pyrogram_api():
|
||||
mark_chat_unread
|
||||
get_chat_event_log
|
||||
get_chat_online_count
|
||||
get_send_as_chats
|
||||
set_send_as_chat
|
||||
set_chat_protected_content
|
||||
""",
|
||||
users="""
|
||||
Users
|
||||
@ -260,8 +253,6 @@ def pyrogram_api():
|
||||
get_chat_admin_invite_links_count
|
||||
get_chat_admins_with_invite_links
|
||||
delete_chat_admin_invite_links
|
||||
approve_chat_join_request
|
||||
decline_chat_join_request
|
||||
""",
|
||||
contacts="""
|
||||
Contacts
|
||||
@ -287,7 +278,6 @@ def pyrogram_api():
|
||||
send_game
|
||||
set_game_score
|
||||
get_game_high_scores
|
||||
set_bot_commands
|
||||
""",
|
||||
authorization="""
|
||||
Authorization
|
||||
@ -364,7 +354,6 @@ def pyrogram_api():
|
||||
ChatEvent
|
||||
ChatEventFilter
|
||||
ChatMemberUpdated
|
||||
ChatJoinRequest
|
||||
Dialog
|
||||
Restriction
|
||||
""",
|
||||
@ -389,7 +378,6 @@ def pyrogram_api():
|
||||
Poll
|
||||
PollOption
|
||||
Dice
|
||||
Reaction
|
||||
VoiceChatScheduled
|
||||
VoiceChatStarted
|
||||
VoiceChatEnded
|
||||
@ -426,8 +414,6 @@ def pyrogram_api():
|
||||
InlineQueryResultArticle
|
||||
InlineQueryResultPhoto
|
||||
InlineQueryResultAnimation
|
||||
InlineQueryResultAudio
|
||||
InlineQueryResultVideo
|
||||
ChosenInlineResult
|
||||
""",
|
||||
input_message_content="""
|
||||
@ -513,7 +499,7 @@ def pyrogram_api():
|
||||
Chat.set_title
|
||||
Chat.set_description
|
||||
Chat.set_photo
|
||||
Chat.ban_member
|
||||
Chat.kick_member
|
||||
Chat.unban_member
|
||||
Chat.restrict_member
|
||||
Chat.promote_member
|
||||
@ -524,7 +510,6 @@ def pyrogram_api():
|
||||
Chat.join
|
||||
Chat.leave
|
||||
Chat.mark_unread
|
||||
Chat.set_protected_content
|
||||
""",
|
||||
user="""
|
||||
User
|
||||
@ -544,11 +529,6 @@ def pyrogram_api():
|
||||
inline_query="""
|
||||
InlineQuery
|
||||
InlineQuery.answer
|
||||
""",
|
||||
chat_join_request="""
|
||||
ChatJoinRequest
|
||||
ChatJoinRequest.approve
|
||||
ChatJoinRequest.decline
|
||||
"""
|
||||
)
|
||||
|
||||
|
21
compiler/docs/template/bound-methods.rst
vendored
21
compiler/docs/template/bound-methods.rst
vendored
@ -1,11 +1,12 @@
|
||||
Bound Methods
|
||||
=============
|
||||
|
||||
Some Pyrogram types define what are called bound methods. Bound methods are functions attached to a type which are
|
||||
accessed via an instance of that type. They make it even easier to call specific methods by automatically inferring
|
||||
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
|
||||
|
||||
@ -14,7 +15,7 @@ some of the required arguments.
|
||||
|
||||
@app.on_message()
|
||||
def hello(client, message)
|
||||
message.reply("hi")
|
||||
message.reply_text("hi")
|
||||
|
||||
|
||||
app.run()
|
||||
@ -91,17 +92,3 @@ InlineQuery
|
||||
:hidden:
|
||||
|
||||
{inline_query_toctree}
|
||||
|
||||
ChatJoinRequest
|
||||
---------------
|
||||
|
||||
.. hlist::
|
||||
:columns: 2
|
||||
|
||||
{chat_join_request_hlist}
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
{chat_join_request_toctree}
|
||||
|
||||
|
7
compiler/docs/template/methods.rst
vendored
7
compiler/docs/template/methods.rst
vendored
@ -1,17 +1,18 @@
|
||||
Available Methods
|
||||
=================
|
||||
|
||||
This page is about Pyrogram methods. All the methods listed here are bound to a :class:`~pyrogram.Client` instance.
|
||||
Some other utility functions can instead be found in the main package directly.
|
||||
This page is about Pyrogram methods. All the methods listed here are bound to a :class:`~pyrogram.Client` instance,
|
||||
except for :meth:`~pyrogram.idle()`, which is a special function that can be found in the main package directly.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 6
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
app.send_message("me", "hi")
|
||||
app.send_message("haskell", "hi")
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
|
1
compiler/docs/template/types.rst
vendored
1
compiler/docs/template/types.rst
vendored
@ -6,6 +6,7 @@ Unless required as argument to a client method, most of the types don't need to
|
||||
are only returned by other methods. You also don't need to import them, unless you want to type-hint your variables.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1
|
||||
|
||||
from pyrogram.types import User, Message, ...
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -52,7 +52,6 @@ CHANNEL_TOO_LARGE The channel is too large to be deleted; this error is issued w
|
||||
CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content
|
||||
CHAT_ABOUT_TOO_LONG The chat about text is too long
|
||||
CHAT_ADMIN_REQUIRED The method requires chat admin privileges
|
||||
CHAT_FORWARDS_RESTRICTED The chat restricts forwarding content
|
||||
CHAT_ID_EMPTY The provided chat id is empty
|
||||
CHAT_ID_INVALID The chat id being used is invalid or not known yet. Make sure you see the chat before interacting with it
|
||||
CHAT_INVALID The chat is invalid
|
||||
@ -62,7 +61,6 @@ CHAT_NOT_MODIFIED The chat settings (title, permissions, photo, etc..) were not
|
||||
CHAT_RESTRICTED The chat is restricted and cannot be used
|
||||
CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat
|
||||
CHAT_TITLE_EMPTY The chat title is empty
|
||||
CHAT_TOO_BIG The chat is too big for this action
|
||||
CODE_EMPTY The provided code is empty
|
||||
CODE_HASH_INVALID The provided code hash invalid
|
||||
CODE_INVALID The provided code is invalid (i.e. from email)
|
||||
@ -250,7 +248,7 @@ RANDOM_ID_INVALID The provided random ID is invalid
|
||||
RANDOM_LENGTH_INVALID The random length is invalid
|
||||
RANGES_INVALID Invalid range provided
|
||||
REACTION_EMPTY The reaction provided is empty
|
||||
REACTION_INVALID Invalid reaction provided (only valid emoji are allowed)
|
||||
REACTION_INVALID Invalid reaction provided (only emoji are allowed)
|
||||
REFLECTOR_NOT_AVAILABLE The call reflector is not available
|
||||
REPLY_MARKUP_BUY_EMPTY Reply markup for buy button empty
|
||||
REPLY_MARKUP_GAME_EMPTY The provided reply markup for the game is empty
|
||||
|
|
@ -2,7 +2,7 @@ id message
|
||||
ACTIVE_USER_REQUIRED The method is only available to already activated users
|
||||
AUTH_KEY_INVALID The key is invalid
|
||||
AUTH_KEY_PERM_EMPTY The method is unavailable for temporary authorization key, not bound to permanent
|
||||
AUTH_KEY_UNREGISTERED The key is not registered in the system. Delete your session file and login again
|
||||
AUTH_KEY_UNREGISTERED The key is not registered in the system
|
||||
SESSION_EXPIRED The authorization has expired
|
||||
SESSION_PASSWORD_NEEDED The two-step verification is enabled and a password is required
|
||||
SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions
|
||||
|
|
@ -1,3 +1,2 @@
|
||||
id message
|
||||
Timeout Telegram is having internal problems. Please try again later.
|
||||
ApiCallError Telegram is having internal problems. Please try again later.
|
||||
Timeout Telegram is having internal problems. Please try again later.
|
|
8
docs/README.md
Normal file
8
docs/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Pyrogram Docs
|
||||
|
||||
- Install requirements.
|
||||
- Install `pandoc` and `latexmk`.
|
||||
- HTML: `make html`
|
||||
- PDF: `make latexpdf`
|
||||
|
||||
TODO: Explain better
|
@ -1,6 +1,6 @@
|
||||
sphinx
|
||||
sphinx_rtd_theme==1.0.0
|
||||
sphinx_rtd_theme
|
||||
sphinx_copybutton
|
||||
pypandoc
|
||||
requests
|
||||
sphinx-autobuild
|
||||
sphinx-autobuild
|
7
docs/robots.txt
Normal file
7
docs/robots.txt
Normal file
@ -0,0 +1,7 @@
|
||||
User-agent: *
|
||||
|
||||
Allow: /
|
||||
|
||||
Disallow: /old*
|
||||
|
||||
Sitemap: https://docs.pyrogram.org/sitemap.xml
|
84
docs/scripts/releases.py
Normal file
84
docs/scripts/releases.py
Normal file
@ -0,0 +1,84 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import pypandoc
|
||||
import requests
|
||||
|
||||
URL = "https://api.github.com/repos/pyrogram/pyrogram/releases"
|
||||
DEST = Path("../source/releases")
|
||||
INTRO = """
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
Release notes for Pyrogram releases will describe what's new in each version, and will also make you aware of any
|
||||
backwards-incompatible changes made in that version.
|
||||
|
||||
When upgrading to a new version of Pyrogram, you will need to check all the breaking changes in order to find
|
||||
incompatible code in your application, but also to take advantage of new features and improvements.
|
||||
|
||||
**Contents**
|
||||
|
||||
""".lstrip("\n")
|
||||
|
||||
shutil.rmtree(DEST, ignore_errors=True)
|
||||
DEST.mkdir(parents=True)
|
||||
|
||||
releases = requests.get(URL).json()
|
||||
|
||||
with open(DEST / "index.rst", "w") as index:
|
||||
index.write(INTRO)
|
||||
|
||||
tags = []
|
||||
|
||||
for release in releases:
|
||||
tag = release["tag_name"]
|
||||
title = release["name"]
|
||||
name = title.split(" - ")[1]
|
||||
|
||||
date = datetime.strptime(
|
||||
release["published_at"],
|
||||
"%Y-%m-%dT%H:%M:%SZ"
|
||||
).strftime("%b %d, %Y")
|
||||
|
||||
body = pypandoc.convert_text(
|
||||
release["body"].replace(r"\r\n", "\n"),
|
||||
"rst",
|
||||
format="markdown_github",
|
||||
extra_args=["--wrap=none"]
|
||||
)
|
||||
|
||||
tarball_url = release["tarball_url"]
|
||||
zipball_url = release["zipball_url"]
|
||||
|
||||
index.write("- :doc:`{} <{}>`\n".format(title, tag))
|
||||
tags.append(tag)
|
||||
|
||||
with open(DEST / "{}.rst".format(tag), "w") as page:
|
||||
page.write("Pyrogram " + tag + "\n" + "=" * (len(tag) + 9) + "\n\n")
|
||||
page.write("\t\tReleased on " + str(date) + "\n\n")
|
||||
page.write("- :download:`Source Code (zip) <{}>`\n".format(zipball_url))
|
||||
page.write("- :download:`Source Code (tar.gz) <{}>`\n\n".format(tarball_url))
|
||||
page.write(name + "\n" + "-" * len(name) + "\n\n")
|
||||
page.write(body + "\n\n")
|
||||
|
||||
index.write("\n.. toctree::\n :hidden:\n\n")
|
||||
index.write("\n".join(" {}".format(tag) for tag in tags))
|
81
docs/scripts/sitemap.py
Normal file
81
docs/scripts/sitemap.py
Normal file
@ -0,0 +1,81 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
|
||||
canonical = "https://docs.pyrogram.org/"
|
||||
|
||||
dirs = {
|
||||
".": ("weekly", 1.0),
|
||||
"intro": ("weekly", 0.9),
|
||||
"start": ("weekly", 0.9),
|
||||
"api": ("weekly", 0.8),
|
||||
"topics": ("weekly", 0.8),
|
||||
"releases": ("weekly", 0.8),
|
||||
"telegram": ("weekly", 0.6)
|
||||
}
|
||||
|
||||
|
||||
def now():
|
||||
return datetime.datetime.today().strftime("%Y-%m-%d")
|
||||
|
||||
|
||||
with open("sitemap.xml", "w") as f:
|
||||
f.write('<?xml version="1.0" encoding="utf-8"?>\n')
|
||||
f.write('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n')
|
||||
|
||||
urls = []
|
||||
|
||||
|
||||
def search(path):
|
||||
try:
|
||||
for j in os.listdir(path):
|
||||
search(f"{path}/{j}")
|
||||
except NotADirectoryError:
|
||||
if not path.endswith(".rst"):
|
||||
return
|
||||
|
||||
path = path.split("/")[2:]
|
||||
|
||||
if path[0].endswith(".rst"):
|
||||
folder = "."
|
||||
else:
|
||||
folder = path[0]
|
||||
|
||||
path = f"{canonical}{'/'.join(path)}"[:-len(".rst")]
|
||||
|
||||
if path.endswith("index"):
|
||||
path = path[:-len("index")]
|
||||
|
||||
urls.append((path, now(), *dirs[folder]))
|
||||
|
||||
|
||||
search("../source")
|
||||
|
||||
urls.sort(key=lambda x: x[3], reverse=True)
|
||||
|
||||
for i in urls:
|
||||
f.write(f" <url>\n")
|
||||
f.write(f" <loc>{i[0]}</loc>\n")
|
||||
f.write(f" <lastmod>{i[1]}</lastmod>\n")
|
||||
f.write(f" <changefreq>{i[2]}</changefreq>\n")
|
||||
f.write(f" <priority>{i[3]}</priority>\n")
|
||||
f.write(f" </url>\n")
|
||||
|
||||
f.write("</urlset>")
|
BIN
docs/source/_images/favicon.ico
Normal file
BIN
docs/source/_images/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 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 |
@ -8,6 +8,7 @@ found starting from this page.
|
||||
This page is about the Client class, which exposes high-level methods for an easy access to the API.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1-3
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
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
|
||||
|
||||
|
@ -5,6 +5,7 @@ Handlers are used to instruct Pyrogram about which kind of updates you'd like to
|
||||
For a much more convenient way of registering callback functions have a look at :doc:`Decorators <decorators>` instead.
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 2, 11
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.handlers import MessageHandler
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -29,37 +29,35 @@ from pygments.styles.friendly import FriendlyStyle
|
||||
FriendlyStyle.background_color = "#f3f2f1"
|
||||
|
||||
project = "Pyrogram"
|
||||
copyright = f"2017-present, Dan"
|
||||
copyright = f"2017-{datetime.now().year}, Dan"
|
||||
author = "Dan"
|
||||
|
||||
version = ".".join(__version__.split(".")[:-1])
|
||||
|
||||
extensions = [
|
||||
"sphinx.ext.autodoc",
|
||||
"sphinx.ext.napoleon",
|
||||
"sphinx.ext.autosummary",
|
||||
"sphinx_copybutton"
|
||||
"sphinx_copybutton",
|
||||
"sphinx_tabs.tabs"
|
||||
]
|
||||
|
||||
master_doc = "index"
|
||||
source_suffix = ".rst"
|
||||
autodoc_member_order = "bysource"
|
||||
|
||||
templates_path = ["_resources/templates"]
|
||||
html_copy_source = False
|
||||
version = __version__
|
||||
release = version
|
||||
|
||||
templates_path = ["_templates"]
|
||||
|
||||
napoleon_use_rtype = False
|
||||
napoleon_use_param = False
|
||||
|
||||
pygments_style = "friendly"
|
||||
|
||||
copybutton_prompt_text = "$ "
|
||||
|
||||
suppress_warnings = ["image.not_readable"]
|
||||
|
||||
html_title = "Pyrogram Documentation"
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
html_static_path = ["_resources/static"]
|
||||
html_static_path = ["_static"]
|
||||
html_show_sourcelink = True
|
||||
html_show_copyright = False
|
||||
html_theme_options = {
|
||||
@ -67,15 +65,17 @@ html_theme_options = {
|
||||
"collapse_navigation": True,
|
||||
"sticky_navigation": False,
|
||||
"logo_only": True,
|
||||
"display_version": False,
|
||||
"display_version": True,
|
||||
"style_external_links": True
|
||||
}
|
||||
|
||||
html_logo = "_resources/static/img/pyrogram.png"
|
||||
html_favicon = "_resources/static/img/favicon.ico"
|
||||
napoleon_use_param = False
|
||||
|
||||
html_logo = "_images/pyrogram.png"
|
||||
html_favicon = "_images/favicon.ico"
|
||||
|
||||
latex_engine = "xelatex"
|
||||
latex_logo = "_resources/static/img/pyrogram.png"
|
||||
latex_logo = "_images/pyrogram.png"
|
||||
|
||||
latex_elements = {
|
||||
"pointsize": "12pt",
|
||||
|
407
docs/source/faq.rst
Normal file
407
docs/source/faq.rst
Normal file
@ -0,0 +1,407 @@
|
||||
Pyrogram FAQ
|
||||
============
|
||||
|
||||
.. role:: strike
|
||||
:class: strike
|
||||
|
||||
This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general.
|
||||
|
||||
.. tip::
|
||||
|
||||
If you think something interesting could be added here, feel free to propose it by opening a `Feature Request`_.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
||||
What is Pyrogram?
|
||||
-----------------
|
||||
|
||||
**Pyrogram** is an elegant, easy-to-use Telegram_ client library and framework written from the ground up in Python and
|
||||
C. It enables you to easily create custom applications for both user and bot identities (bot API alternative) via the
|
||||
:doc:`MTProto API <topics/mtproto-vs-botapi>` with the Python programming language.
|
||||
|
||||
.. _Telegram: https://telegram.org
|
||||
|
||||
Where does the name come from?
|
||||
------------------------------
|
||||
|
||||
The name "Pyrogram" is composed by **pyro**, which comes from the Greek word *πῦρ (pyr)*, meaning fire, and **gram**,
|
||||
from *Telegram*. The word *pyro* itself is built from *Python*, **py** for short, and the suffix **ro** to come up with
|
||||
the word *fire*, which also inspired the project logo.
|
||||
|
||||
How old is Pyrogram?
|
||||
--------------------
|
||||
|
||||
Pyrogram was first released on December 12, 2017. The actual work on the framework began roughly three months prior to the
|
||||
initial public release on `GitHub`_.
|
||||
|
||||
.. _GitHub: https://github.com/pyrogram/pyrogram
|
||||
|
||||
Why Pyrogram?
|
||||
-------------
|
||||
|
||||
- **Easy**: You can install Pyrogram with pip and start building your applications right away.
|
||||
- **Elegant**: Low-level details are abstracted and re-presented in a much nicer and easier way.
|
||||
- **Fast**: Crypto parts are boosted up by TgCrypto_, a high-performance library written in pure C.
|
||||
- **Asynchronous**: Allows both synchronous and asynchronous models to fit all usage needs.
|
||||
- **Documented**: API methods, types and public interfaces are all well documented.
|
||||
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
|
||||
- **Updated**, to make use of the latest Telegram API version and features.
|
||||
- **Bot API-like**: Similar to the Bot API in its simplicity, but much more powerful and detailed.
|
||||
- **Pluggable**: The :doc:`Smart Plugin <topics/smart-plugins>` system allows to write components with minimal
|
||||
boilerplate code.
|
||||
- **Comprehensive**: Execute any :doc:`advanced action <topics/advanced-usage>` an official client is able to do, and
|
||||
even more.
|
||||
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
|
||||
Why is Pyrogram defined as both Client Library and Framework?
|
||||
-------------------------------------------------------------
|
||||
|
||||
Simply because it falls in both categories, depending on how you use it.
|
||||
|
||||
Pyrogram as a client library makes it easy and intuitive accessing the Telegram API by offering idiomatic Python code
|
||||
that is generated or hand-written. Low-level details and client-server communication protocols are handled under the
|
||||
hood. Pyrogram acts as a client library when *you call* its methods and use its types in a batch application that
|
||||
executes a set of instructions.
|
||||
|
||||
Pyrogram as a framework makes it easy to handle live events by allowing you to register event handlers that will be
|
||||
executed as soon as they arrive from the server side. Pyrogram acts as a framework when it's Pyrogram itself that
|
||||
*calls your code*, that is, your registered event handlers. Such applications are usually started and left online
|
||||
indefinitely, until you decide to stop them.
|
||||
|
||||
What can MTProto do more than the Bot API?
|
||||
------------------------------------------
|
||||
|
||||
For a detailed answer, please refer to the :doc:`MTProto vs. Bot API <topics/mtproto-vs-botapi>` page.
|
||||
|
||||
Why do I need an API key for bots?
|
||||
----------------------------------
|
||||
|
||||
Requests against the official bot API endpoint are made via JSON/HTTP, but are handled by an intermediate server
|
||||
application that implements the MTProto protocol -- just like Pyrogram -- and uses its own API key, which is always
|
||||
required, but hidden to the public.
|
||||
|
||||
.. figure:: https://i.imgur.com/WvwBoZo.png
|
||||
:align: center
|
||||
|
||||
Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to
|
||||
identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone
|
||||
number only.
|
||||
|
||||
Can I use Webhooks?
|
||||
-------------------
|
||||
|
||||
Lots of people ask this question because they are used to the bot API, but things are different in Pyrogram!
|
||||
|
||||
There is no webhook in Pyrogram, simply because there is no HTTP involved, by default. However, a similar technique is
|
||||
being used to make receiving updates efficient.
|
||||
|
||||
Pyrogram uses persistent connections via TCP sockets to interact with the server and instead of actively asking for
|
||||
updates every time (polling), Pyrogram will simply sit down and wait for the server to send updates by itself
|
||||
the very moment they are available (server push).
|
||||
|
||||
Can I use the same file_id across different accounts?
|
||||
-----------------------------------------------------
|
||||
|
||||
No, Telegram doesn't allow this.
|
||||
|
||||
File ids are personal and bound to a specific account; an attempt in using a foreign file id will result in errors such
|
||||
as ``[400 MEDIA_EMPTY]``.
|
||||
|
||||
The only exception are stickers' file ids; you can use them across different accounts without any problem, like this
|
||||
one: ``CAADBAADyg4AAvLQYAEYD4F7vcZ43AI``.
|
||||
|
||||
Can I use Bot API's file_id values in Pyrogram?
|
||||
-----------------------------------------------
|
||||
|
||||
Yes! All file ids you take or might have taken from the Bot API are 100% compatible and re-usable in Pyrogram.
|
||||
The opposite is also valid, you can take any file id generated by Pyrogram and re-use in the Bot API.
|
||||
|
||||
Can I use multiple clients at once on the same account?
|
||||
-------------------------------------------------------
|
||||
|
||||
Yes, you can. Both user and bot accounts are able to run multiple sessions in parallel (up to 10 per account). However,
|
||||
you must pay attention and not use the *same* exact session in more than one client at the same time. In other words:
|
||||
|
||||
- Avoid copying your session file: even if you rename the file, the copied sessions will still point to a specific one
|
||||
stored in the server.
|
||||
|
||||
- Make sure that only one instance of your script runs, using your session file.
|
||||
|
||||
If you -- even accidentally -- fail to do so, all the previous session copies will immediately stop receiving updates
|
||||
and eventually the server will start throwing the error ``[406 AUTH_KEY_DUPLICATED]``, inviting you to login again.
|
||||
|
||||
Why is that so? Because the server has recognized two identical sessions are running in two different locations, and
|
||||
concludes it could possibly be due to a cloned/stolen device. Having the session terminated in such occasions will
|
||||
protect the user's privacy.
|
||||
|
||||
So, the only correct way to run multiple clients on the same account is authorizing your account (either user or bot)
|
||||
from the beginning every time, and use one separate session for each parallel client you are going to use.
|
||||
|
||||
I started a client and nothing happens!
|
||||
---------------------------------------
|
||||
|
||||
If you are connecting from Russia, China or Iran :doc:`you need a proxy <topics/proxy>`, because Telegram could be
|
||||
partially or totally blocked in those countries. More information about this block can be found at
|
||||
`Wikipedia <https://en.wikipedia.org/wiki/Blocking_Telegram_in_Russia>`_.
|
||||
|
||||
Another possible cause might be network issues, either yours or Telegram's. To confirm this, add the following code on
|
||||
the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable network
|
||||
in a bunch of seconds:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
Another way to confirm you aren't able to connect to Telegram is by pinging the IP addresses below and see whether ping
|
||||
fails or not.
|
||||
|
||||
What are the IP addresses of Telegram Data Centers?
|
||||
---------------------------------------------------
|
||||
|
||||
The Telegram cloud is currently composed by a decentralized, multi-DC infrastructure (currently 5 DCs, each of which can
|
||||
work independently) spread in different locations worldwide. However, some of the less busy DCs have been lately
|
||||
dismissed and their IP addresses are now kept as aliases to the nearest one.
|
||||
|
||||
.. csv-table:: Production Environment
|
||||
:header: ID, Location, IPv4, IPv6
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
DC1, "MIA, Miami FL, USA", ``149.154.175.53``, ``2001:b28:f23d:f001::a``
|
||||
DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a``
|
||||
DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a``
|
||||
DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a``
|
||||
DC5, "SIN, Singapore, SG", ``91.108.56.130``, ``2001:b28:f23f:f005::a``
|
||||
|
||||
.. csv-table:: Test Environment
|
||||
:header: ID, Location, IPv4, IPv6
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e``
|
||||
DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e``
|
||||
DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e``
|
||||
|
||||
.. centered:: More info about the Test Environment can be found :doc:`here <topics/test-servers>`.
|
||||
|
||||
***** Alias DC
|
||||
|
||||
Thanks to `@FrayxRulez <https://t.me/tgbetachat/104921>`_ for telling about alias DCs.
|
||||
|
||||
I want to migrate my account from DCX to DCY.
|
||||
---------------------------------------------
|
||||
|
||||
This question is often asked by people who find their account(s) always being connected to DC1 - USA (for example), but
|
||||
are connecting from a place far away (e.g DC4 - Europe), thus resulting in slower interactions when using the API
|
||||
because of the great physical distance between the user and its associated DC.
|
||||
|
||||
When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be created
|
||||
in, based on the phone number origin.
|
||||
|
||||
Even though Telegram `documentations <https://core.telegram.org/api/datacenter#user-migration>`_ state the server might
|
||||
decide to automatically migrate a user in case of prolonged usages from a distant, unusual location and albeit this
|
||||
mechanism is also `confirmed <https://twitter.com/telegram/status/427131446655197184>`_ to exist by Telegram itself,
|
||||
it's currently not possible to have your account migrated, in any way, simply because the feature was once planned but
|
||||
not yet implemented.
|
||||
|
||||
Thanks to `@gabriel <https://t.me/AnotherGroup/217699>`_ for confirming the feature was not implemented yet.
|
||||
|
||||
Why is my client reacting slowly in supergroups?
|
||||
------------------------------------------------
|
||||
|
||||
This issue affects only some supergroups or only some members within the same supergroup. Mostly, it affects supergroups
|
||||
whose creator's account (and thus the supergroup itself) lives inside a **different DC**, far away from yours, but could
|
||||
also depend on where a member is connecting from.
|
||||
|
||||
Because of how Telegram works internally, every single message you receive from and send to other members must pass
|
||||
through the creator's DC, and in the worst case where you, the creator and another member all belong to three different
|
||||
DCs, the other member messages have to go through from its DC to the creator's DC and finally to your DC. This process
|
||||
will inevitably take its time.
|
||||
|
||||
To confirm this theory and see it by yourself, you can test in a supergroup where you are sure all parties live
|
||||
inside the same DC. In this case the responses will be faster.
|
||||
|
||||
Another reason that makes responses come slowly is that messages are **dispatched by priority**. Depending on the kind
|
||||
of member, some users receive messages faster than others and for big and busy supergroups the delay might become
|
||||
noticeable, especially if you are among the lower end of the priority list:
|
||||
|
||||
1. Creator.
|
||||
2. Administrators.
|
||||
3. Bots.
|
||||
4. Mentioned users.
|
||||
5. Recent online users.
|
||||
6. Everyone else.
|
||||
|
||||
Thanks to `@Manuel15 <https://t.me/PyrogramChat/76990>`_ for the priority list.
|
||||
|
||||
I keep getting PEER_ID_INVALID error!
|
||||
-------------------------------------
|
||||
|
||||
The error in question is ``[400 PEER_ID_INVALID]``, and could mean several things:
|
||||
|
||||
- The chat id you tried to use is simply wrong, double check it.
|
||||
- The chat id refers to a group or channel you are not a member of.
|
||||
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
|
||||
- The chat id refers to a user or chat your current session hasn't met yet.
|
||||
|
||||
About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to
|
||||
contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching
|
||||
for usernames, meeting them in a common group, having their phone contacts saved, getting a message mentioning them
|
||||
(either a forward or a mention in the message text) or obtaining the dialogs list.
|
||||
|
||||
Code hangs when I stop, restart, add/remove_handler
|
||||
---------------------------------------------------
|
||||
|
||||
You tried to ``.stop()``, ``.restart()``, ``.add_handler()`` or ``.remove_handler()`` *inside* a running handler, but
|
||||
that can't be done because the way Pyrogram deals with handlers would make it hang.
|
||||
|
||||
When calling one of the methods above inside an event handler, Pyrogram needs to wait for all running handlers to finish
|
||||
in order to safely continue. In other words, since your handler is blocking the execution by waiting for the called
|
||||
method to finish and since Pyrogram needs to wait for your handler to finish, you are left with a deadlock.
|
||||
|
||||
The solution to this problem is to pass ``block=False`` to such methods so that they return immediately and the actual
|
||||
code called asynchronously.
|
||||
|
||||
UnicodeEncodeError: '<encoding>' codec can't encode …
|
||||
-----------------------------------------------------
|
||||
|
||||
Where ``<encoding>`` might be *ascii*, *cp932*, *charmap* or anything else other than **utf-8**. This error usually
|
||||
shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to
|
||||
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to a
|
||||
better terminal altogether.
|
||||
|
||||
Uploading with URLs gives error WEBPAGE_CURL_FAILED
|
||||
---------------------------------------------------
|
||||
|
||||
When uploading media files using an URL, the server automatically tries to download the media and uploads it to the
|
||||
Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the
|
||||
media exceeds 20 MB in size. In such cases, your only option is to download the media yourself and upload from your
|
||||
local machine.
|
||||
|
||||
sqlite3.OperationalError: database is locked
|
||||
--------------------------------------------
|
||||
|
||||
This error occurs when more than one process is using the same session file, that is, when you run two or more clients
|
||||
at the same time using the same session name.
|
||||
|
||||
It could also occur when a background script is still running and you forgot about it. In this case, you either restart
|
||||
your system or find and kill the process that is locking the database. On Unix based systems, you can do the following:
|
||||
|
||||
#. ``cd`` into your session file directory.
|
||||
#. ``fuser my_account.session`` to find the process id.
|
||||
#. ``kill 1234`` to gracefully stop the process.
|
||||
#. If the last command doesn't help, use ``kill -9 1234`` instead.
|
||||
|
||||
If you want to run multiple clients on the same account, you must authorize your account (either user or bot)
|
||||
from the beginning every time, and use different session names for each parallel client you are going to use.
|
||||
|
||||
sqlite3.OperationalError: unable to open database file
|
||||
------------------------------------------------------
|
||||
|
||||
Stackoverflow to the rescue: https://stackoverflow.com/questions/4636970
|
||||
|
||||
sqlite3.InterfaceError: Error binding parameter 0
|
||||
-------------------------------------------------
|
||||
|
||||
This error occurs when you pass a chat id value of the wrong type when trying to call a method. Most likely, you
|
||||
accidentally passed the whole user or chat object instead of the id or username.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Wrong. You passed the whole Chat instance
|
||||
app.send_message(chat, "text")
|
||||
|
||||
# Correct
|
||||
app.send_message(chat.id, "text")
|
||||
|
||||
My verification code expires immediately!
|
||||
-----------------------------------------
|
||||
|
||||
That is because you likely shared it across any of your Telegram chats. Yes, that's right: the server keeps scanning the
|
||||
messages you send and if an active verification code is found it will immediately expire, automatically.
|
||||
|
||||
The reason behind this is to protect unaware users from giving their account access to any potential scammer, but if you
|
||||
legitimately want to share your account(s) verification codes, consider scrambling them, e.g. ``12345`` → ``1-2-3-4-5``.
|
||||
|
||||
How can avoid Flood Waits?
|
||||
--------------------------
|
||||
|
||||
Long story short: make less requests, and remember that the API is designed to be used by official apps, by real people;
|
||||
anything above normal usage could be limited.
|
||||
|
||||
This question is being asked quite a lot of times, but the bottom line is that nobody knows the exact limits and it's
|
||||
unlikely that such information will be ever disclosed, because otherwise people could easily circumvent them and defeat
|
||||
their whole purpose.
|
||||
|
||||
Do also note that Telegram wants to be a safe and reliable place and that limits exist to protect itself from abuses.
|
||||
Having said that, here's some insights about limits:
|
||||
|
||||
- They are tuned by Telegram based on real people usage and can change anytime.
|
||||
- Some limits are be applied to single sessions, some others apply to the whole account.
|
||||
- Limits vary based on methods and the arguments passed to methods. For example: log-ins are expensive and thus have
|
||||
stricter limits; replying to a user command could cause a flood wait in case the user starts flooding, but
|
||||
such limit will only be applied to that particular chat (i.e.: other users are not affected).
|
||||
- You can catch Flood Wait exceptions in your code and wait the required seconds before continuing, this way:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import time
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
try:
|
||||
... # Your code
|
||||
except FloodWait as e:
|
||||
time.sleep(e.x) # Wait "x" seconds before continuing
|
||||
|
||||
|
||||
More info about error handling can be found `here <start/errors>`_.
|
||||
|
||||
My account has been deactivated/limited!
|
||||
----------------------------------------
|
||||
|
||||
First of all, you should understand that Telegram wants to be a safe place for people to stay in, and to pursue this
|
||||
goal there are automatic protection systems running to prevent flood and spam, as well as a moderation team of humans
|
||||
who review reports.
|
||||
|
||||
.. centered:: Pyrogram is a tool at your commands; it only does what you tell it to do, the rest is up to you.
|
||||
|
||||
Having said that, here's a list of what Telegram definitely doesn't like:
|
||||
|
||||
- Flood, abusing the API.
|
||||
- Spam, sending unsolicited messages or adding people to unwanted groups and channels.
|
||||
- Virtual/VoIP and cheap real numbers, because they are relatively easy to get and likely used for spam/flood.
|
||||
|
||||
And thanks to `@koteeq <https://t.me/koteeq>`_, here's a good explanation of how, probably, the system works:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script
|
||||
async src="https://telegram.org/js/telegram-widget.js?5"
|
||||
data-telegram-post="PyrogramChat/69424"
|
||||
data-width="100%">
|
||||
</script>
|
||||
<br><br>
|
||||
|
||||
However, you might be right, and your account was deactivated/limited without any good reason. This could happen because
|
||||
of mistakes by either the automatic systems or a moderator. In such cases you can kindly email Telegram at
|
||||
recover@telegram.org, contact `@smstelegram`_ on Twitter or use `this form`_.
|
||||
|
||||
Are there any secret easter eggs?
|
||||
---------------------------------
|
||||
|
||||
Yes. If you found one, `let me know`_!
|
||||
|
||||
.. _let me know: https://t.me/pyrogram
|
||||
|
||||
.. _@smstelegram: https://twitter.com/smstelegram
|
||||
.. _this form: https://telegram.org/support
|
||||
|
||||
.. _Bug Report: https://github.com/pyrogram/pyrogram/issues/new?labels=bug&template=bug_report.md
|
||||
.. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md
|
@ -1,11 +0,0 @@
|
||||
Client started, but nothing happens
|
||||
===================================
|
||||
|
||||
A possible cause might be network issues, either yours or Telegram's. To check this, add the following code at
|
||||
the top of your script and run it again. You should see some error mentioning a socket timeout or an unreachable
|
||||
network:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
@ -1,12 +0,0 @@
|
||||
Code hangs when calling stop, restart, add/remove_handler
|
||||
=========================================================
|
||||
|
||||
You tried to ``.stop()``, ``.restart()``, ``.add_handler()`` or ``.remove_handler()`` inside a running handler, but
|
||||
that can't be done because the way Pyrogram deals with handlers would make it hang.
|
||||
|
||||
When calling one of the methods above inside an event handler, Pyrogram needs to wait for all running handlers to finish
|
||||
in order to continue. Since your handler is blocking the execution by waiting for the called method to finish
|
||||
and since Pyrogram needs to wait for your handler to finish, you are left with a deadlock.
|
||||
|
||||
The solution to this problem is to pass ``block=False`` to such methods so that they return immediately and the actual
|
||||
code called asynchronously.
|
@ -1,23 +0,0 @@
|
||||
How to avoid Flood Waits?
|
||||
=========================
|
||||
|
||||
Slow things down and make less requests. Moreover, exact limits are unknown and can change anytime based on normal
|
||||
usages.
|
||||
|
||||
When a flood wait happens the server will tell you how much time to wait before continuing.
|
||||
The following shows how to catch the exception in your code and wait the required seconds.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import time
|
||||
from pyrogram.errors import FloodWait
|
||||
|
||||
...
|
||||
try:
|
||||
... # Your code
|
||||
except FloodWait as e:
|
||||
await asyncio.sleep(e.x) # Wait "x" seconds before continuing
|
||||
...
|
||||
|
||||
|
||||
More info about error handling can be found :doc:`here <../start/errors>`.
|
@ -1,9 +0,0 @@
|
||||
How to use webhooks?
|
||||
====================
|
||||
|
||||
There is no webhook in Pyrogram, simply because there is no HTTP involved. However, a similar technique is
|
||||
being used to make receiving updates efficient.
|
||||
|
||||
Pyrogram uses persistent connections via TCP sockets to interact with the server and instead of actively asking for
|
||||
updates every time (polling), Pyrogram will sit down and wait for the server to send updates by itself the very moment
|
||||
they are available (server push).
|
@ -1,47 +0,0 @@
|
||||
Frequently Asked Questions
|
||||
==========================
|
||||
|
||||
This FAQ page provides answers to common questions about Pyrogram and, to some extent, Telegram in general.
|
||||
|
||||
**Contents**
|
||||
|
||||
- :doc:`why-is-the-api-key-needed-for-bots`
|
||||
- :doc:`how-to-use-webhooks`
|
||||
- :doc:`using-the-same-file-id-across-different-accounts`
|
||||
- :doc:`using-multiple-clients-at-once-on-the-same-account`
|
||||
- :doc:`client-started-but-nothing-happens`
|
||||
- :doc:`what-are-the-ip-addresses-of-telegram-data-centers`
|
||||
- :doc:`migrating-the-account-to-another-data-center`
|
||||
- :doc:`why-is-the-client-reacting-slowly-in-supergroups-channels`
|
||||
- :doc:`peer-id-invalid-error`
|
||||
- :doc:`code-hangs-when-calling-stop-restart-add-remove-handler`
|
||||
- :doc:`unicodeencodeerror-codec-cant-encode`
|
||||
- :doc:`uploading-with-urls-gives-error-webpage-curl-failed`
|
||||
- :doc:`why-is-the-event-handler-triggered-twice-or-more`
|
||||
- :doc:`sqlite3-operationalerror-database-is-locked`
|
||||
- :doc:`sqlite3-interfaceerror-error-binding-parameter`
|
||||
- :doc:`socket-send-raised-exception-oserror-timeouterror`
|
||||
- :doc:`how-to-avoid-flood-waits`
|
||||
- :doc:`the-account-has-been-limited-deactivated`
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
|
||||
why-is-the-api-key-needed-for-bots
|
||||
how-to-use-webhooks
|
||||
using-the-same-file-id-across-different-accounts
|
||||
using-multiple-clients-at-once-on-the-same-account
|
||||
client-started-but-nothing-happens
|
||||
what-are-the-ip-addresses-of-telegram-data-centers
|
||||
migrating-the-account-to-another-data-center
|
||||
why-is-the-client-reacting-slowly-in-supergroups-channels
|
||||
peer-id-invalid-error
|
||||
code-hangs-when-calling-stop-restart-add-remove-handler
|
||||
unicodeencodeerror-codec-cant-encode
|
||||
uploading-with-urls-gives-error-webpage-curl-failed
|
||||
why-is-the-event-handler-triggered-twice-or-more
|
||||
sqlite3-operationalerror-database-is-locked
|
||||
sqlite3-interfaceerror-error-binding-parameter
|
||||
socket-send-raised-exception-oserror-timeouterror
|
||||
how-to-avoid-flood-waits
|
||||
the-account-has-been-limited-deactivated
|
@ -1,10 +0,0 @@
|
||||
Migrating the account to another data center
|
||||
============================================
|
||||
|
||||
This question is asked by people who find their account always being connected to one DC (data center), but are
|
||||
connecting from a place far away, thus resulting in slower interactions when using the API because of the greater
|
||||
physical distance between the user and the associated DC.
|
||||
|
||||
When registering an account for the first time, is up to Telegram to decide which DC the new user is going to be
|
||||
created in. It's also up to the server to decide whether to automatically migrate a user in case of prolonged usages
|
||||
from a distant location.
|
@ -1,14 +0,0 @@
|
||||
PEER_ID_INVALID error
|
||||
=====================
|
||||
|
||||
This error could mean several things:
|
||||
|
||||
- The chat id you tried to use is simply wrong, check it again.
|
||||
- The chat id refers to a group or channel you are not a member of.
|
||||
- The chat id argument you passed is in form of a string; you have to convert it into an integer with ``int(chat_id)``.
|
||||
- The chat id refers to a user or chat your current session hasn't met yet.
|
||||
|
||||
About the last point: in order for you to meet a user and thus communicate with them, you should ask yourself how to
|
||||
contact people using official apps. The answer is the same for Pyrogram too and involves normal usages such as searching
|
||||
for usernames, meeting them in a common group, having their phone contacts saved, getting a message mentioning them
|
||||
or obtaining the dialogs list.
|
@ -1,10 +0,0 @@
|
||||
socket.send() raised exception, OSError(), TimeoutError()
|
||||
=========================================================
|
||||
|
||||
If you get this error chances are you are blocking the event loop for too long.
|
||||
In general, it means you are executing thread-blocking code that prevents the event loop from
|
||||
running properly. For example:
|
||||
|
||||
- You are using ``time.sleep()`` instead of ``asyncio.sleep()``.
|
||||
- You are running processing loops that take too much time to complete.
|
||||
- You are reading/writing files to disk that take too much time to complete.
|
@ -1,13 +0,0 @@
|
||||
sqlite3.InterfaceError: Error binding parameter
|
||||
===============================================
|
||||
|
||||
This error occurs when you pass a chat id value of the wrong type when trying to call a method. Most likely, you
|
||||
accidentally passed the whole user or chat object instead of the id or username.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Wrong. You passed the whole Chat instance
|
||||
app.send_message(chat, "text")
|
||||
|
||||
# Correct
|
||||
app.send_message(chat.id, "text")
|
@ -1,17 +0,0 @@
|
||||
sqlite3.OperationalError: database is locked
|
||||
============================================
|
||||
|
||||
This error occurs when more than one process is using the same session file, that is, when you run two or more clients
|
||||
at the same time using the same session name or in case another program has accessed the file.
|
||||
|
||||
For example, it could occur when a background script is still running and you forgot about it. In this case, you either
|
||||
restart your system or find and kill the process that is locking the database. On Unix based systems, you can try the
|
||||
following:
|
||||
|
||||
#. ``cd`` into your session file directory.
|
||||
#. ``fuser my_account.session`` to find the process id.
|
||||
#. ``kill 1234`` to gracefully stop the process.
|
||||
#. If the last command doesn't help, use ``kill -9 1234`` instead.
|
||||
|
||||
If you want to run multiple clients on the same account, you must authorize your account (either user or bot)
|
||||
from the beginning every time, and use different session names for each parallel client you are going to use.
|
@ -1,16 +0,0 @@
|
||||
The account has been limited/deactivated
|
||||
========================================
|
||||
|
||||
Pyrogram is a framework that interfaces with Telegram; it is at your commands, meaning it only does what you tell it to
|
||||
do, the rest is up to you and Telegram (see `Telegram's ToS`_).
|
||||
|
||||
If you found your account being limited/deactivated, it could be due spam/flood/abuse of the API or the usage of certain
|
||||
virtual/VoIP numbers.
|
||||
|
||||
If you think your account was limited/deactivated by mistake, you can write to recover@telegram.org, contact
|
||||
`@SpamBot`_ or use `this form`_.
|
||||
|
||||
.. _@SpamBot: https://t.me/spambot
|
||||
.. _this form: https://telegram.org/support
|
||||
.. _Telegram's ToS: https://telegram.org/tos
|
||||
|
@ -1,7 +0,0 @@
|
||||
UnicodeEncodeError: '...' codec can't encode ...
|
||||
================================================
|
||||
|
||||
Where ``<encoding>`` might be *ascii*, *cp932*, *charmap* or anything else other than *utf-8*. This error usually
|
||||
shows up when you try to print something and has very little to do with Pyrogram itself as it is strictly related to
|
||||
your own terminal. To fix it, either find a way to change the encoding settings of your terminal to UTF-8 or switch to
|
||||
another terminal altogether.
|
@ -1,7 +0,0 @@
|
||||
Uploading with URLs gives error WEBPAGE_CURL_FAILED
|
||||
===================================================
|
||||
|
||||
When uploading media files using an URL, the server automatically tries to download the media and uploads it to the
|
||||
Telegram cloud. This error usually happens in case the provided URL is not publicly accessible by Telegram itself or the
|
||||
media file is too large. In such cases, your only option is to download the media yourself and upload it from your
|
||||
local machine.
|
@ -1,7 +0,0 @@
|
||||
Using multiple clients at once on the same account
|
||||
==================================================
|
||||
|
||||
Both user and bot accounts are able to run multiple sessions in parallel. However, you must not use the same session
|
||||
in more than one client at the same time. The correct way to run multiple clients on the same account is by authorizing
|
||||
your account (either user or bot) from the beginning each time, and use one separate session for each parallel client.
|
||||
|
@ -1,6 +0,0 @@
|
||||
Using the same file_id across different accounts
|
||||
================================================
|
||||
|
||||
Telegram file_id strings are bound to the account which generated them. An attempt in using a foreign file id will
|
||||
result in errors such as ``[400 MEDIA_EMPTY]``. The only exception are stickers' file ids; you can use them across
|
||||
different accounts without any problem.
|
@ -1,30 +0,0 @@
|
||||
What are the IP addresses of Telegram Data Centers?
|
||||
===================================================
|
||||
|
||||
Telegram is currently composed by a decentralized, multi-DC infrastructure (currently 5 DCs, each of which can
|
||||
work independently) spread across different locations worldwide. However, some of the less busy DCs have been lately
|
||||
dismissed and their IP addresses are now kept as aliases to the nearest one.
|
||||
|
||||
.. csv-table:: Production Environment
|
||||
:header: ID, Location, IPv4, IPv6
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
DC1, "MIA, Miami FL, USA", ``149.154.175.53``, ``2001:b28:f23d:f001::a``
|
||||
DC2, "AMS, Amsterdam, NL", ``149.154.167.51``, ``2001:67c:4e8:f002::a``
|
||||
DC3*, "MIA, Miami FL, USA", ``149.154.175.100``, ``2001:b28:f23d:f003::a``
|
||||
DC4, "AMS, Amsterdam, NL", ``149.154.167.91``, ``2001:67c:4e8:f004::a``
|
||||
DC5, "SIN, Singapore, SG", ``91.108.56.130``, ``2001:b28:f23f:f005::a``
|
||||
|
||||
.. csv-table:: Test Environment
|
||||
:header: ID, Location, IPv4, IPv6
|
||||
:widths: auto
|
||||
:align: center
|
||||
|
||||
DC1, "MIA, Miami FL, USA", ``149.154.175.10``, ``2001:b28:f23d:f001::e``
|
||||
DC2, "AMS, Amsterdam, NL", ``149.154.167.40``, ``2001:67c:4e8:f002::e``
|
||||
DC3*, "MIA, Miami FL, USA", ``149.154.175.117``, ``2001:b28:f23d:f003::e``
|
||||
|
||||
.. centered:: More info about the Test Environment can be found :doc:`here <../topics/test-servers>`.
|
||||
|
||||
***** Alias DC
|
@ -1,12 +0,0 @@
|
||||
Why is the API key needed for bots?
|
||||
===================================
|
||||
|
||||
Requests against the official bot API endpoints are made via JSON/HTTP and are handled by an intermediate server
|
||||
application that implements the MTProto protocol and uses its own API key to communicate with the MTProto servers.
|
||||
|
||||
.. figure:: //_static/img/mtproto-vs-bot-api.png
|
||||
:align: center
|
||||
|
||||
Using MTProto is the only way to communicate with the actual Telegram servers, and the main API requires developers to
|
||||
identify applications by means of a unique key; the bot token identifies a bot as a user and replaces the user's phone
|
||||
number only.
|
@ -1,18 +0,0 @@
|
||||
Why is the client reacting slowly in supergroups/channels?
|
||||
==========================================================
|
||||
|
||||
Because of how Telegram works internally, every message you receive and send must pass through the creator's DC, and in
|
||||
the worst case where you, the creator and another member all belong to three different DCs, the other member messages
|
||||
have to go through from their DC to the creator's DC and finally to your DC. This is applied to each message and member
|
||||
of a supergroup/channel and the process will inevitably take its time.
|
||||
|
||||
Another reason that makes responses come slowly is that messages are dispatched by priority. Depending on the kind
|
||||
of member, some users receive messages faster than others and for big and busy supergroups the delay might become
|
||||
noticeable, especially if you are among the lower end of the priority list:
|
||||
|
||||
1. Creator.
|
||||
2. Administrators.
|
||||
3. Bots.
|
||||
4. Mentioned users.
|
||||
5. Recent online users.
|
||||
6. Everyone else.
|
@ -1,28 +0,0 @@
|
||||
Why is the event handler called twice or more?
|
||||
==============================================
|
||||
|
||||
The event handler is being called twice or more because one or more message edit events have arrived.
|
||||
By default, Pyrogram listens to both new and edit message events inside ``on_message`` handlers. To prevent edit events
|
||||
from calling the handler, use the "not edited" filter ``~filters.edited``.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
...
|
||||
|
||||
@app.on_message(... & ~filters.edited)
|
||||
async def handler(client, message):
|
||||
...
|
||||
|
||||
Or, avoid handling any edited message altogether this way:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
...
|
||||
|
||||
@app.on_message(filters.edited)
|
||||
async def edited(client, message):
|
||||
pass
|
||||
|
||||
... # other handlers
|
86
docs/source/glossary.rst
Normal file
86
docs/source/glossary.rst
Normal file
@ -0,0 +1,86 @@
|
||||
Pyrogram Glossary
|
||||
=================
|
||||
|
||||
This page contains a list of common words with brief explanations related to Pyrogram and, to some extent, Telegram in
|
||||
general. Some words may as well link to dedicated articles in case the topic is covered in a more detailed fashion.
|
||||
|
||||
.. tip::
|
||||
|
||||
If you think something interesting could be added here, feel free to propose it by opening a `Feature Request`_.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
||||
Terms
|
||||
-----
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
API
|
||||
Application Programming Interface: a set of methods, protocols and tools that make it easier to develop programs
|
||||
by providing useful building blocks to the developer.
|
||||
|
||||
API key
|
||||
A secret code used to authenticate and/or authorize a specific application to Telegram in order for it to
|
||||
control how the API is being used, for example, to prevent abuses of the API.
|
||||
:doc:`More on API keys <intro/setup>`.
|
||||
|
||||
DC
|
||||
Also known as *data center*, is a place where lots of computer systems are housed and used together in order to
|
||||
achieve high quality and availability for services.
|
||||
|
||||
RPC
|
||||
Acronym for Remote Procedure Call, that is, a function which gets executed at some remote place (i.e. Telegram
|
||||
server) and not in your local machine.
|
||||
|
||||
RPCError
|
||||
An error caused by an RPC which must be returned in place of the successful result in order to let the caller
|
||||
know something went wrong. :doc:`More on RPCError <start/errors>`.
|
||||
|
||||
MTProto
|
||||
The name of the custom-made, open and encrypted protocol by Telegram, implemented in Pyrogram.
|
||||
:doc:`More on MTProto <topics/mtproto-vs-botapi>`.
|
||||
|
||||
MTProto API
|
||||
The Telegram main API Pyrogram makes use of, which is able to connect both users and normal bots to Telegram
|
||||
using MTProto as application layer protocol and execute any method Telegram provides from its public TL-schema.
|
||||
:doc:`More on MTProto API <topics/mtproto-vs-botapi>`.
|
||||
|
||||
Bot API
|
||||
The Telegram Bot API that is able to only connect normal bots only to Telegram using HTTP as application layer
|
||||
protocol and allows to execute a sub-set of the main Telegram API.
|
||||
:doc:`More on Bot API <topics/mtproto-vs-botapi>`.
|
||||
|
||||
Pyrogrammer
|
||||
A developer that uses Pyrogram to build Telegram applications.
|
||||
|
||||
Userbot
|
||||
Also known as *user bot* or *ubot* for short, is a user logged in by third-party Telegram libraries --- such as
|
||||
Pyrogram --- to automate some behaviours, like sending messages or reacting to text commands or any other event.
|
||||
Not to be confused with *bot*, that is, a normal Telegram bot created by `@BotFather <https://t.me/botfather>`_.
|
||||
|
||||
Session
|
||||
Also known as *login session*, is a strictly personal piece of data created and held by both parties
|
||||
(client and server) which is used to grant permission into a single account without having to start a new
|
||||
authorization process from scratch.
|
||||
|
||||
Callback
|
||||
Also known as *callback function*, is a user-defined generic function that *can be* registered to and then
|
||||
called-back by the framework when specific events occurs.
|
||||
|
||||
Handler
|
||||
An object that wraps around a callback function that is *actually meant* to be registered into the framework,
|
||||
which will then be able to handle a specific kind of events, such as a new incoming message, for example.
|
||||
:doc:`More on Handlers <start/updates>`.
|
||||
|
||||
Decorator
|
||||
Also known as *function decorator*, in Python, is a callable object that is used to modify another function.
|
||||
Decorators in Pyrogram are used to automatically register callback functions for handling updates.
|
||||
:doc:`More on Decorators <start/updates>`.
|
||||
|
||||
.. _Feature Request: https://github.com/pyrogram/pyrogram/issues/new?labels=enhancement&template=feature_request.md
|
@ -5,8 +5,7 @@ Welcome to Pyrogram
|
||||
|
||||
<div align="center">
|
||||
<a href="/">
|
||||
<div class="pyrogram-logo-index"><img src="_static/pyrogram.png" alt="Pyrogram"></div>
|
||||
<div class="pyrogram-text pyrogram-text-index">Pyrogram</div>
|
||||
<div><img src="_static/pyrogram.png" alt="Pyrogram Logo" width="420"></div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -15,15 +14,15 @@ Welcome to Pyrogram
|
||||
|
||||
<br>
|
||||
<a href="https://github.com/pyrogram/pyrogram">
|
||||
Development
|
||||
Source Code
|
||||
</a>
|
||||
•
|
||||
<a href="https://docs.pyrogram.org/releases">
|
||||
<a href="https://github.com/pyrogram/pyrogram/releases">
|
||||
Releases
|
||||
</a>
|
||||
•
|
||||
<a href="https://t.me/pyrogram">
|
||||
News
|
||||
<a href="https://t.me/Pyrogram">
|
||||
Community
|
||||
</a>
|
||||
</p>
|
||||
|
||||
@ -36,34 +35,16 @@ Welcome to Pyrogram
|
||||
|
||||
@app.on_message(filters.private)
|
||||
async def hello(client, message):
|
||||
await message.reply("Hello from Pyrogram!")
|
||||
await message.reply_text(f"Hello {message.from_user.mention}")
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
**Pyrogram** is a modern, elegant and asynchronous :doc:`MTProto API <topics/mtproto-vs-botapi>` framework.
|
||||
It enables you to easily interact with the main Telegram API through a user account (custom client) or a bot identity
|
||||
(bot API alternative) using Python.
|
||||
**Pyrogram** is a modern, elegant and easy-to-use Telegram_ 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>`.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
If you'd like to support Pyrogram, you can consider:
|
||||
|
||||
- `Become a GitHub sponsor <https://github.com/sponsors/delivrance>`_.
|
||||
- `Become a LiberaPay patron <https://liberapay.com/delivrance>`_.
|
||||
- `Become an OpenCollective backer <https://opencollective.com/pyrogram>`_.
|
||||
|
||||
Key Features
|
||||
------------
|
||||
|
||||
- **Ready**: Install Pyrogram with pip and start building your applications right away.
|
||||
- **Easy**: Makes the Telegram API simple and intuitive, while still allowing advanced usages.
|
||||
- **Elegant**: Low-level details are abstracted and re-presented in a more convenient way.
|
||||
- **Fast**: Boosted up by :doc:`TgCrypto <topics/tgcrypto>`, a high-performance crypto library written in pure C.
|
||||
- **Type-hinted**: Types and methods are all type-hinted, enabling excellent editor support.
|
||||
- **Async**: Fully asynchronous (also usable synchronously if wanted, for convenience).
|
||||
- **Powerful**: Full access to Telegram's API to execute any official client action and more.
|
||||
.. _Telegram: https://telegram.org
|
||||
|
||||
How the Documentation is Organized
|
||||
----------------------------------
|
||||
@ -72,11 +53,18 @@ Contents are organized into sections composed of self-contained topics which can
|
||||
following them in order using the :guilabel:`Next` button at the end of each page. Here below you can, instead, find a
|
||||
list of the most relevant pages for a quick access.
|
||||
|
||||
.. admonition :: Cloud Credits
|
||||
:class: tip
|
||||
|
||||
If you need a cloud server to host your applications, we recommend using **Hetzner Cloud**. Sign up with
|
||||
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits and help support Pyrogram as
|
||||
well.
|
||||
|
||||
First Steps
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Quick Start <intro/quickstart>`: Overview to get you started quickly.
|
||||
- :doc:`Calling Methods <start/invoking>`: How to call Pyrogram's methods.
|
||||
@ -87,7 +75,7 @@ API Reference
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Pyrogram Client <api/client>`: Reference details about the Client class.
|
||||
- :doc:`Available Methods <api/methods/index>`: List of available high-level methods.
|
||||
@ -98,12 +86,16 @@ Meta
|
||||
^^^^
|
||||
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
:columns: 2
|
||||
|
||||
- :doc:`Pyrogram FAQ <faq/index>`: Answers to common Pyrogram questions.
|
||||
- :doc:`Pyrogram FAQ <faq>`: Answers to common Pyrogram questions.
|
||||
- :doc:`Pyrogram Glossary <glossary>`: List of words with brief explanations.
|
||||
- :doc:`Support Pyrogram <support>`: Ways to show your appreciation.
|
||||
- :doc:`About the License <license>`: Information about the Project license.
|
||||
- :doc:`Release Notes <releases/index>`: Release notes for Pyrogram releases.
|
||||
|
||||
Last updated on |today|
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:caption: Introduction
|
||||
@ -144,13 +136,14 @@ Meta
|
||||
topics/more-on-updates
|
||||
topics/config-file
|
||||
topics/smart-plugins
|
||||
topics/client-settings
|
||||
topics/session-settings
|
||||
topics/tgcrypto
|
||||
topics/storage-engines
|
||||
topics/text-formatting
|
||||
topics/serializing
|
||||
topics/proxy
|
||||
topics/scheduling
|
||||
topics/bots-interaction
|
||||
topics/mtproto-vs-botapi
|
||||
topics/debugging
|
||||
topics/test-servers
|
||||
@ -161,8 +154,10 @@ Meta
|
||||
:hidden:
|
||||
:caption: Meta
|
||||
|
||||
faq/index
|
||||
faq
|
||||
glossary
|
||||
support
|
||||
license
|
||||
releases/index
|
||||
|
||||
.. toctree::
|
||||
|
@ -1,9 +1,16 @@
|
||||
Install Guide
|
||||
=============
|
||||
|
||||
Being a modern Python framework, Pyrogram requires an up to date version of Python to be installed in your system.
|
||||
Being a modern Python library, **Pyrogram** requires Python 3.6+ to be installed in your system.
|
||||
We recommend using the latest versions of both Python 3 and pip.
|
||||
|
||||
- Get **Python 3** from https://www.python.org/downloads/ (or with your package manager).
|
||||
- Get **pip** by following the instructions at https://pip.pypa.io/en/latest/installing/.
|
||||
|
||||
.. important::
|
||||
|
||||
Pyrogram supports **Python 3** only, starting from version 3.6. **PyPy** is supported too.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
@ -29,7 +36,12 @@ Install Pyrogram
|
||||
Bleeding Edge
|
||||
-------------
|
||||
|
||||
You can install the development version from the git ``master`` branch using this command:
|
||||
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'd like to try out the latest Pyrogram features, the `GitHub repo`_ is always kept updated with new changes;
|
||||
you can install the development version straight from the ``master`` branch using this command (note "master.zip" in
|
||||
the link):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -45,6 +57,6 @@ If no error shows up you are good to go.
|
||||
|
||||
>>> import pyrogram
|
||||
>>> pyrogram.__version__
|
||||
'x.y.z'
|
||||
'|version|'
|
||||
|
||||
.. _`Github repo`: http://github.com/pyrogram/pyrogram
|
||||
|
@ -1,54 +1,49 @@
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
The next few steps serve as a quick start to see Pyrogram in action as fast as possible.
|
||||
The next few steps serve as a quick start for all new :term:`Pyrogrammers <Pyrogrammer>` that want to see Pyrogram in
|
||||
action as fast as possible. Let's go!
|
||||
|
||||
Get Pyrogram Real Fast
|
||||
----------------------
|
||||
|
||||
.. admonition :: Cloud Credits
|
||||
:class: tip
|
||||
|
||||
If you need a cloud server to host your applications, try Hetzner Cloud. You can sign up with
|
||||
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits.
|
||||
|
||||
1. Install Pyrogram with ``pip3 install -U pyrogram``.
|
||||
|
||||
2. Get your own Telegram API key from https://my.telegram.org/apps.
|
||||
|
||||
3. Open the text editor of your choice and paste the following:
|
||||
3. Open your best text editor and paste the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import asyncio
|
||||
from pyrogram import Client
|
||||
|
||||
api_id = 12345
|
||||
api_hash = "0123456789abcdef0123456789abcdef"
|
||||
|
||||
async def main():
|
||||
async with Client("my_account", api_id, api_hash) as app:
|
||||
await app.send_message("me", "Greetings from **Pyrogram**!")
|
||||
|
||||
asyncio.run(main())
|
||||
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 ``hello.py``.
|
||||
5. Save the file as ``pyro.py``.
|
||||
|
||||
6. Run the script with ``python3 hello.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. In the next few pages of the introduction, we'll take a much more in-depth look of what
|
||||
we have just done above.
|
||||
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.
|
||||
|
||||
If you are feeling eager to continue you can take a shortcut to :doc:`Calling Methods <../start/invoking>` and come back
|
||||
later to learn some more details.
|
||||
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: https://t.me/Pyrogram
|
||||
|
@ -2,7 +2,7 @@ Project Setup
|
||||
=============
|
||||
|
||||
We have just :doc:`installed Pyrogram <install>`. In this page we'll discuss what you need to do in order to set up a
|
||||
project with the framework.
|
||||
project with the library. Let's see how it's done.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -17,13 +17,18 @@ 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 with your details and register a new Telegram application.
|
||||
#. Done. The API key consists of two parts: **api_id** and **api_hash**. Keep it secret.
|
||||
#. 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 defines a token for a Telegram *application* you are going to build.
|
||||
This means that you are able to authorize multiple users or bots with a single API key.
|
||||
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
|
||||
-------------
|
||||
@ -31,9 +36,9 @@ 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: create a new ``config.ini`` file next to your main script, copy-paste the following and
|
||||
replace the *api_id* and *api_hash* values with your own. This method allows you to keep your credentials out of
|
||||
your code without having to deal with how to load them.
|
||||
- First option (recommended): create a new ``config.ini`` file next to your main script, copy-paste the following and
|
||||
replace the **api_id** and **api_hash** values with your own. This is the preferred method because allows you to
|
||||
keep your credentials out of your code without having to deal with how to load them:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
@ -42,7 +47,8 @@ There are two ways to do so, and you can choose what fits better for you:
|
||||
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:
|
||||
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
|
||||
|
||||
|
16
docs/source/license.rst
Normal file
16
docs/source/license.rst
Normal file
@ -0,0 +1,16 @@
|
||||
About the License
|
||||
=================
|
||||
|
||||
.. image:: https://www.gnu.org/graphics/lgplv3-with-text-154x68.png
|
||||
:align: left
|
||||
|
||||
Pyrogram is free software and is currently licensed under the terms of the
|
||||
`GNU Lesser General Public License v3 or later (LGPLv3+)`_. In short: you may use, redistribute and/or modify it
|
||||
provided that modifications are described and licensed for free under LGPLv3+.
|
||||
|
||||
In other words: you can use and integrate Pyrogram into your code (either open source, under the same or a different
|
||||
license, or even proprietary) for any purpose whatsoever without being required to release the source code of your
|
||||
applications. Derivative works, including modifications to the library itself can only be redistributed under the same
|
||||
LGPLv3+ license.
|
||||
|
||||
.. _GNU Lesser General Public License v3 or later (LGPLv3+): https://github.com/pyrogram/pyrogram/blob/develop/COPYING.lesser
|
@ -26,20 +26,23 @@ the :meth:`~pyrogram.Client.run` method:
|
||||
app = Client("my_account")
|
||||
app.run()
|
||||
|
||||
This starts an interactive shell asking you to input your **phone number**, including your `Country Code`_ (the plus
|
||||
``+`` and minus ``-`` symbols can be omitted) and the **phone code** you will receive in your devices that are already
|
||||
authorized or via SMS:
|
||||
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: +1-123-456-7890
|
||||
Is "+1-123-456-7890" correct? (y/n): y
|
||||
Enter phone code: 12345
|
||||
Logged in successfully
|
||||
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 is personal and 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.
|
||||
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`` file is personal and must be kept secret.
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
Error Handling
|
||||
==============
|
||||
|
||||
Errors can be correctly handled with ``try...except`` blocks in order to control the behaviour of your application.
|
||||
Pyrogram errors all live inside the ``errors`` package:
|
||||
Errors are inevitable when working with the API, and they can 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
|
||||
|
||||
@ -25,10 +25,10 @@ This error is raised every time a method call against Telegram's API was unsucce
|
||||
|
||||
from pyrogram.errors import RPCError
|
||||
|
||||
.. note::
|
||||
.. warning::
|
||||
|
||||
Avoid catching this error everywhere, 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.
|
||||
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
|
||||
----------------
|
||||
@ -84,6 +84,9 @@ whole category of errors and be sure to also handle these unknown errors.
|
||||
In case a whole class of errors is unknown (that is, an error code that is unknown), Pyrogram will raise a special
|
||||
``520 UnknownError`` exception.
|
||||
|
||||
In both cases, Pyrogram will log them in the ``unknown_errors.txt`` file. Users are invited to report
|
||||
these unknown errors in the `discussion group <https://t.me/pyrogram>`_.
|
||||
|
||||
Errors with Values
|
||||
------------------
|
||||
|
||||
|
@ -19,7 +19,7 @@ like send_audio(), send_document(), send_location(), etc...
|
||||
|
||||
with app:
|
||||
app.send_message(
|
||||
"me", # Edit this
|
||||
"haskell", # Edit this
|
||||
"This is a ReplyKeyboardMarkup example",
|
||||
reply_markup=ReplyKeyboardMarkup(
|
||||
[
|
||||
@ -33,7 +33,7 @@ like send_audio(), send_document(), send_location(), etc...
|
||||
)
|
||||
|
||||
app.send_message(
|
||||
"me", # Edit this
|
||||
"haskell", # Edit this
|
||||
"This is a InlineKeyboardMarkup example",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
|
@ -15,7 +15,7 @@ It uses the ``@on_message`` decorator to register a ``MessageHandler`` and appli
|
||||
|
||||
@app.on_message(filters.text & filters.private)
|
||||
def echo(client, message):
|
||||
message.reply(message.text)
|
||||
message.reply_text(message.text)
|
||||
|
||||
|
||||
app.run() # Automatically start() and idle()
|
@ -13,3 +13,9 @@ This example demonstrates a basic API usage
|
||||
with app:
|
||||
# Send a message, Markdown is enabled by default
|
||||
app.send_message("me", "Hi there! I'm using **Pyrogram**")
|
||||
|
||||
# Send a location
|
||||
app.send_location("me", 51.500729, -0.124583)
|
||||
|
||||
# Send a sticker
|
||||
app.send_sticker("me", "CAADBAADzg4AAvLQYAEz_x2EOgdRwBYE")
|
@ -26,6 +26,7 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
|
||||
),
|
||||
url="https://docs.pyrogram.org/intro/install",
|
||||
description="How to install Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton(
|
||||
@ -42,6 +43,7 @@ It uses the @on_inline_query decorator to register an InlineQueryHandler.
|
||||
),
|
||||
url="https://docs.pyrogram.org/start/invoking",
|
||||
description="How to use Pyrogram",
|
||||
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[InlineKeyboardButton(
|
||||
|
@ -11,8 +11,8 @@ This example shows how to query an inline bot (as user).
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
# Get bot results for "hello" from the inline bot @vid
|
||||
bot_results = app.get_inline_bot_results("vid", "hello")
|
||||
# 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)
|
@ -8,7 +8,7 @@ to make it only work for specific messages in a specific chat.
|
||||
|
||||
from pyrogram import Client, emoji, filters
|
||||
|
||||
TARGET = -100123456789 # Target chat. Can also be a list of multiple chat ids/usernames
|
||||
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.org/)'s group chat {}!" # Welcome message
|
||||
|
||||
|
@ -2,7 +2,7 @@ Calling Methods
|
||||
===============
|
||||
|
||||
At this point, we have successfully :doc:`installed Pyrogram <../intro/install>` and :doc:`authorized <auth>` our
|
||||
account; we are now aiming towards the core of the framework.
|
||||
account; we are now aiming towards the core of the library. It's time to start playing with the API!
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -16,6 +16,67 @@ Basic Usage
|
||||
|
||||
Making API method calls with Pyrogram is very simple. Here's a basic example we are going to examine step by step:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
Basic step-by-step
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. Let's begin by importing the Client class:
|
||||
|
||||
.. 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")
|
||||
|
||||
#. The ``with`` context manager is a shortcut for starting, executing and stopping the Client:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
with app:
|
||||
|
||||
#. Now, you can call any method you like:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
Context Manager
|
||||
---------------
|
||||
|
||||
The ``with`` statement starts a context manager used as a shortcut to automatically call :meth:`~pyrogram.Client.start`
|
||||
and :meth:`~pyrogram.Client.stop`, which are methods required for Pyrogram to work properly. The context manager does
|
||||
also gracefully stop the client, even in case of unhandled exceptions in your code.
|
||||
|
||||
This is how Pyrogram looks without the context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
app.start()
|
||||
app.send_message("me", "Hi!")
|
||||
app.stop()
|
||||
|
||||
Asynchronous Calls
|
||||
------------------
|
||||
|
||||
In case you want Pyrogram to run asynchronously (e.g.: if you are using third party libraries that require you to call
|
||||
them with ``await``), use the asynchronous context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
@ -28,24 +89,20 @@ Making API method calls with Pyrogram is very simple. Here's a basic example we
|
||||
|
||||
app.run(main())
|
||||
|
||||
Step-by-step
|
||||
^^^^^^^^^^^^
|
||||
Asynchronous step-by-step
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. Let's begin by importing the Client class.
|
||||
#. Import the Client class and create an instance:
|
||||
|
||||
.. 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")
|
||||
|
||||
#. Async methods can't be executed at the top level, because they must be inside an async context.
|
||||
Here we define an async function and put our code inside. Also notice the ``await`` keyword in front of the method
|
||||
call; this is required for all asynchronous methods.
|
||||
#. Async methods can't normally be executed at the top level, because they must be inside an async-defined function;
|
||||
here we define one and put our code inside; the context manager is also being used differently in asyncio and
|
||||
method calls require the await keyword:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -53,72 +110,10 @@ Step-by-step
|
||||
async with app:
|
||||
await app.send_message("me", "Hi!")
|
||||
|
||||
#. Finally, we tell Python to schedule our ``main()`` async function by using Pyrogram's :meth:`~pyrogram.Client.run`
|
||||
method.
|
||||
#. Finally, we tell Python to schedule our ``main()`` async function, which in turn will execute Pyrogram's methods.
|
||||
Using :meth:`~pyrogram.Client.run` this way is a friendly alternative for the much more verbose
|
||||
``asyncio.get_event_loop().run_until_complete(main())``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.run(main())
|
||||
|
||||
Context Manager
|
||||
---------------
|
||||
|
||||
The ``async with`` statement starts a context manager, which is used as a shortcut for starting, executing and stopping
|
||||
the Client, asynchronously. It does so by automatically calling :meth:`~pyrogram.Client.start` and
|
||||
:meth:`~pyrogram.Client.stop` in a more convenient way which also gracefully stops the client, even in case of
|
||||
unhandled exceptions in your code.
|
||||
|
||||
Below there's the same example as above, but without the use of the context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
async def main():
|
||||
await app.start()
|
||||
await app.send_message("me", "Hi!")
|
||||
await app.stop()
|
||||
|
||||
app.run(main())
|
||||
|
||||
Using asyncio.run()
|
||||
-------------------
|
||||
|
||||
Alternatively to the :meth:`~pyrogram.Client.run` method, you can use Python's ``asyncio.run()`` to execute the main
|
||||
function, with one little caveat: the Client instance (and possibly other asyncio resources you are going to use) must
|
||||
be instantiated inside the main function.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import asyncio
|
||||
from pyrogram import Client
|
||||
|
||||
async def main():
|
||||
app = Client("my_account")
|
||||
|
||||
async with app:
|
||||
await app.send_message("me", "Hi!")
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
Synchronous Calls
|
||||
------------------
|
||||
|
||||
Pyrogram is an asynchronous framework, but it also provides a convenience way for calling methods without the need
|
||||
of async/await keywords and the extra boilerplate. In case you want Pyrogram to run synchronously, simply use the
|
||||
synchronous context manager:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
with app:
|
||||
app.send_message("me", "Hi!")
|
||||
|
||||
As you can see, the non-async example becomes less cluttered. Use Pyrogram in this non-asynchronous way only when you
|
||||
want to write something without the boilerplate or in case you want to combine Pyrogram with other libraries that are
|
||||
not async.
|
@ -1,8 +1,8 @@
|
||||
Handling Updates
|
||||
================
|
||||
|
||||
Calling :doc:`API methods <invoking>` sequentially is one way to use Pyrogram, but how to react when, for example, a
|
||||
new message arrives? This page deals with updates and how to handle such events in Pyrogram.
|
||||
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.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -14,9 +14,10 @@ new message arrives? This page deals with updates and how to handle such events
|
||||
Defining 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>`.
|
||||
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.
|
||||
@ -39,51 +40,50 @@ The most elegant way to register a message handler is by using the :meth:`~pyrog
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
|
||||
@app.on_message()
|
||||
async def my_handler(client, message):
|
||||
await message.forward("me")
|
||||
def my_handler(client, message):
|
||||
message.forward("me")
|
||||
|
||||
|
||||
app.run()
|
||||
|
||||
The defined function ``my_handler``, which accepts the two arguments *(client, message)*, will be the function that gets
|
||||
executed every time a new message arrives.
|
||||
|
||||
In the last line we see again the :meth:`~pyrogram.Client.run` method, this time used without any argument.
|
||||
Its purpose here is simply to automatically :meth:`~pyrogram.Client.start`, keep the Client online so that it can listen
|
||||
for updates and :meth:`~pyrogram.Client.stop` it once you hit ``CTRL+C``.
|
||||
|
||||
Synchronous handlers
|
||||
Asynchronous handlers
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can also have synchronous handlers; you only need to define the callback function without using ``async def`` and
|
||||
call API methods by not placing ``await`` in front of them:
|
||||
You can also have asynchronous handlers; you only need to define the callback function using ``async def`` and call API
|
||||
methods by placing ``await`` in front of them:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.on_message()
|
||||
def my_handler(client, message):
|
||||
message.forward("me")
|
||||
async def my_handler(client, message):
|
||||
await message.forward("me")
|
||||
|
||||
.. note::
|
||||
|
||||
You can mix ``def`` and ``async def`` handlers as much as you like, Pyrogram will still work concurrently and
|
||||
efficiently regardless of what you choose. However, it is recommended to use Pyrogram in its native, asynchronous
|
||||
form at all times, unless you want to write something without the boilerplate or in case you want to combine
|
||||
Pyrogram with other libraries that are not async.
|
||||
You can mix ``def`` and ``async def`` handlers as much as you need, Pyrogram will still work concurrently and
|
||||
efficiently regardless of what you choose.
|
||||
|
||||
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. It is useful in case you want to programmatically add handlers.
|
||||
function and registers it in your Client. It is useful in case you want to programmatically add handlers (or in case,
|
||||
for some reason, you don't like to use decorators).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pyrogram import Client
|
||||
from pyrogram.handlers import MessageHandler
|
||||
|
||||
async def my_function(client, message):
|
||||
await message.forward("me")
|
||||
|
||||
def my_function(client, message):
|
||||
message.forward("me")
|
||||
|
||||
|
||||
app = Client("my_account")
|
||||
|
||||
@ -92,12 +92,12 @@ function and registers it in your Client. It is useful in case you want to progr
|
||||
|
||||
app.run()
|
||||
|
||||
The same about synchronous handlers applies for :meth:`~pyrogram.Client.add_handler`:
|
||||
The same about asynchronous handlers applies for :meth:`~pyrogram.Client.add_handler`:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def my_function(client, message):
|
||||
message.forward("me")
|
||||
async def my_function(client, message):
|
||||
await message.forward("me")
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -1,62 +1,66 @@
|
||||
Support Pyrogram
|
||||
================
|
||||
|
||||
.. raw:: html
|
||||
As a developer, you probably understand that "open source" doesn't mean "free work". If you wish to tip me for Pyrogram
|
||||
-- or any of my `other works`_ -- you can do so by the ways shown below. Your appreciation means a lot and helps
|
||||
staying motivated!
|
||||
|
||||
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||
|
||||
<div style="float: right; margin-bottom: 10px">
|
||||
<a class="github-button"
|
||||
href="https://github.com/pyrogram/pyrogram/fork"
|
||||
data-icon="octicon-repo-forked" data-size="large" data-show-count="true"
|
||||
aria-label="Fork pyrogram/pyrogram on GitHub">Fork</a>
|
||||
|
||||
<a class="github-button"
|
||||
href="https://github.com/pyrogram/pyrogram"
|
||||
data-icon="octicon-star" data-size="large"
|
||||
data-show-count="true" aria-label="Star pyrogram/pyrogram on GitHub">Star</a>
|
||||
</div>
|
||||
|
||||
<br style="clear: both"/>
|
||||
|
||||
Pyrogram is a free and open source project.
|
||||
If you enjoy Pyrogram and would like to show your appreciation, consider donating or becoming
|
||||
a sponsor of the project. You can support Pyrogram via the ways shown below:
|
||||
--- `Dan`_
|
||||
|
||||
-----
|
||||
|
||||
GitHub Sponsor
|
||||
--------------
|
||||
Star
|
||||
----
|
||||
|
||||
`Become a GitHub sponsor <https://github.com/sponsors/delivrance>`_.
|
||||
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`_.
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<a class="github-button"
|
||||
href="https://github.com/sponsors/delivrance"
|
||||
data-icon="octicon-heart"
|
||||
data-size="large"
|
||||
aria-label="Sponsor @delivrance on GitHub">
|
||||
Sponsor</a>
|
||||
<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>
|
||||
|
||||
-----
|
||||
|
||||
LiberaPay Patron
|
||||
----------------
|
||||
Sponsor
|
||||
-------
|
||||
|
||||
`Become a LiberaPay patron <https://liberapay.com/delivrance>`_.
|
||||
You can become a GitHub sponsor:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script src="https://liberapay.com/delivrance/widgets/button.js"></script>
|
||||
<iframe
|
||||
src="https://github.com/sponsors/delivrance/button"
|
||||
title="Sponsor delivrance"
|
||||
height="40" width="120"
|
||||
style="border: 0px; padding-top: 5px; margin-top: -5px">
|
||||
</iframe>
|
||||
|
||||
-----
|
||||
|
||||
OpenCollective Backer
|
||||
---------------------
|
||||
Donate
|
||||
------
|
||||
|
||||
`Become an OpenCollective backer <https://opencollective.com/pyrogram>`_
|
||||
You can donate via PayPal using the button below:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<script src="https://opencollective.com/pyrogram/banner.js"></script>
|
||||
<form action="https://www.paypal.com/donate" method="post" target="_top">
|
||||
<input type="hidden" name="hosted_button_id" value="WMKAVFE47XEML" />
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
|
||||
<img alt="" border="0" src="https://www.paypal.com/en_IT/i/scr/pixel.gif" width="1" height="1" />
|
||||
</form>
|
||||
|
||||
-----
|
||||
|
||||
Cloud Credits
|
||||
-------------
|
||||
|
||||
If you need a cloud server to host your applications, try **Hetzner Cloud**. You can sign up with
|
||||
`this link <https://hetzner.cloud/?ref=9CyT92gZEINU>`_ to get €20 in cloud credits and help support Pyrogram and
|
||||
my `other projects`_.
|
||||
|
||||
.. _Star on GitHub: https://github.com/pyrogram/pyrogram
|
||||
.. _other projects: https://github.com/delivrance
|
||||
.. _other works: https://github.com/delivrance
|
||||
.. _Dan: https://t.me/haskell
|
||||
|
@ -1,8 +1,9 @@
|
||||
Advanced Usage
|
||||
==============
|
||||
|
||||
Pyrogram's API -- which consists of well documented :doc:`methods <../api/methods/index>` and
|
||||
:doc:`types <../api/types/index>` -- exists to provide an easier interface to the more complex Telegram API.
|
||||
Pyrogram's API, which consists of well documented convenience :doc:`methods <../api/methods/index>` and facade
|
||||
:doc:`types <../api/types/index>`, 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.
|
||||
@ -20,18 +21,25 @@ 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:`~pyrogram.raw.functions` and :mod:`~pyrogram.raw.types`.
|
||||
|
||||
As already hinted, raw functions and types can be less convenient. This section will therefore explain some pitfalls to
|
||||
take into consideration when working with the raw API.
|
||||
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
|
||||
some pitfalls to take into consideration when working with the raw API.
|
||||
|
||||
.. tip::
|
||||
.. hint::
|
||||
|
||||
Every available high-level method in Pyrogram is built on top of these raw functions.
|
||||
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
|
||||
:doc:`plenty of them <../api/methods/index>` are already re-implemented by providing a much simpler and cleaner
|
||||
interface which is very similar to the Bot API (yet much more powerful).
|
||||
|
||||
If you think a raw function should be wrapped and added as a high-level method, feel free to ask in our Community_!
|
||||
|
||||
Invoking Functions
|
||||
------------------
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Unlike the :doc:`methods <../api/methods/index>` found in Pyrogram's API, which can be called in the usual simple way,
|
||||
functions to be invoked from the raw Telegram API have a different way of usage.
|
||||
functions to be invoked from the raw Telegram API have a different way of usage and are more complex.
|
||||
|
||||
First of all, both :doc:`raw functions <../telegram/functions/index>` and :doc:`raw types <../telegram/types/index>`
|
||||
live in their respective packages (and sub-packages): ``pyrogram.raw.functions``, ``pyrogram.raw.types``. They all exist
|
||||
@ -53,12 +61,12 @@ Here's some examples:
|
||||
with Client("my_account") as app:
|
||||
app.send(
|
||||
functions.account.UpdateProfile(
|
||||
first_name="First Name", last_name="Last Name",
|
||||
about="New bio text"
|
||||
first_name="Dan", last_name="Tès",
|
||||
about="Bio written from Pyrogram"
|
||||
)
|
||||
)
|
||||
|
||||
- Set online/offline status:
|
||||
- Disable links to your account when someone forwards your messages:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -66,13 +74,14 @@ Here's some examples:
|
||||
from pyrogram.raw import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
# Set online status
|
||||
app.send(functions.account.UpdateStatus(offline=False))
|
||||
app.send(
|
||||
functions.account.SetPrivacy(
|
||||
key=types.PrivacyKeyForwards(),
|
||||
rules=[types.InputPrivacyValueDisallowAll()]
|
||||
)
|
||||
)
|
||||
|
||||
# Set offline status
|
||||
app.send(functions.account.UpdateStatus(offline=True))
|
||||
|
||||
- Get chat info:
|
||||
- Invite users to your channel/supergroup:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -80,18 +89,21 @@ Here's some examples:
|
||||
from pyrogram.raw import functions, types
|
||||
|
||||
with Client("my_account") as app:
|
||||
r = app.send(
|
||||
functions.channels.GetFullChannel(
|
||||
channel=app.resolve_peer("username")
|
||||
app.send(
|
||||
functions.channels.InviteToChannel(
|
||||
channel=app.resolve_peer(123456789), # ID or Username
|
||||
users=[ # The users you want to invite
|
||||
app.resolve_peer(23456789), # By ID
|
||||
app.resolve_peer("username"), # By username
|
||||
app.resolve_peer("+393281234567"), # By phone number
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
print(r)
|
||||
|
||||
Chat IDs
|
||||
--------
|
||||
^^^^^^^^
|
||||
|
||||
The way Telegram works makes it not possible to directly send a message to a user or a chat by using their IDs only.
|
||||
The way Telegram works makes it impossible to directly send a message to a user or a chat by using their IDs only.
|
||||
Instead, a pair of ``id`` and ``access_hash`` wrapped in a so called ``InputPeer`` is always needed. Pyrogram allows
|
||||
sending messages with IDs only thanks to cached access hashes.
|
||||
|
||||
@ -100,17 +112,18 @@ Whenever an InputPeer is needed you must pass one of these:
|
||||
|
||||
- :class:`~pyrogram.raw.types.InputPeerUser` - Users
|
||||
- :class:`~pyrogram.raw.types.InputPeerChat` - Basic Chats
|
||||
- :class:`~pyrogram.raw.types.InputPeerChannel` - Channels & Supergroups
|
||||
- :class:`~pyrogram.raw.types.InputPeerChannel` - Either Channels or Supergroups
|
||||
|
||||
But you don't necessarily have to manually instantiate each object because Pyrogram already provides
|
||||
But you don't necessarily have to manually instantiate each object because, luckily for you, Pyrogram already provides
|
||||
: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
|
||||
all positive within their respective raw types.
|
||||
|
||||
Things are different when working with Pyrogram's API because having them in the same space could lead to
|
||||
collisions, and that's why Pyrogram uses a slightly different representation for each kind of ID.
|
||||
Things are different when working with Pyrogram's API because having them in the same space can theoretically lead to
|
||||
collisions, and that's why Pyrogram (as well as the official Bot API) uses a slightly different representation for each
|
||||
kind of ID.
|
||||
|
||||
For example, given the ID *123456789*, here's how Pyrogram can tell entities apart:
|
||||
|
||||
|
50
docs/source/topics/bots-interaction.rst
Normal file
50
docs/source/topics/bots-interaction.rst
Normal file
@ -0,0 +1,50 @@
|
||||
Bots Interaction
|
||||
================
|
||||
|
||||
Users can interact with other bots via plain text messages as well as inline queries.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
:depth: 1
|
||||
:local:
|
||||
|
||||
-----
|
||||
|
||||
Inline Bots
|
||||
-----------
|
||||
|
||||
- If a bot accepts inline queries, you can call it by using
|
||||
:meth:`~pyrogram.Client.get_inline_bot_results` to get the list of its inline results for a query:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Get bot results for "Fuzz Universe" from the inline bot @vid
|
||||
bot_results = app.get_inline_bot_results("vid", "Fuzz Universe")
|
||||
|
||||
.. figure:: https://i.imgur.com/IAqLs54.png
|
||||
:width: 90%
|
||||
:align: center
|
||||
:figwidth: 60%
|
||||
|
||||
``get_inline_bot_results()`` is the equivalent action of writing ``@vid Fuzz Universe`` and getting the
|
||||
results list.
|
||||
|
||||
- After you retrieved the bot results, you can use
|
||||
:meth:`~pyrogram.Client.send_inline_bot_result` to send a chosen result to any chat:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Send the first result to your own chat
|
||||
app.send_inline_bot_result(
|
||||
"me",
|
||||
bot_results.query_id,
|
||||
bot_results.results[0].id
|
||||
)
|
||||
|
||||
.. figure:: https://i.imgur.com/wwxr7B7.png
|
||||
:width: 90%
|
||||
:align: center
|
||||
:figwidth: 60%
|
||||
|
||||
``send_inline_bot_result()`` is the equivalent action of choosing a result from the list and sending it
|
||||
to a chat.
|
@ -15,7 +15,7 @@ Introduction
|
||||
------------
|
||||
|
||||
The idea behind using a configuration file is to help keeping your code free of private settings information such as
|
||||
the API Key and Proxy, without having you to 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.
|
||||
|
||||
@ -23,7 +23,7 @@ fill in the necessary parts.
|
||||
|
||||
The configuration file is optional, but recommended. If, for any reason, you prefer not to use it, there's always an
|
||||
alternative way to configure Pyrogram via Client's parameters. Doing so, you can have full control on how to store
|
||||
and load your settings.
|
||||
and load your settings (e.g.: from environment variables).
|
||||
|
||||
Settings specified via Client's parameter have higher priority and will override any setting stored in the
|
||||
configuration file.
|
||||
|
@ -87,7 +87,7 @@ Finally, the filter usage remains the same:
|
||||
Filters with Arguments
|
||||
----------------------
|
||||
|
||||
A more flexible filter would be one that accepts "pyrogram" or any other string as argument at usage time.
|
||||
A much cooler filter would be one that accepts "pyrogram" or any other string as argument at usage time.
|
||||
A dynamic filter like this will make use of named arguments for the :meth:`~pyrogram.filters.create` method and the
|
||||
first argument of the callback function, which is a reference to the filter object itself holding the extra data passed
|
||||
via named arguments.
|
||||
|
@ -2,7 +2,7 @@ Debugging
|
||||
=========
|
||||
|
||||
When working with the API, chances are you'll stumble upon bugs, get stuck and start wondering how to continue. Nothing
|
||||
to actually worry about since Pyrogram provides some commodities to help you in this.
|
||||
to actually worry about -- that's normal -- and luckily for you, Pyrogram provides some commodities to help you in this.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -27,8 +27,8 @@ Consider the following code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
me = app.get_users("me")
|
||||
print(me) # User
|
||||
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.types.User` instance, in this case. The output on your terminal will be something similar to this:
|
||||
@ -36,9 +36,9 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"_": "User",
|
||||
"id": 123456789,
|
||||
"is_self": true,
|
||||
"_": "pyrogram.User",
|
||||
"id": 23122162,
|
||||
"is_self": false,
|
||||
"is_contact": false,
|
||||
"is_mutual_contact": false,
|
||||
"is_deleted": false,
|
||||
@ -46,13 +46,19 @@ This will show a JSON representation of the object returned by :meth:`~pyrogram.
|
||||
"is_verified": false,
|
||||
"is_restricted": false,
|
||||
"is_support": false,
|
||||
"first_name": "Pyrogram",
|
||||
"is_scam": false,
|
||||
"first_name": "Dan",
|
||||
"status": {
|
||||
"_": "pyrogram.UserStatus",
|
||||
"user_id": 23122162,
|
||||
"recently": true
|
||||
},
|
||||
"username": "haskell",
|
||||
"language_code": "en",
|
||||
"photo": {
|
||||
"_": "ChatPhoto",
|
||||
"small_file_id": "AbCdE...EdCbA",
|
||||
"small_photo_unique_id": "VwXyZ...ZyXwV",
|
||||
"big_file_id": "AbCdE...EdCbA",
|
||||
"big_photo_unique_id": "VwXyZ...ZyXwV"
|
||||
"_": "pyrogram.ChatPhoto",
|
||||
"small_file_id": "AQADBAAD8tBgAQAEJjCxGgAEo5IBAAIC",
|
||||
"big_file_id": "AQADBAAD8tBgAQAEJjCxGgAEpZIBAAEBAg"
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,23 +69,37 @@ Accessing Attributes
|
||||
--------------------
|
||||
|
||||
Even though you see a JSON output, it doesn't mean we are dealing with dictionaries; in fact, all Pyrogram types are
|
||||
fully-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``:
|
||||
full-fledged Python objects and the correct way to access any attribute of them is by using the dot notation ``.``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
photo = me.photo
|
||||
print(photo) # ChatPhoto
|
||||
dan_photo = dan.photo
|
||||
print(dan_photo) # ChatPhoto
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"_": "ChatPhoto",
|
||||
"small_file_id": "AbCdE...EdCbA",
|
||||
"small_photo_unique_id": "VwXyZ...ZyXwV",
|
||||
"big_file_id": "AbCdE...EdCbA",
|
||||
"big_photo_unique_id": "VwXyZ...ZyXwV"
|
||||
"_": "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
|
||||
-------------------------
|
||||
|
||||
@ -91,8 +111,8 @@ error. The correct way to get the object type is by using the built-in function
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
status = me.status
|
||||
print(type(status))
|
||||
dan_status = dan.status
|
||||
print(type(dan_status))
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@ -105,8 +125,8 @@ And to check if an object is an instance of a given class, you use the built-in
|
||||
|
||||
from pyrogram.types import UserStatus
|
||||
|
||||
status = me.status
|
||||
print(isinstance(status, UserStatus))
|
||||
dan_status = dan.status
|
||||
print(isinstance(dan_status, UserStatus))
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
|
@ -24,6 +24,7 @@ group. Dispatching groups hold one or more handlers and are processed sequential
|
||||
For example, take these two handlers:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 1, 6
|
||||
|
||||
@app.on_message(filters.text | filters.sticker)
|
||||
def text_or_sticker(client, message):
|
||||
|
@ -1,10 +1,10 @@
|
||||
MTProto vs. Bot API
|
||||
===================
|
||||
|
||||
Pyrogram is a framework written from the ground up that acts as a fully-fledged Telegram client based on the MTProto
|
||||
API. This means that Pyrogram is able to execute any official client and bot API action and more. 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.
|
||||
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.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -19,11 +19,10 @@ 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 in order to distinguish it
|
||||
from the Bot API. The main Telegram 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. Clients that make use of Telegram's main API, such as
|
||||
Pyrogram, implement all these details.
|
||||
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
|
||||
@ -32,12 +31,12 @@ Pyrogram, implement all these details.
|
||||
What is the Bot API?
|
||||
--------------------
|
||||
|
||||
The `Bot API`_ is an HTTP(S) interface for building normal bots using a sub-set of the main Telegram 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.
|
||||
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:: //_static/img/mtproto-vs-bot-api.png
|
||||
.. figure:: https://i.imgur.com/WvwBoZo.png
|
||||
:align: center
|
||||
|
||||
.. _Bot API: https://core.telegram.org/bots/api
|
||||
@ -45,8 +44,8 @@ servers using MTProto.
|
||||
Advantages of the MTProto API
|
||||
-----------------------------
|
||||
|
||||
Here is a non-exhaustive list of all the advantages in using MTProto-based libraries -- such as Pyrogram -- instead of
|
||||
the official HTTP Bot API. Using Pyrogram you can:
|
||||
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
|
||||
@ -70,7 +69,7 @@ the official HTTP Bot API. Using Pyrogram you can:
|
||||
.. hlist::
|
||||
:columns: 1
|
||||
|
||||
- :guilabel:`+` **Run multiple sessions at once (for both user and bot identities)**
|
||||
- :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.
|
||||
|
||||
|
@ -14,8 +14,8 @@ non-asynchronous contexts. For more detailed information, you can visit and lear
|
||||
|
||||
-----
|
||||
|
||||
Using apscheduler
|
||||
-----------------
|
||||
Using ``apscheduler``
|
||||
---------------------
|
||||
|
||||
- Install with ``pip3 install apscheduler``
|
||||
- Documentation: https://apscheduler.readthedocs.io
|
||||
|
@ -24,7 +24,8 @@ If you want a nicely formatted, human readable JSON representation of any object
|
||||
...
|
||||
|
||||
with app:
|
||||
r = app.get_chat("me")
|
||||
r = app.get_chat("haskell")
|
||||
|
||||
print(str(r))
|
||||
|
||||
.. tip::
|
||||
@ -47,7 +48,7 @@ as the process requires the package to be in scope.
|
||||
...
|
||||
|
||||
with app:
|
||||
r = app.get_chat("me")
|
||||
r = app.get_chat("haskell")
|
||||
|
||||
print(repr(r))
|
||||
print(eval(repr(r)) == r) # True
|
||||
|
@ -1,12 +1,24 @@
|
||||
Client Settings
|
||||
===============
|
||||
Session Settings
|
||||
================
|
||||
|
||||
You can control the way your client appears in the Active Sessions menu of an official client by changing some client
|
||||
settings. By default you will see something like the following:
|
||||
As you may probably know, Telegram allows users (and bots) having more than one session (authorizations) registered
|
||||
in the system at the same time.
|
||||
|
||||
- Device Model: ``CPython x.y.z``
|
||||
- Application: ``Pyrogram x.y.z``
|
||||
- System Version: ``Linux x.y.z``
|
||||
Briefly explaining, sessions are simply new logins in your account. They can be reviewed in the settings of an official
|
||||
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/YaqtMLO.png
|
||||
:width: 600
|
||||
:align: center
|
||||
|
||||
**A Pyrogram session running on Linux, Python 3.7.**
|
||||
|
||||
That's how a session looks like on the Android app, showing the three main pieces of information.
|
||||
|
||||
- ``app_version``: **Pyrogram 0.13.0**
|
||||
- ``device_model``: **CPython 3.7.2**
|
||||
- ``system_version``: **Linux 4.15.0-23-generic**
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
@ -1,9 +1,9 @@
|
||||
Smart Plugins
|
||||
=============
|
||||
|
||||
Pyrogram embeds a smart, lightweight yet powerful plugin system that is meant to further simplify the organization
|
||||
of large projects and to provide a way for creating pluggable (modular) components that can be easily shared across
|
||||
different Pyrogram applications with minimal boilerplate code.
|
||||
Pyrogram embeds a **smart**, lightweight yet powerful plugin system that is meant to further simplify the organization
|
||||
of large projects and to provide a way for creating pluggable (modular) components that can be **easily shared** across
|
||||
different Pyrogram applications with **minimal boilerplate code**.
|
||||
|
||||
.. tip::
|
||||
|
||||
@ -74,8 +74,8 @@ after importing your modules, like this:
|
||||
|
||||
This is already nice and doesn't add *too much* boilerplate code, but things can get boring still; you have to
|
||||
manually ``import``, manually :meth:`~pyrogram.Client.add_handler` and manually instantiate each
|
||||
:class:`~pyrogram.handlers.MessageHandler` object because you can't use decorators for your functions.
|
||||
So, what if you could? Smart Plugins solve this issue by taking care of handlers registration automatically.
|
||||
:class:`~pyrogram.handlers.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
|
||||
-------------------
|
||||
@ -91,6 +91,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
This is the same example application as shown above, written using the Smart Plugin system.
|
||||
|
||||
.. code-block:: text
|
||||
:emphasize-lines: 2, 3
|
||||
|
||||
myproject/
|
||||
plugins/
|
||||
@ -101,6 +102,7 @@ Setting up your Pyrogram project to accommodate Smart Plugins is pretty straight
|
||||
- ``plugins/handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 4, 9
|
||||
|
||||
from pyrogram import Client, filters
|
||||
|
||||
@ -162,7 +164,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, by design. Learn more at :doc:`More on Updates <more-on-updates>`.
|
||||
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``
|
||||
@ -298,30 +300,32 @@ In the previous section we've explained how to specify which plugins to load and
|
||||
starts. Here we'll show, instead, how to unload and load again a previously registered plugin at runtime.
|
||||
|
||||
Each function decorated with the usual ``on_message`` decorator (or any other decorator that deals with Telegram
|
||||
updates) will be modified in such a way that a special ``handlers`` attribute pointing to a list of tuples of
|
||||
updates) will be modified in such a way that a special ``handler`` attribute pointing to a tuple of
|
||||
*(handler: Handler, group: int)* is attached to the function object itself.
|
||||
|
||||
- ``plugins/handlers.py``
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 5, 6
|
||||
|
||||
@Client.on_message(filters.text & filters.private)
|
||||
def echo(client, message):
|
||||
message.reply(message.text)
|
||||
|
||||
print(echo)
|
||||
print(echo.handlers)
|
||||
print(echo.handler)
|
||||
|
||||
- Printing ``echo`` will show something like ``<function echo at 0x10e3b6598>``.
|
||||
|
||||
- Printing ``echo.handlers`` will reveal the handlers, that is, a list of tuples containing the actual handlers and
|
||||
the groups they were registered on ``[(<MessageHandler object at 0x10e3abc50>, 0)]``.
|
||||
- Printing ``echo.handler`` will reveal the handler, that is, a tuple containing the actual handler and the group it
|
||||
was registered on ``(<MessageHandler object at 0x10e3abc50>, 0)``.
|
||||
|
||||
Unloading
|
||||
^^^^^^^^^
|
||||
|
||||
In order to unload a plugin, all you need to do is obtain a reference to it by importing the relevant module and call
|
||||
:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* instance:
|
||||
:meth:`~pyrogram.Client.remove_handler` Client's method with your function's *handler* special attribute preceded by the
|
||||
star ``*`` operator as argument. Example:
|
||||
|
||||
- ``main.py``
|
||||
|
||||
@ -329,19 +333,16 @@ In order to unload a plugin, all you need to do is obtain a reference to it by i
|
||||
|
||||
from plugins.handlers import echo
|
||||
|
||||
handlers = echo.handlers
|
||||
...
|
||||
|
||||
for h in handlers:
|
||||
app.remove_handler(*h)
|
||||
app.remove_handler(*echo.handler)
|
||||
|
||||
The star ``*`` operator is used to unpack the tuple into positional arguments so that *remove_handler* will receive
|
||||
exactly what is needed. The same could have been achieved with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
handlers = echo.handlers
|
||||
handler, group = handlers[0]
|
||||
|
||||
handler, group = echo.handler
|
||||
app.remove_handler(handler, group)
|
||||
|
||||
Loading
|
||||
@ -358,7 +359,4 @@ using :meth:`~pyrogram.Client.add_handler` instead. Example:
|
||||
|
||||
...
|
||||
|
||||
handlers = echo.handlers
|
||||
|
||||
for h in handlers:
|
||||
app.add_handler(*h)
|
||||
app.add_handler(*echo.handler)
|
@ -18,18 +18,28 @@ Persisting Sessions
|
||||
In order to make a client reconnect successfully between restarts, that is, without having to start a new
|
||||
authorization process from scratch each time, Pyrogram needs to store the generated session data somewhere.
|
||||
|
||||
Other useful data being stored is peers' cache. In short, peers are all those entities you can chat with, such as users
|
||||
or bots, basic groups, but also channels and supergroups. Because of how Telegram works, a unique pair of **id** and
|
||||
**access_hash** is needed to contact a peer. This, plus other useful info such as the peer type, is what is stored
|
||||
inside a session storage.
|
||||
|
||||
So, if you ever wondered how is Pyrogram able to contact peers just by asking for their ids, it's because of this very
|
||||
reason: the peer *id* is looked up in the internal database and the available *access_hash* is retrieved, which is then
|
||||
used to correctly invoke API methods.
|
||||
|
||||
Different Storage Engines
|
||||
-------------------------
|
||||
|
||||
Pyrogram offers two different types of storage engines: a **File Storage** and a **Memory Storage**.
|
||||
These engines are well integrated in the framework and require a minimal effort to set up. Here's how they work:
|
||||
Let's now talk about how Pyrogram actually stores all the relevant data. Pyrogram offers two different types of storage
|
||||
engines: a **File Storage** and a **Memory Storage**. These engines are well integrated in the library and require a
|
||||
minimal effort to set up. Here's how they work:
|
||||
|
||||
File Storage
|
||||
^^^^^^^^^^^^
|
||||
|
||||
This is the most common storage engine. It is implemented by using **SQLite**, which will store the session details.
|
||||
The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve
|
||||
data whenever they are needed.
|
||||
This is the most common storage engine. It is implemented by using **SQLite**, which will store the session and peers
|
||||
details. The database will be saved to disk as a single portable file and is designed to efficiently store and retrieve
|
||||
peers whenever they are needed.
|
||||
|
||||
To use this type of engine, simply pass any name of your choice to the ``session_name`` parameter of the
|
||||
:obj:`~pyrogram.Client` constructor, as usual:
|
||||
@ -58,8 +68,8 @@ session name "**:memory:**" to the ``session_name`` parameter of the :obj:`~pyro
|
||||
with Client(":memory:") as app:
|
||||
print(app.get_me())
|
||||
|
||||
This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop
|
||||
a client, the entire database is discarded and the session details used for logging in again will be lost forever.
|
||||
This storage engine is still backed by SQLite, but the database exists purely in memory. This means that, once you stop a
|
||||
client, the entire database is discarded and the session details used for logging in again will be lost forever.
|
||||
|
||||
Session Strings
|
||||
---------------
|
||||
@ -74,8 +84,8 @@ In case you want to use an in-memory storage, but also want to keep access to th
|
||||
with Client(":memory:") as app:
|
||||
print(app.export_session_string())
|
||||
|
||||
...and save the resulting string. You can use this string as session name the next time you want to login
|
||||
using the same session; the storage used will still be in-memory:
|
||||
...and save the resulting (quite long) string somewhere. You can use this string as session name the next time you want
|
||||
to login using the same session; the storage used will still be completely in-memory:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -86,5 +96,11 @@ using the same session; the storage used will still be in-memory:
|
||||
with Client(session_string) as app:
|
||||
print(app.get_me())
|
||||
|
||||
Session strings are useful when you want to run authorized Pyrogram clients on platforms where their ephemeral
|
||||
filesystems makes it harder for a file-based storage engine to properly work as intended.
|
||||
Session strings are useful when you want to run authorized Pyrogram clients on platforms like
|
||||
`Heroku <https://www.heroku.com/>`_, where their ephemeral filesystems makes it much harder for a file-based storage
|
||||
engine to properly work as intended.
|
||||
|
||||
But, why is the session string so long? Can't it be shorter? No, it can't. The session string already packs the bare
|
||||
minimum data Pyrogram needs to successfully reconnect to an authorized session, and the 2048-bits auth key is the major
|
||||
contributor to the overall length. Needless to say that this string, as well as any other session storage, represent
|
||||
strictly personal data. Keep them safe.
|
||||
|
@ -15,7 +15,8 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
|
||||
.. note::
|
||||
|
||||
If this is the first time you login into test servers, you will be asked to register your account first.
|
||||
Accounts registered on test servers reside in a different, parallel instance of a Telegram server.
|
||||
Don't worry about your contacts and chats, they will be kept untouched inside the production environment;
|
||||
accounts authorized on test servers reside in a different, parallel instance of a Telegram database.
|
||||
|
||||
.. contents:: Contents
|
||||
:backlinks: none
|
||||
@ -27,15 +28,19 @@ Telegram's test servers without hassle. All you need to do is start a new sessio
|
||||
Test Mode in Official Apps
|
||||
--------------------------
|
||||
|
||||
You can also login yourself into test servers using official desktop apps, such as Telegram Web and Telegram Desktop:
|
||||
You can also login yourself into test servers using official desktop apps, such as Webogram and TDesktop:
|
||||
|
||||
- **Telegram Web**: Login here: https://web.telegram.org/?test=1
|
||||
- **Telegram Desktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
|
||||
- **Webogram**: Login here: https://web.telegram.org/?test=1
|
||||
- **TDesktop**: Hold ``Alt+Shift`` and right click on "Add account", then choose "Test server".
|
||||
|
||||
Test Numbers
|
||||
------------
|
||||
|
||||
Beside normal numbers, the test environment allows you to login with reserved test numbers.
|
||||
Valid phone numbers follow the pattern ``99966XYYYY``, where ``X`` is the DC number (1 to 3) and ``YYYY`` are random
|
||||
numbers. Users with such numbers always get ``XXXXX`` or ``XXXXXX`` as the confirmation code (the DC number, repeated
|
||||
five or six times).
|
||||
numbers. Users with such numbers always get ``XXXXX`` as the confirmation code (the DC number, repeated five times).
|
||||
|
||||
.. important::
|
||||
|
||||
Do not store any important or private information in such test users' accounts; anyone can make use of the
|
||||
simplified authorization mechanism and login at any time.
|
||||
|
@ -14,7 +14,7 @@ Text Formatting
|
||||
:class: strike-italic
|
||||
|
||||
Pyrogram uses a custom Markdown dialect for text formatting which adds some unique features that make writing styled
|
||||
texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a
|
||||
texts easier in both Markdown and HTML. You can send sophisticated text messages and media captions using a great
|
||||
variety of decorations that can also be nested in order to combine multiple styles together.
|
||||
|
||||
.. contents:: Contents
|
||||
@ -34,9 +34,8 @@ list of the basic styles currently supported by Pyrogram.
|
||||
- *italic*
|
||||
- :strike:`strike`
|
||||
- :underline:`underline`
|
||||
- spoiler
|
||||
- `text URL <https://pyrogram.org>`_
|
||||
- `user text mention <tg://user?id=123456789>`_
|
||||
- `user text mention <https://t.me/haskell>`_
|
||||
- ``inline fixed-width code``
|
||||
- .. code-block:: text
|
||||
|
||||
@ -64,11 +63,9 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
|
||||
|
||||
~~strike~~
|
||||
|
||||
||spoiler||
|
||||
[text URL](https://docs.pyrogram.org/)
|
||||
|
||||
[text URL](https://pyrogram.org/)
|
||||
|
||||
[text user mention](tg://user?id=123456789)
|
||||
[text user mention](tg://user?id=23122162)
|
||||
|
||||
`inline fixed-width code`
|
||||
|
||||
@ -83,13 +80,13 @@ To strictly use this mode, pass "markdown" to the *parse_mode* parameter when us
|
||||
.. code-block:: python
|
||||
|
||||
app.send_message(
|
||||
"me",
|
||||
"haskell",
|
||||
(
|
||||
"**bold**, "
|
||||
"__italic__, "
|
||||
"--underline--, "
|
||||
"~~strike~~, "
|
||||
"||spoiler||, "
|
||||
"[mention](tg://user?id=23122162), "
|
||||
"[URL](https://pyrogram.org), "
|
||||
"`code`, "
|
||||
"```"
|
||||
@ -116,11 +113,9 @@ The following tags are currently supported:
|
||||
|
||||
<s>strike</s>, <del>strike</del>, <strike>strike</strike>
|
||||
|
||||
<spoiler>spoiler</spoiler>
|
||||
<a href="http://docs.pyrogram.org/">text URL</a>
|
||||
|
||||
<a href="https://pyrogram.org/">text URL</a>
|
||||
|
||||
<a href="tg://user?id=123456789">inline mention</a>
|
||||
<a href="tg://user?id=23122162">inline mention</a>
|
||||
|
||||
<code>inline fixed-width code</code>
|
||||
|
||||
@ -135,13 +130,13 @@ The following tags are currently supported:
|
||||
.. code-block:: python
|
||||
|
||||
app.send_message(
|
||||
"me",
|
||||
"haskell",
|
||||
(
|
||||
"<b>bold</b>, "
|
||||
"<i>italic</i>, "
|
||||
"<u>underline</u>, "
|
||||
"<s>strike</s>, "
|
||||
"<spoiler>spoiler</spoiler>, "
|
||||
"<a href=\"tg://user?id=23122162\">mention</a>, "
|
||||
"<a href=\"https://pyrogram.org/\">URL</a>, "
|
||||
"<code>code</code>\n\n"
|
||||
"<pre>"
|
||||
@ -179,7 +174,7 @@ This means you can combine together both syntaxes in the same text:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.send_message("me", "**bold**, <i>italic</i>")
|
||||
app.send_message("haskell", "**bold**, <i>italic</i>")
|
||||
|
||||
Result:
|
||||
|
||||
@ -190,8 +185,8 @@ If you don't like this behaviour you can always choose to only enable either Mar
|
||||
|
||||
.. code-block::
|
||||
|
||||
app.send_message("me", "**bold**, <i>italic</i>", parse_mode="markdown")
|
||||
app.send_message("me", "**bold**, <i>italic</i>", parse_mode="html")
|
||||
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="markdown")
|
||||
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode="html")
|
||||
|
||||
Result:
|
||||
|
||||
@ -204,7 +199,7 @@ as-is.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
app.send_message("me", "**bold**, <i>italic</i>", parse_mode=None)
|
||||
app.send_message("haskell", "**bold**, <i>italic</i>", parse_mode=None)
|
||||
|
||||
Result:
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
Fast Crypto
|
||||
===========
|
||||
|
||||
Pyrogram's speed can be boosted up by TgCrypto_, a high-performance, easy-to-install cryptography library specifically
|
||||
written in C for Pyrogram as a Python extension.
|
||||
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 [1]_ as a Python extension.
|
||||
|
||||
TgCrypto is a replacement for a slower Python-only alternative and implements the cryptographic algorithms Telegram
|
||||
requires, namely: AES-256-IGE, AES-256-CTR and AES-256-CBC.
|
||||
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).
|
||||
|
||||
Installation
|
||||
------------
|
||||
@ -14,10 +14,10 @@ Installation
|
||||
|
||||
$ pip3 install -U tgcrypto
|
||||
|
||||
.. note:: When TgCrypto is not detected in your system, Pyrogram will automatically fall back to a slower Python-only
|
||||
implementation and will show you a warning.
|
||||
.. note:: Being a C extension for Python, TgCrypto is an optional but *highly recommended* dependency; when TgCrypto is
|
||||
not detected in your system, Pyrogram will automatically fall back to PyAES and will show you a warning.
|
||||
|
||||
The reason about being an optional package is that TgCrypto requires extra system tools in order to be compiled.
|
||||
The reason about being an optional package is that TgCrypto requires some extra system tools in order to be compiled.
|
||||
The errors you receive when trying to install TgCrypto are system dependent, but also descriptive enough to understand
|
||||
what you should do next:
|
||||
|
||||
@ -26,4 +26,7 @@ what you should do next:
|
||||
- **Linux**: Install a proper C compiler (``gcc``, ``clang``) and the Python header files (``python3-dev``).
|
||||
- **Termux**: Install ``clang`` package.
|
||||
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
.. _TgCrypto: https://github.com/pyrogram/tgcrypto
|
||||
|
||||
.. [1] Although TgCrypto is intended for Pyrogram, it is shipped as a standalone package and can thus be used for
|
||||
other Python projects too.
|
||||
|
@ -19,15 +19,16 @@ Single Filters
|
||||
|
||||
Let's start right away with a simple example:
|
||||
|
||||
- This example will show you how to **only** handle messages containing a :class:`~pyrogram.types.Sticker` object and
|
||||
- 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.sticker)
|
||||
@app.on_message(filters.audio)
|
||||
def my_handler(client, message):
|
||||
print(message)
|
||||
|
||||
@ -35,6 +36,7 @@ Let's start right away with a simple example:
|
||||
callback function itself:
|
||||
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 9
|
||||
|
||||
from pyrogram import filters
|
||||
from pyrogram.handlers import MessageHandler
|
||||
@ -44,12 +46,12 @@ Let's start right away with a simple example:
|
||||
print(message)
|
||||
|
||||
|
||||
app.add_handler(MessageHandler(my_handler, filters.sticker))
|
||||
app.add_handler(MessageHandler(my_handler, filters.audio))
|
||||
|
||||
Combining Filters
|
||||
-----------------
|
||||
|
||||
Filters can be used in a more advanced way by inverting and combining more filters together using bitwise
|
||||
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).
|
||||
|
@ -1,8 +1,8 @@
|
||||
Voice Calls
|
||||
===========
|
||||
|
||||
Both private voice calls and group voice calls are currently supported by third-party, external libraries that integrate
|
||||
with Pyrogram.
|
||||
Both private voice calls and group voice calls are currently supported by third-party libraries that integrate with
|
||||
Pyrogram.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -16,9 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__version__ = "1.4.0"
|
||||
__version__ = "1.2.9"
|
||||
__license__ = "GNU Lesser General Public License v3 or later (LGPLv3+)"
|
||||
__copyright__ = "Copyright (C) 2017-present Dan <https://github.com/delivrance>"
|
||||
__copyright__ = "Copyright (C) 2017-2021 Dan <https://github.com/delivrance>"
|
||||
|
||||
from concurrent.futures.thread import ThreadPoolExecutor
|
||||
|
||||
@ -35,14 +35,14 @@ class ContinuePropagation(StopAsyncIteration):
|
||||
pass
|
||||
|
||||
|
||||
from asyncio import get_event_loop
|
||||
import asyncio
|
||||
|
||||
from . import raw, types, filters, handlers, emoji
|
||||
from .client import Client
|
||||
from .sync import idle
|
||||
|
||||
# Save the main thread loop for future references
|
||||
main_event_loop = get_event_loop()
|
||||
main_event_loop = asyncio.get_event_loop()
|
||||
|
||||
CRYPTO_EXECUTOR_SIZE_THRESHOLD = 512
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -32,11 +32,9 @@ from pathlib import Path
|
||||
from typing import Union, List, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import __version__, __license__
|
||||
from pyrogram import raw
|
||||
from pyrogram import utils
|
||||
from pyrogram.crypto import aes
|
||||
from pyrogram.errors import CDNFileHashMismatch
|
||||
from pyrogram.errors import (
|
||||
SessionPasswordNeeded,
|
||||
VolumeLocNotFound, ChannelPrivate,
|
||||
@ -107,11 +105,6 @@ class Client(Methods, Scaffold):
|
||||
Only applicable for new sessions and will be ignored in case previously created sessions are loaded.
|
||||
Defaults to False.
|
||||
|
||||
mode (``int``, *optional*):
|
||||
The connection mode to use.
|
||||
Defaults to Obfuscated TCPAbridged (3),
|
||||
The list of modes are available at `connection/connection.py`
|
||||
|
||||
bot_token (``str``, *optional*):
|
||||
Pass your Bot API token to create a bot session, e.g.: "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
|
||||
Only applicable for new sessions.
|
||||
@ -193,7 +186,6 @@ class Client(Methods, Scaffold):
|
||||
ipv6: bool = False,
|
||||
proxy: dict = None,
|
||||
test_mode: bool = False,
|
||||
mode: int = 3,
|
||||
bot_token: str = None,
|
||||
phone_number: str = None,
|
||||
phone_code: str = None,
|
||||
@ -222,7 +214,6 @@ class Client(Methods, Scaffold):
|
||||
# TODO: Make code consistent, use underscore for private/protected fields
|
||||
self._proxy = proxy
|
||||
self.test_mode = test_mode
|
||||
self.mode = mode
|
||||
self.bot_token = bot_token
|
||||
self.phone_number = phone_number
|
||||
self.phone_code = phone_code
|
||||
@ -289,10 +280,6 @@ class Client(Methods, Scaffold):
|
||||
if self.bot_token:
|
||||
return await self.sign_in_bot(self.bot_token)
|
||||
|
||||
print(f"Welcome to Pyrogram (version {__version__})")
|
||||
print(f"Pyrogram is free software and comes with ABSOLUTELY NO WARRANTY. Licensed\n"
|
||||
f"under the terms of the {__license__}.\n")
|
||||
|
||||
while True:
|
||||
try:
|
||||
if not self.phone_number:
|
||||
@ -440,6 +427,7 @@ class Client(Methods, Scaffold):
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
:emphasize-lines: 10,14,18,22
|
||||
|
||||
from pyrogram import Client
|
||||
|
||||
@ -447,23 +435,23 @@ class Client(Methods, Scaffold):
|
||||
|
||||
with app:
|
||||
# Default combined mode: Markdown + HTML
|
||||
app.send_message("me", "1. **markdown** and <i>html</i>")
|
||||
app.send_message("haskell", "1. **markdown** and <i>html</i>")
|
||||
|
||||
# Force Markdown-only, HTML is disabled
|
||||
app.set_parse_mode("markdown")
|
||||
app.send_message("me", "2. **markdown** and <i>html</i>")
|
||||
app.send_message("haskell", "2. **markdown** and <i>html</i>")
|
||||
|
||||
# Force HTML-only, Markdown is disabled
|
||||
app.set_parse_mode("html")
|
||||
app.send_message("me", "3. **markdown** and <i>html</i>")
|
||||
app.send_message("haskell", "3. **markdown** and <i>html</i>")
|
||||
|
||||
# Disable the parser completely
|
||||
app.set_parse_mode(None)
|
||||
app.send_message("me", "4. **markdown** and <i>html</i>")
|
||||
app.send_message("haskell", "4. **markdown** and <i>html</i>")
|
||||
|
||||
# Bring back the default combined mode
|
||||
app.set_parse_mode()
|
||||
app.send_message("me", "5. **markdown** and <i>html</i>")
|
||||
app.send_message("haskell", "5. **markdown** and <i>html</i>")
|
||||
"""
|
||||
|
||||
self.parse_mode = parse_mode
|
||||
@ -928,6 +916,9 @@ class Client(Methods, Scaffold):
|
||||
while True:
|
||||
chunk = r.bytes
|
||||
|
||||
if not chunk:
|
||||
break
|
||||
|
||||
f.write(chunk)
|
||||
|
||||
offset += limit
|
||||
@ -947,9 +938,6 @@ class Client(Methods, Scaffold):
|
||||
else:
|
||||
await self.loop.run_in_executor(self.executor, func)
|
||||
|
||||
if len(chunk) < limit:
|
||||
break
|
||||
|
||||
r = await session.send(
|
||||
raw.functions.upload.GetFile(
|
||||
location=location,
|
||||
@ -1021,7 +1009,7 @@ class Client(Methods, Scaffold):
|
||||
# https://core.telegram.org/cdn#verifying-files
|
||||
for i, h in enumerate(hashes):
|
||||
cdn_chunk = decrypted_chunk[h.limit * i: h.limit * (i + 1)]
|
||||
CDNFileHashMismatch.check(h.hash == sha256(cdn_chunk).digest())
|
||||
assert h.hash == sha256(cdn_chunk).digest(), f"Invalid CDN hash part {i}"
|
||||
|
||||
f.write(decrypted_chunk)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -34,9 +34,7 @@ class Connection:
|
||||
1: TCPAbridged,
|
||||
2: TCPIntermediate,
|
||||
3: TCPAbridgedO,
|
||||
4: TCPIntermediateO,
|
||||
5: TCPPaddedIntermediate,
|
||||
6: TCPPaddedIntermediateO
|
||||
4: TCPIntermediateO
|
||||
}
|
||||
|
||||
def __init__(self, dc_id: int, test_mode: bool, ipv6: bool, proxy: dict, media: bool = False, mode: int = 3):
|
||||
@ -48,7 +46,7 @@ class Connection:
|
||||
self.address = DataCenter(dc_id, test_mode, ipv6, media)
|
||||
self.mode = self.MODES.get(mode, TCPAbridged)
|
||||
|
||||
self.protocol = None # type: Optional[TCP]
|
||||
self.protocol = None # type: TCP
|
||||
|
||||
async def connect(self):
|
||||
for i in range(Connection.MAX_RETRIES):
|
||||
@ -71,7 +69,7 @@ class Connection:
|
||||
))
|
||||
break
|
||||
else:
|
||||
log.warning("Connection failed! Retrying...")
|
||||
log.warning("Connection failed! Trying again...")
|
||||
raise TimeoutError
|
||||
|
||||
def close(self):
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -21,6 +21,4 @@ from .tcp_abridged import TCPAbridged
|
||||
from .tcp_abridged_o import TCPAbridgedO
|
||||
from .tcp_full import TCPFull
|
||||
from .tcp_intermediate import TCPIntermediate
|
||||
from .tcp_padded_intermediate import TCPPaddedIntermediate
|
||||
from .tcp_intermediate_o import TCPIntermediateO
|
||||
from .tcp_padded_intermediate_o import TCPPaddedIntermediateO
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -24,12 +24,14 @@ import time
|
||||
|
||||
try:
|
||||
import socks
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
except ImportError as e:
|
||||
e.msg = (
|
||||
"PySocks is missing and Pyrogram can't run without. "
|
||||
"Please install it using \"pip3 install pysocks\"."
|
||||
)
|
||||
|
||||
raise e
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
@ -17,6 +17,7 @@
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from .tcp import TCP
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
# Copyright (C) 2017-2021 Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user