Pyrofork: Add forward_story method

Signed-off-by: wulan17 <wulan17@nusantararom.org>
This commit is contained in:
wulan17 2023-12-06 22:33:13 +07:00
parent 33d9fef0fb
commit c949de63c5
No known key found for this signature in database
GPG key ID: 318CD6CD3A6AC0A5
4 changed files with 139 additions and 4 deletions

View file

@ -274,6 +274,7 @@ def pyrogram_api():
delete_stories delete_stories
edit_story edit_story
export_story_link export_story_link
forward_story
get_all_stories get_all_stories
get_stories get_stories
get_stories_history get_stories_history

View file

@ -21,6 +21,7 @@ from .delete_profile_photos import DeleteProfilePhotos
from .delete_stories import DeleteStories from .delete_stories import DeleteStories
from .edit_story import EditStory from .edit_story import EditStory
from .export_story_link import ExportStoryLink from .export_story_link import ExportStoryLink
from .forward_story import ForwardStory
from .get_chat_photos import GetChatPhotos from .get_chat_photos import GetChatPhotos
from .get_chat_photos_count import GetChatPhotosCount from .get_chat_photos_count import GetChatPhotosCount
from .get_common_chats import GetCommonChats from .get_common_chats import GetCommonChats
@ -44,6 +45,7 @@ class Users(
DeleteStories, DeleteStories,
EditStory, EditStory,
ExportStoryLink, ExportStoryLink,
ForwardStory,
GetCommonChats, GetCommonChats,
GetChatPhotos, GetChatPhotos,
SetProfilePhoto, SetProfilePhoto,

View file

@ -0,0 +1,120 @@
# Pyrofork - Telegram MTProto API Client Library for Python
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# This file is part of Pyrofork.
#
# Pyrofork 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.
#
# Pyrofork 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 Pyrofork. If not, see <http://www.gnu.org/licenses/>.
from typing import List, Union
import pyrogram
from pyrogram import enums, types
class ForwardStory:
def _split(self, message, entities, *args, **kwargs):
return message, entities
async def forward_story(
self: "pyrogram.Client",
from_chat_id: Union[int, str],
from_story_id: int,
channel_id: int = 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,
caption: str = None,
parse_mode: "enums.ParseMode" = None,
caption_entities: List["types.MessageEntity"] = None,
period: int = None
) -> "types.Story":
"""Forward a story.
.. include:: /_includes/usable-by/users.rst
Parameters:
from_chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat/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).
from_story_id (``int``):
Unique identifier of original story.
channel_id (``int``, *optional*):
Unique identifier (int) of the target channel.
If you want to forward story to a channel.
privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*):
Story privacy.
Defaults to :obj:`~pyrogram.enums.StoriesPrivacyRules.PUBLIC`
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.
caption (``str``, *optional*):
Story caption, 0-1024 characters.
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*.
period (``int``, *optional*):
How long the story will posted, in secs.
only for premium users.
Returns:
:obj:`~pyrogram.types.Story` a single story is returned.
Example:
.. code-block:: python
# forward a story
await app.forward_story(from_chat_id='wulan17', from_story_id=1, caption='Hello guys.')
Raises:
ValueError: In case of invalid arguments.
"""
return await self.send_story(
channel_id=channel_id,
privacy=privacy,
allowed_users=allowed_users,
denied_users=denied_users,
pinned=pinned,
protect_content=protect_content,
caption=caption,
caption_entities=caption_entities,
parse_mode=parse_mode,
period=period,
forward_from_chat_id=from_chat_id,
forward_from_story_id=from_story_id
)

View file

@ -18,7 +18,7 @@
import os import os
import re import re
from typing import List from typing import List, Union
import pyrogram import pyrogram
from pyrogram import enums, raw, types, utils from pyrogram import enums, raw, types, utils
@ -44,7 +44,9 @@ class SendStory:
caption: str = None, caption: str = None,
parse_mode: "enums.ParseMode" = None, parse_mode: "enums.ParseMode" = None,
caption_entities: List["types.MessageEntity"] = None, caption_entities: List["types.MessageEntity"] = None,
period: int = None period: int = None,
forward_from_chat_id: Union[int, str] = None,
forward_from_story_id: int = None
) -> "types.Story": ) -> "types.Story":
"""Send new story. """Send new story.
@ -227,7 +229,8 @@ class SendStory:
] ]
) )
else: else:
raise ValueError("You need to pass one of the following parameter animation/photo/video!") if forward_from_chat_id is None:
raise ValueError("You need to pass one of the following parameter animation/photo/video/forward_from_chat_id!")
text, entities = self._split(**await utils.parse_text_entities(self, caption, parse_mode, caption_entities)) text, entities = self._split(**await utils.parse_text_entities(self, caption, parse_mode, caption_entities))
@ -246,6 +249,12 @@ class SendStory:
users = [await self.resolve_peer(user_id) for user_id in denied_users] users = [await self.resolve_peer(user_id) for user_id in denied_users]
privacy_rules.append(raw.types.InputPrivacyValueDisallowUsers(users=users)) privacy_rules.append(raw.types.InputPrivacyValueDisallowUsers(users=users))
if forward_from_chat_id is not None:
forward_from_chat = await self.resolve_peer(forward_from_chat_id)
media = raw.types.InputMediaEmpty()
if forward_from_story_id is None:
raise ValueError("You need to pass forward_from_story_id to forward story!")
r = await self.invoke( r = await self.invoke(
raw.functions.stories.SendStory( raw.functions.stories.SendStory(
peer=peer, peer=peer,
@ -256,7 +265,10 @@ class SendStory:
noforwards=protect_content, noforwards=protect_content,
caption=text, caption=text,
entities=entities, entities=entities,
period=period period=period,
fwd_from_id=forward_from_chat,
fwd_from_story=forward_from_story_id if forward_from_chat_id is not None else None,
fwd_modified=True if forward_from_chat_id is not None and caption is not None else False
) )
) )
return await types.Story._parse(self, r.updates[0].story, r.updates[0].peer) return await types.Story._parse(self, r.updates[0].story, r.updates[0].peer)