Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Notifier] [Bluesky] Allow to attach website preview card #59667

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,16 @@ public function attachMedia(File $file, string $description = ''): static

return $this;
}

public function attachCard(string $uri, File $thumb, string $title = '', string $description = ''): static
{
$this->options['external'] = [
'uri' => $uri,
'thumb' => $thumb,
'title' => $title,
'description' => $description,
];

return $this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,26 @@ protected function doSend(MessageInterface $message): SentMessage
unset($options['attach']);
}

if (isset($options['external'])) {
$uploadedMedia = $this->uploadMedia([
[
'file' => $options['external']['thumb'],
'description' => $options['external']['description'],
],
]);

$options['record']['embed'] = [
'$type' => 'app.bsky.embed.external',
'external' => [
'uri' => $options['external']['uri'],
'title' => $options['external']['title'],
'description' => $options['external']['description'],
'thumb' => $uploadedMedia[array_key_first($uploadedMedia)]['image'],
],
];
unset($options['external']);
}

$response = $this->client->request('POST', \sprintf('https://%s/xrpc/com.atproto.repo.createRecord', $this->getEndpoint()), [
'auth_bearer' => $this->authSession['accessJwt'] ?? null,
'json' => $options,
Expand Down
5 changes: 5 additions & 0 deletions 5 src/Symfony/Component/Notifier/Bridge/Bluesky/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

7.3
---

* Add option to attach a website preview card

7.2
---

Expand Down
24 changes: 24 additions & 0 deletions 24 src/Symfony/Component/Notifier/Bridge/Bluesky/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,30 @@ DSN example
BLUESKY_DSN=bluesky://nyholm.bsky.social:p4ssw0rd@bsky.social
```

Adding Options to a Message
---------------------------

Use a `BlueskyOptions` object to add options to the message:

```php
use Symfony\Component\Notifier\Bridge\Bluesky\BlueskyOptions;
use Symfony\Component\Notifier\Message\ChatMessage;

$message = new ChatMessage('My message');

// Add website preview card to the message
$options = (new BlueskyOptions())
->attachCard('https://example.com', new File('image.jpg'))
// You can also add media to the message
//->attachMedia(new File($command->fileName), 'description')
;

// Add the custom options to the Bluesky message and send the message
$message->options($options);

$chatter->send($message);
```

Resources
---------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,12 @@ public function testParseFacetsUrlWithTrickyRegex()
$this->assertEquals($expected, $this->parseFacets($input));
}

public function testWithMedia()
/**
* @dataProvider sendMessageWithEmbedDataProvider
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using dataProvider to add website card preview to previous test.

*/
public function testWithEmbed(BlueskyOptions $blueskyOptions, string $expectedJsonResponse)
{
$transport = $this->createTransport(new MockHttpClient((function () {
$transport = $this->createTransport(new MockHttpClient((function () use ($expectedJsonResponse) {
yield function (string $method, string $url, array $options) {
$this->assertSame('POST', $method);
$this->assertSame('https://bsky.social/xrpc/com.atproto.server.createSession', $url);
Expand All @@ -299,23 +302,49 @@ public function testWithMedia()
]]);
};

yield function (string $method, string $url, array $options) {
yield function (string $method, string $url, array $options) use ($expectedJsonResponse) {
$this->assertSame('POST', $method);
$this->assertSame('https://bsky.social/xrpc/com.atproto.repo.createRecord', $url);
$this->assertArrayHasKey('authorization', $options['normalized_headers']);
$this->assertSame('{"repo":null,"collection":"app.bsky.feed.post","record":{"$type":"app.bsky.feed.post","text":"Hello World!","createdAt":"2024-04-28T08:40:17.000000Z","embed":{"$type":"app.bsky.embed.images","images":[{"alt":"A fixture","image":{"$type":"blob","ref":{"$link":"bafkreibabalobzn6cd366ukcsjycp4yymjymgfxcv6xczmlgpemzkz3cfa"},"mimeType":"image\/png","size":760898}}]}}}', $options['body']);
$this->assertSame($expectedJsonResponse, $options['body']);

return new JsonMockResponse(['cid' => '103254962155278888']);
};
})()));

$options = (new BlueskyOptions())
->attachMedia(new File(__DIR__.'/fixtures.gif'), 'A fixture');
$result = $transport->send(new ChatMessage('Hello World!', $options));
$result = $transport->send(new ChatMessage('Hello World!', $blueskyOptions));

$this->assertSame('103254962155278888', $result->getMessageId());
}

public function sendMessageWithEmbedDataProvider(): iterable
{
yield 'With media' => [
'options' => (new BlueskyOptions())->attachMedia(new File(__DIR__.'/fixtures.gif'), 'A fixture'),
'expectedResponse' => '{"repo":null,"collection":"app.bsky.feed.post","record":{"$type":"app.bsky.feed.post","text":"Hello World!","createdAt":"2024-04-28T08:40:17.000000Z","embed":{"$type":"app.bsky.embed.images","images":[{"alt":"A fixture","image":{"$type":"blob","ref":{"$link":"bafkreibabalobzn6cd366ukcsjycp4yymjymgfxcv6xczmlgpemzkz3cfa"},"mimeType":"image\/png","size":760898}}]}}}',
];

yield 'With website preview card and all optionnal informations' => [
'options' => (new BlueskyOptions())
->attachCard(
'https://example.com',
new File(__DIR__.'/fixtures.gif'),
'Fork me im famous',
'Click here to go to website!'
),
'expectedResponse' => '{"repo":null,"collection":"app.bsky.feed.post","record":{"$type":"app.bsky.feed.post","text":"Hello World!","createdAt":"2024-04-28T08:40:17.000000Z","embed":{"$type":"app.bsky.embed.external","external":{"uri":"https:\/\/example.com","title":"Fork me im famous","description":"Click here to go to website!","thumb":{"$type":"blob","ref":{"$link":"bafkreibabalobzn6cd366ukcsjycp4yymjymgfxcv6xczmlgpemzkz3cfa"},"mimeType":"image\/png","size":760898}}}}}',
];

yield 'With website preview card and minimal information' => [
'options' => (new BlueskyOptions())
->attachCard(
'https://example.com',
new File(__DIR__.'/fixtures.gif')
),
'expectedResponse' => '{"repo":null,"collection":"app.bsky.feed.post","record":{"$type":"app.bsky.feed.post","text":"Hello World!","createdAt":"2024-04-28T08:40:17.000000Z","embed":{"$type":"app.bsky.embed.external","external":{"uri":"https:\/\/example.com","title":"","description":"","thumb":{"$type":"blob","ref":{"$link":"bafkreibabalobzn6cd366ukcsjycp4yymjymgfxcv6xczmlgpemzkz3cfa"},"mimeType":"image\/png","size":760898}}}}}',
];
}

/**
* A small helper function to test BlueskyTransport::parseFacets().
*/
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.