mirror of
https://github.com/TeamPGM/pyrogram.git
synced 2024-11-27 16:45:19 +00:00
Add support for stories
This commit is contained in:
parent
f2b417a16d
commit
3a01fea2c2
@ -26,7 +26,7 @@ from pyrogram import utils
|
||||
from pyrogram.handlers import (
|
||||
CallbackQueryHandler, MessageHandler, EditedMessageHandler, DeletedMessagesHandler,
|
||||
UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler,
|
||||
ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler
|
||||
ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler, StoryHandler
|
||||
)
|
||||
from pyrogram.raw.types import (
|
||||
UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
|
||||
@ -35,7 +35,7 @@ from pyrogram.raw.types import (
|
||||
UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery,
|
||||
UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll,
|
||||
UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant,
|
||||
UpdateBotChatInviteRequester
|
||||
UpdateBotChatInviteRequester, UpdateStory
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -52,6 +52,7 @@ class Dispatcher:
|
||||
POLL_UPDATES = (UpdateMessagePoll,)
|
||||
CHOSEN_INLINE_RESULT_UPDATES = (UpdateBotInlineSend,)
|
||||
CHAT_JOIN_REQUEST_UPDATES = (UpdateBotChatInviteRequester,)
|
||||
NEW_STORY_UPDATES = (UpdateStory,)
|
||||
|
||||
def __init__(self, client: "pyrogram.Client"):
|
||||
self.client = client
|
||||
@ -127,6 +128,12 @@ class Dispatcher:
|
||||
ChatJoinRequestHandler
|
||||
)
|
||||
|
||||
async def story_parser(update, _, __):
|
||||
return (
|
||||
await pyrogram.types.Story._parse(self.client, update.story, update.peer),
|
||||
StoryHandler
|
||||
)
|
||||
|
||||
self.update_parsers = {
|
||||
Dispatcher.NEW_MESSAGE_UPDATES: message_parser,
|
||||
Dispatcher.EDIT_MESSAGE_UPDATES: edited_message_parser,
|
||||
@ -137,7 +144,8 @@ class Dispatcher:
|
||||
Dispatcher.POLL_UPDATES: poll_parser,
|
||||
Dispatcher.CHOSEN_INLINE_RESULT_UPDATES: chosen_inline_result_parser,
|
||||
Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser,
|
||||
Dispatcher.CHAT_JOIN_REQUEST_UPDATES: chat_join_request_parser
|
||||
Dispatcher.CHAT_JOIN_REQUEST_UPDATES: chat_join_request_parser,
|
||||
Dispatcher.NEW_STORY_UPDATES: story_parser
|
||||
}
|
||||
|
||||
self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}
|
||||
|
@ -29,21 +29,25 @@ from .next_code_type import NextCodeType
|
||||
from .parse_mode import ParseMode
|
||||
from .poll_type import PollType
|
||||
from .sent_code_type import SentCodeType
|
||||
from .stories_privacy import StoriesPrivacy
|
||||
from .stories_privacy_rules import StoriesPrivacyRules
|
||||
from .user_status import UserStatus
|
||||
|
||||
__all__ = [
|
||||
'ChatAction',
|
||||
'ChatEventAction',
|
||||
'ChatMemberStatus',
|
||||
'ChatMembersFilter',
|
||||
'ChatType',
|
||||
'MessageEntityType',
|
||||
'MessageMediaType',
|
||||
'MessageServiceType',
|
||||
'MessagesFilter',
|
||||
'NextCodeType',
|
||||
'ParseMode',
|
||||
'PollType',
|
||||
'SentCodeType',
|
||||
'ChatAction',
|
||||
'ChatEventAction',
|
||||
'ChatMemberStatus',
|
||||
'ChatMembersFilter',
|
||||
'ChatType',
|
||||
'MessageEntityType',
|
||||
'MessageMediaType',
|
||||
'MessageServiceType',
|
||||
'MessagesFilter',
|
||||
'NextCodeType',
|
||||
'ParseMode',
|
||||
'PollType',
|
||||
'SentCodeType',
|
||||
'StoriesPrivacy',
|
||||
'StoriesPrivacyRules',
|
||||
'UserStatus'
|
||||
]
|
||||
|
@ -68,3 +68,6 @@ class MessageMediaType(AutoName):
|
||||
|
||||
GAME = auto()
|
||||
"Game media"
|
||||
|
||||
STORY = auto()
|
||||
"Story media"
|
||||
|
39
pyrogram/enums/stories_privacy.py
Normal file
39
pyrogram/enums/stories_privacy.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from enum import auto
|
||||
from .auto_name import AutoName
|
||||
|
||||
|
||||
class StoriesPrivacy(AutoName):
|
||||
"""Stories privacy type enumeration used in :obj:`~pyrogram.method.SendStory`."""
|
||||
|
||||
PUBLIC = auto()
|
||||
"Public stories"
|
||||
|
||||
CLOSE_FRIENDS = auto()
|
||||
"Close friends stories"
|
||||
|
||||
CONTACTS = auto()
|
||||
"Contacts only stories"
|
||||
|
||||
PRIVATE = auto()
|
||||
"Private stories"
|
||||
|
||||
NO_CONTACTS = auto()
|
||||
"Hide stories from contacts"
|
39
pyrogram/enums/stories_privacy_rules.py
Normal file
39
pyrogram/enums/stories_privacy_rules.py
Normal file
@ -0,0 +1,39 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from enum import auto
|
||||
from .auto_name import AutoName
|
||||
|
||||
|
||||
class StoriesPrivacyRules(AutoName):
|
||||
"""Stories privacy rules type enumeration used in :obj:`~pyrogram.method.SendStory`."""
|
||||
|
||||
PUBLIC = auto()
|
||||
"Public stories"
|
||||
|
||||
CLOSE_FRIENDS = auto()
|
||||
"Close friends stories"
|
||||
|
||||
CONTACTS = auto()
|
||||
"Contacts only stories"
|
||||
|
||||
PRIVATE = auto()
|
||||
"Private stories"
|
||||
|
||||
NO_CONTACTS = auto()
|
||||
"Hide stories from contacts"
|
@ -27,4 +27,5 @@ from .inline_query_handler import InlineQueryHandler
|
||||
from .message_handler import MessageHandler
|
||||
from .poll_handler import PollHandler
|
||||
from .raw_update_handler import RawUpdateHandler
|
||||
from .story_handler import StoryHandler
|
||||
from .user_status_handler import UserStatusHandler
|
||||
|
49
pyrogram/handlers/story_handler.py
Normal file
49
pyrogram/handlers/story_handler.py
Normal file
@ -0,0 +1,49 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Callable
|
||||
|
||||
from .handler import Handler
|
||||
|
||||
|
||||
class StoryHandler(Handler):
|
||||
"""The Story handler class. Used to handle new stories.
|
||||
It is intended to be used with :meth:`~pyrogram.Client.add_handler`
|
||||
|
||||
For a nicer way to register this handler, have a look at the
|
||||
:meth:`~pyrogram.Client.on_story` decorator.
|
||||
|
||||
Parameters:
|
||||
callback (``Callable``):
|
||||
Pass a function that will be called when a new Stories arrives. It takes *(client, story)*
|
||||
as positional arguments (look at the section below for a detailed description).
|
||||
|
||||
filters (:obj:`Filters`):
|
||||
Pass one or more filters to allow only a subset of stories to be passed
|
||||
in your callback function.
|
||||
|
||||
Other parameters:
|
||||
client (:obj:`~pyrogram.Client`):
|
||||
The Client itself, useful when you want to call other API methods inside the story handler.
|
||||
|
||||
story (:obj:`~pyrogram.types.Story`):
|
||||
The received story.
|
||||
"""
|
||||
|
||||
def __init__(self, callback: Callable, filters=None):
|
||||
super().__init__(callback, filters)
|
@ -26,6 +26,7 @@ from .invite_links import InviteLinks
|
||||
from .messages import Messages
|
||||
from .password import Password
|
||||
from .users import Users
|
||||
from .stories import Stories
|
||||
from .utilities import Utilities
|
||||
|
||||
|
||||
@ -37,6 +38,7 @@ class Methods(
|
||||
Password,
|
||||
Chats,
|
||||
Users,
|
||||
Stories,
|
||||
Messages,
|
||||
Decorators,
|
||||
Utilities,
|
||||
|
@ -28,6 +28,7 @@ from .on_message import OnMessage
|
||||
from .on_poll import OnPoll
|
||||
from .on_raw_update import OnRawUpdate
|
||||
from .on_user_status import OnUserStatus
|
||||
from .on_story import OnStory
|
||||
|
||||
|
||||
class Decorators(
|
||||
@ -42,6 +43,7 @@ class Decorators(
|
||||
OnPoll,
|
||||
OnChosenInlineResult,
|
||||
OnChatMemberUpdated,
|
||||
OnChatJoinRequest
|
||||
OnChatJoinRequest,
|
||||
OnStory
|
||||
):
|
||||
pass
|
||||
|
61
pyrogram/methods/decorators/on_story.py
Normal file
61
pyrogram/methods/decorators/on_story.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Callable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.filters import Filter
|
||||
|
||||
|
||||
class OnStory:
|
||||
def on_story(
|
||||
self=None,
|
||||
filters=None,
|
||||
group: int = 0
|
||||
) -> Callable:
|
||||
"""Decorator for handling new stories.
|
||||
|
||||
This does the same thing as :meth:`~pyrogram.Client.add_handler` using the
|
||||
:obj:`~pyrogram.handlers.StoryHandler`.
|
||||
|
||||
Parameters:
|
||||
filters (:obj:`~pyrogram.filters`, *optional*):
|
||||
Pass one or more filters to allow only a subset of stories to be passed
|
||||
in your function.
|
||||
|
||||
group (``int``, *optional*):
|
||||
The group identifier, defaults to 0.
|
||||
"""
|
||||
|
||||
def decorator(func: Callable) -> Callable:
|
||||
if isinstance(self, pyrogram.Client):
|
||||
self.add_handler(pyrogram.handlers.StoryHandler(func, filters), group)
|
||||
elif isinstance(self, Filter) or self is None:
|
||||
if not hasattr(func, "handlers"):
|
||||
func.handlers = []
|
||||
|
||||
func.handlers.append(
|
||||
(
|
||||
pyrogram.handlers.StoryHandler(func, self),
|
||||
group if filters is None else filters
|
||||
)
|
||||
)
|
||||
|
||||
return func
|
||||
|
||||
return decorator
|
@ -48,6 +48,7 @@ class SendAnimation:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -123,6 +124,9 @@ class SendAnimation:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -230,12 +234,13 @@ class SendAnimation:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -46,6 +46,7 @@ class SendAudio:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -116,6 +117,9 @@ class SendAudio:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -217,12 +221,13 @@ class SendAudio:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -36,6 +36,7 @@ class SendCachedMedia:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -84,6 +85,9 @@ class SendCachedMedia:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -102,12 +106,13 @@ class SendCachedMedia:
|
||||
|
||||
await app.send_cached_media("me", file_id)
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=utils.get_input_media_from_file_id(file_id),
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -32,6 +32,7 @@ class SendDice:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -69,6 +70,9 @@ class SendDice:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -94,12 +98,13 @@ class SendDice:
|
||||
# Send a basketball
|
||||
await app.send_dice(chat_id, "🏀")
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=raw.types.InputMediaDice(emoticon=emoji),
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -44,6 +44,7 @@ class SendDocument:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -108,6 +109,9 @@ class SendDocument:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -195,12 +199,13 @@ class SendDocument:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -45,6 +45,7 @@ class SendMediaGroup:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
) -> List["types.Message"]:
|
||||
@ -72,6 +73,9 @@ class SendMediaGroup:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -395,12 +399,13 @@ class SendMediaGroup:
|
||||
)
|
||||
)
|
||||
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMultiMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
multi_media=multi_media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content
|
||||
),
|
||||
|
@ -35,6 +35,7 @@ class SendMessage:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -78,6 +79,9 @@ class SendMessage:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -128,12 +132,13 @@ class SendMessage:
|
||||
|
||||
message, entities = (await utils.parse_text_entities(self, text, parse_mode, entities)).values()
|
||||
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMessage(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
no_webpage=disable_web_page_preview or None,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
reply_markup=await reply_markup.write(self) if reply_markup else None,
|
||||
|
@ -42,6 +42,7 @@ class SendPhoto:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -99,6 +100,9 @@ class SendPhoto:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -179,12 +183,13 @@ class SendPhoto:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -38,6 +38,7 @@ class SendSticker:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -77,6 +78,9 @@ class SendSticker:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -154,12 +158,13 @@ class SendSticker:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -49,6 +49,7 @@ class SendVideo:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -129,6 +130,9 @@ class SendVideo:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message.
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -236,12 +240,13 @@ class SendVideo:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -40,6 +40,7 @@ class SendVideoNote:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -91,6 +92,9 @@ class SendVideoNote:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -178,12 +182,13 @@ class SendVideoNote:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
@ -42,6 +42,7 @@ class SendVoice:
|
||||
disable_notification: bool = None,
|
||||
message_thread_id: int = None,
|
||||
reply_to_message_id: int = None,
|
||||
reply_to_story_id: int = None,
|
||||
schedule_date: datetime = None,
|
||||
protect_content: bool = None,
|
||||
reply_markup: Union[
|
||||
@ -94,6 +95,9 @@ class SendVoice:
|
||||
reply_to_message_id (``int``, *optional*):
|
||||
If the message is a reply, ID of the original message
|
||||
|
||||
reply_to_story_id (``int``, *optional*):
|
||||
Unique identifier for the target story.
|
||||
|
||||
schedule_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date when the message will be automatically sent.
|
||||
|
||||
@ -179,12 +183,13 @@ class SendVoice:
|
||||
|
||||
while True:
|
||||
try:
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.messages.SendMedia(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
peer=peer,
|
||||
media=media,
|
||||
silent=disable_notification or None,
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id),
|
||||
reply_to=utils.get_reply_to(reply_to_message_id, message_thread_id, peer, reply_to_story_id),
|
||||
random_id=self.rnd_id(),
|
||||
schedule_date=utils.datetime_to_timestamp(schedule_date),
|
||||
noforwards=protect_content,
|
||||
|
46
pyrogram/methods/stories/__init__.py
Normal file
46
pyrogram/methods/stories/__init__.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from .apply_boost import ApplyBoost
|
||||
from .delete_stories import DeleteStories
|
||||
from .edit_story import EditStory
|
||||
from .export_story_link import ExportStoryLink
|
||||
from .get_all_stories import GetAllStories
|
||||
from .get_peer_stories import GetPeerStories
|
||||
from .get_stories_archive import GetStoriesArchive
|
||||
from .get_stories import GetStories
|
||||
from .increment_story_views import IncrementStoryViews
|
||||
from .read_stories import ReadStories
|
||||
from .send_story import SendStory
|
||||
from .toggle_stories_pinned import ToggleStoriesPinned
|
||||
|
||||
class Stories(
|
||||
ApplyBoost,
|
||||
DeleteStories,
|
||||
EditStory,
|
||||
ExportStoryLink,
|
||||
GetAllStories,
|
||||
GetPeerStories,
|
||||
GetStories,
|
||||
GetStoriesArchive,
|
||||
IncrementStoryViews,
|
||||
ReadStories,
|
||||
SendStory,
|
||||
ToggleStoriesPinned
|
||||
):
|
||||
pass
|
53
pyrogram/methods/stories/apply_boost.py
Normal file
53
pyrogram/methods/stories/apply_boost.py
Normal file
@ -0,0 +1,53 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
|
||||
|
||||
class ApplyBoost:
|
||||
async def apply_boost(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
) -> bool:
|
||||
"""Apply boost
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
|
||||
Returns:
|
||||
``str``: On success, a bool is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Apply boost to chat id
|
||||
app.apply_boost(chat_id)
|
||||
"""
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.ApplyBoost(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
)
|
||||
)
|
||||
|
||||
return r
|
67
pyrogram/methods/stories/delete_stories.py
Normal file
67
pyrogram/methods/stories/delete_stories.py
Normal file
@ -0,0 +1,67 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List, Union, Iterable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class DeleteStories:
|
||||
async def delete_stories(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
story_ids: Union[int, Iterable[int]],
|
||||
) -> List[int]:
|
||||
"""Delete stories.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
story_ids (``int`` | ``list``):
|
||||
Unique identifier (int) or list of unique identifiers (list of int) for the target stories.
|
||||
|
||||
Returns:
|
||||
List of ``int``: List of deleted stories IDs
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Delete a single story
|
||||
app.delete_stories(chat_id, 1)
|
||||
|
||||
# Delete multiple stories
|
||||
app.delete_stories(chat_id, [1, 2])
|
||||
"""
|
||||
is_iterable = not isinstance(story_ids, int)
|
||||
ids = list(story_ids) if is_iterable else [story_ids]
|
||||
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.DeleteStories(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=ids
|
||||
)
|
||||
)
|
||||
|
||||
return types.List(r)
|
233
pyrogram/methods/stories/edit_story.py
Normal file
233
pyrogram/methods/stories/edit_story.py
Normal file
@ -0,0 +1,233 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import re
|
||||
from typing import List, Union, BinaryIO, Callable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import enums, raw, types, utils, StopTransmission
|
||||
from pyrogram.errors import FilePartMissing
|
||||
|
||||
class EditStory:
|
||||
async def edit_story(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
story_id: int,
|
||||
media: Union[str, BinaryIO] = None,
|
||||
caption: str = None,
|
||||
duration: int = 0,
|
||||
width: int = 0,
|
||||
height: int = 0,
|
||||
thumb: Union[str, BinaryIO] = None,
|
||||
supports_streaming: bool = True,
|
||||
file_name: str = None,
|
||||
privacy: "enums.StoriesPrivacyRules" = None,
|
||||
allowed_users: List[int] = None,
|
||||
denied_users: List[int] = None,
|
||||
allowed_chats: List[int] = None,
|
||||
denied_chats: List[int] = None,
|
||||
parse_mode: "enums.ParseMode" = None,
|
||||
caption_entities: List["types.MessageEntity"] = None,
|
||||
progress: Callable = None,
|
||||
progress_args: tuple = ()
|
||||
) -> "types.Story":
|
||||
"""Edit story.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Note: You must pass one of following paramater *animation*, *photo*, *video*
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
media (``str`` | ``BinaryIO``, *optional*):
|
||||
Video or photo to send.
|
||||
Pass a file_id as string to send a animation that exists on the Telegram servers,
|
||||
pass an HTTP URL as a string for Telegram to get a animation from the Internet,
|
||||
pass a file path as string to upload a new animation that exists on your local machine, or
|
||||
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
|
||||
|
||||
caption (``str``, *optional*):
|
||||
Story caption, 0-1024 characters.
|
||||
|
||||
duration (``int``, *optional*):
|
||||
Duration of sent video in seconds.
|
||||
|
||||
width (``int``, *optional*):
|
||||
Video width.
|
||||
|
||||
height (``int``, *optional*):
|
||||
Video height.
|
||||
|
||||
thumb (``str`` | ``BinaryIO``, *optional*):
|
||||
Thumbnail of the video sent.
|
||||
The thumbnail should be in JPEG format and less than 200 KB in size.
|
||||
A thumbnail's width and height should not exceed 320 pixels.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
|
||||
privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*):
|
||||
Story privacy.
|
||||
Defaults to :obj:`~pyrogram.enums.StoriesPrivacyRules.PUBLIC`
|
||||
|
||||
allowed_chats (List of ``int``, *optional*):
|
||||
List of chat_id which participant allowed to view the story.
|
||||
|
||||
denied_chats (List of ``int``, *optional*):
|
||||
List of chat_id which participant denied to view the story.
|
||||
|
||||
allowed_users (List of ``int``, *optional*):
|
||||
List of user_id whos allowed to view the story.
|
||||
|
||||
denied_users (List of ``int``, *optional*):
|
||||
List of user_id whos denied to view the story.
|
||||
|
||||
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
|
||||
By default, texts are parsed using both Markdown and HTML styles.
|
||||
You can combine both syntaxes together.
|
||||
|
||||
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in the caption, which can be specified instead of *parse_mode*.
|
||||
|
||||
progress (``Callable``, *optional*):
|
||||
Pass a callback function to view the file transmission progress.
|
||||
The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
|
||||
detailed description) and will be called back each time a new file chunk has been successfully
|
||||
transmitted.
|
||||
|
||||
progress_args (``tuple``, *optional*):
|
||||
Extra custom arguments for the progress callback function.
|
||||
You can pass anything you need to be available in the progress callback scope; for example, a Message
|
||||
object or a Client instance in order to edit the message with the updated progress status.
|
||||
|
||||
Returns:
|
||||
:obj:`~pyrogram.types.Story` a single story is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Send new photo story
|
||||
photo_id = "abcd12345"
|
||||
await app.send_story(photo=photo_id, caption='Hello guys.')
|
||||
|
||||
Raises:
|
||||
ValueError: In case of invalid arguments.
|
||||
"""
|
||||
# TODO: media_areas
|
||||
|
||||
if privacy:
|
||||
privacy_rules = [types.StoriesPrivacyRules(type=privacy)]
|
||||
|
||||
message, entities = (await utils.parse_text_entities(self, caption, parse_mode, caption_entities)).values()
|
||||
|
||||
try:
|
||||
if isinstance(media, str):
|
||||
if os.path.isfile(media):
|
||||
thumb = await self.save_file(thumb)
|
||||
file = await self.save_file(media, progress=progress, progress_args=progress_args)
|
||||
mime_type = self.guess_mime_type(file.name)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaUploadedDocument(
|
||||
mime_type=mime_type,
|
||||
file=file,
|
||||
thumb=thumb,
|
||||
attributes=[
|
||||
raw.types.DocumentAttributeVideo(
|
||||
duration=duration,
|
||||
w=width,
|
||||
h=height,
|
||||
),
|
||||
raw.types.DocumentAttributeFilename(file_name=file_name or os.path.basename(media))
|
||||
]
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaUploadedPhoto(
|
||||
file=file,
|
||||
)
|
||||
elif re.match("^https?://", media):
|
||||
mime_type = self.guess_mime_type(media)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaDocumentExternal(
|
||||
url=media,
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaPhotoExternal(
|
||||
url=media,
|
||||
)
|
||||
else:
|
||||
media = utils.get_input_media_from_file_id(media)
|
||||
else:
|
||||
thumb = await self.save_file(thumb)
|
||||
file = await self.save_file(media, progress=progress, progress_args=progress_args)
|
||||
mime_type = self.guess_mime_type(file.name)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaUploadedDocument(
|
||||
mime_type=mime_type,
|
||||
file=file,
|
||||
thumb=thumb,
|
||||
attributes=[
|
||||
raw.types.DocumentAttributeVideo(
|
||||
supports_streaming=supports_streaming or None,
|
||||
duration=duration,
|
||||
w=width,
|
||||
h=height,
|
||||
),
|
||||
raw.types.DocumentAttributeFilename(file_name=file_name or media.name)
|
||||
]
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaUploadedPhoto(
|
||||
file=file,
|
||||
)
|
||||
|
||||
if allowed_chats:
|
||||
chats = [await self.resolve_peer(chat_id) for chat_id in allowed_chats]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueAllowChatParticipants(chats=chats))
|
||||
if denied_chats:
|
||||
chats = [await self.resolve_peer(chat_id) for chat_id in denied_chats]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueDisallowChatParticipants(chats=chats))
|
||||
if allowed_users:
|
||||
users = [await self.resolve_peer(user_id) for user_id in allowed_users]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueAllowUsers(users=users))
|
||||
if denied_users:
|
||||
users = [await self.resolve_peer(user_id) for user_id in denied_users]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueDisallowUsers(users=users))
|
||||
|
||||
while True:
|
||||
try:
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.EditStory(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=story_id,
|
||||
media=media,
|
||||
caption=message,
|
||||
entities=entities,
|
||||
privacy_rules=privacy_rules,
|
||||
)
|
||||
)
|
||||
except FilePartMissing as e:
|
||||
await self.save_file(media, file_id=file.id, file_part=e.value)
|
||||
else:
|
||||
for i in r.updates:
|
||||
if isinstance(i, raw.types.UpdateStory):
|
||||
return await types.Story._parse(self, i.story, i.peer)
|
||||
except StopTransmission:
|
||||
return None
|
61
pyrogram/methods/stories/export_story_link.py
Normal file
61
pyrogram/methods/stories/export_story_link.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class ExportStoryLink:
|
||||
async def export_story_link(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
story_id: int,
|
||||
) -> "types.ExportedStoryLink":
|
||||
"""Export a story link.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
story_id (``int``):
|
||||
Unique identifier of the target story.
|
||||
|
||||
Returns:
|
||||
``str``: On success, a link to the exported story is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Export a story link
|
||||
link = app.export_story_link(chat_id, 1)
|
||||
"""
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.ExportStoryLink(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=story_id
|
||||
)
|
||||
)
|
||||
|
||||
return r.link
|
61
pyrogram/methods/stories/get_all_stories.py
Normal file
61
pyrogram/methods/stories/get_all_stories.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import AsyncGenerator, Union, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class GetAllStories:
|
||||
async def get_all_stories(
|
||||
self: "pyrogram.Client",
|
||||
next: Optional[bool] = None,
|
||||
hidden: Optional[bool] = None,
|
||||
state: Optional[str] = None,
|
||||
) -> Optional[AsyncGenerator["types.Story", None]]:
|
||||
"""Get all active stories.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Returns:
|
||||
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Get all active story
|
||||
async for story in app.get_all_stories():
|
||||
print(story)
|
||||
|
||||
Raises:
|
||||
ValueError: In case of invalid arguments.
|
||||
"""
|
||||
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.GetAllStories(
|
||||
next=next,
|
||||
hidden=hidden,
|
||||
state=state
|
||||
)
|
||||
)
|
||||
|
||||
for peer_story in r.peer_stories:
|
||||
for story in peer_story.stories:
|
||||
yield await types.Story._parse(self, story, peer_story.peer)
|
63
pyrogram/methods/stories/get_peer_stories.py
Normal file
63
pyrogram/methods/stories/get_peer_stories.py
Normal file
@ -0,0 +1,63 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import AsyncGenerator, Union, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class GetPeerStories:
|
||||
async def get_peer_stories(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str]
|
||||
) -> Optional[AsyncGenerator["types.Story", None]]:
|
||||
"""Get all active stories from an user by using user identifiers.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
For your personal story you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
Returns:
|
||||
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Get all active story from spesific user
|
||||
async for story in app.get_peer_stories(chat_id):
|
||||
print(story)
|
||||
|
||||
Raises:
|
||||
ValueError: In case of invalid arguments.
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.GetPeerStories(
|
||||
peer=peer
|
||||
)
|
||||
)
|
||||
|
||||
for story in r.stories.stories:
|
||||
yield await types.Story._parse(self, story, peer)
|
76
pyrogram/methods/stories/get_stories.py
Normal file
76
pyrogram/methods/stories/get_stories.py
Normal file
@ -0,0 +1,76 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union, Iterable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class GetStories:
|
||||
async def get_stories(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
story_ids: Union[int, Iterable[int]],
|
||||
) -> "types.Stories":
|
||||
"""Get stories by id.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target user.
|
||||
For your personal story you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
story_ids (List of ``int`` ``32-bit``):
|
||||
Pass a single story identifier or an iterable of story ids (as integers) to get the content of the
|
||||
story themselves.
|
||||
|
||||
Returns:
|
||||
:obj:`~pyrogram.types.Story` | List of :obj:`~pyrogram.types.Story`: In case *story_ids* was not
|
||||
a list, a single story is returned, otherwise a list of stories is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Get stories by id
|
||||
stories = await app.get_stories_by_id(chat_id, [1, 2, 3])
|
||||
|
||||
for story in stories:
|
||||
print(story)
|
||||
"""
|
||||
is_iterable = not isinstance(story_ids, int)
|
||||
ids = list(story_ids) if is_iterable else [story_ids]
|
||||
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.GetStoriesByID(
|
||||
peer=peer,
|
||||
id=ids
|
||||
)
|
||||
)
|
||||
|
||||
stories = []
|
||||
|
||||
for i in r.updates:
|
||||
if isinstance(i, raw.types.stories.PeerStories):
|
||||
stories = [await types.Story._parse(self, story, peer) for story in r.stories]
|
||||
|
||||
return types.List(stories) if is_iterable else stories[0]
|
74
pyrogram/methods/stories/get_stories_archive.py
Normal file
74
pyrogram/methods/stories/get_stories_archive.py
Normal file
@ -0,0 +1,74 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import AsyncGenerator, Union, Optional
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
from pyrogram import types
|
||||
|
||||
|
||||
class GetStoriesArchive:
|
||||
async def get_stories_archive(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
limit: int = 0,
|
||||
offset_id: int = 0
|
||||
) -> Optional[AsyncGenerator["types.Story", None]]:
|
||||
"""Get stories archive.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
limit (``int``, *optional*):
|
||||
Limits the number of stories to be retrieved.
|
||||
By default, no limit is applied and all stories are returned.
|
||||
|
||||
offset_id (``int``, *optional*):
|
||||
Identifier of the first story to be returned.
|
||||
|
||||
Returns:
|
||||
``Generator``: On success, a generator yielding :obj:`~pyrogram.types.Story` objects is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Get story archive
|
||||
async for story in app.get_stories_archive(chat_id):
|
||||
print(story)
|
||||
|
||||
Raises:
|
||||
ValueError: In case of invalid arguments.
|
||||
"""
|
||||
peer = await self.resolve_peer(chat_id)
|
||||
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.GetStoriesArchive(
|
||||
peer=peer,
|
||||
offset_id=offset_id,
|
||||
limit=limit
|
||||
)
|
||||
)
|
||||
|
||||
for story in r.stories:
|
||||
yield await types.Story._parse(self, story, peer)
|
60
pyrogram/methods/stories/increment_story_views.py
Normal file
60
pyrogram/methods/stories/increment_story_views.py
Normal file
@ -0,0 +1,60 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
|
||||
|
||||
class IncrementStoryViews:
|
||||
async def increment_story_views(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
story_id: int,
|
||||
) -> bool:
|
||||
"""Increment story views.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
story_id (``int``):
|
||||
Unique identifier of the target story.
|
||||
|
||||
Returns:
|
||||
``bool``: On success, True is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Increment story views
|
||||
await app.increment_story_views(chat_id, 1)
|
||||
"""
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.IncrementStoryViews(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=story_id
|
||||
)
|
||||
)
|
||||
|
||||
return r
|
60
pyrogram/methods/stories/read_stories.py
Normal file
60
pyrogram/methods/stories/read_stories.py
Normal file
@ -0,0 +1,60 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw, types
|
||||
|
||||
|
||||
class ReadStories:
|
||||
async def read_stories(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
max_id: int = 0,
|
||||
) -> List[int]:
|
||||
"""Read stories.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
max_id (``int``, *optional*):
|
||||
Maximum identifier of the target story to read.
|
||||
|
||||
Returns:
|
||||
List of ``int``: On success, a list of read stories is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Read stories
|
||||
await app.read_stories(chat_id)
|
||||
"""
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.ReadStories(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
max_id=max_id
|
||||
)
|
||||
)
|
||||
|
||||
return types.List(r)
|
252
pyrogram/methods/stories/send_story.py
Normal file
252
pyrogram/methods/stories/send_story.py
Normal file
@ -0,0 +1,252 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import re
|
||||
from typing import List, Union, BinaryIO, Callable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import enums, raw, types, utils, StopTransmission
|
||||
from pyrogram.errors import FilePartMissing
|
||||
|
||||
class SendStory:
|
||||
async def send_story(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
media: Union[str, BinaryIO],
|
||||
caption: str = None,
|
||||
period: int = None,
|
||||
duration: int = 0,
|
||||
width: int = 0,
|
||||
height: int = 0,
|
||||
thumb: Union[str, BinaryIO] = None,
|
||||
supports_streaming: bool = True,
|
||||
file_name: str = None,
|
||||
privacy: "enums.StoriesPrivacyRules" = None,
|
||||
allowed_users: List[int] = None,
|
||||
denied_users: List[int] = None,
|
||||
allowed_chats: List[int] = None,
|
||||
denied_chats: List[int] = None,
|
||||
pinned: bool = None,
|
||||
protect_content: bool = None,
|
||||
parse_mode: "enums.ParseMode" = None,
|
||||
caption_entities: List["types.MessageEntity"] = None,
|
||||
progress: Callable = None,
|
||||
progress_args: tuple = ()
|
||||
) -> "types.Story":
|
||||
"""Send new story.
|
||||
|
||||
.. include:: /_includes/usable-by/users.rst
|
||||
|
||||
Note: You must pass one of following paramater *animation*, *photo*, *video*
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
For a contact that exists in your Telegram address book you can use his phone number (str).
|
||||
|
||||
media (``str`` | ``BinaryIO``):
|
||||
Video or photo to send.
|
||||
Pass a file_id as string to send a animation that exists on the Telegram servers,
|
||||
pass an HTTP URL as a string for Telegram to get a animation from the Internet,
|
||||
pass a file path as string to upload a new animation that exists on your local machine, or
|
||||
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
|
||||
|
||||
caption (``str``, *optional*):
|
||||
Story caption, 0-1024 characters.
|
||||
|
||||
period (``int``, *optional*):
|
||||
How long the story will posted, in secs.
|
||||
only for premium users.
|
||||
|
||||
duration (``int``, *optional*):
|
||||
Duration of sent video in seconds.
|
||||
|
||||
width (``int``, *optional*):
|
||||
Video width.
|
||||
|
||||
height (``int``, *optional*):
|
||||
Video height.
|
||||
|
||||
thumb (``str`` | ``BinaryIO``, *optional*):
|
||||
Thumbnail of the video sent.
|
||||
The thumbnail should be in JPEG format and less than 200 KB in size.
|
||||
A thumbnail's width and height should not exceed 320 pixels.
|
||||
Thumbnails can't be reused and can be only uploaded as a new file.
|
||||
|
||||
privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*):
|
||||
Story privacy.
|
||||
Defaults to :obj:`~pyrogram.enums.StoriesPrivacyRules.PUBLIC`
|
||||
|
||||
allowed_chats (List of ``int``, *optional*):
|
||||
List of chat_id which participant allowed to view the story.
|
||||
|
||||
denied_chats (List of ``int``, *optional*):
|
||||
List of chat_id which participant denied to view the story.
|
||||
|
||||
allowed_users (List of ``int``, *optional*):
|
||||
List of user_id whos allowed to view the story.
|
||||
|
||||
denied_users (List of ``int``, *optional*):
|
||||
List of user_id whos denied to view the story.
|
||||
|
||||
pinned (``bool``, *optional*):
|
||||
if True, the story will be pinned.
|
||||
default to False.
|
||||
|
||||
protect_content (``bool``, *optional*):
|
||||
Protects the contents of the sent story from forwarding and saving.
|
||||
default to False.
|
||||
|
||||
parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*):
|
||||
By default, texts are parsed using both Markdown and HTML styles.
|
||||
You can combine both syntaxes together.
|
||||
|
||||
caption_entities (List of :obj:`~pyrogram.types.MessageEntity`):
|
||||
List of special entities that appear in the caption, which can be specified instead of *parse_mode*.
|
||||
|
||||
progress (``Callable``, *optional*):
|
||||
Pass a callback function to view the file transmission progress.
|
||||
The function must take *(current, total)* as positional arguments (look at Other Parameters below for a
|
||||
detailed description) and will be called back each time a new file chunk has been successfully
|
||||
transmitted.
|
||||
|
||||
progress_args (``tuple``, *optional*):
|
||||
Extra custom arguments for the progress callback function.
|
||||
You can pass anything you need to be available in the progress callback scope; for example, a Message
|
||||
object or a Client instance in order to edit the message with the updated progress status.
|
||||
|
||||
Returns:
|
||||
:obj:`~pyrogram.types.Story` a single story is returned.
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Send new photo story
|
||||
photo_id = "abcd12345"
|
||||
await app.send_story(photo=photo_id, caption='Hello guys.')
|
||||
|
||||
Raises:
|
||||
ValueError: In case of invalid arguments.
|
||||
"""
|
||||
# TODO: media_areas
|
||||
|
||||
if privacy:
|
||||
privacy_rules = [types.StoriesPrivacyRules(type=privacy)]
|
||||
else:
|
||||
privacy_rules = [types.StoriesPrivacyRules(type=enums.StoriesPrivacyRules.PUBLIC)]
|
||||
|
||||
message, entities = (await utils.parse_text_entities(self, caption, parse_mode, caption_entities)).values()
|
||||
|
||||
try:
|
||||
if isinstance(media, str):
|
||||
if os.path.isfile(media):
|
||||
thumb = await self.save_file(thumb)
|
||||
file = await self.save_file(media, progress=progress, progress_args=progress_args)
|
||||
mime_type = self.guess_mime_type(file.name)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaUploadedDocument(
|
||||
mime_type=mime_type,
|
||||
file=file,
|
||||
thumb=thumb,
|
||||
attributes=[
|
||||
raw.types.DocumentAttributeVideo(
|
||||
duration=duration,
|
||||
w=width,
|
||||
h=height,
|
||||
),
|
||||
raw.types.DocumentAttributeFilename(file_name=file_name or os.path.basename(media))
|
||||
]
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaUploadedPhoto(
|
||||
file=file,
|
||||
)
|
||||
elif re.match("^https?://", media):
|
||||
mime_type = self.guess_mime_type(media)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaDocumentExternal(
|
||||
url=media,
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaPhotoExternal(
|
||||
url=media,
|
||||
)
|
||||
else:
|
||||
media = utils.get_input_media_from_file_id(media)
|
||||
else:
|
||||
thumb = await self.save_file(thumb)
|
||||
file = await self.save_file(media, progress=progress, progress_args=progress_args)
|
||||
mime_type = self.guess_mime_type(file.name)
|
||||
if mime_type == "video/mp4":
|
||||
media = raw.types.InputMediaUploadedDocument(
|
||||
mime_type=mime_type,
|
||||
file=file,
|
||||
thumb=thumb,
|
||||
attributes=[
|
||||
raw.types.DocumentAttributeVideo(
|
||||
supports_streaming=supports_streaming or None,
|
||||
duration=duration,
|
||||
w=width,
|
||||
h=height,
|
||||
),
|
||||
raw.types.DocumentAttributeFilename(file_name=file_name or media.name)
|
||||
]
|
||||
)
|
||||
else:
|
||||
media = raw.types.InputMediaUploadedPhoto(
|
||||
file=file,
|
||||
)
|
||||
|
||||
if allowed_chats:
|
||||
chats = [await self.resolve_peer(chat_id) for chat_id in allowed_chats]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueAllowChatParticipants(chats=chats))
|
||||
if denied_chats:
|
||||
chats = [await self.resolve_peer(chat_id) for chat_id in denied_chats]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueDisallowChatParticipants(chats=chats))
|
||||
if allowed_users:
|
||||
users = [await self.resolve_peer(user_id) for user_id in allowed_users]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueAllowUsers(users=users))
|
||||
if denied_users:
|
||||
users = [await self.resolve_peer(user_id) for user_id in denied_users]
|
||||
privacy_rules.append(raw.types.InputPrivacyValueDisallowUsers(users=users))
|
||||
|
||||
while True:
|
||||
try:
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.SendStory(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
media=media,
|
||||
privacy_rules=privacy_rules,
|
||||
random_id=self.rnd_id(),
|
||||
pinned=pinned,
|
||||
noforwards=protect_content,
|
||||
caption=message,
|
||||
entities=entities,
|
||||
period=period,
|
||||
)
|
||||
)
|
||||
except FilePartMissing as e:
|
||||
await self.save_file(media, file_id=file.id, file_part=e.value)
|
||||
else:
|
||||
for i in r.updates:
|
||||
if isinstance(i, raw.types.UpdateStory):
|
||||
return await types.Story._parse(self, i.story, i.peer)
|
||||
except StopTransmission:
|
||||
return None
|
68
pyrogram/methods/stories/toggle_stories_pinned.py
Normal file
68
pyrogram/methods/stories/toggle_stories_pinned.py
Normal file
@ -0,0 +1,68 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List, Union, Iterable
|
||||
|
||||
import pyrogram
|
||||
from pyrogram import raw
|
||||
|
||||
|
||||
class ToggleStoriesPinned:
|
||||
async def toggle_stories_pinned(
|
||||
self: "pyrogram.Client",
|
||||
chat_id: Union[int, str],
|
||||
stories_ids: Union[int, Iterable[int]],
|
||||
pinned: bool,
|
||||
) -> List[int]:
|
||||
"""Toggle stories pinned.
|
||||
|
||||
.. include:: /_includes/usable-by/users-bots.rst
|
||||
|
||||
Parameters:
|
||||
chat_id (``int`` | ``str``):
|
||||
Unique identifier (int) or username (str) of the target chat.
|
||||
For your personal cloud (Saved Messages) you can simply use "me" or "self".
|
||||
|
||||
stories_ids (List of ``int`` ``32-bit``):
|
||||
List of unique identifiers of the target stories.
|
||||
|
||||
pinned (``bool``):
|
||||
If set to ``True``, the stories will be pinned.
|
||||
|
||||
Returns:
|
||||
List of ``int``: List of pinned stories IDs
|
||||
|
||||
Example:
|
||||
.. code-block:: python
|
||||
|
||||
# Pin a single story
|
||||
await app.toggle_stories_pinned(chat_id, 123456789, True)
|
||||
|
||||
"""
|
||||
is_iterable = not isinstance(stories_ids, int)
|
||||
stories_ids = list(stories_ids) if is_iterable else [stories_ids]
|
||||
|
||||
r = await self.invoke(
|
||||
raw.functions.stories.TogglePinned(
|
||||
peer=await self.resolve_peer(chat_id),
|
||||
id=stories_ids,
|
||||
pinned=pinned
|
||||
)
|
||||
)
|
||||
|
||||
return types.List(r)
|
@ -18,8 +18,9 @@
|
||||
|
||||
from .input_message_content import InputMessageContent
|
||||
from .input_reply_to_message import InputReplyToMessage
|
||||
from .input_reply_to_story import InputReplyToStory
|
||||
from .input_text_message_content import InputTextMessageContent
|
||||
|
||||
__all__ = [
|
||||
"InputMessageContent", "InputReplyToMessage", "InputTextMessageContent"
|
||||
"InputMessageContent", "InputReplyToMessage", "InputReplyToStory", "InputTextMessageContent"
|
||||
]
|
||||
|
48
pyrogram/types/input_message_content/input_reply_to_story.py
Normal file
48
pyrogram/types/input_message_content/input_reply_to_story.py
Normal file
@ -0,0 +1,48 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import raw
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class InputReplyToStory(Object):
|
||||
"""Contains information about a target replied story.
|
||||
|
||||
Parameters:
|
||||
user_id (:obj:`~pyrogram.raw.types.InputUser`):
|
||||
An InputUser.
|
||||
|
||||
story_id (``int``):
|
||||
Unique identifier for the target story.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
user_id: "raw.types.InputUser" = None,
|
||||
story_id: int = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.user_id = user_id
|
||||
self.story_id = story_id
|
||||
|
||||
def write(self):
|
||||
return raw.types.InputReplyToStory(
|
||||
user_id=self.user_id,
|
||||
story_id=self.story_id
|
||||
).write()
|
@ -38,6 +38,11 @@ from .poll_option import PollOption
|
||||
from .reaction import Reaction
|
||||
from .sticker import Sticker
|
||||
from .stripped_thumbnail import StrippedThumbnail
|
||||
from .stories_privacy_rules import StoriesPrivacyRules
|
||||
from .story import Story
|
||||
from .story_deleted import StoryDeleted
|
||||
from .story_skipped import StorySkipped
|
||||
from .story_views import StoryViews
|
||||
from .thumbnail import Thumbnail
|
||||
from .venue import Venue
|
||||
from .video import Video
|
||||
@ -46,11 +51,13 @@ from .voice import Voice
|
||||
from .web_app_data import WebAppData
|
||||
from .web_page import WebPage
|
||||
from .message_reactions import MessageReactions
|
||||
from .message_story import MessageStory
|
||||
|
||||
__all__ = [
|
||||
"Animation", "Audio", "Contact", "Document", "ForumTopic", "ForumTopicCreated",
|
||||
"ForumTopicClosed", "ForumTopicReopened", "ForumTopicEdited", "GeneralTopicHidden",
|
||||
"GeneralTopicUnhidden", "Game", "Location", "Message", "MessageEntity", "Photo", "Thumbnail",
|
||||
"StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice",
|
||||
"WebPage", "Dice", "Reaction", "WebAppData", "MessageReactions"
|
||||
"StrippedThumbnail", "Story", "StoryDeleted", "StorySkipped", "StoryViews", "StoriesPrivacyRules", "Poll", "PollOption", "Sticker",
|
||||
"Venue", "Video", "VideoNote", "Voice", "WebPage", "Dice", "Reaction", "WebAppData",
|
||||
"MessageReactions", "MessageStory"
|
||||
]
|
||||
|
@ -180,6 +180,9 @@ class Message(Object, Update):
|
||||
game (:obj:`~pyrogram.types.Game`, *optional*):
|
||||
Message is a game, information about the game.
|
||||
|
||||
story (:obj:`~pyrogram.types.MessageStory`):
|
||||
Message is a story, information about the story.
|
||||
|
||||
video (:obj:`~pyrogram.types.Video`, *optional*):
|
||||
Message is a video, information about the video.
|
||||
|
||||
@ -376,6 +379,7 @@ class Message(Object, Update):
|
||||
sticker: "types.Sticker" = None,
|
||||
animation: "types.Animation" = None,
|
||||
game: "types.Game" = None,
|
||||
story: "types.MessageStory" = None,
|
||||
video: "types.Video" = None,
|
||||
voice: "types.Voice" = None,
|
||||
video_note: "types.VideoNote" = None,
|
||||
@ -462,6 +466,7 @@ class Message(Object, Update):
|
||||
self.sticker = sticker
|
||||
self.animation = animation
|
||||
self.game = game
|
||||
self.story = story
|
||||
self.video = video
|
||||
self.voice = voice
|
||||
self.video_note = video_note
|
||||
@ -744,6 +749,7 @@ class Message(Object, Update):
|
||||
contact = None
|
||||
venue = None
|
||||
game = None
|
||||
story = None
|
||||
audio = None
|
||||
voice = None
|
||||
animation = None
|
||||
@ -776,6 +782,9 @@ class Message(Object, Update):
|
||||
elif isinstance(media, raw.types.MessageMediaGame):
|
||||
game = types.Game._parse(client, message)
|
||||
media_type = enums.MessageMediaType.GAME
|
||||
elif isinstance(media, raw.types.MessageMediaStory):
|
||||
story = types.MessageStory._parse(media)
|
||||
media_type = enums.MessageMediaType.STORY
|
||||
elif isinstance(media, raw.types.MessageMediaDocument):
|
||||
doc = media.document
|
||||
|
||||
@ -904,6 +913,7 @@ class Message(Object, Update):
|
||||
voice=voice,
|
||||
animation=animation,
|
||||
game=game,
|
||||
story=story,
|
||||
video=video,
|
||||
video_note=video_note,
|
||||
sticker=sticker,
|
||||
|
56
pyrogram/types/messages_and_media/message_story.py
Normal file
56
pyrogram/types/messages_and_media/message_story.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import raw
|
||||
from ..object import Object
|
||||
|
||||
|
||||
class MessageStory(Object):
|
||||
"""Contains information about a forwarded story.
|
||||
|
||||
Parameters:
|
||||
chat_id (``int``):
|
||||
Unique user identifier of story sender.
|
||||
|
||||
story_id (``int``):
|
||||
Unique story identifier.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
chat_id: int,
|
||||
story_id: int
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.chat_id = chat_id
|
||||
self.story_id = story_id
|
||||
|
||||
@staticmethod
|
||||
def _parse(message_story: "raw.types.MessageMediaStory") -> "MessageStory":
|
||||
if isinstance(message_story.peer, raw.types.PeerChannel):
|
||||
chat_id = message_story.peer.channel_id
|
||||
else:
|
||||
chat_id = message_story.peer.user_id
|
||||
|
||||
return MessageStory(
|
||||
chat_id=chat_id,
|
||||
story_id=message_story.id
|
||||
)
|
47
pyrogram/types/messages_and_media/stories_privacy_rules.py
Normal file
47
pyrogram/types/messages_and_media/stories_privacy_rules.py
Normal file
@ -0,0 +1,47 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import enums, raw
|
||||
from ..object import Object
|
||||
|
||||
class StoriesPrivacyRules(Object):
|
||||
"""A story privacy rules.
|
||||
|
||||
Parameters:
|
||||
type (:obj:`~pyrogram.enums.StoriesPrivacyRules`):
|
||||
Story privacy type.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
type: "enums.StoriesPrivacyRules"
|
||||
):
|
||||
super().__init__()
|
||||
self.type = type
|
||||
|
||||
def write(self):
|
||||
if self.type == enums.StoriesPrivacyRules.PUBLIC:
|
||||
return raw.types.InputPrivacyValueAllowAll().write()
|
||||
if self.type == enums.StoriesPrivacyRules.CLOSE_FRIENDS:
|
||||
return raw.types.InputPrivacyValueAllowCloseFriends().write()
|
||||
if self.type == enums.StoriesPrivacyRules.CONTACTS:
|
||||
return raw.types.InputPrivacyValueAllowContacts().write()
|
||||
if self.type == enums.StoriesPrivacyRules.NO_CONTACTS:
|
||||
return raw.types.InputPrivacyValueDisallowContacts().write()
|
||||
if self.type == enums.StoriesPrivacyRules.PRIVATE:
|
||||
return raw.types.InputPrivacyValueDisallowAll().write()
|
1498
pyrogram/types/messages_and_media/story.py
Normal file
1498
pyrogram/types/messages_and_media/story.py
Normal file
File diff suppressed because it is too large
Load Diff
63
pyrogram/types/messages_and_media/story_deleted.py
Normal file
63
pyrogram/types/messages_and_media/story_deleted.py
Normal file
@ -0,0 +1,63 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram import raw, types
|
||||
from typing import Union
|
||||
from ..object import Object
|
||||
from ..update import Update
|
||||
|
||||
class StoryDeleted(Object, Update):
|
||||
"""A deleted story.
|
||||
|
||||
Parameters:
|
||||
id (``int``):
|
||||
Unique story identifier.
|
||||
|
||||
from_user (:obj:`~pyrogram.types.User`, *optional*):
|
||||
Sender of the story.
|
||||
|
||||
sender_chat (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||
Sender of the story. If the story is from channel.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: "pyrogram.Client" = None,
|
||||
id: int,
|
||||
from_user: Union["types.User", "types.Chat"] = None
|
||||
):
|
||||
super().__init__(client)
|
||||
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
|
||||
async def _parse(
|
||||
client: "pyrogram.Client",
|
||||
stories: raw.base.StoryItem,
|
||||
peer: Union["raw.types.PeerChannel", "raw.types.PeerUser"]
|
||||
) -> "StoryDeleted":
|
||||
from_user = await client.get_users(peer.user_id) if isinstance(peer, raw.types.PeerUser) else await client.get_chat(peer.channel_id)
|
||||
|
||||
return StoryDeleted(
|
||||
id=stories.id,
|
||||
from_user=from_user,
|
||||
client=client
|
||||
)
|
84
pyrogram/types/messages_and_media/story_skipped.py
Normal file
84
pyrogram/types/messages_and_media/story_skipped.py
Normal file
@ -0,0 +1,84 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from datetime import datetime
|
||||
from pyrogram import raw, types, utils
|
||||
from typing import Union
|
||||
from ..object import Object
|
||||
from ..update import Update
|
||||
|
||||
class StorySkipped(Object, Update):
|
||||
"""A skipped story.
|
||||
|
||||
Parameters:
|
||||
id (``int``):
|
||||
Unique story identifier.
|
||||
|
||||
from_user (:obj:`~pyrogram.types.User`, *optional*):
|
||||
Sender of the story.
|
||||
|
||||
sender_chat (:obj:`~pyrogram.types.Chat`, *optional*):
|
||||
Sender of the story. If the story is from channel.
|
||||
|
||||
date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date the story was sent.
|
||||
|
||||
expire_date (:py:obj:`~datetime.datetime`, *optional*):
|
||||
Date the story will be expired.
|
||||
|
||||
close_friends (``bool``, *optional*):
|
||||
True, if the Story is shared with close_friends only.
|
||||
"""
|
||||
|
||||
# TODO: Add Privacy
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
client: "pyrogram.Client" = None,
|
||||
id: int,
|
||||
from_user: Union["types.User", "types.Chat"] = None,
|
||||
date: datetime,
|
||||
expire_date: datetime,
|
||||
close_friends: bool = None
|
||||
):
|
||||
super().__init__(client)
|
||||
|
||||
self.id = id
|
||||
self.from_user = from_user
|
||||
self.date = date
|
||||
self.expire_date = expire_date
|
||||
self.close_friends = close_friends
|
||||
|
||||
async def _parse(
|
||||
client: "pyrogram.Client",
|
||||
stories: raw.base.StoryItem,
|
||||
peer: Union["raw.types.PeerChannel", "raw.types.PeerUser"]
|
||||
) -> "StorySkipped":
|
||||
from_user = await client.get_users(peer.user_id) if isinstance(peer, raw.types.PeerUser) else await client.get_chat(peer.channel_id)
|
||||
|
||||
return StorySkipped(
|
||||
id=stories.id,
|
||||
from_user=from_user,
|
||||
date=utils.timestamp_to_datetime(stories.date),
|
||||
expire_date=utils.timestamp_to_datetime(stories.expire_date),
|
||||
close_friends=stories.close_friends,
|
||||
client=client
|
||||
)
|
74
pyrogram/types/messages_and_media/story_views.py
Normal file
74
pyrogram/types/messages_and_media/story_views.py
Normal file
@ -0,0 +1,74 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from pyrogram import raw, types
|
||||
from typing import List
|
||||
from ..object import Object
|
||||
|
||||
class StoryViews(Object):
|
||||
"""Contains information about a story viewers.
|
||||
|
||||
Parameters:
|
||||
views_count (``int`` ``32-bit``):
|
||||
Views count.
|
||||
|
||||
has_viewers (``bool``, *optional*):
|
||||
Has viewers.
|
||||
|
||||
forwards_count (``int`` ``32-bit``, *optional*):
|
||||
Forwards count.
|
||||
|
||||
reactions (List of :obj:`~pyrogram.types.Reaction`, *optional*):
|
||||
Reactions list.
|
||||
|
||||
reactions_count (``int`` ``32-bit``, *optional*):
|
||||
Reactions count.
|
||||
|
||||
recent_viewers (List of ``int`` ``64-bit``, *optional*):
|
||||
Viewers list.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, *,
|
||||
views_count: int,
|
||||
has_viewers: bool = None,
|
||||
forwards_count: int = None,
|
||||
reactions: List["types.Reaction"] = None,
|
||||
reactions_count: int = None,
|
||||
recent_viewers: List[int] = None
|
||||
):
|
||||
super().__init__()
|
||||
|
||||
self.views_count = views_count
|
||||
self.has_viewers = has_viewers
|
||||
self.forwards_count = forwards_count
|
||||
self.reactions = reactions
|
||||
self.reactions_count = reactions_count
|
||||
self.recent_viewers = recent_viewers
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, storyviews: "raw.types.StoryViews") -> "StoryViews":
|
||||
return StoryViews(
|
||||
views_count=getattr(storyviews, "views_count", None),
|
||||
has_viewers=getattr(storyviews, "has_viewers", None),
|
||||
forwards_count=getattr(storyviews, "forwards_count", None),
|
||||
reactions=[
|
||||
types.Reaction._parse_count(client, reaction) for reaction in storyviews.reactions
|
||||
] or None,
|
||||
recent_viewers=getattr(storyviews, "recent_viewers", None)
|
||||
)
|
@ -248,16 +248,21 @@ def get_peer_type(peer_id: int) -> str:
|
||||
raise ValueError(f"Peer id invalid: {peer_id}")
|
||||
|
||||
def get_reply_to(
|
||||
reply_to_message_id: Optional[int],
|
||||
message_thread_id: Optional[int],
|
||||
) -> Optional[raw.types.InputReplyToMessage]:
|
||||
if not any((reply_to_message_id, message_thread_id)):
|
||||
return None
|
||||
reply_to_message_id: Optional[int] = None,
|
||||
message_thread_id: Optional[int] = None,
|
||||
user_id: Optional[raw.types.InputUser] = None,
|
||||
reply_to_story_id: Optional[int] = None
|
||||
) -> Optional[Union[raw.types.InputReplyToMessage, raw.types.InputReplyToStory]]:
|
||||
if all((user_id, reply_to_story_id)):
|
||||
return raw.types.InputReplyToStory(user_id=user_id, story_id=reply_to_story_id) # type: ignore[arg-type]
|
||||
|
||||
return raw.types.InputReplyToMessage(
|
||||
reply_to_msg_id=reply_to_message_id or message_thread_id, # type: ignore[arg-type]
|
||||
top_msg_id=message_thread_id if reply_to_message_id else None,
|
||||
)
|
||||
if any((reply_to_message_id, message_thread_id)):
|
||||
return raw.types.InputReplyToMessage(
|
||||
reply_to_msg_id=reply_to_message_id or message_thread_id, # type: ignore[arg-type]
|
||||
top_msg_id=message_thread_id if reply_to_message_id else None,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def get_channel_id(peer_id: int) -> int:
|
||||
return MAX_CHANNEL_ID - peer_id
|
||||
|
125
update_bot_precheckout_query.py
Normal file
125
update_bot_precheckout_query.py
Normal file
@ -0,0 +1,125 @@
|
||||
# Pyrogram - Telegram MTProto API Client Library for Python
|
||||
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
|
||||
#
|
||||
# This file is part of Pyrogram.
|
||||
#
|
||||
# Pyrogram is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Pyrogram is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
from pyrogram.raw.core.primitives import Int, Long, Int128, Int256, Bool, Bytes, String, Double, Vector
|
||||
from pyrogram.raw.core import TLObject
|
||||
from pyrogram import raw
|
||||
from typing import List, Optional, Any
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# !!! WARNING !!! #
|
||||
# This is a generated file! #
|
||||
# All changes made in this file will be lost! #
|
||||
# # # # # # # # # # # # # # # # # # # # # # # #
|
||||
|
||||
|
||||
class UpdateBotPrecheckoutQuery(TLObject): # type: ignore
|
||||
"""Telegram API type.
|
||||
|
||||
Constructor of :obj:`~pyrogram.raw.base.Update`.
|
||||
|
||||
Details:
|
||||
- Layer: ``165``
|
||||
- ID: ``8CAA9A96``
|
||||
|
||||
Parameters:
|
||||
query_id (``int`` ``64-bit``):
|
||||
N/A
|
||||
|
||||
user_id (``int`` ``64-bit``):
|
||||
N/A
|
||||
|
||||
payload (``bytes``):
|
||||
N/A
|
||||
|
||||
currency (``str``):
|
||||
N/A
|
||||
|
||||
total_amount (``int`` ``64-bit``):
|
||||
N/A
|
||||
|
||||
info (:obj:`PaymentRequestedInfo <pyrogram.raw.base.PaymentRequestedInfo>`, *optional*):
|
||||
N/A
|
||||
|
||||
shipping_option_id (``str``, *optional*):
|
||||
N/A
|
||||
|
||||
"""
|
||||
|
||||
__slots__: List[str] = ["query_id", "user_id", "payload", "currency", "total_amount", "info", "shipping_option_id"]
|
||||
|
||||
ID = 0x8caa9a96
|
||||
QUALNAME = "types.UpdateBotPrecheckoutQuery"
|
||||
|
||||
def __init__(self, *, query_id: int, user_id: int, payload: bytes, currency: str, total_amount: int, info: "raw.base.PaymentRequestedInfo" = None, shipping_option_id: Optional[str] = None) -> None:
|
||||
self.query_id = query_id # long
|
||||
self.user_id = user_id # long
|
||||
self.payload = payload # bytes
|
||||
self.currency = currency # string
|
||||
self.total_amount = total_amount # long
|
||||
self.info = info # flags.0?PaymentRequestedInfo
|
||||
self.shipping_option_id = shipping_option_id # flags.1?string
|
||||
|
||||
@staticmethod
|
||||
def read(b: BytesIO, *args: Any) -> "UpdateBotPrecheckoutQuery":
|
||||
|
||||
flags = Int.read(b)
|
||||
|
||||
query_id = Long.read(b)
|
||||
|
||||
user_id = Long.read(b)
|
||||
|
||||
payload = Bytes.read(b)
|
||||
|
||||
info = TLObject.read(b) if flags & (1 << 0) else None
|
||||
|
||||
shipping_option_id = String.read(b) if flags & (1 << 1) else None
|
||||
currency = String.read(b)
|
||||
|
||||
total_amount = Long.read(b)
|
||||
|
||||
return UpdateBotPrecheckoutQuery(query_id=query_id, user_id=user_id, payload=payload, currency=currency, total_amount=total_amount, info=info, shipping_option_id=shipping_option_id)
|
||||
|
||||
def write(self, *args) -> bytes:
|
||||
b = BytesIO()
|
||||
b.write(Int(self.ID, False))
|
||||
|
||||
flags = 0
|
||||
flags |= (1 << 0) if self.info is not None else 0
|
||||
flags |= (1 << 1) if self.shipping_option_id is not None else 0
|
||||
b.write(Int(flags))
|
||||
|
||||
b.write(Long(self.query_id))
|
||||
|
||||
b.write(Long(self.user_id))
|
||||
|
||||
b.write(Bytes(self.payload))
|
||||
|
||||
if self.info is not None:
|
||||
b.write(self.info.write())
|
||||
|
||||
if self.shipping_option_id is not None:
|
||||
b.write(String(self.shipping_option_id))
|
||||
|
||||
b.write(String(self.currency))
|
||||
|
||||
b.write(Long(self.total_amount))
|
||||
|
||||
return b.getvalue()
|
Loading…
Reference in New Issue
Block a user