From dc9ca57e5214d227fc39921804a192f255891885 Mon Sep 17 00:00:00 2001 From: netkas Date: Tue, 8 Oct 2024 13:58:22 -0400 Subject: [PATCH] Add support for sending documents --- src/TgBotLib/Bot.php | 1 + src/TgBotLib/Enums/Methods.php | 3 + src/TgBotLib/Methods/SendDocument.php | 133 ++++++++++++++++++++ tests/TgBotLib/Methods/SendDocumentTest.php | 35 ++++++ tests/TgBotLib/Methods/sample/password.txt | 10 ++ 5 files changed, 182 insertions(+) create mode 100644 src/TgBotLib/Methods/SendDocument.php create mode 100644 tests/TgBotLib/Methods/SendDocumentTest.php create mode 100644 tests/TgBotLib/Methods/sample/password.txt diff --git a/src/TgBotLib/Bot.php b/src/TgBotLib/Bot.php index 855d745..2bbb34c 100644 --- a/src/TgBotLib/Bot.php +++ b/src/TgBotLib/Bot.php @@ -37,6 +37,7 @@ * @method MessageId[] copyMessages(string|int $chat_id, string|int $from_chat_id, int[] $message_ids, ?int $message_thread_id=null, ?bool $disable_notification=null, ?bool $protect_content=null, ?bool $remove_caption=null) Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, they are skipped. Service messages, paid media messages, giveaway messages, giveaway winners messages, and invoice messages can't be copied. A quiz poll can be copied only if the value of the field correct_option_id is known to the bot. The method is analogous to the method forwardMessages, but the copied messages don't have a link to the original message. Album grouping is kept for copied messages. On success, an array of MessageId of the sent messages is returned. * @method Message sendPhoto(string|int $chat_id, string $photo, ?string $business_connection_id=null, ?int $message_thread_id=null, ?string $caption=null, ?string|ParseMode $parse_mode=null, ?MessageEntity[] $caption_entities=null, ?bool $show_caption_above_media=null, ?bool $disable_notification=null, ?bool $protect_content=null, ?string $message_effect_id=null, ?ReplyParameters $reply_parameters=null, InlineKeyboardMarkup|ReplyKeyboardMarkup|ReplyKeyboardRemove|ForceReply|null $reply_markup=null) Use this method to send photos. On success, the sent Message is returned. * @method Message sendAudio(string|int $chat_id, string $audio, ?string $business_connection_id=null, ?int $message_thread_id=null, ?string $caption=null, ?string|ParseMode $parse_mode=null, ?MessageEntity[] $caption_entities=null, ?int $duration=null, ?string $performer=null, ?string $title=null, ?string $thumb=null, ?bool $disable_notification=null, ?bool $protect_content=null, ?string $message_effect_id=null, ?ReplyParameters $reply_parameters=null, InlineKeyboardMarkup|ReplyKeyboardMarkup|ReplyKeyboardRemove|ForceReply|null $reply_markup=null) Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .MP3 or .M4A format. On success, the sent Message is returned. Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future. + * @method Message sendDocument(string|int $chat_id, string $document, ?int $message_thread_id=null, ?string $thumbnail=null, ?string $caption=null, ?string|ParseMode $parse_mode=null, ?MessageEntity[] $caption_entities=null, ?bool $disable_content_type_detection=null, ?bool $disable_notification=null, ?bool $protect_content=null, ?string $message_effect_id=null, ?ReplyParameters $reply_parameters=null, InlineKeyboardMarkup|ReplyKeyboardMarkup|ReplyKeyboardRemove|ForceReply|null $reply_markup=null) Use this method to send general files. On success, the sent Message is returned. Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. */ class Bot { diff --git a/src/TgBotLib/Enums/Methods.php b/src/TgBotLib/Enums/Methods.php index 6c26495..079a7bf 100644 --- a/src/TgBotLib/Enums/Methods.php +++ b/src/TgBotLib/Enums/Methods.php @@ -13,6 +13,7 @@ use TgBotLib\Methods\GetMe; use TgBotLib\Methods\Logout; use TgBotLib\Methods\SendAudio; + use TgBotLib\Methods\SendDocument; use TgBotLib\Methods\SendMessage; use TgBotLib\Methods\SendPhoto; @@ -28,6 +29,7 @@ case COPY_MESSAGES = 'copyMessages'; case SEND_PHOTO = 'sendPhoto'; case SEND_AUDIO = 'sendAudio'; + case SEND_DOCUMENT = 'sendDocument'; /** * Executes a command on the provided bot with the given parameters. @@ -51,6 +53,7 @@ self::COPY_MESSAGES => CopyMessages::execute($bot, $parameters), self::SEND_PHOTO => SendPhoto::execute($bot, $parameters), self::SEND_AUDIO => SendAudio::execute($bot, $parameters), + self::SEND_DOCUMENT => SendDocument::execute($bot, $parameters), }; } } diff --git a/src/TgBotLib/Methods/SendDocument.php b/src/TgBotLib/Methods/SendDocument.php new file mode 100644 index 0000000..5e880a9 --- /dev/null +++ b/src/TgBotLib/Methods/SendDocument.php @@ -0,0 +1,133 @@ +value; + } + + if(isset($parameters['caption_entities']) && is_array($parameters['caption_entities'])) + { + $entities = []; + foreach($parameters['caption_entities'] as $entity) + { + if($entity instanceof MessageEntity) + { + $entities[] = $entity->toArray(); + } + else + { + $entities[] = $entity; + } + } + $parameters['caption_entities'] = $entities; + } + + if(isset($parameters['reply_parameters']) && $parameters['reply_parameters'] instanceof ReplyParameters) + { + $parameters['reply_parameters'] = $parameters['reply_parameters']->toArray(); + } + + if(isset($parameters['reply_markup']) && $parameters['reply_markup'] instanceof ObjectTypeInterface) + { + $parameters['reply_markup'] = $parameters['reply_markup']->toArray(); + } + + // Handle file uploads + $hasLocalDocument = isset($parameters['document']) && is_string($parameters['document']) && + file_exists($parameters['document']) && is_file($parameters['document']); + $hasLocalThumb = isset($parameters['thumbnail']) && is_string($parameters['thumbnail']) && + file_exists($parameters['thumbnail']) && is_file($parameters['thumbnail']); + + if ($hasLocalDocument || $hasLocalThumb) + { + $files = []; + + if ($hasLocalDocument) + { + $files['document'] = $parameters['document']; + unset($parameters['document']); + } + + if ($hasLocalThumb) + { + $files['thumbnail'] = $parameters['thumbnail']; + unset($parameters['thumbnail']); + } + + if (count($files) > 1) + { + // Multiple files to upload + $curl = self::buildMultiUpload($bot, Methods::SEND_DOCUMENT->value, $files, $parameters); + } + else + { + // Single file to upload + $fileParam = array_key_first($files); + $curl = self::buildUpload($bot, Methods::SEND_DOCUMENT->value, $fileParam, $files[$fileParam], $parameters); + } + + return Message::fromArray(self::executeCurl($curl)); + } + + // If no local files to upload, use regular POST method + return Message::fromArray(self::executeCurl(self::buildPost($bot, Methods::SEND_DOCUMENT->value, $parameters))); + } + + /** + * @inheritDoc + */ + public static function getRequiredParameters(): ?array + { + return [ + 'chat_id', + 'document' + ]; + } + + /** + * @inheritDoc + */ + public static function getOptionalParameters(): ?array + { + return [ + 'business_connection_id', + 'message_thread_id', + 'thumbnail', + 'caption', + 'parse_mode', + 'caption_entities', + 'disable_content_type_detection', + 'disable_notification', + 'protect_content', + 'message_effect_id', + 'reply_parameters', + 'reply_markup' + ]; + } +} \ No newline at end of file diff --git a/tests/TgBotLib/Methods/SendDocumentTest.php b/tests/TgBotLib/Methods/SendDocumentTest.php new file mode 100644 index 0000000..dde18b3 --- /dev/null +++ b/tests/TgBotLib/Methods/SendDocumentTest.php @@ -0,0 +1,35 @@ +sendDocument( + chat_id: TEST_CHAT_ID, + document: self::TEST_DOCUMENT_PATH, + caption: 'Test Unit: testSendDocument', + ); + + $this->assertInstanceOf(Message::class, $result); + $this->assertEquals('Test Unit: testSendDocument', $result->getCaption()); + } +} diff --git a/tests/TgBotLib/Methods/sample/password.txt b/tests/TgBotLib/Methods/sample/password.txt new file mode 100644 index 0000000..919d9e5 --- /dev/null +++ b/tests/TgBotLib/Methods/sample/password.txt @@ -0,0 +1,10 @@ +The Plague: Our recent unknown intruder penetrated using the superuser account, giving him access to our whole system. + +Margo: Precisely what you're paid to prevent. + +The Plague: Someone didn't bother reading my carefully prepared memo on commonly-used passwords. Now, then, as I so +meticulously pointed out, the four most-used passwords are: love, sex, secret, and... + +Margo: [glares at The Plague] + +The Plague: god. So, would your holiness care to change her password? \ No newline at end of file