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

Interactive Slack Notification Channel Laravel Package

spatie/interactive-slack-notification-channel

Send interactive Slack notifications from Laravel using Slack Block Kit. Configure a token and optional channel on your Notifiable, post rich messages with buttons/inputs, and use Slack API responses to reply in threads for follow-up order events.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require spatie/interactive-slack-notification-channel
    
  2. Configure Slack

    • Add Slack credentials to .env:
      SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
      SLACK_SIGNING_SECRET=your_signing_secret_here
      
    • Publish config (optional):
      php artisan vendor:publish --provider="Spatie\SlackNotificationChannel\SlackNotificationChannelServiceProvider"
      
  3. First Notification Use Laravel's Notification facade to send a basic message:

    use Spatie\SlackNotificationChannel\SlackMessage;
    use Illuminate\Support\Facades\Notification;
    
    Notification::route('slack', 'user@email.com')
                ->notify(new SlackMessage('Hello from Laravel!'));
    
  4. Verify Check Slack for the message. Ensure the webhook URL is correct and the signing secret is properly configured.


Implementation Patterns

Core Workflows

  1. Basic Notifications Extend Spatie\SlackNotificationChannel\SlackMessage for custom content:

    use Spatie\SlackNotificationChannel\SlackMessage;
    
    class OrderShippedNotification extends SlackMessage
    {
        public function __construct(public string $orderId)
        {
            $this->title = "Order #{$orderId} Shipped";
            $this->content = "Your order has been shipped!";
        }
    }
    
  2. Interactive Components Add buttons, modals, or select menus using Slack's block kit:

    class ApprovalRequestNotification extends SlackMessage
    {
        public function toSlackMessage()
        {
            return [
                'blocks' => [
                    [
                        'type' => 'section',
                        'text' => [
                            'type' => 'mrkdwn',
                            'text' => 'Approve this request?',
                        ],
                    ],
                    [
                        'type' => 'actions',
                        'elements' => [
                            [
                                'type' => 'button',
                                'text' => [
                                    'type' => 'plain_text',
                                    'text' => 'Approve',
                                ],
                                'value' => 'approve_request',
                                'action_id' => 'approve_request',
                            ],
                            [
                                'type' => 'button',
                                'text' => [
                                    'type' => 'plain_text',
                                    'text' => 'Reject',
                                ],
                                'value' => 'reject_request',
                                'action_id' => 'reject_request',
                            ],
                        ],
                    ],
                ],
            ];
        }
    }
    
  3. Routing Notifications Route notifications to specific Slack channels/users:

    // Via notification route
    Notification::route('slack', '#general-channel')
                ->notify(new SlackMessage('Team update!'));
    
    // Via user model (if using `HasNotifications`)
    $user->routeNotificationFor('slack', '#alerts-channel');
    
  4. Handling Interactive Events Register a Slack event listener to process button clicks/modals:

    use Spatie\SlackNotificationChannel\SlackEvent;
    
    public function handle(SlackEvent $event)
    {
        if ($event->action->action_id === 'approve_request') {
            // Logic for approval
        }
    }
    

    Register in EventServiceProvider:

    protected $listen = [
        SlackEvent::class => [
            \App\Listeners\HandleSlackInteractions::class,
        ],
    ];
    

Integration Tips

  1. Laravel Queues Queue notifications for async delivery:

    Notification::route('slack', '#notifications')
                ->notify(new SlackMessage('Async update!'))
                ->onQueue('slack');
    
  2. Dynamic Content Use Laravel's blade-like syntax for dynamic content:

    class UserWelcomeNotification extends SlackMessage
    {
        public function __construct(public User $user)
        {
            $this->title = "Welcome, {$this->user->name}!";
            $this->content = "You've joined our team. Your role: **{$this->user->role}**.";
        }
    }
    
  3. Attachments Add file attachments or images:

    class ReportNotification extends SlackMessage
    {
        public function toSlackMessage()
        {
            return [
                'attachments' => [
                    [
                        'title' => 'Monthly Report',
                        'image_url' => 'https://example.com/report.png',
                    ],
                ],
            ];
        }
    }
    
  4. Testing Use SlackMessageTestCase for unit tests:

    use Spatie\SlackNotificationChannel\Tests\SlackMessageTestCase;
    
    class ApprovalNotificationTest extends SlackMessageTestCase
    {
        public function test_message_structure()
        {
            $notification = new ApprovalRequestNotification();
            $this->assertEquals('Approve this request?', $notification->title);
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Webhook URL Validation

    • Issue: Messages fail silently if the webhook URL is invalid.
    • Fix: Test the URL in Slack's webhook tester first. Enable SLACK_DEBUG in config to log errors:
      SLACK_DEBUG=true
      
  2. Signing Secret Mismatch

    • Issue: Interactive events may be rejected if the signing secret doesn’t match Slack’s.
    • Fix: Verify the secret in Slack’s app settings under Basic Information > App Credentials. Regenerate if needed.
  3. Rate Limits

    • Issue: Slack imposes rate limits (e.g., 1 message/second for webhooks).
    • Fix: Queue notifications and implement exponential backoff for retries:
      $notification->onQueue('slack')->delay(now()->addSeconds(10));
      
  4. Interactive Event Delays

    • Issue: Slack may take up to 30 seconds to process interactive events.
    • Fix: Use SlackEvent::fresh() to re-fetch events if needed:
      $event = SlackEvent::fresh($event->payload);
      
  5. Block Kit Validation

    • Issue: Invalid block kit JSON causes Slack to ignore the message.
    • Fix: Validate blocks using Slack’s block kit builder or tools like slack-blocks.

Debugging Tips

  1. Enable Debug Logging Add to config/slack-notification-channel.php:

    'debug' => env('SLACK_DEBUG', false),
    

    Check logs for raw Slack responses:

    tail -f storage/logs/laravel.log | grep slack
    
  2. Inspect Raw Payloads Dump the raw Slack payload in your event handler:

    public function handle(SlackEvent $event)
    {
        \Log::debug('Raw payload:', $event->payload);
    }
    
  3. Test Locally Use ngrok to expose your local Slack event endpoint:

    ngrok http --host=localhost --subdomain=slack-events
    

    Configure Slack’s Event Subscriptions to point to https://slack-events.ngrok.io/slack/events.


Extension Points

  1. Custom Slack Client Bind a custom GuzzleHttp\Client for advanced HTTP options:

    $this->app->bind(\Spatie\SlackNotificationChannel\SlackClient::class, function () {
        return new SlackClient(
            new GuzzleHttp\Client(['timeout' => 30])
        );
    });
    
  2. Override Default Message Structure Extend Spatie\SlackNotificationChannel\SlackMessage to modify the default toSlackMessage() method:

    class CustomSlackMessage extends SlackMessage
    {
        public function toSlackMessage()
        {
            return array_merge(
                parent::toSlackMessage(),
                ['mrkdwn_in' => ['text']] // Example: Add global formatting
            );
        }
    }
    
  3. Add Middleware Attach middleware to notifications for pre/post-processing:

    class AddFooterMiddleware
    {
        public function handle($notifiable, $notification)
        {
            if ($notification instanceof SlackMessage) {
                $notification->content .= "\n\n*Powered by Laravel*";
            }
            return $notification;
        }
    }
    

    Register in AppServiceProvider:

    Notification::extend('slack', function ($app) {
        $channel =
    
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