Skip to content

Commit 68725da

Browse files
feature #47349 [Notifier] Allow to update Slack messages (maxim-dovydenok-busuu)
This PR was merged into the 6.3 branch. Discussion ---------- [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 | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #47274 | License | MIT | Doc PR | symfony/symfony-docs#17214 This pull request allows to update slack messages, for example to keep entity statuses up-to-date: ```php // On entity creation $message = sprintf('Entity #%s (%s)', $entity->getId(), $entity->getStatus()); $sentMessage = $this->chatter->send(new ChatMessage($message)); // On status changes $message = sprintf('Entity #%s (%s)', $entity->getId(), $entity->getStatus()); $this->chatter->send(new ChatMessage($message, new UpdateMessageSlackOptions($sentMessage->getFullMessageId()))); ``` Commits ------- e410909 [Notifier] Allow to update Slack messages
2 parents d8d93c6 + e410909 commit 68725da

File tree

6 files changed

+119
-11
lines changed

6 files changed

+119
-11
lines changed

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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 41 additions & 0 deletions
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

Lines changed: 5 additions & 7 deletions
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

Lines changed: 41 additions & 3 deletions
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
}
Lines changed: 26 additions & 0 deletions
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)
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