Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Bluesky Notification Channel Laravel Package

spatie/laravel-bluesky-notification-channel

Laravel notification channel for Bluesky (spatie/laravel-bluesky-notification-channel). Send posts via Laravel’s notification system using a simple BlueskyPost builder; automatically detects links, mentions, and hashtags and renders rich text.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-bluesky-notification-channel
    

    Publish the config (if needed):

    php artisan vendor:publish --provider="Spatie\BlueskyNotificationChannel\BlueskyNotificationServiceProvider"
    
  2. Configure .env: Add your Bluesky API credentials:

    BLUESKY_API_KEY=your_api_key_here
    BLUESKY_API_SECRET=your_api_secret_here
    BLUESKY_ACCESS_TOKEN=your_access_token_here
    
  3. First Use Case: Send a notification via a Notification class:

    use Illuminate\Bus\Queueable;
    use Illuminate\Notifications\Notification;
    use Spatie\BlueskyNotificationChannel\BlueskyChannel;
    use Spatie\BlueskyNotificationChannel\BlueskyPost;
    
    class BlueskyNotification extends Notification
    {
        use Queueable;
    
        public function via($notifiable)
        {
            return [BlueskyChannel::class];
        }
    
        public function toBluesky($notifiable)
        {
            return BlueskyPost::make()
                ->text('Hello from Laravel! Check out ' . url('/'))
                ->language('en');
        }
    }
    

Implementation Patterns

Core Workflows

  1. Basic Notification:

    // In a controller or job
    $user->notify(new BlueskyNotification());
    
  2. Dynamic Content: Use variables in text() and leverage Laravel’s string interpolation:

    public function toBluesky($notifiable)
    {
        return BlueskyPost::make()
            ->text("Hi {$notifiable->name}, your order #{$notifiable->order_id} is ready!")
            ->language('en');
    }
    
  3. Rich Text Features: Automatically formats URLs, mentions (@user), and hashtags (#tag):

    ->text('Visit @spatie for more: https://spatie.be #laravel');
    
  4. Queueing: Use Laravel’s queue system for async delivery:

    $user->notify((new BlueskyNotification())->delay(now()->addMinutes(5)));
    
  5. Customizing the Post: Add metadata or embeds (if supported by Bluesky’s API):

    ->text('Check this out!')
    ->embed('https://example.com/post') // Hypothetical; verify API support
    ->language('en');
    

Integration Tips

  1. Notifiable Models: Ensure your model uses Notifiable trait and implements route():

    use Illuminate\Notifications\Notifiable;
    
    class User extends Authenticatable
    {
        use Notifiable;
    
        public function routeNotificationForBluesky()
        {
            return $this->bluesky_handle; // Custom accessor for Bluesky handle
        }
    }
    
  2. Testing: Use mocks for API calls in tests:

    $this->mock(Spatie\BlueskyNotificationChannel\BlueskyClient::class, function ($mock) {
        $mock->shouldReceive('post')
             ->once()
             ->andReturn(['success' => true]);
    });
    
  3. Error Handling: Extend the BlueskyChannel to handle failures gracefully:

    public function send($notifiable, $notification)
    {
        try {
            parent::send($notifiable, $notification);
        } catch (\Exception $e) {
            Log::error("Bluesky notification failed: " . $e->getMessage());
            // Fallback to email/SMS
        }
    }
    

Gotchas and Tips

Pitfalls

  1. API Rate Limits: Bluesky’s API may throttle requests. Implement retries with exponential backoff:

    use Illuminate\Support\Facades\Http;
    
    Http::timeout(30)->retry(3, 100);
    
  2. Handle Validation: Ensure text() isn’t empty or exceeds Bluesky’s character limits (~300 chars for posts, ~1000 for replies). Validate in toBluesky():

    if (strlen($text) > 300) {
        throw new \Exception('Bluesky post exceeds character limit.');
    }
    
  3. Authentication: If using OAuth, ensure tokens are refreshed before expiry. Store tokens securely (e.g., Laravel Sanctum or database).

  4. Rich Text Parsing: Bluesky’s rich text parsing may not support all HTML tags. Test edge cases like nested links or special characters.


Debugging

  1. Log API Responses: Enable debug mode in the config:

    BLUESKY_DEBUG=true
    

    Logs will appear in storage/logs/laravel.log.

  2. Check HTTP Status Codes: Bluesky may return 429 (rate-limited) or 401 (invalid token). Handle these in a custom channel class.

  3. Verify Handles: Ensure routeNotificationForBluesky() returns a valid Bluesky handle (e.g., user.bsky.social).


Extension Points

  1. Custom Post Types: Extend BlueskyPost to support replies or likes:

    class BlueskyReply extends BlueskyPost
    {
        public function replyTo(string $parentPostUri): self
        {
            $this->replyTo = $parentPostUri;
            return $this;
        }
    }
    
  2. Webhook Integration: Use Laravel’s HandleIncomingWebhook to process Bluesky events (e.g., replies to your posts).

  3. Multi-Language Support: Add language detection logic:

    public function toBluesky($notifiable)
    {
        $language = app()->getLocale();
        return BlueskyPost::make()
            ->text('Hello!')
            ->language($language);
    }
    
  4. Fallback Channels: Combine with other channels (e.g., email) for reliability:

    public function via($notifiable)
    {
        return [BlueskyChannel::class, MailChannel::class];
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport