2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 13:27:47 +00:00

Merge develop -> asyncio

This commit is contained in:
Dan 2019-09-07 16:01:31 +02:00
commit 96334e0dba
19 changed files with 183 additions and 46 deletions

View File

@ -125,3 +125,4 @@ WEBDOCUMENT_URL_INVALID The web document URL is invalid
WEBDOCUMENT_MIME_INVALID The web document mime type is invalid WEBDOCUMENT_MIME_INVALID The web document mime type is invalid
BUTTON_URL_INVALID The button url is invalid BUTTON_URL_INVALID The button url is invalid
AUTH_BYTES_INVALID The authorization bytes are invalid AUTH_BYTES_INVALID The authorization bytes are invalid
CHANNELS_TOO_MUCH You have joined too many channels or supergroups
1 id message
125 WEBDOCUMENT_MIME_INVALID The web document mime type is invalid
126 BUTTON_URL_INVALID The button url is invalid
127 AUTH_BYTES_INVALID The authorization bytes are invalid
128 CHANNELS_TOO_MUCH You have joined too many channels or supergroups

View File

@ -21,7 +21,13 @@ import logging
from collections import OrderedDict from collections import OrderedDict
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api.types import (
UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
UpdateEditMessage, UpdateEditChannelMessage,
UpdateDeleteMessages, UpdateDeleteChannelMessages,
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery,
UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll
)
from . import utils from . import utils
from ..handlers import ( from ..handlers import (
CallbackQueryHandler, MessageHandler, DeletedMessagesHandler, CallbackQueryHandler, MessageHandler, DeletedMessagesHandler,
@ -33,23 +39,24 @@ log = logging.getLogger(__name__)
class Dispatcher: class Dispatcher:
NEW_MESSAGE_UPDATES = ( NEW_MESSAGE_UPDATES = (
types.UpdateNewMessage, UpdateNewMessage,
types.UpdateNewChannelMessage UpdateNewChannelMessage,
UpdateNewScheduledMessage
) )
EDIT_MESSAGE_UPDATES = ( EDIT_MESSAGE_UPDATES = (
types.UpdateEditMessage, UpdateEditMessage,
types.UpdateEditChannelMessage UpdateEditChannelMessage,
) )
DELETE_MESSAGES_UPDATES = ( DELETE_MESSAGES_UPDATES = (
types.UpdateDeleteMessages, UpdateDeleteMessages,
types.UpdateDeleteChannelMessages UpdateDeleteChannelMessages
) )
CALLBACK_QUERY_UPDATES = ( CALLBACK_QUERY_UPDATES = (
types.UpdateBotCallbackQuery, UpdateBotCallbackQuery,
types.UpdateInlineBotCallbackQuery UpdateInlineBotCallbackQuery
) )
MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES MESSAGE_UPDATES = NEW_MESSAGE_UPDATES + EDIT_MESSAGE_UPDATES
@ -65,7 +72,10 @@ class Dispatcher:
self.groups = OrderedDict() self.groups = OrderedDict()
async def message_parser(update, users, chats): async def message_parser(update, users, chats):
return await pyrogram.Message._parse(self.client, update.message, users, chats), MessageHandler return await pyrogram.Message._parse(
self.client, update.message, users, chats,
isinstance(update, UpdateNewScheduledMessage)
), MessageHandler
async def deleted_messages_parser(update, users, chats): async def deleted_messages_parser(update, users, chats):
return utils.parse_deleted_messages(self.client, update), DeletedMessagesHandler return utils.parse_deleted_messages(self.client, update), DeletedMessagesHandler
@ -86,9 +96,9 @@ class Dispatcher:
Dispatcher.MESSAGE_UPDATES: message_parser, Dispatcher.MESSAGE_UPDATES: message_parser,
Dispatcher.DELETE_MESSAGES_UPDATES: deleted_messages_parser, Dispatcher.DELETE_MESSAGES_UPDATES: deleted_messages_parser,
Dispatcher.CALLBACK_QUERY_UPDATES: callback_query_parser, Dispatcher.CALLBACK_QUERY_UPDATES: callback_query_parser,
(types.UpdateUserStatus,): user_status_parser, (UpdateUserStatus,): user_status_parser,
(types.UpdateBotInlineQuery,): inline_query_parser, (UpdateBotInlineQuery,): inline_query_parser,
(types.UpdateMessagePoll,): poll_parser (UpdateMessagePoll,): poll_parser
} }
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple} self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}

View File

@ -208,6 +208,12 @@ class Filters:
*animation*, *voice*, *video_note*, *contact*, *location*, *venue*, *poll*. *animation*, *voice*, *video_note*, *contact*, *location*, *venue*, *poll*.
""" """
scheduled = create(lambda _, m: bool(m.scheduled), "ScheduledFilter")
"""Filter messages that have been scheduled (not yet sent)."""
from_scheduled = create(lambda _, m: bool(m.from_scheduled), "FromScheduledFilter")
"""Filter new automatically sent messages that were previously scheduled."""
@staticmethod @staticmethod
def command( def command(
commands: str or list, commands: str or list,

View File

@ -39,6 +39,7 @@ class SendAnimation(BaseClient):
thumb: str = None, thumb: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -98,6 +99,9 @@ class SendAnimation(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -183,6 +187,7 @@ class SendAnimation(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -191,11 +196,15 @@ class SendAnimation(BaseClient):
await self.save_file(animation, file_id=file.id, file_part=e.x) await self.save_file(animation, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
message = await pyrogram.Message._parse( message = await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
if unsave: if unsave:

View File

@ -37,6 +37,7 @@ class SendAudio(BaseClient):
title: str = None, title: str = None,
thumb: str = None, disable_notification: bool = None, thumb: str = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -94,6 +95,9 @@ class SendAudio(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -180,6 +184,7 @@ class SendAudio(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -188,11 +193,15 @@ class SendAudio(BaseClient):
await self.save_file(audio, file_id=file.id, file_part=e.x) await self.save_file(audio, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -32,6 +32,7 @@ class SendCachedMedia(BaseClient):
parse_mode: Union[str, None] = object, parse_mode: Union[str, None] = object,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -72,6 +73,9 @@ class SendCachedMedia(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -92,15 +96,17 @@ class SendCachedMedia(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -30,8 +30,10 @@ class SendContact(BaseClient):
phone_number: str, phone_number: str,
first_name: str, first_name: str,
last_name: str = None, last_name: str = None,
vcard: str = None, disable_notification: bool = None, vcard: str = None,
disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -66,6 +68,9 @@ class SendContact(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -91,14 +96,16 @@ class SendContact(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None reply_markup=reply_markup.write() if reply_markup else None
) )
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -30,10 +30,12 @@ class SendDocument(BaseClient):
self, self,
chat_id: Union[int, str], chat_id: Union[int, str],
document: str, document: str,
thumb: str = None, caption: str = "", thumb: str = None,
caption: str = "",
parse_mode: Union[str, None] = object, parse_mode: Union[str, None] = object,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -80,6 +82,9 @@ class SendDocument(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -155,6 +160,7 @@ class SendDocument(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -163,11 +169,15 @@ class SendDocument(BaseClient):
await self.save_file(document, file_id=file.id, file_part=e.x) await self.save_file(document, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -31,6 +31,7 @@ class SendLocation(BaseClient):
longitude: float, longitude: float,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -59,6 +60,9 @@ class SendLocation(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -84,14 +88,16 @@ class SendLocation(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None reply_markup=reply_markup.write() if reply_markup else None
) )
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -32,6 +32,7 @@ class SendMessage(BaseClient):
disable_web_page_preview: bool = None, disable_web_page_preview: bool = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -67,6 +68,9 @@ class SendMessage(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -121,6 +125,7 @@ class SendMessage(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
message=message, message=message,
entities=entities entities=entities
@ -151,9 +156,10 @@ class SendMessage(BaseClient):
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -35,6 +35,7 @@ class SendPhoto(BaseClient):
ttl_seconds: int = None, ttl_seconds: int = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -80,6 +81,9 @@ class SendPhoto(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -151,6 +155,7 @@ class SendPhoto(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -159,11 +164,15 @@ class SendPhoto(BaseClient):
await self.save_file(photo, file_id=file.id, file_part=e.x) await self.save_file(photo, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -31,6 +31,7 @@ class SendPoll(BaseClient):
options: List[str], options: List[str],
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -59,6 +60,9 @@ class SendPoll(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -88,14 +92,16 @@ class SendPoll(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None reply_markup=reply_markup.write() if reply_markup else None
) )
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return pyrogram.Message._parse( return pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -32,6 +32,7 @@ class SendSticker(BaseClient):
sticker: str, sticker: str,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -62,6 +63,9 @@ class SendSticker(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -129,6 +133,7 @@ class SendSticker(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
message="" message=""
) )
@ -137,11 +142,15 @@ class SendSticker(BaseClient):
await self.save_file(sticker, file_id=file.id, file_part=e.x) await self.save_file(sticker, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -35,6 +35,7 @@ class SendVenue(BaseClient):
foursquare_type: str = "", foursquare_type: str = "",
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -76,6 +77,9 @@ class SendVenue(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -108,14 +112,16 @@ class SendVenue(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None reply_markup=reply_markup.write() if reply_markup else None
) )
) )
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )

View File

@ -39,6 +39,7 @@ class SendVideo(BaseClient):
supports_streaming: bool = True, supports_streaming: bool = True,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -98,6 +99,9 @@ class SendVideo(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message. If the message is a reply, ID of the original message.
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -179,6 +183,7 @@ class SendVideo(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -187,11 +192,15 @@ class SendVideo(BaseClient):
await self.save_file(video, file_id=file.id, file_part=e.x) await self.save_file(video, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -35,6 +35,7 @@ class SendVideoNote(BaseClient):
thumb: str = None, thumb: str = None,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -77,6 +78,9 @@ class SendVideoNote(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -147,6 +151,7 @@ class SendVideoNote(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
message="" message=""
) )
@ -155,11 +160,15 @@ class SendVideoNote(BaseClient):
await self.save_file(video_note, file_id=file.id, file_part=e.x) await self.save_file(video_note, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -35,6 +35,7 @@ class SendVoice(BaseClient):
duration: int = 0, duration: int = 0,
disable_notification: bool = None, disable_notification: bool = None,
reply_to_message_id: int = None, reply_to_message_id: int = None,
schedule_date: int = None,
reply_markup: Union[ reply_markup: Union[
"pyrogram.InlineKeyboardMarkup", "pyrogram.InlineKeyboardMarkup",
"pyrogram.ReplyKeyboardMarkup", "pyrogram.ReplyKeyboardMarkup",
@ -78,6 +79,9 @@ class SendVoice(BaseClient):
reply_to_message_id (``int``, *optional*): reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message If the message is a reply, ID of the original message
schedule_date (``int``, *optional*):
Date when the message will be automatically sent. Unix time.
reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*):
Additional interface options. An object for an inline keyboard, custom reply keyboard, Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user. instructions to remove reply keyboard or to force a reply from the user.
@ -151,6 +155,7 @@ class SendVoice(BaseClient):
silent=disable_notification or None, silent=disable_notification or None,
reply_to_msg_id=reply_to_message_id, reply_to_msg_id=reply_to_message_id,
random_id=self.rnd_id(), random_id=self.rnd_id(),
schedule_date=schedule_date,
reply_markup=reply_markup.write() if reply_markup else None, reply_markup=reply_markup.write() if reply_markup else None,
**await self.parser.parse(caption, parse_mode) **await self.parser.parse(caption, parse_mode)
) )
@ -159,11 +164,15 @@ class SendVoice(BaseClient):
await self.save_file(voice, file_id=file.id, file_part=e.x) await self.save_file(voice, file_id=file.id, file_part=e.x)
else: else:
for i in r.updates: for i in r.updates:
if isinstance(i, (types.UpdateNewMessage, types.UpdateNewChannelMessage)): if isinstance(
i,
(types.UpdateNewMessage, types.UpdateNewChannelMessage, types.UpdateNewScheduledMessage)
):
return await pyrogram.Message._parse( return await pyrogram.Message._parse(
self, i.message, self, i.message,
{i.id: i for i in r.users}, {i.id: i for i in r.users},
{i.id: i for i in r.chats} {i.id: i for i in r.chats},
is_scheduled=isinstance(i, types.UpdateNewScheduledMessage)
) )
except BaseClient.StopTransmission: except BaseClient.StopTransmission:
return None return None

View File

@ -282,6 +282,8 @@ class Message(Object, Update):
mentioned: bool = None, mentioned: bool = None,
empty: bool = None, empty: bool = None,
service: bool = None, service: bool = None,
scheduled: bool = None,
from_scheduled: bool = None,
media: bool = None, media: bool = None,
edit_date: int = None, edit_date: int = None,
media_group_id: str = None, media_group_id: str = None,
@ -344,6 +346,8 @@ class Message(Object, Update):
self.mentioned = mentioned self.mentioned = mentioned
self.empty = empty self.empty = empty
self.service = service self.service = service
self.scheduled = scheduled
self.from_scheduled = from_scheduled
self.media = media self.media = media
self.edit_date = edit_date self.edit_date = edit_date
self.media_group_id = media_group_id self.media_group_id = media_group_id
@ -387,7 +391,7 @@ class Message(Object, Update):
@staticmethod @staticmethod
async def _parse(client, message: types.Message or types.MessageService or types.MessageEmpty, users: dict, async def _parse(client, message: types.Message or types.MessageService or types.MessageEmpty, users: dict,
chats: dict, replies: int = 1): chats: dict, is_scheduled: bool = False, replies: int = 1):
if isinstance(message, types.MessageEmpty): if isinstance(message, types.MessageEmpty):
return Message(message_id=message.id, empty=True, client=client) return Message(message_id=message.id, empty=True, client=client)
@ -620,6 +624,8 @@ class Message(Object, Update):
forward_signature=forward_signature, forward_signature=forward_signature,
forward_date=forward_date, forward_date=forward_date,
mentioned=message.mentioned, mentioned=message.mentioned,
scheduled=is_scheduled,
from_scheduled=message.from_scheduled,
media=bool(media) or None, media=bool(media) or None,
edit_date=message.edit_date, edit_date=message.edit_date,
media_group_id=message.grouped_id, media_group_id=message.grouped_id,

View File

@ -20,6 +20,7 @@ from struct import pack
import pyrogram import pyrogram
from pyrogram.api import types from pyrogram.api import types
from pyrogram.errors import PeerIdInvalid
from ..object import Object from ..object import Object
from ...ext.utils import encode from ...ext.utils import encode
@ -58,7 +59,10 @@ class ChatPhoto(Object):
loc_small = chat_photo.photo_small loc_small = chat_photo.photo_small
loc_big = chat_photo.photo_big loc_big = chat_photo.photo_big
try:
peer = client.resolve_peer(peer_id) peer = client.resolve_peer(peer_id)
except PeerIdInvalid:
return None
if isinstance(peer, types.InputPeerUser): if isinstance(peer, types.InputPeerUser):
peer_id = peer.user_id peer_id = peer.user_id