Skip to content
Open
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f14cb4b
Add animation, photo, sticker, video in InputPollOption
SpEcHiDe Apr 4, 2026
27ef600
Add send_poll
SpEcHiDe Apr 4, 2026
05b2dcd
Added the field poll_option_id to the class ReplyParameters, allowing…
SpEcHiDe Apr 4, 2026
36b17d1
Added the field reply_to_poll_option_id to the class Message.
SpEcHiDe Apr 4, 2026
477de79
Rename TranslatedText to FormattedText
SpEcHiDe Apr 4, 2026
32d8398
Add unknown_errors
SpEcHiDe Apr 4, 2026
84b2410
send_poll
SpEcHiDe Apr 4, 2026
3d5d1d5
changes
SpEcHiDe Apr 4, 2026
ac04e67
changes
SpEcHiDe Apr 5, 2026
e81334a
changes
SpEcHiDe Apr 5, 2026
25f07a6
changes
SpEcHiDe Apr 5, 2026
1374584
changes
SpEcHiDe Apr 5, 2026
07ee41f
changes
SpEcHiDe Apr 5, 2026
788f111
KeyboardButtonRequestManagedBot
SpEcHiDe Apr 5, 2026
e09576e
Added the field can_manage_bots to the class User.
SpEcHiDe Apr 5, 2026
f0bb1a5
Added updates about the creation of managed bots and the change of th…
SpEcHiDe Apr 5, 2026
b584ea4
docs
SpEcHiDe Apr 5, 2026
98e88be
changes
SpEcHiDe Apr 5, 2026
8b9f22c
Add note
SpEcHiDe Apr 5, 2026
0b208ae
changes
SpEcHiDe Apr 6, 2026
6110a39
docs
SpEcHiDe Apr 6, 2026
54c70f2
bound
SpEcHiDe Apr 6, 2026
aed56c2
add_poll_option, delete_poll_option
SpEcHiDe Apr 6, 2026
cf24853
docs
SpEcHiDe Apr 6, 2026
a7c63d7
Add tone in translate_message_text and translate_text
SpEcHiDe Apr 6, 2026
b1f1e8d
Add undocumented parameters in send_poll and reply_poll
SpEcHiDe Apr 6, 2026
e0e4d7b
Add unknown_errors
SpEcHiDe Apr 6, 2026
f04cfde
changes
SpEcHiDe Apr 6, 2026
f8ffa17
docs
SpEcHiDe Apr 6, 2026
408023c
add missing entities
SpEcHiDe Apr 6, 2026
643b3eb
Add unread_poll_vote_count in ForumTopic and Dialog
SpEcHiDe Apr 6, 2026
0416531
Add uses_unofficial_app to Chat
SpEcHiDe Apr 6, 2026
a35c76a
live photo
SpEcHiDe Apr 6, 2026
fd90125
Merge branch 'dev' into LP
SpEcHiDe Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions pyrogram/methods/messages/send_photo.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async def send_photo(
"types.ReplyKeyboardRemove",
"types.ForceReply"
] = None,
video: Union[str, "io.BytesIO"] = None,
reply_to_message_id: int = None,
progress: Callable = None,
progress_args: tuple = ()
Expand Down Expand Up @@ -146,6 +147,14 @@ async def send_photo(
Additional interface options. An object for an inline keyboard, custom reply keyboard,
instructions to remove reply keyboard or to force a reply from the user.

video (``str`` | :obj:`io.BytesIO`):
Video of the live photo.
Pass a file_id as string to send a video that exists on the Telegram servers,
pass an HTTP URL as a string for Telegram to get a video from the Internet,
pass a file path as string to upload a new video that exists on your local machine, or
pass a binary file-like object with its attribute ".name" set for in-memory uploads.
Pass None if the photo isn't a live photo.

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
Expand Down Expand Up @@ -204,14 +213,61 @@ async def send_photo(
file = None
ttl_seconds = 0x7FFFFFFF if view_once else ttl_seconds

live_photo = False
live_video_photo_si = None

try:
if video:
live_photo = True

is_bytes_io = isinstance(video, io.BytesIO)
is_uploaded_file = is_bytes_io or os.path.isfile(video)
is_external_url = not is_uploaded_file and re.match("^https?://", video)

if is_bytes_io and not hasattr(video, "name"):
video.name = "video.mp4"
if is_uploaded_file:
live_photo_video_file = await self.invoke(
raw.functions.messages.UploadMedia(
business_connection_id=business_connection_id,
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaUploadedDocument(
file=await self.save_file(video)
)
)
)
live_video_photo_si = raw.types.InputDocument(
id=live_photo_video_file.document.id,
access_hash=live_photo_video_file.document.access_hash,
file_reference=live_photo_video_file.document.file_reference
)
elif is_external_url:
live_photo_video_file = await self.invoke(
raw.functions.messages.UploadMedia(
business_connection_id=business_connection_id,
peer=await self.resolve_peer(chat_id),
media=raw.types.InputMediaDocumentExternal(
url=video
)
)
)
live_video_photo_si = raw.types.InputDocument(
id=live_photo_video_file.document.id,
access_hash=live_photo_video_file.document.access_hash,
file_reference=live_photo_video_file.document.file_reference
)
else:
live_video_photo_si = (utils.get_input_media_from_file_id(video, FileType.VIDEO)).id

if isinstance(photo, str):
if os.path.isfile(photo):
file = await self.save_file(photo, progress=progress, progress_args=progress_args)
media = raw.types.InputMediaUploadedPhoto(
file=file,
ttl_seconds=ttl_seconds,
spoiler=has_spoiler,
live_photo=live_photo,
video=live_video_photo_si,
)
elif re.match("^https?://", photo):
media = raw.types.InputMediaPhotoExternal(
Expand All @@ -226,6 +282,8 @@ async def send_photo(
ttl_seconds=ttl_seconds,
has_spoiler=has_spoiler
)
media.live_photo = live_photo
media.video = live_video_photo_si
else:
file = await self.save_file(photo, progress=progress, progress_args=progress_args)
media = raw.types.InputMediaUploadedPhoto(
Expand Down