Compare commits

...

11 commits

Author SHA1 Message Date
KurimuzonAkuma
86ac12c213
Add transfer_business_account_stars method
Some checks failed
Build-docs / build (push) Has been cancelled
Pyrofork / build (macos-latest, 3.10) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.11) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.12) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.13) (push) Has been cancelled
Pyrofork / build (macos-latest, 3.9) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.10) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.11) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.12) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.13) (push) Has been cancelled
Pyrofork / build (ubuntu-latest, 3.9) (push) Has been cancelled
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:58:51 +07:00
KurimuzonAkuma
aa446c2333
Add get_business_account_gifts and get_business_account_star_balance method
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:58:15 +07:00
wulan17
aee9eefbbf
pyrofork: Add reply_to_monoforum_id parameter to supported send_*
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:01 +07:00
wulan17
4e0e79c80f
pyrofork: Add STARS_AMOUNT_INVALID exception
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:01 +07:00
wulan17
cf3eb7125f
pyrofork: Add paid_message_price_changed field to Message
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:01 +07:00
wulan17
be313aa666
pyrofork: Add ALLOW_PAYMENT_REQUIRED_X exception
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:00 +07:00
wulan17
1bcdcba89b
pyrofork: Add linked_forum field to Chat
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:00 +07:00
wulan17
88d8a40900
pyrofork: Drop Chat.is_forum and add new ChatType (FORUM)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:00 +07:00
wulan17
a8a7bb5c03
pyrofork: Add new ChatType (MONOFORUM)
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:42:00 +07:00
uNickz
eb9954a5cf
pyrofork: Add file_name param on InputMedia
* Add file_name param on InputMedia

Add file_name param on:
 - InputMediaVideo
 - InputMediaAudio
 - InputMediaDocument

---------

Co-authored-by: KurimuzonAkuma <31959970+KurimuzonAkuma@users.noreply.github.com>
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:41:59 +07:00
wulan17
b35123c93e
pyrofork: Refactor Message.link
Signed-off-by: wulan17 <wulan17@komodos.id>
2025-06-10 20:41:59 +07:00
35 changed files with 560 additions and 22 deletions

View file

@ -411,6 +411,9 @@ def pyrogram_api():
answer_shipping_query
delete_business_messages
get_business_connection
get_business_account_gifts
get_business_account_star_balance
transfer_business_account_stars
""",
authorization="""
Authorization
@ -605,6 +608,7 @@ def pyrogram_api():
Invoice
LabeledPrice
PaidMedia
PaidMessagePriceChanged
PaymentForm
PaymentInfo
PaymentRefunded
@ -714,6 +718,7 @@ def pyrogram_api():
InputMessageContent
InputMessageContent
InputReplyToMessage
InputReplyToMonoforum
InputReplyToStory
InputTextMessageContent
InputLocationMessageContent

View file

@ -35,6 +35,7 @@ BOT_GAMES_DISABLED Bot games cannot be used in this type of chat
BOT_GROUPS_BLOCKED This bot can't be added to groups
BOT_INLINE_DISABLED The inline feature of the bot is disabled
BOT_INVALID This is not a valid bot
BOT_INVOICE_INVALID The provided invoice is invalid
BOT_METHOD_INVALID The method can't be used by bots
BOT_MISSING This method can only be run by a bot
BOT_ONESIDE_NOT_AVAIL Bots can't pin messages for one side only in private chats
@ -46,6 +47,7 @@ BROADCAST_CALLS_DISABLED Broadcast calls disabled
BROADCAST_ID_INVALID The channel is invalid
BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels
BROADCAST_REQUIRED The request can only be used with a channel
BUSINESS_BOT_MISSING Business bot missing
BUTTON_DATA_INVALID The button callback data is invalid or too large
BUTTON_ID_INVALID The button_id parameter is invalid
BUTTON_TEXT_INVALID The specified button text is invalid
@ -503,3 +505,4 @@ BOOSTS_EMPTY You can't modify the icon of the General topic.
BOOST_NOT_MODIFIED You're already boosting the specified channel.
PAYMENT_REQUIRED The payment is required
BOOST_PEER_INVALID The specified `boost_peer` is invalid.
STARS_AMOUNT_INVALID The specified `amount` is invalid.
1 id message
35 BOT_GROUPS_BLOCKED This bot can't be added to groups
36 BOT_INLINE_DISABLED The inline feature of the bot is disabled
37 BOT_INVALID This is not a valid bot
38 BOT_INVOICE_INVALID The provided invoice is invalid
39 BOT_METHOD_INVALID The method can't be used by bots
40 BOT_MISSING This method can only be run by a bot
41 BOT_ONESIDE_NOT_AVAIL Bots can't pin messages for one side only in private chats
47 BROADCAST_ID_INVALID The channel is invalid
48 BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels
49 BROADCAST_REQUIRED The request can only be used with a channel
50 BUSINESS_BOT_MISSING Business bot missing
51 BUTTON_DATA_INVALID The button callback data is invalid or too large
52 BUTTON_ID_INVALID The button_id parameter is invalid
53 BUTTON_TEXT_INVALID The specified button text is invalid
505 BOOST_NOT_MODIFIED You're already boosting the specified channel.
506 PAYMENT_REQUIRED The payment is required
507 BOOST_PEER_INVALID The specified `boost_peer` is invalid.
508 STARS_AMOUNT_INVALID The specified `amount` is invalid.

View file

@ -44,3 +44,4 @@ GROUPCALL_ALREADY_STARTED The groupcall has already started, you can join direct
GROUPCALL_FORBIDDEN The group call has already ended
LIVE_DISABLED Story is disabled server-side
CHAT_GUEST_SEND_FORBIDDEN You need to join the discussion group before commenting
ALLOW_PAYMENT_REQUIRED_X Payment of {value} stars is required to perform this action
1 id message
44 GROUPCALL_FORBIDDEN The group call has already ended
45 LIVE_DISABLED Story is disabled server-side
46 CHAT_GUEST_SEND_FORBIDDEN You need to join the discussion group before commenting
47 ALLOW_PAYMENT_REQUIRED_X Payment of {value} stars is required to perform this action

View file

@ -39,3 +39,9 @@ class ChatType(AutoName):
CHANNEL = auto()
"Chat is a channel"
FORUM = auto()
"Chat is a forum"
MONOFORUM = auto()
"Chat is a monoforum"

View file

@ -132,3 +132,6 @@ class MessageServiceType(AutoName):
SCREENSHOT_TAKEN = auto()
"Screenshot taken"
PAID_MESSAGE_PRICE_CHANGED = auto()
"Paid message price changed"

View file

@ -21,6 +21,9 @@ from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .answer_shipping_query import AnswerShippingQuery
from .delete_business_messages import DeleteBusinessMessages
from .get_business_connection import GetBusinessConnection
from .get_business_account_gifts import GetBusinessAccountGifts
from .get_business_account_star_balance import GetBusinessAccountStarBalance
from .transfer_business_account_stars import TransferBusinessAccountStars
class TelegramBusiness(
@ -28,5 +31,8 @@ class TelegramBusiness(
AnswerShippingQuery,
DeleteBusinessMessages,
GetBusinessConnection,
GetBusinessAccountGifts,
GetBusinessAccountStarBalance,
TransferBusinessAccountStars,
):
pass

View file

@ -0,0 +1,129 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# 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 Optional
import pyrogram
from pyrogram import raw, types
class GetBusinessAccountGifts:
async def get_business_account_gifts(
self: "pyrogram.Client",
business_connection_id: str,
exclude_unsaved: Optional[bool] = None,
exclude_saved: Optional[bool] = None,
exclude_unlimited: Optional[bool] = None,
exclude_limited: Optional[bool] = None,
exclude_upgraded: Optional[bool] = None,
sort_by_price: Optional[bool] = None,
limit: int = 0,
offset: str = "",
):
"""Return the gifts received and owned by a managed business account.
.. note::
Requires the `can_view_gifts_and_stars` business bot right.
.. include:: /_includes/usable-by/bots.rst
Parameters:
business_connection_id (``str``):
Unique identifier of business connection on behalf of which to send the request.
exclude_unsaved (``bool``, *optional*):
Pass True to exclude gifts that arent saved to the accounts profile page.
exclude_saved (``bool``, *optional*):
Pass True to exclude gifts that are saved to the accounts profile page.
exclude_unlimited (``bool``, *optional*):
Pass True to exclude gifts that can be purchased an unlimited number of times.
exclude_limited (``bool``, *optional*):
Pass True to exclude gifts that can be purchased a limited number of times.
exclude_upgraded (``bool``, *optional*):
Pass True to exclude upgraded gifts.
sort_by_price (``bool``, *optional*):
Pass True to sort results by gift price instead of send date. Sorting is applied before pagination.
offset (``str``, *optional*):
Offset of the first entry to return as received from the previous request.
limit (``int``, *optional*):
The maximum number of gifts to be returned.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Gift` objects.
Example:
.. code-block:: python
async for gift in app.get_business_account_gifts(connection_id):
print(gift)
"""
current = 0
total = abs(limit) or (1 << 31) - 1
limit = min(100, total)
connection_info = await self.get_business_connection(business_connection_id)
while True:
r = await self.invoke(
raw.functions.payments.GetSavedStarGifts(
peer=await self.resolve_peer(connection_info.user.id),
offset=offset,
limit=limit,
exclude_unsaved=exclude_unsaved,
exclude_saved=exclude_saved,
exclude_unlimited=exclude_unlimited,
exclude_limited=exclude_limited,
exclude_unique=exclude_upgraded,
sort_by_value=sort_by_price
),
sleep_threshold=60,
business_connection_id=business_connection_id
)
users = {i.id: i for i in r.users}
chats = {i.id: i for i in r.chats}
user_star_gifts = [
await types.Gift._parse_saved(self, gift, users, chats)
for gift in r.gifts
]
if not user_star_gifts:
return
for gift in user_star_gifts:
yield gift
current += 1
if current >= total:
return
offset = r.next_offset
if not offset:
return

View file

@ -0,0 +1,61 @@
# Pyrogram - Telegram MTProto API Client Library for Python
# Copyright (C) 2017-present Dan <https://github.com/delivrance>
# Copyright (C) 2022-present Mayuri-Chan <https://github.com/Mayuri-Chan>
#
# 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 Optional, Union
import pyrogram
from pyrogram import raw
class GetBusinessAccountStarBalance:
async def get_business_account_star_balance(
self: "pyrogram.Client",
business_connection_id: str,
) -> int:
"""Return the amount of Telegram Stars owned by a managed business account.
.. note::
Requires the `can_view_gifts_and_stars` business bot right.
.. include:: /_includes/usable-by/bots.rst
Parameters:
business_connection_id (``str``):
Unique identifier of business connection on behalf of which to send the request.
Returns:
``int``: On success, the current stars balance is returned.
Example:
.. code-block:: python
# Get stars balance
await app.get_business_account_star_balance("connection_id")
"""
connection_info = await self.get_business_connection(business_connection_id)
r = await self.invoke(
raw.functions.payments.GetStarsStatus(
peer=await self.resolve_peer(connection_info.user.id),
),
business_connection_id=business_connection_id
)
return r.balance.amount

View file

@ -0,0 +1,72 @@
# 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
class TransferBusinessAccountStars:
async def transfer_business_account_stars(
self: "pyrogram.Client",
business_connection_id: str,
star_count: int,
) -> bool:
"""Transfers Telegram Stars from the business account balance to the bots balance.
.. note::
Requires the `can_transfer_stars` business bot right.
.. include:: /_includes/usable-by/users.rst
Parameters:
business_connection_id (``str``):
Unique identifier of the business connection.
star_count (``int`` | ``str``):
Number of Telegram Stars to transfer, 1-10000.
Returns:
``bool``: On success, True is returned.
"""
# Why telegram won't let us just use InputPeerSelf :(
if self.me:
bot_id = self.me.id
else:
bot_id = (
await self.invoke(raw.functions.users.GetUsers(id=[raw.types.InputPeerSelf()]))
)[0].id
invoice = raw.types.InputInvoiceBusinessBotTransferStars(
bot=await self.resolve_peer(bot_id), stars=star_count
)
payment_form = await self.invoke(
raw.functions.payments.GetPaymentForm(invoice=invoice),
business_connection_id=business_connection_id,
)
await self.invoke(
raw.functions.payments.SendStarsForm(
form_id=payment_form.form_id,
invoice=invoice,
),
business_connection_id=business_connection_id,
)
return True

View file

@ -52,6 +52,7 @@ class SendAnimation:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -145,6 +146,11 @@ class SendAnimation:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -226,6 +232,7 @@ class SendAnimation:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -50,6 +50,7 @@ class SendAudio:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
message_effect_id: int = None,
@ -137,6 +138,11 @@ class SendAudio:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -216,6 +222,7 @@ class SendAudio:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -40,6 +40,7 @@ class SendCachedMedia:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -104,6 +105,11 @@ class SendCachedMedia:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -144,6 +150,7 @@ class SendCachedMedia:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -38,6 +38,7 @@ class SendContact:
business_connection_id: str = None,
reply_to_message_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -95,6 +96,11 @@ class SendContact:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -139,6 +145,7 @@ class SendContact:
reply_to_message_id=reply_to_message_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -36,6 +36,7 @@ class SendDice:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -91,6 +92,11 @@ class SendDice:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -143,6 +149,7 @@ class SendDice:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -48,6 +48,7 @@ class SendDocument:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
message_effect_id: int = None,
@ -129,6 +130,11 @@ class SendDocument:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -203,6 +209,7 @@ class SendDocument:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -38,6 +38,7 @@ class SendLocation:
business_connection_id: str = None,
reply_to_message_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -89,6 +90,11 @@ class SendLocation:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
reply_to_message_id (``int``, *optional*):
If the message is a reply, ID of the original message
@ -136,6 +142,7 @@ class SendLocation:
reply_to_message_id=reply_to_message_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -56,6 +56,7 @@ class SendMediaGroup:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -104,6 +105,11 @@ class SendMediaGroup:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -180,6 +186,7 @@ class SendMediaGroup:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode,
@ -271,7 +278,7 @@ class SendMediaGroup:
w=i.width,
h=i.height
),
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media)),
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
]
if is_animation:
attributes.append(raw.types.DocumentAttributeAnimated())
@ -339,7 +346,7 @@ class SendMediaGroup:
w=i.width,
h=i.height
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "video.mp4")),
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "video.mp4")),
],
),
),
@ -371,7 +378,7 @@ class SendMediaGroup:
performer=i.performer,
title=i.title
),
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media)),
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
],
),
),
@ -419,7 +426,7 @@ class SendMediaGroup:
performer=i.performer,
title=i.title
),
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "audio.mp3")),
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "audio.mp3")),
],
),
),
@ -445,7 +452,7 @@ class SendMediaGroup:
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media)),
raw.types.DocumentAttributeFilename(file_name=i.file_name or os.path.basename(i.media)),
],
),
),
@ -490,7 +497,7 @@ class SendMediaGroup:
file=file,
thumb=thumb,
attributes=[
raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "file.zip")),
raw.types.DocumentAttributeFilename(file_name=i.file_name or getattr(i.media, "name", "file.zip")),
],
),
),

View file

@ -39,6 +39,7 @@ class SendMessage:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: int = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -100,6 +101,11 @@ class SendMessage:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of the monoforum.
for reply to message from a monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -174,6 +180,7 @@ class SendMessage:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -46,6 +46,7 @@ class SendPhoto:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -122,6 +123,11 @@ class SendPhoto:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -203,6 +209,7 @@ class SendPhoto:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -44,6 +44,7 @@ class SendSticker:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -104,6 +105,11 @@ class SendSticker:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -178,6 +184,7 @@ class SendSticker:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -50,6 +50,7 @@ class SendVideo:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
cover: Union[str, BinaryIO] = None,
@ -151,6 +152,11 @@ class SendVideo:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -251,6 +257,7 @@ class SendVideo:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -45,6 +45,7 @@ class SendVideoNote:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
parse_mode: Optional["enums.ParseMode"] = None,
@ -118,6 +119,11 @@ class SendVideoNote:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -197,6 +203,7 @@ class SendVideoNote:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -46,6 +46,7 @@ class SendVoice:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -121,6 +122,11 @@ class SendVoice:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -189,6 +195,7 @@ class SendVoice:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -39,6 +39,7 @@ class SendWebPage:
reply_to_message_id: int = None,
reply_to_story_id: int = None,
reply_to_chat_id: Union[int, str] = None,
reply_to_monoforum_id: Union[int, str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
schedule_date: datetime = None,
@ -106,6 +107,11 @@ class SendWebPage:
for reply to message from another chat.
You can also use chat public link in form of *t.me/<username>* (str).
reply_to_monoforum_id (``int`` | ``str``, *optional*):
Unique identifier for the target user of monoforum.
for reply to message from monoforum.
for channel administrators only.
quote_text (``str``, *optional*):
Text to quote.
for reply_to_message only.
@ -161,6 +167,7 @@ class SendWebPage:
reply_to_story_id=reply_to_story_id,
message_thread_id=message_thread_id,
reply_to_chat_id=reply_to_chat_id,
reply_to_monoforum_id=reply_to_monoforum_id,
quote_text=quote_text,
quote_entities=quote_entities,
parse_mode=parse_mode

View file

@ -17,7 +17,7 @@
# 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 pyrogram import raw, types
from pyrogram import enums, raw, types
from ..object import Object
from typing import Union

View file

@ -62,6 +62,10 @@ class InputMediaAudio(InputMedia):
title (``str``, *optional*):
Title of the audio
file_name (``str``, *optional*):
File name of the audio sent.
Defaults to file's path basename.
"""
def __init__(
@ -73,7 +77,8 @@ class InputMediaAudio(InputMedia):
caption_entities: List[MessageEntity] = None,
duration: int = 0,
performer: str = "",
title: str = ""
title: str = "",
file_name: str = None
):
super().__init__(media, caption, parse_mode, caption_entities)
@ -81,3 +86,4 @@ class InputMediaAudio(InputMedia):
self.duration = duration
self.performer = performer
self.title = title
self.file_name = file_name

View file

@ -51,6 +51,10 @@ class InputMediaDocument(InputMedia):
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*.
file_name (``str``, *optional*):
File name of the document sent.
Defaults to file's path basename.
"""
def __init__(
@ -59,8 +63,10 @@ class InputMediaDocument(InputMedia):
thumb: str = None,
caption: str = "",
parse_mode: Optional["enums.ParseMode"] = None,
caption_entities: List[MessageEntity] = None
caption_entities: List[MessageEntity] = None,
file_name: str = None
):
super().__init__(media, caption, parse_mode, caption_entities)
self.thumb = thumb
self.file_name = file_name

View file

@ -62,6 +62,10 @@ class InputMediaVideo(InputMedia):
duration (``int``, *optional*):
Video duration.
file_name (``str``, *optional*):
File name of the video sent.
Defaults to file's path basename.
supports_streaming (``bool``, *optional*):
Pass True, if the uploaded video is suitable for streaming.
@ -79,6 +83,7 @@ class InputMediaVideo(InputMedia):
width: int = 0,
height: int = 0,
duration: int = 0,
file_name: str = None,
supports_streaming: bool = True,
has_spoiler: bool = None,
):
@ -88,5 +93,6 @@ class InputMediaVideo(InputMedia):
self.width = width
self.height = height
self.duration = duration
self.file_name = file_name
self.supports_streaming = supports_streaming
self.has_spoiler = has_spoiler

View file

@ -19,6 +19,7 @@
from .input_message_content import InputMessageContent
from .input_reply_to_message import InputReplyToMessage
from .input_reply_to_monoforum import InputReplyToMonoforum
from .input_reply_to_story import InputReplyToStory
from .input_text_message_content import InputTextMessageContent
from .input_location_message_content import InputLocationMessageContent
@ -29,6 +30,7 @@ from .input_invoice_message_content import InputInvoiceMessageContent
__all__ = [
"InputMessageContent",
"InputReplyToMessage",
"InputReplyToMonoforum",
"InputReplyToStory",
"InputTextMessageContent",
"InputLocationMessageContent",

View file

@ -0,0 +1,43 @@
# 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 pyrogram import raw
from ..object import Object
class InputReplyToMonoforum(Object):
"""Contains information about a target replied monoforum.
Parameters:
monoforum_peer (:obj:`~pyrogram.raw.types.InputPeer`):
An InputPeer.
"""
def __init__(
self, *,
monoforum_peer: "raw.types.InputPeer"
):
super().__init__()
self.monoforum_peer = monoforum_peer
def write(self):
return raw.types.InputReplyToMonoForum(
monoforum_peer_id=self.monoforum_peer
).write()

View file

@ -480,6 +480,7 @@ class Message(Object, Update):
gift_code: "types.GiftCode" = None,
gift: "types.Gift" = None,
screenshot_taken: "types.ScreenshotTaken" = None,
paid_message_price_changed: "types.PaidMessagePriceChanged" = None,
invoice: "types.Invoice" = None,
story: Union["types.MessageStory", "types.Story"] = None,
alternative_videos: List["types.AlternativeVideo"] = None,
@ -596,6 +597,7 @@ class Message(Object, Update):
self.gift_code = gift_code
self.gift = gift
self.screenshot_taken = screenshot_taken
self.paid_message_price_changed = paid_message_price_changed
self.invoice = invoice
self.story = story
self.video = video
@ -760,6 +762,7 @@ class Message(Object, Update):
gift_code = None
gift = None
screenshot_taken = None
paid_message_price_changed = None
service_type = None
chat_join_type = None
@ -881,6 +884,9 @@ class Message(Object, Update):
elif isinstance(action, raw.types.MessageActionScreenshotTaken):
screenshot_taken = types.ScreenshotTaken()
service_type = enums.MessageServiceType.SCREENSHOT_TAKEN
elif isinstance(action, raw.types.MessageActionPaidMessagesPrice):
paid_message_price_changed = types.PaidMessagePriceChanged._parse(action)
service_type = enums.MessageServiceType.PAID_MESSAGE_PRICE_CHANGED
parsed_message = Message(
id=message.id,
@ -926,6 +932,7 @@ class Message(Object, Update):
contact_registered=contact_registered,
gift_code=gift_code,
screenshot_taken=screenshot_taken,
paid_message_price_changed=paid_message_price_changed,
raw=message,
chat_join_type=chat_join_type,
client=client
@ -970,7 +977,7 @@ class Message(Object, Update):
else:
parsed_message.message_thread_id = message.reply_to.reply_to_msg_id
parsed_message.is_topic_message = True
elif parsed_message.chat.is_forum and parsed_message.message_thread_id is None:
elif parsed_message.chat.type == enums.ChatType.FORUM and parsed_message.message_thread_id is None:
parsed_message.message_thread_id = 1
parsed_message.is_topic_message = True
@ -1299,7 +1306,7 @@ class Message(Object, Update):
pass
else:
parsed_message.reply_to_story = reply_to_story
if parsed_message.chat.is_forum and parsed_message.message_thread_id is None:
if parsed_message.chat.type == enums.ChatType.FORUM and parsed_message.message_thread_id is None:
parsed_message.message_thread_id = 1
parsed_message.is_topic_message = True
@ -1314,9 +1321,14 @@ class Message(Object, Update):
self.chat.type in (enums.ChatType.GROUP, enums.ChatType.SUPERGROUP, enums.ChatType.CHANNEL)
and self.chat.username
):
if self.chat.type == enums.ChatType.SUPERGROUP and self.message_thread_id:
return f"https://t.me/{self.chat.username}/{self.message_thread_id}/{self.id}"
return f"https://t.me/{self.chat.username}/{self.id}"
else:
return f"https://t.me/c/{utils.get_channel_id(self.chat.id)}/{self.id}"
if self.chat.type == enums.ChatType.PRIVATE:
return f"tg://openmessage?user_id={self.from_user.id}&message_id={self.id}"
if self.message_thread_id:
return f"https://t.me/c/{utils.get_channel_id(self.chat.id)}/{self.message_thread_id}/{self.id}"
return f"https://t.me/c/{utils.get_channel_id(self.chat.id)}/{self.id}"
@property
def content(self) -> str:

View file

@ -27,6 +27,7 @@ from .input_stars_transaction import InputStarsTransaction
from .invoice import Invoice
from .labeled_price import LabeledPrice
from .paid_media import PaidMedia
from .paid_message_price_changed import PaidMessagePriceChanged
from .payment_form import PaymentForm
from .payment_info import PaymentInfo
from .payment_refunded import PaymentRefunded
@ -46,6 +47,7 @@ __all__ = [
"Invoice",
"LabeledPrice",
"PaidMedia",
"PaidMessagePriceChanged",
"PaymentForm",
"PaymentInfo",
"PaymentRefunded",

View file

@ -0,0 +1,49 @@
# 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
from pyrogram import raw
from pyrogram import types
from ..object import Object
class PaidMessagePriceChanged(Object):
"""A PaidMessagePriceChanged.
Parameters:
stars_amount (``int``):
Amount of stars.
extended_media (List of :obj:`~pyrogram.types.Animation` | :obj:`~pyrogram.types.ExtendedMediaPreview` | :obj:`~pyrogram.types.Photo` | :obj:`~pyrogram.types.Video`, *optional*):
Extended media.
"""
def __init__(
self,
*,
stars_amount: int,
):
super().__init__()
self.stars_amount = stars_amount
@staticmethod
def _parse(action: "raw.types.MessageActionPaidMessagesPrice") -> "PaidMessagePriceChanged":
return PaidMessagePriceChanged(
stars_amount=action.stars
)

View file

@ -56,9 +56,6 @@ class Chat(Object):
is_support (``bool``):
True, if this chat is part of the Telegram support team. Users and bots only.
is_forum (``bool``, *optional*):
True, if the supergroup chat is a forum
is_participants_hidden (``bool``, *optional*):
True, if the chat members are hidden.
Returned only in :meth:`~pyrogram.Client.get_chat`.
@ -170,6 +167,10 @@ class Chat(Object):
The linked discussion group (in case of channels) or the linked channel (in case of supergroups).
Returned only in :meth:`~pyrogram.Client.get_chat`.
linked_forum (:obj:`~pyrogram.types.Chat`, *optional*):
The linked monoforum (in case of channels) or the linked channel (in case of monoforum).
Returned only in :meth:`~pyrogram.Client.get_chat`.
send_as_chat (:obj:`~pyrogram.types.Chat`, *optional*):
The default "send_as" chat.
Returned only in :meth:`~pyrogram.Client.get_chat`.
@ -231,7 +232,6 @@ class Chat(Object):
is_scam: bool = None,
is_fake: bool = None,
is_support: bool = None,
is_forum: bool = None,
is_participants_hidden: bool = None,
is_join_request: bool = None,
is_join_to_send: bool = None,
@ -263,6 +263,7 @@ class Chat(Object):
permissions: "types.ChatPermissions" = None,
distance: int = None,
linked_chat: "types.Chat" = None,
linked_forum: "types.Chat" = None,
send_as_chat: "types.Chat" = None,
available_reactions: Optional["types.ChatReactions"] = None,
usernames: List["types.Username"] = None,
@ -286,7 +287,6 @@ class Chat(Object):
self.is_scam = is_scam
self.is_fake = is_fake
self.is_support = is_support
self.is_forum = is_forum
self.is_participants_hidden = is_participants_hidden
self.is_join_request = is_join_request
self.is_join_to_send = is_join_to_send
@ -318,6 +318,7 @@ class Chat(Object):
self.permissions = permissions
self.distance = distance
self.linked_chat = linked_chat
self.linked_forum = linked_forum
self.send_as_chat = send_as_chat
self.available_reactions = available_reactions
self.usernames = usernames
@ -394,6 +395,16 @@ class Chat(Object):
restriction_reason = getattr(channel, "restriction_reason", [])
user_name = getattr(channel, "username", None)
active_usernames = getattr(channel, "usernames", [])
if getattr(channel, "monoforum", None):
chat_type = enums.ChatType.MONOFORUM
elif getattr(channel, "forum", None):
chat_type = enums.ChatType.FORUM
elif getattr(channel, "megagroup", None):
chat_type = enums.ChatType.SUPERGROUP
elif getattr(channel, "broadcast", None):
chat_type = enums.ChatType.CHANNEL
else:
chat_type = enums.ChatType.GROUP
usernames = None
if len(active_usernames) >= 1:
usernames = []
@ -410,13 +421,12 @@ class Chat(Object):
return Chat(
id=peer_id,
type=enums.ChatType.SUPERGROUP if getattr(channel, "megagroup", None) else enums.ChatType.CHANNEL,
type=chat_type,
is_verified=getattr(channel, "verified", None),
is_restricted=getattr(channel, "restricted", None),
is_creator=getattr(channel, "creator", None),
is_scam=getattr(channel, "scam", None),
is_fake=getattr(channel, "fake", None),
is_forum=getattr(channel, "forum", None),
is_join_request=getattr(channel, "join_request", None),
is_join_to_send=getattr(channel, "join_to_send", None),
is_slowmode_enabled=getattr(channel, "slowmode_enabled", None),
@ -546,9 +556,14 @@ class Chat(Object):
linked_chat_raw = chats.get(full_chat.linked_chat_id, None)
linked_forum_raw = chats.get(getattr(chat_raw, "linked_monoforum_id"), None)
if linked_chat_raw:
parsed_chat.linked_chat = Chat._parse_channel_chat(client, linked_chat_raw)
if linked_forum_raw:
parsed_chat.linked_forum = Chat._parse_channel_chat(client, linked_forum_raw)
default_send_as = full_chat.default_send_as
if default_send_as:

View file

@ -487,6 +487,7 @@ async def get_reply_to(
reply_to_message_id: int = None,
reply_to_story_id: int = None,
message_thread_id: int = None,
reply_to_monoforum_id: Union[int,str] = None,
reply_to_chat_id: Union[int,str] = None,
quote_text: str = None,
quote_entities: List["types.MessageEntity"] = None,
@ -495,7 +496,12 @@ async def get_reply_to(
):
reply_to = None
reply_to_chat = None
if reply_to_message_id or message_thread_id:
if reply_to_monoforum_id:
peer = await client.resolve_peer(reply_to_monoforum_id)
reply_to = types.InputReplyToMonoforum(
monoforum_peer=peer
)
elif reply_to_message_id or message_thread_id:
text, entities = (await parse_text_entities(client, quote_text, parse_mode, quote_entities)).values()
if reply_to_chat_id is not None:
reply_to_chat = await client.resolve_peer(reply_to_chat_id)
@ -507,7 +513,7 @@ async def get_reply_to(
quote_entities=entities,
quote_offset=quote_offset,
)
if reply_to_story_id:
elif reply_to_story_id:
peer = await client.resolve_peer(chat_id)
reply_to = types.InputReplyToStory(
peer=peer,