Add SendMediaGroup method to send media albums

This commit is contained in:
netkas 2024-10-10 12:15:42 -04:00
parent 0145279516
commit 891bd6f183
3 changed files with 167 additions and 0 deletions

View file

@ -15,6 +15,7 @@
use TgBotLib\Methods\SendAnimation;
use TgBotLib\Methods\SendAudio;
use TgBotLib\Methods\SendDocument;
use TgBotLib\Methods\SendMediaGroup;
use TgBotLib\Methods\SendMessage;
use TgBotLib\Methods\SendPaidMedia;
use TgBotLib\Methods\SendPhoto;
@ -40,6 +41,7 @@
case SEND_VOICE = 'sendVoice';
case SEND_VIDEO_NOTE = 'sendVideoNote';
case SEND_PAID_MEDIA = 'sendPaidMedia';
case SEND_MEDIA_GROUP = 'sendMediaGroup';
/**
* Executes a command on the provided bot with the given parameters.
@ -69,6 +71,7 @@
self::SEND_VOICE => SendVoice::execute($bot, $parameters),
self::SEND_VIDEO_NOTE => SendVideoNote::execute($bot, $parameters),
self::SEND_PAID_MEDIA => SendPaidMedia::execute($bot, $parameters),
self::SEND_MEDIA_GROUP => SendMediaGroup::execute($bot, $parameters),
};
}
}

View file

@ -0,0 +1,115 @@
<?php
namespace TgBotLib\Methods;
use TgBotLib\Abstracts\Method;
use TgBotLib\Bot;
use TgBotLib\Enums\Methods;
use TgBotLib\Exceptions\TelegramException;
use TgBotLib\Objects\InputMedia;
use TgBotLib\Objects\Message;
use TgBotLib\Objects\ReplyParameters;
class SendMediaGroup extends Method
{
/**
* Use this method to send a group of photos, videos, documents or audios as an album.
* Documents and audio files can be only grouped in an album with messages of the same type.
* On success, an array of Messages that were sent is returned.
*
* @param Bot $bot
* @param array $parameters
* @return Message[]
* @throws TelegramException
*/
public static function execute(Bot $bot, array $parameters = []): array
{
if (!isset($parameters['media']) || !is_array($parameters['media']))
{
throw new TelegramException('Media parameter must be an array');
}
$mediaCount = count($parameters['media']);
if ($mediaCount < 2 || $mediaCount > 10)
{
throw new TelegramException('Media array must include 2-10 items');
}
$hasLocalFiles = false;
$attachments = [];
$processedMedia = [];
foreach ($parameters['media'] as $index => $mediaItem)
{
if (!($mediaItem instanceof InputMedia))
{
throw new TelegramException('Invalid media item type');
}
$mediaArray = $mediaItem->toArray();
// Check for local files in the media
if (isset($mediaArray['media']) && is_string($mediaArray['media']) && file_exists($mediaArray['media']) && is_file($mediaArray['media']))
{
$hasLocalFiles = true;
$attachmentKey = "file{$index}";
$attachments[$attachmentKey] = $mediaArray['media'];
$mediaArray['media'] = "attach://{$attachmentKey}";
}
// Check for local thumbnail
if (isset($mediaArray['thumbnail']) && is_string($mediaArray['thumbnail']) && file_exists($mediaArray['thumbnail']) && is_file($mediaArray['thumbnail']))
{
$hasLocalFiles = true;
$thumbKey = "thumb{$index}";
$attachments[$thumbKey] = $mediaArray['thumbnail'];
$mediaArray['thumbnail'] = "attach://{$thumbKey}";
}
$processedMedia[] = $mediaArray;
}
// Update parameters with processed media
$parameters['media'] = json_encode($processedMedia);
// Handle reply parameters
if (isset($parameters['reply_parameters']) && $parameters['reply_parameters'] instanceof ReplyParameters)
{
$parameters['reply_parameters'] = $parameters['reply_parameters']->toArray();
}
$curl = $hasLocalFiles
? self::buildMultiUpload($bot, Methods::SEND_MEDIA_GROUP->value, $attachments, $parameters)
: self::buildPost($bot, Methods::SEND_MEDIA_GROUP->value, $parameters);
$result = self::executeCurl($curl);
return array_map(function ($messageData) {return Message::fromArray($messageData);}, $result);
}
/**
* @inheritDoc
*/
public static function getRequiredParameters(): ?array
{
return [
'chat_id',
'media'
];
}
/**
* @inheritDoc
*/
public static function getOptionalParameters(): ?array
{
return [
'business_connection_id',
'message_thread_id',
'disable_notification',
'protect_content',
'message_effect_id',
'reply_parameters'
];
}
}

View file

@ -0,0 +1,49 @@
<?php
namespace TgBotLib\Methods;
use PHPUnit\Framework\TestCase;
use TgBotLib\Bot;
use TgBotLib\Enums\Types\ParseMode;
use TgBotLib\Objects\InputMedia\InputMediaPhoto;
use TgBotLib\Objects\LinkPreviewOptions;
use TgBotLib\Objects\Message;
class SendMediaGroupTest extends TestCase
{
const string TEST_IMAGE_PATH = __DIR__ . DIRECTORY_SEPARATOR . 'sample' . DIRECTORY_SEPARATOR . 'oj_simpson.png';
private static Bot $bot;
/**
* @return void
*/
public static function setUpBeforeClass(): void
{
self::$bot = new Bot(BOT_TOKEN);
self::$bot->setAutoRetry(true);
}
/**
* Tests the `sendMessage` function of the bot instance.
*
* @return void
*/
public function testSendMediaGroup(): void
{
$result = self::$bot->sendMediaGroup(
chat_id: TEST_CHAT_ID,
media: [
(new InputMediaPhoto())->setMedia(self::TEST_IMAGE_PATH),
(new InputMediaPhoto())->setMedia(self::TEST_IMAGE_PATH)
]
);
$this->assertIsArray($result);
foreach ($result as $message)
{
$this->assertInstanceOf(Message::class, $message);
}
}
}