Skip to content

Commit 0ba9064

Browse files
committed
Fix BC with sending photo in Telegram by file_id
1 parent f1ac295 commit 0ba9064

File tree

4 files changed

+124
-24
lines changed

4 files changed

+124
-24
lines changed

src/Symfony/Component/Notifier/Bridge/Telegram/README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ With a Telegram message, you can use the `TelegramOptions` class to add
5454
[message options](https://core.telegram.org/bots/api).
5555

5656
```php
57-
use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\Button\InlineKeyboardButton;
58-
use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\InlineKeyboardMarkup;
5957
use Symfony\Component\Notifier\Bridge\Telegram\TelegramOptions;
6058
use Symfony\Component\Notifier\Message\ChatMessage;
6159

@@ -76,15 +74,32 @@ $chatMessage->options($telegramOptions);
7674
$chatter->send($chatMessage);
7775
```
7876

77+
[Telegram supports 3 ways](https://core.telegram.org/bots/api#sending-files) for passing photo:
78+
79+
* Pass image HTTP URL to Telegram
80+
```
81+
$telegramOptions = (new TelegramOptions())
82+
->photo('https://symfony.com/favicons/android-chrome-192x192.png');
83+
```
84+
* Pass Telegram file_id
85+
```
86+
$telegramOptions = (new TelegramOptions())
87+
->photo('ABCDEF');
88+
```
89+
* Post the file using multipart/form-data
90+
```
91+
$telegramOptions = (new TelegramOptions())
92+
->uploadPhoto('files/android-chrome-192x192.png');
93+
```
94+
95+
7996
Adding Location to a Message
8097
----------------------------
8198

8299
With a Telegram message, you can use the `TelegramOptions` class to add
83100
[message options](https://core.telegram.org/bots/api).
84101

85102
```php
86-
use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\Button\InlineKeyboardButton;
87-
use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\InlineKeyboardMarkup;
88103
use Symfony\Component\Notifier\Bridge\Telegram\TelegramOptions;
89104
use Symfony\Component\Notifier\Message\ChatMessage;
90105

src/Symfony/Component/Notifier/Bridge/Telegram/TelegramOptions.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ public function photo(string $url): static
112112
return $this;
113113
}
114114

115+
/**
116+
* @return $this
117+
*/
118+
public function uploadPhoto(string $path): static
119+
{
120+
$this->options['upload_photo'] = $path;
121+
122+
return $this;
123+
}
124+
115125
/**
116126
* @return $this
117127
*/

src/Symfony/Component/Notifier/Bridge/Telegram/TelegramTransport.php

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,15 @@ protected function doSend(MessageInterface $message): SentMessage
7777
$options['text'] = preg_replace('/([_*\[\]()~`>#+\-=|{}.!])/', '\\\\$1', $message->getSubject());
7878
}
7979

80+
if (isset($options['upload_photo'])) {
81+
$options['photo'] = fopen($options['upload_photo'], 'r');
82+
$optionsContainer = 'body';
83+
unset($options['upload_photo']);
84+
}
85+
8086
if (isset($options['photo'])) {
8187
$options['caption'] = $options['text'];
8288
unset($options['text']);
83-
if ($this->isPhotoPrivate($options['photo'])) {
84-
$options['photo'] = fopen($options['photo'], 'r');
85-
$optionsContainer = 'body';
86-
}
8789
}
8890

8991
$endpoint = sprintf('https://%s/bot%s/%s', $this->getEndpoint(), $this->token, $this->getPath($options));
@@ -133,12 +135,4 @@ private function getAction(array $options): string
133135
default => 'post',
134136
};
135137
}
136-
137-
private function isPhotoPrivate(string $photo): bool
138-
{
139-
return match (parse_url($photo, \PHP_URL_SCHEME)) {
140-
'http', 'https' => false,
141-
default => true,
142-
};
143-
}
144138
}

src/Symfony/Component/Notifier/Bridge/Telegram/Tests/TelegramTransportTest.php

Lines changed: 89 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ public function testSendWithMarkdownShouldEscapeSpecialCharacters()
331331
$transport->send(new ChatMessage('I contain special characters _ * [ ] ( ) ~ ` > # + - = | { } . ! to send.'));
332332
}
333333

334-
public function testSendPhotoWithOptions()
334+
public function testSendPhotoByHttpUrlWithOptions()
335335
{
336336
$response = $this->createMock(ResponseInterface::class);
337337
$response->expects($this->exactly(2))
@@ -412,7 +412,88 @@ public function testSendPhotoWithOptions()
412412
$this->assertEquals('telegram://api.telegram.org?channel=testChannel', $sentMessage->getTransport());
413413
}
414414

415-
public function testSendLocalPhotoWithOptions()
415+
public function testSendPhotoByFileIdWithOptions()
416+
{
417+
$response = $this->createMock(ResponseInterface::class);
418+
$response->expects($this->exactly(2))
419+
->method('getStatusCode')
420+
->willReturn(200);
421+
422+
$content = <<<JSON
423+
{
424+
"ok": true,
425+
"result": {
426+
"message_id": 1,
427+
"from": {
428+
"id": 12345678,
429+
"is_bot": true,
430+
"first_name": "YourBot",
431+
"username": "YourBot"
432+
},
433+
"chat": {
434+
"id": 1234567890,
435+
"first_name": "John",
436+
"last_name": "Doe",
437+
"username": "JohnDoe",
438+
"type": "private"
439+
},
440+
"date": 1459958199,
441+
"photo": [
442+
{
443+
"file_id": "ABCDEF",
444+
"file_unique_id" : "ABCDEF1",
445+
"file_size": 1378,
446+
"width": 90,
447+
"height": 51
448+
},
449+
{
450+
"file_id": "ABCDEF",
451+
"file_unique_id" : "ABCDEF2",
452+
"file_size": 19987,
453+
"width": 320,
454+
"height": 180
455+
}
456+
],
457+
"caption": "Hello from Bot!"
458+
}
459+
}
460+
JSON;
461+
462+
$response->expects($this->once())
463+
->method('getContent')
464+
->willReturn($content)
465+
;
466+
467+
$expectedBody = [
468+
'photo' => 'ABCDEF',
469+
'has_spoiler' => true,
470+
'chat_id' => 'testChannel',
471+
'parse_mode' => 'MarkdownV2',
472+
'caption' => 'testMessage',
473+
];
474+
475+
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
476+
$this->assertStringEndsWith('/sendPhoto', $url);
477+
$this->assertSame($expectedBody, json_decode($options['body'], true));
478+
479+
return $response;
480+
});
481+
482+
$transport = self::createTransport($client, 'testChannel');
483+
484+
$messageOptions = new TelegramOptions();
485+
$messageOptions
486+
->photo('ABCDEF')
487+
->hasSpoiler(true)
488+
;
489+
490+
$sentMessage = $transport->send(new ChatMessage('testMessage', $messageOptions));
491+
492+
$this->assertEquals(1, $sentMessage->getMessageId());
493+
$this->assertEquals('telegram://api.telegram.org?channel=testChannel', $sentMessage->getTransport());
494+
}
495+
496+
public function testSendPhotoByUploadWithOptions()
416497
{
417498
$response = $this->createMock(ResponseInterface::class);
418499
$response->expects($this->exactly(2))
@@ -470,11 +551,6 @@ public function testSendLocalPhotoWithOptions()
470551

471552
$this->assertSame('Content-Length: 576', $options['normalized_headers']['content-length'][0]);
472553
$expectedBody = <<<BODY
473-
--{$matches['boundary']}
474-
Content-Disposition: form-data; name="photo"; filename="fixtures.png"
475-
Content-Type: image/png
476-
477-
%s
478554
--{$matches['boundary']}
479555
Content-Disposition: form-data; name="has_spoiler"
480556
@@ -488,6 +564,11 @@ public function testSendLocalPhotoWithOptions()
488564
489565
MarkdownV2
490566
--{$matches['boundary']}
567+
Content-Disposition: form-data; name="photo"; filename="fixtures.png"
568+
Content-Type: image/png
569+
570+
%s
571+
--{$matches['boundary']}
491572
Content-Disposition: form-data; name="caption"
492573
493574
testMessage
@@ -510,7 +591,7 @@ public function testSendLocalPhotoWithOptions()
510591

511592
$messageOptions = new TelegramOptions();
512593
$messageOptions
513-
->photo(__DIR__.'/fixtures.png')
594+
->uploadPhoto(__DIR__.'/fixtures.png')
514595
->hasSpoiler(true)
515596
;
516597

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy