mirror of
https://github.com/Mayuri-Chan/pyrofork.git
synced 2026-01-05 14:54:51 +00:00
Merge branch 'develop' into asyncio
# Conflicts: # pyrogram/client/methods/chats/set_chat_description.py
This commit is contained in:
commit
9100a43f7b
13 changed files with 127 additions and 79 deletions
|
|
@ -95,4 +95,5 @@ PHOTO_EXT_INVALID The photo extension is invalid
|
||||||
EXTERNAL_URL_INVALID The external media URL is invalid
|
EXTERNAL_URL_INVALID The external media URL is invalid
|
||||||
CHAT_NOT_MODIFIED The chat settings were not modified
|
CHAT_NOT_MODIFIED The chat settings were not modified
|
||||||
RESULTS_TOO_MUCH The result contains too many items
|
RESULTS_TOO_MUCH The result contains too many items
|
||||||
RESULT_ID_DUPLICATE The result contains items with duplicated identifiers
|
RESULT_ID_DUPLICATE The result contains items with duplicated identifiers
|
||||||
|
ACCESS_TOKEN_INVALID The bot access token is invalid
|
||||||
|
|
|
@ -10,13 +10,14 @@ can be freely used as basic building blocks for your own applications without wo
|
||||||
|
|
||||||
Example | Description
|
Example | Description
|
||||||
---: | :---
|
---: | :---
|
||||||
[**hello**](hello.py) | Demonstration of basic API usage
|
[**hello_world**](hello_world.py) | Demonstration of basic API usage
|
||||||
[**echo**](echo.py) | Reply to every private text message
|
[**echobot**](echobot.py) | Echo every private text message
|
||||||
[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat)
|
[**welcome**](welcome.py) | The Welcome Bot in [@PyrogramChat](https://t.me/pyrogramchat)
|
||||||
[**history**](history.py) | Get the full message history of a chat
|
[**history**](history.py) | Get the full message history of a chat
|
||||||
[**chat_members**](chat_members.py) | Get all the members of a chat
|
[**chat_members**](chat_members.py) | Get all the members of a chat
|
||||||
[**dialogs**](dialogs.py) | Get all of your dialog chats
|
[**dialogs**](dialogs.py) | Get all of your dialog chats
|
||||||
[**inline_bots**](inline_bots.py) | Query an inline bot and send a result to a chat
|
[**using_inline_bots**](using_inline_bots.py) | Query an inline bot (as user) and send a result to a chat
|
||||||
[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots
|
[**keyboards**](keyboards.py) | Send normal and inline keyboards using regular bots
|
||||||
[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses
|
[**callback_queries**](callback_queries.py) | Handle queries coming from inline button presses
|
||||||
|
[**inline_queries**](inline_queries.py) | Handle inline queries
|
||||||
[**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided)
|
[**raw_updates**](raw_updates.py) | Handle raw updates (old, should be avoided)
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ It uses the @on_callback_query decorator to register a CallbackQueryHandler.
|
||||||
|
|
||||||
from pyrogram import Client
|
from pyrogram import Client
|
||||||
|
|
||||||
app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||||
|
|
||||||
|
|
||||||
@app.on_callback_query()
|
@app.on_callback_query()
|
||||||
def answer(client, callback_query):
|
def answer(client, callback_query):
|
||||||
callback_query.answer('Button contains: "{}"'.format(callback_query.data), show_alert=True)
|
callback_query.answer("Button contains: '{}'".format(callback_query.data), show_alert=True)
|
||||||
|
|
||||||
|
|
||||||
app.run() # Automatically start() and idle()
|
app.run() # Automatically start() and idle()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from pyrogram import Client
|
from pyrogram import Client
|
||||||
|
|
||||||
app = Client("my_count")
|
app = Client("my_account")
|
||||||
target = "pyrogramchat" # Target channel/supergroup
|
target = "pyrogramchat" # Target channel/supergroup
|
||||||
|
|
||||||
with app:
|
with app:
|
||||||
|
|
|
||||||
54
examples/inline_queries.py
Normal file
54
examples/inline_queries.py
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
"""This example shows how to handle inline queries.
|
||||||
|
Two results are generated when users invoke the bot inline mode, e.g.: @pyrogrambot hi.
|
||||||
|
It uses the @on_inline_query decorator to register an InlineQueryHandler.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from pyrogram import (
|
||||||
|
Client, InlineQueryResultArticle, InputTextMessageContent, InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
|
)
|
||||||
|
|
||||||
|
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||||
|
|
||||||
|
|
||||||
|
@app.on_inline_query()
|
||||||
|
def answer(client, inline_query):
|
||||||
|
inline_query.answer(
|
||||||
|
results=[
|
||||||
|
InlineQueryResultArticle(
|
||||||
|
id=uuid4(),
|
||||||
|
title="Installation",
|
||||||
|
input_message_content=InputTextMessageContent(
|
||||||
|
"Here's how to install **Pyrogram**"
|
||||||
|
),
|
||||||
|
url="https://docs.pyrogram.ml/start/Installation",
|
||||||
|
description="How to install Pyrogram",
|
||||||
|
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||||
|
reply_markup=InlineKeyboardMarkup(
|
||||||
|
[
|
||||||
|
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Installation")]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
InlineQueryResultArticle(
|
||||||
|
id=uuid4(),
|
||||||
|
title="Usage",
|
||||||
|
input_message_content=InputTextMessageContent(
|
||||||
|
"Here's how to use **Pyrogram**"
|
||||||
|
),
|
||||||
|
url="https://docs.pyrogram.ml/start/Usage",
|
||||||
|
description="How to use Pyrogram",
|
||||||
|
thumb_url="https://i.imgur.com/JyxrStE.png",
|
||||||
|
reply_markup=InlineKeyboardMarkup(
|
||||||
|
[
|
||||||
|
[InlineKeyboardButton("Open website", url="https://docs.pyrogram.ml/start/Usage")]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
cache_time=1
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
app.run() # Automatically start() and idle()
|
||||||
|
|
@ -10,7 +10,7 @@ like send_audio(), send_document(), send_location(), etc...
|
||||||
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
from pyrogram import Client, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
|
|
||||||
# Create a client using your bot token
|
# Create a client using your bot token
|
||||||
app = Client("123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11")
|
||||||
|
|
||||||
with app:
|
with app:
|
||||||
app.send_message(
|
app.send_message(
|
||||||
|
|
@ -33,19 +33,17 @@ with app:
|
||||||
reply_markup=InlineKeyboardMarkup(
|
reply_markup=InlineKeyboardMarkup(
|
||||||
[
|
[
|
||||||
[ # First row
|
[ # First row
|
||||||
|
|
||||||
InlineKeyboardButton( # Generates a callback query when pressed
|
InlineKeyboardButton( # Generates a callback query when pressed
|
||||||
"Button",
|
"Button",
|
||||||
callback_data=b"data"
|
callback_data=b"data" # Note how callback_data must be bytes
|
||||||
), # Note how callback_data must be bytes
|
),
|
||||||
InlineKeyboardButton( # Opens a web URL
|
InlineKeyboardButton( # Opens a web URL
|
||||||
"URL",
|
"URL",
|
||||||
url="https://docs.pyrogram.ml"
|
url="https://docs.pyrogram.ml"
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[ # Second row
|
[ # Second row
|
||||||
# Opens the inline interface
|
InlineKeyboardButton( # Opens the inline interface
|
||||||
InlineKeyboardButton(
|
|
||||||
"Choose chat",
|
"Choose chat",
|
||||||
switch_inline_query="pyrogram"
|
switch_inline_query="pyrogram"
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import shutil
|
||||||
import struct
|
import struct
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import warnings
|
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from hashlib import sha256, md5
|
from hashlib import sha256, md5
|
||||||
|
|
@ -41,6 +40,10 @@ from typing import Union, List
|
||||||
|
|
||||||
from pyrogram.api import functions, types
|
from pyrogram.api import functions, types
|
||||||
from pyrogram.api.core import Object
|
from pyrogram.api.core import Object
|
||||||
|
from pyrogram.client.handlers import DisconnectHandler
|
||||||
|
from pyrogram.client.handlers.handler import Handler
|
||||||
|
from pyrogram.client.methods.password.utils import compute_check
|
||||||
|
from pyrogram.crypto import AES
|
||||||
from pyrogram.errors import (
|
from pyrogram.errors import (
|
||||||
PhoneMigrate, NetworkMigrate, PhoneNumberInvalid,
|
PhoneMigrate, NetworkMigrate, PhoneNumberInvalid,
|
||||||
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
|
PhoneNumberUnoccupied, PhoneCodeInvalid, PhoneCodeHashEmpty,
|
||||||
|
|
@ -49,10 +52,6 @@ from pyrogram.errors import (
|
||||||
VolumeLocNotFound, UserMigrate, FileIdInvalid, ChannelPrivate, PhoneNumberOccupied,
|
VolumeLocNotFound, UserMigrate, FileIdInvalid, ChannelPrivate, PhoneNumberOccupied,
|
||||||
PasswordRecoveryNa, PasswordEmpty
|
PasswordRecoveryNa, PasswordEmpty
|
||||||
)
|
)
|
||||||
from pyrogram.client.handlers import DisconnectHandler
|
|
||||||
from pyrogram.client.handlers.handler import Handler
|
|
||||||
from pyrogram.client.methods.password.utils import compute_check
|
|
||||||
from pyrogram.crypto import AES
|
|
||||||
from pyrogram.session import Auth, Session
|
from pyrogram.session import Auth, Session
|
||||||
from .ext.utils import ainput
|
from .ext.utils import ainput
|
||||||
from .ext import utils, Syncer, BaseClient, Dispatcher
|
from .ext import utils, Syncer, BaseClient, Dispatcher
|
||||||
|
|
@ -283,10 +282,10 @@ class Client(Methods, BaseClient):
|
||||||
self.is_bot = True
|
self.is_bot = True
|
||||||
self.bot_token = self.session_name
|
self.bot_token = self.session_name
|
||||||
self.session_name = self.session_name.split(":")[0]
|
self.session_name = self.session_name.split(":")[0]
|
||||||
warnings.warn('\nYou are using a bot token as session name.\n'
|
log.warning('\nWARNING: You are using a bot token as session name!\n'
|
||||||
'It will be deprecated in next update, please use session file name to load '
|
'This usage will be deprecated soon. Please use a session file name to load '
|
||||||
'existing sessions and bot_token argument to create new sessions.',
|
'an existing session and the bot_token argument to create new sessions.\n'
|
||||||
DeprecationWarning, stacklevel=2)
|
'More info: https://docs.pyrogram.ml/start/Setup#bot-authorization\n')
|
||||||
|
|
||||||
self.load_config()
|
self.load_config()
|
||||||
await self.load_session()
|
await self.load_session()
|
||||||
|
|
|
||||||
|
|
@ -222,14 +222,16 @@ class Filters:
|
||||||
- poll"""
|
- poll"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def command(command: str or list,
|
def command(
|
||||||
prefix: str or list = "/",
|
commands: str or list,
|
||||||
separator: str = " ",
|
prefix: str or list = "/",
|
||||||
case_sensitive: bool = False):
|
separator: str = " ",
|
||||||
|
case_sensitive: bool = False
|
||||||
|
):
|
||||||
"""Filter commands, i.e.: text messages starting with "/" or any other custom prefix.
|
"""Filter commands, i.e.: text messages starting with "/" or any other custom prefix.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
command (``str`` | ``list``):
|
commands (``str`` | ``list``):
|
||||||
The command or list of commands as string the filter should look for.
|
The command or list of commands as string the filter should look for.
|
||||||
Examples: "start", ["start", "help", "settings"]. When a message text containing
|
Examples: "start", ["start", "help", "settings"]. When a message text containing
|
||||||
a command arrives, the command itself and its arguments will be stored in the *command*
|
a command arrives, the command itself and its arguments will be stored in the *command*
|
||||||
|
|
@ -249,31 +251,25 @@ class Filters:
|
||||||
Examples: when True, command="Start" would trigger /Start but not /start.
|
Examples: when True, command="Start" would trigger /Start but not /start.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def f(_, m):
|
def func(flt, message):
|
||||||
if m.text:
|
text = message.text or message.caption
|
||||||
for i in _.p:
|
|
||||||
if m.text.startswith(i):
|
if text:
|
||||||
t = m.text.split(_.s)
|
for p in flt.p:
|
||||||
c, a = t[0][len(i):], t[1:]
|
if text.startswith(p):
|
||||||
c = c if _.cs else c.lower()
|
s = text.split(flt.s)
|
||||||
m.command = ([c] + a) if c in _.c else None
|
c, a = s[0][len(p):], s[1:]
|
||||||
|
c = c if flt.cs else c.lower()
|
||||||
|
message.command = ([c] + a) if c in flt.c else None
|
||||||
break
|
break
|
||||||
|
|
||||||
return bool(m.command)
|
return bool(message.command)
|
||||||
|
|
||||||
return create(
|
commands = commands if type(commands) is list else [commands]
|
||||||
"Command",
|
commands = {c if case_sensitive else c.lower() for c in commands}
|
||||||
f,
|
prefixes = set(prefix) if prefix else {""}
|
||||||
c={command if case_sensitive
|
|
||||||
else command.lower()}
|
return create("Command", func=func, c=commands, p=prefixes, s=separator, cs=case_sensitive)
|
||||||
if not isinstance(command, list)
|
|
||||||
else {c if case_sensitive
|
|
||||||
else c.lower()
|
|
||||||
for c in command},
|
|
||||||
p=set(prefix) if prefix else {""},
|
|
||||||
s=separator,
|
|
||||||
cs=case_sensitive
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def regex(pattern, flags: int = 0):
|
def regex(pattern, flags: int = 0):
|
||||||
|
|
@ -311,21 +307,20 @@ class Filters:
|
||||||
|
|
||||||
def __init__(self, users: int or str or list = None):
|
def __init__(self, users: int or str or list = None):
|
||||||
users = [] if users is None else users if type(users) is list else [users]
|
users = [] if users is None else users if type(users) is list else [users]
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
{"me" if i in ["me", "self"] else i.lower().strip("@") if type(i) is str else i for i in users}
|
"me" if u in ["me", "self"]
|
||||||
if type(users) is list else
|
else u.lower().strip("@") if type(u) is str
|
||||||
{"me" if users in ["me", "self"] else users.lower().strip("@") if type(users) is str else users}
|
else u for u in users
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, message):
|
def __call__(self, message):
|
||||||
return bool(
|
return (message.from_user
|
||||||
message.from_user
|
and (message.from_user.id in self
|
||||||
and (message.from_user.id in self
|
or (message.from_user.username
|
||||||
or (message.from_user.username
|
and message.from_user.username.lower() in self)
|
||||||
and message.from_user.username.lower() in self)
|
or ("me" in self
|
||||||
or ("me" in self
|
and message.from_user.is_self)))
|
||||||
and message.from_user.is_self))
|
|
||||||
)
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
# noinspection PyPep8Naming
|
||||||
class chat(Filter, set):
|
class chat(Filter, set):
|
||||||
|
|
@ -343,21 +338,21 @@ class Filters:
|
||||||
|
|
||||||
def __init__(self, chats: int or str or list = None):
|
def __init__(self, chats: int or str or list = None):
|
||||||
chats = [] if chats is None else chats if type(chats) is list else [chats]
|
chats = [] if chats is None else chats if type(chats) is list else [chats]
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
{"me" if i in ["me", "self"] else i.lower().strip("@") if type(i) is str else i for i in chats}
|
"me" if c in ["me", "self"]
|
||||||
if type(chats) is list else
|
else c.lower().strip("@") if type(c) is str
|
||||||
{"me" if chats in ["me", "self"] else chats.lower().strip("@") if type(chats) is str else chats}
|
else c for c in chats
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, message):
|
def __call__(self, message):
|
||||||
return bool(
|
return (message.chat
|
||||||
message.chat
|
and (message.chat.id in self
|
||||||
and (message.chat.id in self
|
or (message.chat.username
|
||||||
or (message.chat.username
|
and message.chat.username.lower() in self)
|
||||||
and message.chat.username.lower() in self)
|
or ("me" in self
|
||||||
or ("me" in self and message.from_user
|
and message.from_user
|
||||||
and message.from_user.is_self
|
and message.from_user.is_self
|
||||||
and not message.outgoing))
|
and not message.outgoing)))
|
||||||
)
|
|
||||||
|
|
||||||
dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162))
|
dan = create("Dan", lambda _, m: bool(m.from_user and m.from_user.id == 23122162))
|
||||||
|
|
|
||||||
|
|
@ -47,15 +47,13 @@ class SetChatDescription(BaseClient):
|
||||||
"""
|
"""
|
||||||
peer = await self.resolve_peer(chat_id)
|
peer = await self.resolve_peer(chat_id)
|
||||||
|
|
||||||
if isinstance(peer, types.InputPeerChannel):
|
if isinstance(peer, (types.InputPeerChannel, types.InputPeerChat)):
|
||||||
await self.send(
|
await self.send(
|
||||||
functions.channels.EditAbout(
|
functions.messages.EditChatAbout(
|
||||||
channel=peer,
|
peer=peer,
|
||||||
about=description
|
about=description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif isinstance(peer, types.InputPeerChat):
|
|
||||||
raise ValueError("The chat_id \"{}\" belongs to a basic group".format(chat_id))
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id))
|
raise ValueError("The chat_id \"{}\" belongs to a user".format(chat_id))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pyrogram.api import types
|
from pyrogram.api import types
|
||||||
from .inline_query_result import InlineQueryResult
|
from .inline_query_result import InlineQueryResult
|
||||||
|
|
||||||
|
|
@ -61,7 +63,7 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
id: str,
|
id: Any,
|
||||||
title: str,
|
title: str,
|
||||||
input_message_content,
|
input_message_content,
|
||||||
reply_markup=None,
|
reply_markup=None,
|
||||||
|
|
@ -84,7 +86,7 @@ class InlineQueryResultArticle(InlineQueryResult):
|
||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
return types.InputBotInlineResult(
|
return types.InputBotInlineResult(
|
||||||
id=self.id,
|
id=str(self.id),
|
||||||
type=self.type,
|
type=self.type,
|
||||||
send_message=self.input_message_content.write(self.reply_markup),
|
send_message=self.input_message_content.write(self.reply_markup),
|
||||||
title=self.title,
|
title=self.title,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue