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

Skip to content

Commit f23e8e4

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 f23e8e4

File tree

6 files changed

+122
-11
lines changed

6 files changed

+122
-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

+42-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
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;
18+
use Symfony\Component\Notifier\Bridge\Slack\UpdateMessageSlackOptions;
1719
use Symfony\Component\Notifier\Exception\InvalidArgumentException;
1820
use Symfony\Component\Notifier\Exception\LogicException;
1921
use Symfony\Component\Notifier\Exception\TransportException;
@@ -115,7 +117,7 @@ public function testSendWithOptions()
115117

116118
$response->expects($this->once())
117119
->method('getContent')
118-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
120+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
119121

120122
$expectedBody = json_encode(['channel' => $channel, 'text' => $message]);
121123

@@ -130,6 +132,8 @@ public function testSendWithOptions()
130132
$sentMessage = $transport->send(new ChatMessage('testMessage'));
131133

132134
$this->assertSame('1503435956.000247', $sentMessage->getMessageId());
135+
$this->assertInstanceOf(SlackSentMessage::class, $sentMessage);
136+
$this->assertSame('C123456', $sentMessage->getChannelId());
133137
}
134138

135139
public function testSendWithNotification()
@@ -145,7 +149,7 @@ public function testSendWithNotification()
145149

146150
$response->expects($this->once())
147151
->method('getContent')
148-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
152+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
149153

150154
$notification = new Notification($message);
151155
$chatMessage = ChatMessage::fromNotification($notification);
@@ -223,7 +227,7 @@ public function testSendIncludesContentTypeWithCharset()
223227

224228
$response->expects($this->once())
225229
->method('getContent')
226-
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247']));
230+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
227231

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

264268
$transport->send(new ChatMessage('testMessage'));
265269
}
270+
271+
public function testUpdateMessage()
272+
{
273+
$response = $this->createMock(ResponseInterface::class);
274+
275+
$response->expects($this->exactly(2))
276+
->method('getStatusCode')
277+
->willReturn(200);
278+
279+
$response->expects($this->once())
280+
->method('getContent')
281+
->willReturn(json_encode(['ok' => true, 'ts' => '1503435956.000247', 'channel' => 'C123456']));
282+
283+
$sentMessage = new SlackSentMessage(new ChatMessage('Hello'), 'slack', 'C123456', '1503435956.000247');
284+
$chatMessage = $sentMessage->getUpdateMessage('Hello World');
285+
286+
$expectedBody = json_encode([
287+
'channel' => 'C123456',
288+
'ts' => '1503435956.000247',
289+
'text' => 'Hello World',
290+
]);
291+
292+
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
293+
$this->assertJsonStringEqualsJsonString($expectedBody, $options['body']);
294+
$this->assertStringEndsWith('chat.update', $url);
295+
296+
return $response;
297+
});
298+
299+
$transport = $this->createTransport($client, 'another-channel');
300+
301+
$sentMessage = $transport->send($chatMessage);
302+
303+
$this->assertSame('1503435956.000247', $sentMessage->getMessageId());
304+
}
266305
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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\Exception\InvalidArgumentException;
15+
16+
/**
17+
* @author Maxim Dovydenok <dovydenok.maxim@gmail.com>
18+
*/
19+
final class UpdateMessageSlackOptions extends SlackOptions
20+
{
21+
public function __construct(string $channelId, string $messageId, array $options = [])
22+
{
23+
$options['channel'] = $channelId;
24+
$options['ts'] = $messageId;
25+
26+
parent::__construct($options);
27+
}
28+
}

0 commit comments

Comments
 (0)
0