8000 [Notifier] Allow to update Slack messages · symfony/symfony@e410909 · GitHub
[go: up one dir, main page]

Skip to content

Commit e410909

Browse files
[Notifier] Allow to update Slack messages
Update existing SlackTransport to allow message updates. Because chat.update API method only allows channel ids, this PR also includes updates to SentMessage
1 parent d8d93c6 commit e410909

File tree

6 files changed

+119
-11
lines changed

6 files changed

+119
-11
lines changed

src/Symfony/Component/Notifier/Bridge/Slack/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.3
5+
---
6+
7+
* Allow to update Slack messages
8+
49
6.0
510
---
611

src/Symfony/Component/Notifier/Bridge/Slack/SlackOptions.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
/**
2222
* @author Fabien Potencier <fabien@symfony.com>
2323
*/
24-
final class SlackOptions implements MessageOptionsInterface
24+
class SlackOptions implements MessageOptionsInterface
2525
{
2626
private const MAX_BLOCKS = 50;
2727

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\Slack;
13+
14+
use Symfony\Component\Notifier\Message\ChatMessage;
15+
use Symfony\Component\Notifier\Message\MessageInterface;
16+
use Symfony\Component\Notifier\Message\SentMessage;
17+
18+
/**
19+
* @author Maxim Dovydenok <dovydenok.maxim@gmail.com>
20+
*/
21+
final class SlackSentMessage extends SentMessage
22+
{
23+
private string $channelId;
24+
25+
public function __construct(MessageInterface $original, string $transport, string $channelId, string $messageId)
26+
{
27+
parent::__construct($original, $transport);
28+
$this->channelId = $channelId;
29+
$this->setMessageId($messageId);
30+
}
31+
32+
public function getChannelId(): string
33+
{
34+
return $this->channelId;
35+
}
36+
37+
public function getUpdateMessage(string $subject, array $options = []): ChatMessage
38+
{
39+
return new ChatMessage($subject, new UpdateMessageSlackOptions($this->channelId, $this->getMessageId(), $options));
40+
}
41+
}

src/Symfony/Component/Notifier/Bridge/Slack/SlackTransport.php

+5-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
1818
use Symfony\Component\Notifier\Message\ChatMessage;
1919
use Symfony\Component\Notifier\Message\MessageInterface;
20-
use Symfony\Component\Notifier\Message\SentMessage;
2120
use Symfony\Component\Notifier\Transport\AbstractTransport;
2221
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2322
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
@@ -63,7 +62,7 @@ public function supports(MessageInterface $message): bool
6362
/**
6463
* @see https://api.slack.com/methods/chat.postMessage
6564
*/
66-
protected function doSend(MessageInterface $message): SentMessage
65+
protected function doSend(MessageInterface $message): SlackSentMessage
6766
{
6867
if (!$message instanceof ChatMessage) {
6968
throw new UnsupportedMessageTypeException(__CLASS__, ChatMessage::class, $message);
@@ -82,7 +81,9 @@ protected function doSend(MessageInterface $message): SentMessage
8281
$options['channel'] = $message->getRecipientId() ?: $this->chatChannel;
8382
}
8483
$options['text'] = $message->getSubject();
85-
$response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/api/chat.postMessage', [
84+
85+
$apiMethod = $opts instanceof UpdateMessageSlackOptions ? 'chat.update' : 'chat.postMessage';
86+
$response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/api/'.$apiMethod, [
8687
'json' => array_filter($options),
8788
'auth_bearer' => $this->accessToken,
8889
'headers' => [
@@ -107,9 +108,6 @@ protected function doSend(MessageInterface $message): SentMessage
107108
throw new TransportException(sprintf('Unable to post the Slack message: "%s"%s.', $result['error'], $errors), $response);
108109
}
109110

110-
$sentMessage = new SentMessage($message, (string) $this);
111-
$sentMessage->setMessageId($result['ts']);
112-
113-
return $sentMessage;
111+
return new SlackSentMessage($message, (string) $this, $result['channel'], $result['ts']);
114112
}
115113
}

src/Symfony/Component/Notifier/Bridge/Slack/Tests/SlackTransportTest.php

+41-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\HttpClient\MockHttpClient;
1515
use Symfony\Component\Notifier\Bridge\Slack\SlackOptions;
16+
use Symfony\Component\Notifier\Bridge\Slack\SlackSentMessage;
1617
use Symfony\Component\Notifier\Bridge\Slack\SlackTransport;
1718
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
1819
use Symfony\Component\Notifier\Exception\LogicException;
@@ -115,7 +116,7 @@ public function testSendWithOptions()
115116

116117
$response->expects($this->once())
117118
->method('getContent')
118-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
119+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
119120

120121
$expectedBody = json_encode(['channel' => $channel, 'text' => $message]);
121122

@@ -130,6 +131,8 @@ public function testSendWithOptions()
130131
$sentMessage = $transport->send(new ChatMessage('testMessage'));
131132

132133
$this->assertSame('1503435956.000247', $sentMessage->getMessageId());
134+
$this->assertInstanceOf(SlackSentMessage::class, $sentMessage);
135+
$this->assertSame('C123456', $sentMessage->getChannelId());
133136
}
134137

135138
public function testSendWithNotification()
@@ -145,7 +148,7 @@ public function testSendWithNotification()
145148

146149
$response->expects($this->once())
147150
->method('getContent')
148-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
151+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
149152

150153
$notification = new Notification($message);
151154
$chatMessage = ChatMessage::fromNotification($notification);
@@ -223,7 +226,7 @@ public function testSendIncludesContentTypeWithCharset()
223226

224227
$response->expects($this->once())
225228
->method('getContent')
226-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
229+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
227230

228231
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response): ResponseInterface {
229232
$this->assertContains('Content-Type: application/json; charset=utf-8', $options['headers']);
@@ -263,4 +266,39 @@ public function testSendWithErrorsIncluded()
263266

264267
$transport->send(new ChatMessage('testMessage'));
265268
}
269+
270+
public function testUpdateMessage()
271+
{
272+
$response = $this->createMock(ResponseInterface::class);
273+
274+
$response->expects($this->exactly(2))
275+
->method('getStatusCode')
276+
->willReturn(200);
277+
278+
$response->expects($this->once())
279+
->method('getContent')
280+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
281+
282+
$sentMessage = new SlackSentMessage(new ChatMessage('Hello'), 'slack', 'C123456', '1503435956.000247');
283+
$chatMessage = $sentMessage->getUpdateMessage('Hello World');
284+
285+
$expectedBody = json_encode([
286+
'channel' => 'C123456',
287+
'ts' => '1503435956.000247',
288+
'text' => 'Hello World',
289+
]);
290+
291+
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
292+
$this->assertJsonStringEqualsJsonString($expectedBody, $options['body']);
293+
$this->assertStringEndsWith('chat.update', $url);
294+
295+
return $response;
296+
});
297+
298+
$transport = $this->createTransport($client, 'another-channel');
299+
300+
$sentMessage = $transport->send($chatMessage);
301+
302+
$this->assertSame('1503435956.000247', $sentMessage->getMessageId());
303+
}
266304
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Notifier\Bridge\Slack;
13+
14+
/**
15+
* @author Maxim Dovydenok <dovydenok.maxim@gmail.com>
16+
*/
17+
final class UpdateMessageSlackOptions extends SlackOptions
18+
{
19+
public function __construct(string $channelId, string $messageId, array $options = [])
20+
{
21+
$options['channel'] = $channelId;
22+
$options['ts'] = $messageId;
23+
24+
parent::__construct($options);
25+
}
26+
}

0 commit comments

Comments
 (0)
0