symfony/linked-in-notifier
Symfony Notifier integration for LinkedIn. Configure a LINKEDIN_DSN with your LinkedIn access token and user ID to send notifications via LinkedIn through Symfony’s notifier system.
Install the Package
composer require symfony/linked-in-notifier
Configure DSN in .env
LINKEDIN_DSN=linkedin://ACCESS_TOKEN:USER_ID@default
ACCESS_TOKEN via LinkedIn API OAuth.USER_ID is your LinkedIn profile ID (extract from https://www.linkedin.com/in/your-profile).First Notification Use Case
Send a simple message via Laravel’s Notification facade:
use Illuminate\Support\Facades\Notification;
use App\Notifications\LinkedInNotification;
Notification::route('linkedin', 'USER_ID')
->notify(new LinkedInNotification('Your profile was viewed!'));
(Note: Requires creating a custom LinkedInChannel—see Implementation Patterns.)
Verify with Symfony Notifier Check Symfony’s Notifier docs for transport setup.
LinkedInTransport in a Laravel NotificationChannel.
// app/Providers/LinkedInServiceProvider.php
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Transport\LinkedInTransport;
public function register()
{
$notifier = new Notifier();
$transport = new LinkedInTransport(config('services.linkedin.dsn'));
$notifier->addTransport('linkedin', $transport);
// Expose to Laravel
app()->singleton('linkedin.notifier', fn() => $notifier);
}
Step 1: Create a custom notification class:
// app/Notifications/LinkedInNotification.php
use Illuminate\Notifications\Notification;
use Symfony\Component\Notifier\Message\Message;
class LinkedInNotification extends Notification
{
public function __construct(private string $message) {}
public function via($notifiable)
{
return ['linkedin'];
}
public function toLinkedIn($notifiable)
{
return new Message($this->message);
}
}
Step 2: Route notifications in your controller:
Notification::route('linkedin', 'USER_ID')
->notify(new LinkedInNotification('Hello from Laravel!'));
Messenger via Laravel Queues by dispatching a job:
// app/Jobs/SendLinkedInNotification.php
use Symfony\Component\Notifier\Notifier;
class SendLinkedInNotification implements ShouldQueue
{
public function handle(Notifier $notifier)
{
$notifier->send(new Message('Queued notification'));
}
}
SendLinkedInNotification::dispatch($notifier);
HttpClient supports retries. Configure in Laravel:
$client = Symfony\Component\HttpClient\HttpClient::create([
'timeout' => 30,
'max_retries' => 3,
]);
LinkedInApiException (if extended) or generic GuzzleException:
try {
$notifier->send($message);
} catch (\Exception $e) {
Log::error("LinkedIn notification failed: " . $e->getMessage());
}
Symfony Dependency Conflicts
HttpClient and Messenger. If your Laravel app uses Guzzle or Laravel Queues, mock or replace these dependencies:
composer require symfony/http-client symfony/messenger
Http facade as a drop-in replacement by creating a custom HttpClient adapter.Missing Webhook Support
VerifyCsrfToken middleware for challenge validation.// app/Http/Middleware/VerifyLinkedInWebhook.php
public function handle($request, Closure $next)
{
$signature = $request->header('X-LinkedIn-Signature');
$expected = hash_hmac('sha256', $request->getContent(), config('services.linkedin.secret'));
if (!hash_equals($expected, $signature)) {
abort(403);
}
return $next($request);
}
Token Expiry
// app/Services/LinkedInAuthService.php
public function refreshToken()
{
$response = Http::asForm()->post('https://www.linkedin.com/oauth/v2/accessToken', [
'grant_type' => 'refresh_token',
'refresh_token' => config('services.linkedin.refresh_token'),
'client_id' => config('services.linkedin.client_id'),
'client_secret' => config('services.linkedin.client_secret'),
]);
return $response->json()['access_token'];
}
No Built-in Message Templates
Message class:
use Symfony\Component\Notifier\Message\Message as BaseMessage;
class LinkedInMessage extends BaseMessage
{
public function __construct(string $subject, string $body, array $options = [])
{
parent::__construct($body, $options);
$this->subject = $subject;
}
public function getSubject(): string
{
return $this->subject;
}
}
$notifier = new Notifier([], [
'debug' => true,
]);
$client = HttpClient::create([
'events' => [
function (StreamEvent $event) {
if ($event->getType() === StreamEvent::RESPONSE) {
Log::debug('LinkedIn API Response', [
'status' => $event->getResponse()->getStatusCode(),
'body' => $event->getResponse()->getContent(false),
]);
}
},
],
]);
Custom Transport Options
LinkedInTransport to add features like:
class CustomLinkedInTransport extends LinkedInTransport
{
public function __construct(string $dsn, private array $customOptions = [])
{
parent::__construct($dsn);
}
protected function getOptions(): array
{
return array_merge(parent::getOptions(), $this->customOptions);
}
}
Multi-User Notifications
Notifiable interface to send to multiple users:
$users = User::whereHas('linkedinProfile')->get();
foreach ($users as $user) {
Notification::route('linkedin', $user->linkedin_id)
->notify(new LinkedInNotification('Group message'));
}
Rich Media Support
Message class:
class RichLinkedInMessage extends LinkedInMessage
{
public function __construct(string $subject, string $body, string $mediaUrl)
{
parent::__construct($subject, $body);
$this->mediaUrl = $mediaUrl;
}
public function getMediaUrl(): string
{
return $this->mediaUrl;
}
}
linkedin://ACCESS_TOKEN:USER_ID@default. Tip: Validate in config/services.php:
'linkedin' => [
'dsn' => env('LINKEDIN_DSN'),
'valid' => filter_var(env('LINKEDIN_DSN'), FILTER_VALIDATE_URL),
],
env() helper to parse the DSN:
$dsn = env('LINKEDIN_DSN');
$parts = explode('://', $dsn);
$credentials = explode(':', $parts[1]);
$accessToken = $credentials[0];
$userId = $credentials[1];
How can I help you explore Laravel packages today?