8000 Add support for Telegram send Document, Audio, Video, Sticker, Animat… · symfony/symfony@612eb3d · GitHub
[go: up one dir, main page]

Skip to content

Commit 612eb3d

Browse files
committed
Add support for Telegram send Document, Audio, Video, Sticker, Animation, Contact and Venue
1 parent 366a1ed commit 612eb3d

File tree

3 files changed

+199
-17
lines changed

3 files changed

+199
-17
lines changed

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

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function photo(string $url): static
117117
*/
118118
public function uploadPhoto(string $path): static
119119
{
120-
$this->options['upload_photo'] = $path;
120+
$this->options['upload']['photo'] = $path;
121121

122122
return $this;
123123
}
@@ -172,8 +172,149 @@ public function answerCallbackQuery(string $callbackQueryId, bool $showAlert = f
172172
*/
173173
public function location(float $latitude, float $longitude): static
174174
{
175-
$this->options['latitude'] = $latitude;
176-
$this->options['longitude'] = $longitude;
175+
$this->options['location'] = ['latitude' => $latitude, 'longitude' => $longitude];
176+
177+
return $this;
178+
}
179+
180+
/**
181+
* @return $this
182+
*/
183+
public function venue(float $latitude, float $longitude, string $title, string $address): static
184+
{
185+
$this->options['venue'] = [
186+
'latitude' => $latitude,
187+
'longitude' => $longitude,
188+
'title' => $title,
189+
'address' => $address
190+
];
191+
192+
return $this;
193+
}
194+
195+
/**
196+
* @return $this
197+
*/
198+
public function document(string $url): static
199+
{
200+
$this->options['document'] = $url;
201+
202+
return $this;
203+
}
204+
205+
/**
206+
* @return $this
207+
*/
208+
public function uploadDocument(string $path): static
209+
{
210+
$this->options['upload']['document'] = $path;
211+
212+
return $this;
213+
}
214+
215+
/**
216+
* @return $this
217+
*/
218+
public function video(string $url): static
219+
{
220+
$this->options['video'] = $url;
221+
222+
return $this;
223+
}
224+
225+
/**
226+
* @return $this
227+
*/
228+
public function uploadVideo(string $path): static
229+
{
230+
$this->options['upload']['video'] = $path;
231+
232+
return $this;
233+
}
234+
235+
/**
236+
* @return $this
237+
*/
238+
public function audio(string $url): static
239+
{
240+
$this->options['audio'] = $url;
241+
242+
return $this;
243+
}
244+
245+
/**
246+
* @return $this
247+
*/
248+
public function uploadAudio(string $path): static
249+
{
250+
$this->options['upload']['audio'] = $path;
251+
252+
return $this;
253+
}
254+
255+
/**
256+
* @return $this
257+
*/
258+
public function animation(string $url): static
259+
{
260+
$this->options['animation'] = $url;
261+
262+
return $this;
263+
}
264+
265+
/**
266+
* @return $this
267+
*/
268+
public function uploadAnimation(string $path): static
269+
{
270+
$this->options['upload']['animation'] = $path;
271+
272+
return $this;
273+
}
274+
275+
/**
276+
* @return $this
277+
*/
278+
public function sticker(string $url, string $emoji = null): static
279+
{
280+
$this->options['sticker'] = $url;
281+
if ($emoji !== null) {
282+
$this->options['emoji'] = $emoji;
283+
}
284+
285+
return $this;
286+
}
287+
288+
/**
289+
* @return $this
290+
*/
291+
public function uploadSticker(string $path, string $emoji = null): static
292+
{
293+
$this->options['upload']['sticker'] = $path;
294+
if ($emoji !== null) {
295+
$this->options['emoji'] = $emoji;
296+
}
297+
298+
return $this;
299+
}
300+
301+
/**
302+
* @return $this
303+
*/
304+
public function contact(string $phoneNumber, string $firstName, ?string $lastName = null, ?string $vCard = null): static
305+
{
306+
$this->options['contact'] = [
307+
'phone_number' => $phoneNumber,
308+
'first_name' => $firstName,
309+
];
310+
311+
if ($lastName !== null) {
312+
$this->options['contact']['last_name'] = $lastName;
313+
}
314+
315+
if ($vCard !== null) {
316+
$this->options['contact']['vcard'] = $vCard;
317+
}
177318

178319
return $this;
179320
}

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

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,29 @@ protected function doSend(MessageInterface $message): SentMessage
7070
$options = $message->getOptions()?->toArray() ?? [];
7171
$optionsContainer = 'json';
7272
$options['chat_id'] ??= $message->getRecipientId() ?: $this->chatChannel;
73-
$options['text'] = $message->getSubject();
73+
$text = $message->getSubject();
7474

7575
if (!isset($options['parse_mode']) || TelegramOptions::PARSE_MODE_MARKDOWN_V2 === $options['parse_mode']) {
7676
$options['parse_mode'] = TelegramOptions::PARSE_MODE_MARKDOWN_V2;
77-
$options['text'] = preg_replace('/([_*\[\]()~`>#+\-=|{}.!\\\\])/', '\\\\$1', $message->getSubject());
77+
$text = preg_replace('/([_*\[\]()~`>#+\-=|{}.!\\\\])/', '\\\\$1', $text);
7878
}
7979

80-
if (isset($options['upload_photo'])) {
81-
$options['photo'] = fopen($options['upload_photo'], 'r');
80+
if (isset($options['upload'])) {
81+
foreach ($options['upload'] as $option => $path) {
82+
$options[$option] = fopen($path, 'r');
83+
}
8284
$optionsContainer = 'body';
83-
unset($options['upload_photo']);
85+
unset($options['upload']);
8486
}
8587

86-
if (isset($options['photo'])) {
87-
$options['caption'] = $options['text'];
88-
unset($options['text']);
88+
$messageOption = $this->getTextOption($options);
89+
if ($messageOption !== null) {
90+
$options[$messageOption] = $text;
8991
}
92+
$method = $this->getPath($options);
93+
$options = $this->expandOptions($options, 'contact', 'location', 'venue');
9094

91-
$endpoint = sprintf('https://%s/bot%s/%s', $this->getEndpoint(), $this->token, $this->getPath($options));
95+
$endpoint = sprintf('https://%s/bot%s/%s', $this->getEndpoint(), $this->token, $method);
9296

9397
$response = $this->client->request('POST', $endpoint, [
9498
$optionsContainer => array_filter($options),
@@ -122,7 +126,14 @@ private function getPath(array $options): string
122126
isset($options['message_id']) => 'editMessageText',
123127
isset($options['callback_query_id']) => 'answerCallbackQuery',
124128
isset($options['photo']) => 'sendPhoto',
125-
(isset($options['longitude']) && isset($options['latitude'])) => 'sendLocation',
129+
isset($options['location']) => 'sendLocation',
130+
isset($options['audio']) => 'sendAudio',
131+
isset($options['document']) => 'sendDocument',
132+
isset($options['video']) => 'sendVideo',
133+
isset($options['animation']) => 'sendAnimation',
134+
isset($options['venue']) => 'sendVenue',
135+
isset($options['contact']) => 'sendContact',
136+
isset($options['sticker']) => 'sendSticker',
126137
default => 'sendMessage',
127138
};
128139
}
@@ -135,4 +146,34 @@ private function getAction(array $options): string
135146
default => 'post',
136147
};
137148
}
149+
150+
private function getTextOption(array $options): ?string
151+
{
152+
return match(true) {
153+
isset($options['photo']) => 'caption',
154+
isset($options['audio']) => 'caption',
155+
isset($options['document']) => 'caption',
156+
isset($options['video']) => 'caption',
157+
isset($options['animation']) => 'caption',
158+
isset($options['sticker']) => null,
159+
isset($options['location']) => null,
160+
isset($options['venue']) => null,
161+
isset($options['contact']) => null,
162+
default => 'text',
163+
};
164+
}
165+
166+
private function expandOptions(array $options, string ...$optionsForExpand): array
167+
{
168+
foreach ($optionsForExpand as $optionForExpand) {
169+
if (isset($options[$optionForExpand])) {
170+
if (is_array($options[$optionForExpand])) {
171+
$options = array_merge($options, $options[$optionForExpand]);
172+
}
173+
unset($options[$optionForExpand]);
174+
}
175+
}
176+
177+
return $options;
178+
}
138179
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public function testSendWithOptions()
129129

130130
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
131131
$this->assertStringEndsWith('/sendMessage', $url);
132-
$this->assertSame($expectedBody, json_decode($options['body'], true));
132+
$this->assertEqualsCanonicalizing($expectedBody, json_decode($options['body'], true));
133133

134134
return $response;
135135
});
@@ -263,7 +263,7 @@ public function testSendWithChannelOverride()
263263
];
264264

265265
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
266-
$this->assertSame($expectedBody, json_decode($options['body'], true));
266+
$this->assertEqualsCanonicalizing($expectedBody, json_decode($options['body'], true));
267267

268268
return $response;
269269
});
@@ -321,7 +321,7 @@ public function testSendWithMarkdownShouldEscapeSpecialCharacters()
321321
];
322322

323323
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
324-
$this->assertSame($expectedBody, json_decode($options['body'], true));
324+
$this->assertEqualsCanonicalizing($expectedBody, json_decode($options['body'], true));
325325

326326
return $response;
327327
});
@@ -649,7 +649,7 @@ public function testSendLocationWithOptions()
649649

650650
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
651651
$this->assertStringEndsWith('/sendLocation', $url);
652-
$this->assertSame($expectedBody, json_decode($options['body'], true));
652+
$this->assertEqualsCanonicalizing($expectedBody, json_decode($options['body'], true));
653653

654654
return $response;
655655
});

0 commit comments

Comments
 (0)
0