1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Notifier\Bridge\LinkedIn;
use Symfony\Component\Notifier\Bridge\LinkedIn\Share\AuthorShare;
use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Exception\TransportException;
use Symfony\Component\Notifier\Exception\UnsupportedMessageTypeException;
use Symfony\Component\Notifier\Message\ChatMessage;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\SentMessage;
use Symfony\Component\Notifier\Transport\AbstractTransport;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
/**
* @author Smaïne Milianni <smaine.milianni@gmail.com>
*
* @see https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/ugc-post-api#sharecontent
*/
final class LinkedInTransport extends AbstractTransport
{
protected const HOST = 'api.linkedin.com';
private string $authToken;
private string $accountId;
public function __construct(#[\SensitiveParameter] string $authToken, string $accountId, ?HttpClientInterface $client = null, ?EventDispatcherInterface $dispatcher = null)
{
$this->authToken = $authToken;
$this->accountId = $accountId;
parent::__construct($client, $dispatcher);
}
public function __toString(): string
{
return \sprintf('linkedin://%s', $this->getEndpoint());
}
public function supports(MessageInterface $message): bool
{
return $message instanceof ChatMessage && (null === $message->getOptions() || $message->getOptions() instanceof LinkedInOptions);
}
/**
* @see https://docs.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/ugc-post-api
*/
protected function doSend(MessageInterface $message): SentMessage
{
if (!$message instanceof ChatMessage) {
throw new UnsupportedMessageTypeException(__CLASS__, ChatMessage::class, $message);
}
if (($options = $message->getOptions()) && !$options instanceof LinkedInOptions) {
throw new LogicException(\sprintf('The "%s" transport only supports instances of "%s" for options.', __CLASS__, LinkedInOptions::class));
}
if (!$options && $notification = $message->getNotification()) {
$options = LinkedInOptions::fromNotification($notification);
$options->author(new AuthorShare($this->accountId));
}
$endpoint = \sprintf('https://%s/v2/ugcPosts', $this->getEndpoint());
$response = $this->client->request('POST', $endpoint, [
'auth_bearer' => $this->authToken,
'headers' => ['X-Restli-Protocol-Version' => '2.0.0'],
'json' => array_filter($options?->toArray() ?? $this->bodyFromMessageWithNoOption($message)),
]);
try {
$statusCode = $response->getStatusCode();
} catch (TransportExceptionInterface $e) {
throw new TransportException('Could not reach the remote LinkedIn server.', $response, 0, $e);
}
if (201 !== $statusCode) {
throw new TransportException(\sprintf('Unable to post the Linkedin message: "%s".', $response->getContent(false)), $response);
}
$result = $response->toArray(false);
if (!$result['id']) {
throw new TransportException(\sprintf('Unable to post the Linkedin message: "%s".', $result['error']), $response);
}
$sentMessage = new SentMessage($message, (string) $this);
$sentMessage->setMessageId($result['id']);
return $sentMessage;
}
private function bodyFromMessageWithNoOption(MessageInterface $message): array
{
return [
'specificContent' => [
'com.linkedin.ugc.ShareContent' => [
'shareCommentary' => [
'attributes' => [],
'text' => $message->getSubject(),
],
'shareMediaCategory' => 'NONE',
],
],
'visibility' => [
'com.linkedin.ugc.MemberNetworkVisibility' => 'PUBLIC',
],
'lifecycleState' => 'PUBLISHED',
'author' => \sprintf('urn:li:person:%s', $this->accountId),
];
}
}
|