Skip to content

Commit 92c8f4c

Browse files
committed
Fix upload files
1 parent fa7875a commit 92c8f4c

File tree

5 files changed

+232
-154
lines changed

5 files changed

+232
-154
lines changed

src/Api.php

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
3434
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
3535
use InvalidArgumentException;
36+
use JsonException;
3637
use LogicException;
3738
use Psr\Log\LoggerInterface;
3839
use Psr\Log\NullLogger;
@@ -470,27 +471,51 @@ public function uploadAttachment(UploadType $type, string $filePath): AbstractAt
470471

471472
$uploadEndpoint = $this->getUploadUrl($type);
472473

473-
$uploadResult = $this->client->upload(
474-
$uploadEndpoint->url,
475-
$fileHandle,
476-
basename($filePath),
477-
);
474+
// For audio and video, the token is received *before* the upload
475+
// The actual upload response is not JSON and can be ignored on success
476+
if ($type === UploadType::Audio || $type === UploadType::Video) {
477+
if (empty($uploadEndpoint->token)) {
478+
throw new SerializationException(
479+
"API did not return a pre-upload token for type '$type->value'."
480+
);
481+
}
482+
$this->client->upload($uploadEndpoint->url, $fileHandle, basename($filePath));
483+
fclose($fileHandle);
478484

485+
return match ($type) {
486+
UploadType::Audio => new AudioAttachmentRequest($uploadEndpoint->token),
487+
UploadType::Video => new VideoAttachmentRequest($uploadEndpoint->token),
488+
};
489+
}
490+
491+
// For images and files, the token is in the response *after* the upload.
492+
$responseBody = $this->client->upload($uploadEndpoint->url, $fileHandle, basename($filePath));
479493
fclose($fileHandle);
480494

481-
if (!isset($uploadResult['token'])) {
482-
throw new SerializationException('Could not find "token" in upload server response.');
495+
try {
496+
$uploadResult = json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
497+
} catch (JsonException $e) {
498+
throw new SerializationException('Failed to decode upload server response JSON.', 0, $e);
499+
}
500+
501+
// Using switch because match expression arms cannot be code blocks.
502+
switch ($type) {
503+
case UploadType::Image:
504+
$photoData = current($uploadResult['photos'] ?? []); // Get first photo from response
505+
if (!isset($photoData['token'])) {
506+
throw new SerializationException('Could not find "token" in photo upload response.');
507+
}
508+
return PhotoAttachmentRequest::fromToken($photoData['token']);
509+
case UploadType::File:
510+
if (!isset($uploadResult['token'])) {
511+
throw new SerializationException('Could not find "token" in file upload response.');
512+
}
513+
return new FileAttachmentRequest($uploadResult['token']);
483514
}
484515

485-
return match ($type) {
486-
UploadType::Image => PhotoAttachmentRequest::fromToken($uploadResult['token']),
487-
UploadType::Video => new VideoAttachmentRequest($uploadResult['token']),
488-
UploadType::Audio => new AudioAttachmentRequest($uploadResult['token']),
489-
UploadType::File => new FileAttachmentRequest($uploadResult['token']), // @phpstan-ignore-line
490-
default => throw new LogicException(
491-
"Attachment creation for type '$type->value' is not yet implemented."
492-
),
493-
};
516+
// @codeCoverageIgnoreStart
517+
throw new LogicException("Attachment creation for type '$type->value' is not yet implemented."); // @phpstan-ignore-line
518+
// @codeCoverageIgnoreEnd
494519
}
495520

496521
/**

src/Client.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public function request(string $method, string $uri, array $queryParams = [], ar
122122
/**
123123
* @inheritDoc
124124
*/
125-
public function upload(string $uri, mixed $fileContents, string $fileName): array
125+
public function upload(string $uri, mixed $fileContents, string $fileName): string
126126
{
127127
$boundary = '--------------------------' . microtime(true);
128128
$bodyStream = $this->streamFactory->createStream();
@@ -152,13 +152,7 @@ public function upload(string $uri, mixed $fileContents, string $fileName): arra
152152

153153
$this->handleErrorResponse($response);
154154

155-
$responseBody = (string)$response->getBody();
156-
157-
try {
158-
return json_decode($responseBody, true, 512, JSON_THROW_ON_ERROR);
159-
} catch (JsonException $e) {
160-
throw new SerializationException('Failed to decode upload server response JSON.', 0, $e);
161-
}
155+
return (string)$response->getBody();
162156
}
163157

164158
/**

src/ClientApiInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ public function request(string $method, string $uri, array $queryParams = [], ar
3232
* @param resource|string $fileContents File content (stream resource or string).
3333
* @param string $fileName The name of the file that will be sent to the server.
3434
*
35-
* @return array<string, mixed>
35+
* @return string The raw response body from the upload server.
3636
* @throws ClientApiException
3737
* @throws NetworkException
3838
* @throws SerializationException
3939
*/
40-
public function upload(string $uri, mixed $fileContents, string $fileName): array;
40+
public function upload(string $uri, mixed $fileContents, string $fileName): string;
4141
}

0 commit comments

Comments
 (0)