1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 04:08:59 +01:00

Merge branch 'xcgu-v8' into v8

This commit is contained in:
Daniil Gentili 2024-04-18 20:03:06 +02:00
commit bc6fdb88b2
2 changed files with 731 additions and 2 deletions

View File

@ -1740,6 +1740,164 @@ abstract class InternalDoc
{
return $this->wrapper->getAPI()->sendPhoto($peer, $file, $caption, $parseMode, $callback, $fileName, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
}
/**
* Sends a sticker.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param Cancellation $cancellation Cancellation.
*
*/
final public function sendSticker(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, ?callable $callback = null, ?string $fileName = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $updateStickersetsOrder = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendSticker($peer, $file, $callback, $fileName, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $updateStickersetsOrder, $forceResend, $cancellation);
}
/**
* Sends a video.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param boolean $spoiler Whether the message is a spoiler
* @param boolean $roundMessage Whether the message should be round
* @param boolean $supportsStreaming Whether the video supports streaming
* @param boolean $noSound Whether the video has no sound
* @param integer|null $duration Duration of the video
* @param integer|null $width Width of the video
* @param integer|null $height Height of the video
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param Cancellation $cancellation Cancellation.
*
*/
final public function sendVideo(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream|null $thumb = null, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, bool $spoiler = false, bool $roundMessage = false, bool $supportsStreaming = false, bool $noSound = false, ?int $duration = null, ?int $width = null, ?int $height = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendVideo($peer, $file, $thumb, $caption, $parseMode, $callback, $fileName, $ttl, $spoiler, $roundMessage, $supportsStreaming, $noSound, $duration, $width, $height, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $forceResend, $cancellation);
}
/**
* Sends a gif.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param boolean $spoiler Whether the message is a spoiler
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
final public function sendGif(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream|null $thumb = null, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, bool $spoiler = false, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendGif($peer, $file, $thumb, $caption, $parseMode, $callback, $fileName, $ttl, $spoiler, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $forceResend, $cancellation);
}
/**
* Sends an audio.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $duration Duration of the audio
* @param string|null $title Title of the audio
* @param string|null $performer Performer of the audio
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
final public function sendAudio(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream|null $thumb = null, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $duration = null, ?string $title = null, ?string $performer = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendAudio($peer, $file, $thumb, $caption, $parseMode, $callback, $fileName, $duration, $title, $performer, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $forceResend, $cancellation);
}
/**
* Sends a voice.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param integer|null $duration Duration of the voice
* @param array|null $waveform Waveform of the voice
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
final public function sendVoice(string|int $peer, \danog\MadelineProto\EventHandler\Message|\danog\MadelineProto\EventHandler\Media|\danog\MadelineProto\LocalFile|\danog\MadelineProto\RemoteUrl|\danog\MadelineProto\BotApiFileId|\Amp\ByteStream\ReadableStream $file, string $caption = '', \danog\MadelineProto\ParseMode $parseMode = \danog\MadelineProto\ParseMode::TEXT, ?callable $callback = null, ?string $fileName = null, ?int $ttl = null, ?int $duration = null, ?array $waveform = null, ?int $replyToMsgId = null, ?int $topMsgId = null, ?array $replyMarkup = null, string|int|null $sendAs = null, ?int $scheduleDate = null, bool $silent = false, bool $noForwards = false, bool $background = false, bool $clearDraft = false, bool $forceResend = false, ?\Amp\Cancellation $cancellation = null): \danog\MadelineProto\EventHandler\Message
{
return $this->wrapper->getAPI()->sendVoice($peer, $file, $caption, $parseMode, $callback, $fileName, $ttl, $duration, $waveform, $replyToMsgId, $topMsgId, $replyMarkup, $sendAs, $scheduleDate, $silent, $noForwards, $background, $clearDraft, $forceResend, $cancellation);
}
/**
* Set NOOP update handler, ignoring all updates.
*/

View File

@ -23,11 +23,17 @@ namespace danog\MadelineProto\MTProtoTools;
use Amp\ByteStream\ReadableBuffer;
use Amp\ByteStream\ReadableStream;
use Amp\Cancellation;
use Amp\Process\Process;
use AssertionError;
use danog\MadelineProto\BotApiFileId;
use danog\MadelineProto\EventHandler\Media;
use danog\MadelineProto\EventHandler\Media\Audio;
use danog\MadelineProto\EventHandler\Media\Document;
use danog\MadelineProto\EventHandler\Media\Gif;
use danog\MadelineProto\EventHandler\Media\Photo;
use danog\MadelineProto\EventHandler\Media\Sticker;
use danog\MadelineProto\EventHandler\Media\Video;
use danog\MadelineProto\EventHandler\Media\Voice;
use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\Exception;
use danog\MadelineProto\LocalFile;
@ -37,7 +43,9 @@ use danog\MadelineProto\Settings;
use danog\MadelineProto\TL\Types\Bytes;
use Webmozart\Assert\Assert;
use function Amp\async;
use function Amp\ByteStream\buffer;
use function Amp\ByteStream\pipe;
/**
* Manages upload and download of files.
@ -108,6 +116,7 @@ trait FilesAbstraction
type: Document::class,
mimeType: $mimeType,
thumb: $thumb,
attributes: [],
peer: $peer,
file: $file,
caption: $caption,
@ -187,6 +196,7 @@ trait FilesAbstraction
type: Photo::class,
mimeType: 'image/jpeg',
thumb: null,
attributes: [],
peer: $peer,
file: $file,
caption: $caption,
@ -209,7 +219,426 @@ trait FilesAbstraction
cancellation: $cancellation
);
}
/**
* Sends a sticker.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $updateStickersetsOrder Whether to move used stickersets to top
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param Cancellation $cancellation Cancellation.
*
*/
public function sendSticker(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
?callable $callback = null,
?string $fileName = null,
?int $replyToMsgId = null,
?int $topMsgId = null,
?array $replyMarkup = null,
int|string|null $sendAs = null,
?int $scheduleDate = null,
bool $silent = false,
bool $noForwards = false,
bool $background = false,
bool $clearDraft = false,
bool $updateStickersetsOrder = false,
bool $forceResend = false,
?Cancellation $cancellation = null,
): Message {
if ($file instanceof Message) {
$file = $file->media;
if ($file === null) {
throw new AssertionError("The message must be a media message!");
}
}
return $this->sendMedia(
type: Sticker::class,
mimeType: 'image/webp',
thumb: null,
attributes: [],
peer: $peer,
file: $file,
caption: '',
parseMode: ParseMode::TEXT,
callback: $callback,
fileName: $fileName,
ttl: null,
spoiler: false,
silent: $silent,
background: $background,
clearDraft: $clearDraft,
noForwards: $noForwards,
updateStickersetsOrder: $updateStickersetsOrder,
replyToMsgId: $replyToMsgId,
topMsgId: $topMsgId,
replyMarkup: $replyMarkup,
scheduleDate: $scheduleDate,
sendAs: $sendAs,
forceResend: $forceResend,
cancellation: $cancellation
);
}
/**
* Sends a video.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param boolean $spoiler Whether the message is a spoiler
* @param boolean $roundMessage Whether the message should be round
* @param boolean $supportsStreaming Whether the video supports streaming
* @param boolean $noSound Whether the video has no sound
* @param integer|null $duration Duration of the video
* @param integer|null $width Width of the video
* @param integer|null $height Height of the video
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param Cancellation $cancellation Cancellation.
*
*/
public function sendVideo(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb = null,
string $caption = '',
ParseMode $parseMode = ParseMode::TEXT,
?callable $callback = null,
?string $fileName = null,
?int $ttl = null,
bool $spoiler = false,
bool $roundMessage = false,
bool $supportsStreaming = true,
bool $noSound = false,
?int $duration = null,
?int $width = null,
?int $height = null,
?int $replyToMsgId = null,
?int $topMsgId = null,
?array $replyMarkup = null,
int|string|null $sendAs = null,
?int $scheduleDate = null,
bool $silent = false,
bool $noForwards = false,
bool $background = false,
bool $clearDraft = false,
bool $forceResend = false,
?Cancellation $cancellation = null,
): Message {
if ($file instanceof Message) {
$file = $file->media;
if ($file === null) {
throw new AssertionError("The message must be a media message!");
}
}
$attributes = [
'round_message' => $roundMessage,
'supports_streaming' => $supportsStreaming,
'no_sound' => $noSound,
'duration' => $duration,
'w' => $width,
'h' => $height,
];
return $this->sendMedia(
type: Video::class,
mimeType: 'video/mp4',
thumb: $thumb,
attributes: $attributes,
peer: $peer,
file: $file,
caption: $caption,
parseMode: $parseMode,
callback: $callback,
fileName: $fileName,
ttl: $ttl,
spoiler: $spoiler,
silent: $silent,
background: $background,
clearDraft: $clearDraft,
noForwards: $noForwards,
updateStickersetsOrder: false,
replyToMsgId: $replyToMsgId,
topMsgId: $topMsgId,
replyMarkup: $replyMarkup,
scheduleDate: $scheduleDate,
sendAs: $sendAs,
forceResend: $forceResend,
cancellation: $cancellation
);
}
/**
* Sends a gif.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param boolean $spoiler Whether the message is a spoiler
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
public function sendGif(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb = null,
string $caption = '',
ParseMode $parseMode = ParseMode::TEXT,
?callable $callback = null,
?string $fileName = null,
?int $ttl = null,
bool $spoiler = false,
?int $replyToMsgId = null,
?int $topMsgId = null,
?array $replyMarkup = null,
int|string|null $sendAs = null,
?int $scheduleDate = null,
bool $silent = false,
bool $noForwards = false,
bool $background = false,
bool $clearDraft = false,
bool $forceResend = false,
?Cancellation $cancellation = null,
): Message {
return $this->sendMedia(
type: Gif::class,
mimeType: 'image/gif',
thumb: $thumb,
attributes: [],
peer: $peer,
file: $file,
caption: $caption,
parseMode: $parseMode,
callback: $callback,
fileName: $fileName,
ttl: $ttl,
spoiler: $spoiler,
silent: $silent,
background: $background,
clearDraft: $clearDraft,
noForwards: $noForwards,
updateStickersetsOrder: false,
replyToMsgId: $replyToMsgId,
topMsgId: $topMsgId,
replyMarkup: $replyMarkup,
scheduleDate: $scheduleDate,
sendAs: $sendAs,
forceResend: $forceResend,
cancellation: $cancellation
);
}
/**
* Sends an audio.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb Optional: Thumbnail to upload
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $duration Duration of the audio
* @param string|null $title Title of the audio
* @param string|null $performer Performer of the audio
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
public function sendAudio(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb = null,
string $caption = '',
ParseMode $parseMode = ParseMode::TEXT,
?callable $callback = null,
?string $fileName = null,
?int $duration = null,
?string $title = null,
?string $performer = null,
?int $replyToMsgId = null,
?int $topMsgId = null,
?array $replyMarkup = null,
int|string|null $sendAs = null,
?int $scheduleDate = null,
bool $silent = false,
bool $noForwards = false,
bool $background = false,
bool $clearDraft = false,
bool $forceResend = false,
?Cancellation $cancellation = null,
): Message {
$attributes = [
'duration' => $duration,
'title' => $title,
'performer' => $performer,
];
return $this->sendMedia(
type: Audio::class,
mimeType: 'audio/mpeg',
thumb: $thumb,
attributes: $attributes,
peer: $peer,
file: $file,
caption: $caption,
parseMode: $parseMode,
callback: $callback,
fileName: $fileName,
ttl: null,
spoiler: null,
silent: $silent,
background: $background,
clearDraft: $clearDraft,
noForwards: $noForwards,
updateStickersetsOrder: false,
replyToMsgId: $replyToMsgId,
topMsgId: $topMsgId,
replyMarkup: $replyMarkup,
scheduleDate: $scheduleDate,
sendAs: $sendAs,
forceResend: $forceResend,
cancellation: $cancellation
);
}
/**
* Sends a voice.
*
* Please use named arguments to call this method.
*
* @param integer|string $peer Destination peer or username.
* @param Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file File to upload: can be a message to reuse media present in a message.
* @param string $caption Caption of document
* @param ParseMode $parseMode Text parse mode for the caption
* @param ?callable(float, float, int) $callback Upload callback (percent, speed in mpbs, time elapsed)
* @param ?string $fileName Optional file name, if absent will be extracted from the passed $file.
* @param integer|null $ttl Time to live
* @param integer|null $duration Duration of the voice
* @param array|null $waveform Waveform of the voice
* @param integer|null $replyToMsgId ID of message to reply to.
* @param integer|null $topMsgId ID of thread where to send the message.
* @param array|null $replyMarkup Keyboard information.
* @param integer|string|null $sendAs Peer to send the message as.
* @param integer|null $scheduleDate Schedule date.
* @param boolean $silent Whether to send the message silently, without triggering notifications.
* @param boolean $noForwards Whether to disable forwards for this message.
* @param boolean $background Send this message as background message
* @param boolean $clearDraft Clears the draft field
* @param boolean $forceResend Whether to forcefully resend the file, even if its type and name are the same.
* @param ?Cancellation $cancellation Cancellation.
*
*/
public function sendVoice(
int|string $peer,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
string $caption = '',
ParseMode $parseMode = ParseMode::TEXT,
?callable $callback = null,
?string $fileName = null,
?int $ttl = null,
?int $duration = null,
?array $waveform = null,
?int $replyToMsgId = null,
?int $topMsgId = null,
?array $replyMarkup = null,
int|string|null $sendAs = null,
?int $scheduleDate = null,
bool $silent = false,
bool $noForwards = false,
bool $background = false,
bool $clearDraft = false,
bool $forceResend = false,
?Cancellation $cancellation = null,
): Message {
$attributes = [
'duration' => $duration,
'waveform' => $waveform,
];
return $this->sendMedia(
type: Voice::class,
mimeType: 'audio/ogg',
thumb: null,
attributes: $attributes,
peer: $peer,
file: $file,
caption: $caption,
parseMode: $parseMode,
callback: $callback,
fileName: $fileName,
ttl: $ttl,
spoiler: null,
silent: $silent,
background: $background,
clearDraft: $clearDraft,
noForwards: $noForwards,
updateStickersetsOrder: false,
replyToMsgId: $replyToMsgId,
topMsgId: $topMsgId,
replyMarkup: $replyMarkup,
scheduleDate: $scheduleDate,
sendAs: $sendAs,
forceResend: $forceResend,
cancellation: $cancellation
);
}
/**
* Sends a media.
*
@ -222,12 +651,13 @@ trait FilesAbstraction
?string $mimeType,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream $file,
Message|Media|LocalFile|RemoteUrl|BotApiFileId|ReadableStream|null $thumb,
array $attributes,
string $caption,
ParseMode $parseMode,
?callable $callback,
?string $fileName,
?int $ttl,
bool $spoiler,
?bool $spoiler,
?int $replyToMsgId,
?int $topMsgId,
?array $replyMarkup,
@ -278,6 +708,34 @@ trait FilesAbstraction
}
$attributes = match ($type) {
Video::class => [
[
'_' => 'documentAttributeVideo',
'round_message' => $file->roundMessage ?? $attributes['round_message'],
'supports_streaming' => $file->supportsStreaming ?? $attributes['supports_streaming'],
'no_sound' => $file->noSound ?? $attributes['no_sound'],
'duration' => $file->duration ?? $attributes['duration'],
'w' => $file->width ?? $attributes['w'],
'h' => $file->height ?? $attributes['h'],
],
],
Audio::class => [
[
'_' => 'documentAttributeAudio',
'duration' => $file->duration ?? $attributes['duration'],
'title' => $file->title ?? $attributes['title'],
'performer' => $file->performer ?? $attributes['performer'],
],
],
Voice::class => [
[
'_' => 'documentAttributeAudio',
'voice' => true,
'duration' => $file->duration ?? $attributes['duration'],
'waveform' => $file->waveform ?? $attributes['waveform'],
],
],
Gif::class => [['_' => 'documentAttributeAnimated']],
default => [],
};
$attributes[] = ['_' => 'documentAttributeFilename', 'file_name' => $fileName];
@ -399,6 +857,80 @@ trait FilesAbstraction
'cancellation' => $cancellation,
];
} else {
if ($reuseId) {
// Reuse
} elseif ($type === Video::class) {
if (Process::start('ffmpeg -version')->join() !== 0) {
$this->logger->logger('Install ffmpeg for video info extraction!');
} elseif ($thumb === null || $attributes[0]['duration'] === null || $attributes[0]['w'] === null || $attributes[0]['h'] === null) {
$file = $this->getStream($file, $cancellation);
$ffmpeg = 'ffmpeg -i pipe: -ss 00:00:01.000 -frames:v 1 -f image2pipe -vcodec mjpeg pipe:1';
$process = Process::start($ffmpeg);
async(fn () => pipe($file, $process->getStdin()))->finally(fn () => $process->getStdin()->close());
$thumb ??= new ReadableBuffer(buffer($process->getStdout()));
$output = buffer($process->getStderr());
if (preg_match('~Duration: (\d{2}:\d{2}:\d{2}\.\d{2}),.*? (\d{3,4})x(\d{3,4})~s', $output, $matches)) {
$time = explode(':', $matches[1]);
$hours = (int) $time[0];
$minutes = (int) $time[1];
$seconds = (int) $time[2];
$duration = $hours * 3600 + $minutes * 60 + $seconds;
$width = $matches[2];
$height = $matches[3];
$attributes[0]['w'] ??= $width;
$attributes[0]['h'] ??= $height;
$attributes[0]['duration'] ??= $duration;
}
}
} elseif ($type === Sticker::class) {
if (!extension_loaded('gd')) {
throw Exception::extension('gd');
}
$file = buffer($this->getStream($file, $cancellation), $cancellation);
$img = imagecreatefromstring($file);
$width = imagesx($img);
$height = imagesy($img);
if ($width > $height) {
$newWidth = 512;
$newHeight = (int) (512 * $height / $width);
} elseif ($width < $height) {
$newWidth = (int) (512 * $width / $height);
$newHeight = 512;
} else {
$newWidth = 512;
$newHeight = 512;
}
$temp = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresized($temp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
$stream = fopen('php://memory', 'r+');
imagewebp($temp, $stream);
rewind($stream);
$file = stream_get_contents($stream);
fclose($stream);
unset($stream);
unset($temp);
$file = new ReadableBuffer($file);
} elseif ($type === Audio::class or $type === Voice::class) {
if (Process::start('ffmpeg -version')->join() !== 0) {
$this->logger->logger('Install ffmpeg for audio info extraction!');
} elseif ($attributes[0]['duration'] === null) {
$file = $this->getStream($file, $cancellation);
$ffmpeg = 'ffmpeg -i pipe: 2>&1';
$process = Process::start($ffmpeg);
async(fn () => pipe($file, $process->getStdin()));
$output = buffer($process->getStdout());
if (preg_match('~Duration: (\d{2}:\d{2}:\d{2}\.\d{2})~', $output, $matches)) {
$time = explode(':', $matches[1]);
$hours = (int) $time[0];
$minutes = (int) $time[1];
$seconds = (int) $time[2];
$duration = $hours * 3600 + $minutes * 60 + $seconds;
$attributes[0]['duration'] = $duration;
}
}
}
$method = 'messages.sendMedia';
$media = match ($type) {
Photo::class => [
@ -407,6 +939,45 @@ trait FilesAbstraction
'file' => $file,
'ttl_seconds' => $ttl,
],
Sticker::class => [
'_' => 'inputMediaUploadedDocument',
'file' => $file,
'mime_type' => $mimeType,
'attributes' => $attributes,
],
Video::class => [
'_' => 'inputMediaUploadedDocument',
'nosound_video' => $attributes[0]['no_sound'],
'spoiler' => $spoiler,
'ttl_seconds' => $ttl,
'force_file' => false,
'file' => $file,
'thumb' => $thumb,
'mime_type' => $mimeType,
'attributes' => $attributes,
],
Gif::class => [
'_' => 'inputMediaUploadedDocument',
'spoiler' => $spoiler,
'ttl_seconds' => $ttl,
'file' => $file,
'thumb' => $thumb,
'mime_type' => $mimeType,
'attributes' => $attributes,
],
Audio::class => [
'_' => 'inputMediaUploadedDocument',
'file' => $file,
'thumb' => $thumb,
'mime_type' => $mimeType,
'attributes' => $attributes,
],
Voice::class => [
'_' => 'inputMediaUploadedDocument',
'file' => $file,
'mime_type' => $mimeType,
'attributes' => $attributes,
],
default => [
'_' => 'inputMediaUploadedDocument',
'spoiler' => $spoiler,
@ -421,7 +992,7 @@ trait FilesAbstraction
if ($reuseId) {
$media['_'] = match ($type) {
Photo::class => 'inputMediaPhoto',
Document::class => 'inputMediaDocument',
default => 'inputMediaDocument',
};
$media['id'] = $reuseId;
} else {