Skip to content

Commit 467b481

Browse files
committed
Add threadKey option fo Google Chat notifier
1 parent 695e105 commit 467b481

File tree

6 files changed

+83
-29
lines changed

6 files changed

+83
-29
lines changed

src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatOptions.php

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
final class GoogleChatOptions implements MessageOptionsInterface
2626
{
27+
private $threadKey;
2728
private $options = [];
2829
private $dirty;
2930

@@ -36,18 +37,6 @@ public static function fromNotification(Notification $notification): self
3637
{
3738
$options = new self();
3839

39-
/* @fixme card is shown after text
40-
$options->card()
41-
->section()
42-
->addWidget(
43-
(new KeyValueWidget())
44-
//->icon($notification->getEmoji())
45-
->topLabel($notification->getImportance())
46-
->content($notification->getSubject(), true)
47-
)
48-
->end()
49-
->end();
50-
*/
5140
$text = $notification->getEmoji().' *'.$notification->getSubject().'* ';
5241

5342
if ($notification->getContent()) {
@@ -56,6 +45,7 @@ public static function fromNotification(Notification $notification): self
5645
if ($exception = $notification->getExceptionAsString()) {
5746
$text .= "\r\n".'```'.$notification->getExceptionAsString().'```';
5847
}
48+
5949
$options->text($text);
6050

6151
return $options;
@@ -104,13 +94,18 @@ public function text(string $text): self
10494
return $this;
10595
}
10696

107-
public function setThread(string $thread): self
97+
public function setThreadKey(?string $threadKey): self
10898
{
109-
$this->options['thread']['name'] = $thread;
99+
$this->threadKey = $threadKey;
110100

111101
return $this;
112102
}
113103

104+
public function getThreadKey(): ?string
105+
{
106+
return $this->threadKey;
107+
}
108+
114109
public function getRecipientId(): ?string
115110
{
116111
return null;

src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatTransport.php

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,17 @@ final class GoogleChatTransport extends AbstractTransport
3535
private $accessKey;
3636
private $accessToken;
3737

38+
/**
39+
* @var ?string
40+
*/
41+
private $threadKey;
42+
3843
/**
3944
* A Google Chat Webhook url looks like this:.
4045
*
41-
* @param string $id The hook id (anything after https://hooks.slack.com/services/)
46+
* @param string $space The space name the the webhook url "/v1/spaces/<space>/messages"
47+
* @param string $accessKey The "key" parameter of the webhook url
48+
* @param string $accessToken The "token" parameter of the webhook url
4249
*/
4350
public function __construct(string $space, string $accessKey, string $accessToken, HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null)
4451
{
@@ -49,9 +56,29 @@ public function __construct(string $space, string $accessKey, string $accessToke
4956
parent::__construct($client, $dispatcher);
5057
}
5158

59+
/**
60+
* Opaque thread identifier string that can be specified to group messages into a single thread.
61+
* If this is the first message with a given thread identifier, a new thread is created.
62+
* Subsequent messages with the same thread identifier will be posted into the same thread.
63+
*
64+
* @see https://developers.google.com/hangouts/chat/reference/rest/v1/spaces.messages/create#query-parameters
65+
*/
66+
public function setThreadKey(?string $threadKey): self
67+
{
68+
$this->threadKey = $threadKey;
69+
70+
return $this;
71+
}
72+
5273
public function __toString(): string
5374
{
54-
return sprintf('googlechat://%s:%s@%s/%s', urlencode($this->accessKey), urlencode($this->accessToken), $this->getEndpoint(), $this->space);
75+
return sprintf('googlechat://%s:%s@%s/%s%s',
76+
urlencode($this->accessKey),
77+
urlencode($this->accessToken),
78+
$this->getEndpoint(),
79+
$this->space,
80+
$this->threadKey ? '?threadKey='.urlencode($this->threadKey) : ''
81+
);
5582
}
5683

5784
public function supports(MessageInterface $message): bool
@@ -80,10 +107,21 @@ protected function doSend(MessageInterface $message): void
80107
}
81108
}
82109

83-
// @todo split message if too long.
110+
if (null !== $this->threadKey && null === $opts->getThreadKey()) {
111+
$opts->setThreadKey($this->threadKey);
112+
}
84113

85-
$options = $opts ? $opts->toArray() : [];
86-
$response = $this->client->request('POST', 'https://'.$this->getEndpoint().'/v1/spaces/'.$this->space.'/messages?key='.urlencode($this->accessKey).'&token='.urlencode($this->accessToken), [
114+
$threadKey = $opts->getThreadKey() ?: $this->threadKey;
115+
116+
$options = $opts->toArray();
117+
$url = sprintf('https://%s/v1/spaces/%s/messages?key=%s&token=%s%s',
118+
$this->getEndpoint(),
119+
$this->space,
120+
urlencode($this->accessKey),
121+
urlencode($this->accessToken),
122+
$threadKey ? '&threadKey='.urlencode($threadKey) : ''
123+
);
124+
$response = $this->client->request('POST', $url, [
87125
'json' => array_filter($options),
88126
]);
89127

@@ -97,11 +135,8 @@ protected function doSend(MessageInterface $message): void
97135
throw new TransportException(sprintf('Unable to post the Google Chat message: "%s".', $result['error']['message'] ?? $response->getContent(false)), $response, $result['error']['code'] ?? $response->getStatusCode());
98136
}
99137

100-
if (!$result['name']) {
138+
if (!\array_key_exists('name', $result)) {
101139
throw new TransportException(sprintf('Unable to post the Google Chat message: "%s".', $response->getContent(false)), $response);
102140
}
103-
104-
// @todo store the thread id to link subsequent messages
105-
//$threadName = $result['thread']['name'];
106141
}
107142
}

src/Symfony/Component/Notifier/Bridge/GoogleChat/GoogleChatTransportFactory.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
final class GoogleChatTransportFactory extends AbstractTransportFactory
2626
{
2727
/**
28-
* @param Dsn $dsn Example: googlechat://chat.googleapis.com/v1/spaces/<space>/messages?key=<accessKey>&token=<accessToken>
28+
* @param Dsn $dsn Format: googlechat://<key>:<token>@chat.googleapis.com/<space>?threadKey=<thread>
2929
*
3030
* @return GoogleChatTransport
3131
*/
@@ -37,19 +37,22 @@ public function create(Dsn $dsn): TransportInterface
3737
$space = explode('/', $dsn->getPath())[1];
3838
$accessKey = $this->getUser($dsn);
3939
$accessToken = $this->getPassword($dsn);
40-
40+
$threadKey = $dsn->getOption('threadKey');
4141
$host = 'default' === $dsn->getHost() ? null : $dsn->getHost();
4242
$port = $dsn->getPort();
4343

44-
return (new GoogleChatTransport($space, $accessKey, $accessToken, $this->client, $this->dispatcher))->setHost($host)->setPort($port);
44+
return (new GoogleChatTransport($space, $accessKey, $accessToken, $this->client, $this->dispatcher))
45+
->setThreadKey($threadKey)
46+
->setHost($host)
47+
->setPort($port);
4548
}
4649

4750
throw new UnsupportedSchemeException($dsn, 'googlechat', $this->getSupportedSchemes());
4851
}
4952

5053
/**
5154
* Creates the GoogleChatTransport using a webhook url provided by Google Chat.
52-
* Example: https://chat.googleapis.com/v1/spaces/<space>/messages?key=<accessKey>&token=<accessToken>.
55+
* Format: https://chat.googleapis.com/v1/spaces/<space>/messages?key=<accessKey>&token=<accessToken>.
5356
*
5457
* @return GoogleChatTransport
5558
*/

src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatOptionsTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ public function testToArray()
156156
$this->assertEquals(json_decode($expected, true), $options->toArray());
157157
}
158158

159+
public function testOptionsWithThread()
160+
{
161+
$thread = 'fgh.ijk';
162+
$options = new GoogleChatOptions();
163+
$options->setThreadKey($thread);
164+
$this->assertSame($thread, $options->getThreadKey());
165+
$options->setThreadKey(null);
166+
$this->assertNull($options->getThreadKey());
167+
}
168+
159169
public function testOptionsNotEnded()
160170
{
161171
$this->expectException(NotEndedComponentException::class);

src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatTransportFactoryTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ public function testCreateWithDsn(): void
3030
$this->assertSame($dsn, (string) $transport);
3131
}
3232

33+
public function testCreateWithThreadKeyInDsn(): void
34+
{
35+
$factory = new GoogleChatTransportFactory();
36+
37+
$dsn = 'googlechat://abcde-fghij:kl_mnopqrstwxyz%3D@chat.googleapis.com/AAAAA_YYYYY?threadKey=abcdefg';
38+
$transport = $factory->create(Dsn::fromString($dsn));
39+
40+
$this->assertSame($dsn, (string) $transport);
41+
}
42+
3343
public function testCreateRequiresCredentials(): void
3444
{
3545
$this->expectException(IncompleteDsnException::class);

src/Symfony/Component/Notifier/Bridge/GoogleChat/Tests/GoogleChatTransportTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,19 +108,20 @@ public function testSendWithOptions(): void
108108

109109
$response->expects($this->once())
110110
->method('getContent')
111-
->willReturn('{"name":"spaces/My-Space/messages/abcdefg.hijklmno","thread":{"name":"spaces/My-Space/threads/abcdefg.hijklmno"}}');
111+
->willReturn('{"name":"spaces/My-Space/messages/abcdefg.hijklmno"}');
112112

113113
$expectedBody = json_encode(['text' => $message]);
114114

115115
$client = new MockHttpClient(function (string $method, string $url, array $options = []) use ($response, $expectedBody): ResponseInterface {
116116
$this->assertSame('POST', $method);
117-
$this->assertSame('https://chat.googleapis.com/v1/spaces/My-Space/messages?key=theAccessKey&token=theAccessToken%3D', $url);
117+
$this->assertSame('https://chat.googleapis.com/v1/spaces/My-Space/messages?key=theAccessKey&token=theAccessToken%3D&threadKey=My-Thread', $url);
118118
$this->assertSame($expectedBody, $options['body']);
119119

120120
return $response;
121121
});
122122

123123
$transport = new GoogleChatTransport('My-Space', 'theAccessKey', 'theAccessToken=', $client);
124+
$transport->setThreadKey('My-Thread');
124125

125126
$transport->send(new ChatMessage('testMessage'));
126127
}

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