2
0
mirror of https://github.com/pyrogram/pyrogram synced 2025-08-29 05:18:10 +00:00

Add support for scheduled messages

This commit is contained in:
Dan 2019-09-07 15:56:37 +02:00
parent c3dde77274
commit 047fe37860
16 changed files with 172 additions and 42 deletions

View File

@ -23,7 +23,13 @@ from queue import Queue
from threading import Thread, Lock from threading import Thread, Lock
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,
@ -35,23 +41,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
@ -68,7 +75,16 @@ class Dispatcher:
self.update_parsers = { self.update_parsers = {
Dispatcher.MESSAGE_UPDATES: Dispatcher.MESSAGE_UPDATES:
lambda upd, usr, cht: (pyrogram.Message._parse(self.client, upd.message, usr, cht), MessageHandler), lambda upd, usr, cht: (
pyrogram.Message._parse(
self.client,
upd.message,
usr,
cht,
isinstance(upd, UpdateNewScheduledMessage)
),
MessageHandler
),
Dispatcher.DELETE_MESSAGES_UPDATES: Dispatcher.DELETE_MESSAGES_UPDATES:
lambda upd, usr, cht: (utils.parse_deleted_messages(self.client, upd), DeletedMessagesHandler), lambda upd, usr, cht: (utils.parse_deleted_messages(self.client, upd), DeletedMessagesHandler),
@ -76,13 +92,13 @@ class Dispatcher:
Dispatcher.CALLBACK_QUERY_UPDATES: Dispatcher.CALLBACK_QUERY_UPDATES:
lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler), lambda upd, usr, cht: (pyrogram.CallbackQuery._parse(self.client, upd, usr), CallbackQueryHandler),
(types.UpdateUserStatus,): (UpdateUserStatus,):
lambda upd, usr, cht: (pyrogram.User._parse_user_status(self.client, upd), UserStatusHandler), lambda upd, usr, cht: (pyrogram.User._parse_user_status(self.client, upd), UserStatusHandler),
(types.UpdateBotInlineQuery,): (UpdateBotInlineQuery,):
lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler), lambda upd, usr, cht: (pyrogram.InlineQuery._parse(self.client, upd, usr), InlineQueryHandler),
(types.UpdateMessagePoll,): (UpdateMessagePoll,):
lambda upd, usr, cht: (pyrogram.Poll._parse_update(self.client, upd), PollHandler) lambda upd, usr, cht: (pyrogram.Poll._parse_update(self.client, upd), PollHandler)
} }

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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -191,11 +196,15 @@ class SendAnimation(BaseClient):
self.save_file(animation, file_id=file.id, file_part=e.x) 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 = pyrogram.Message._parse( message = 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

@ -38,6 +38,7 @@ class SendAudio(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",
@ -95,6 +96,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.
@ -181,6 +185,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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -189,11 +194,15 @@ class SendAudio(BaseClient):
self.save_file(audio, file_id=file.id, file_part=e.x) 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 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)
) )
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,
**self.parser.parse(caption, parse_mode) **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 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

@ -33,6 +33,7 @@ class SendContact(BaseClient):
vcard: str = None, vcard: 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",
@ -67,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.
@ -92,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 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

@ -35,6 +35,7 @@ class SendDocument(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",
@ -81,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.
@ -156,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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -164,11 +169,15 @@ class SendDocument(BaseClient):
self.save_file(document, file_id=file.id, file_part=e.x) 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 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)
) )
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 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 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 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

@ -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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -159,11 +164,15 @@ class SendPhoto(BaseClient):
self.save_file(photo, file_id=file.id, file_part=e.x) 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 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)
) )
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):
self.save_file(sticker, file_id=file.id, file_part=e.x) 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 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)
) )
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 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

@ -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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -187,11 +192,15 @@ class SendVideo(BaseClient):
self.save_file(video, file_id=file.id, file_part=e.x) 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 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)
) )
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):
self.save_file(video_note, file_id=file.id, file_part=e.x) 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 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)
) )
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,
**self.parser.parse(caption, parse_mode) **self.parser.parse(caption, parse_mode)
) )
@ -159,11 +164,15 @@ class SendVoice(BaseClient):
self.save_file(voice, file_id=file.id, file_part=e.x) 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 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)
) )
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
def _parse(client, message: types.Message or types.MessageService or types.MessageEmpty, users: dict, chats: dict, def _parse(client, message: types.Message or types.MessageService or types.MessageEmpty, users: dict, chats: dict,
replies: int = 1): 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,