# Laravel Slack Notification Channel This package provides a Slack notification channel for Laravel applications, enabling developers to send rich messages to Slack workspaces via both webhook and Web API methods. It supports Laravel's notification system and implements Slack's Block Kit framework for creating sophisticated, interactive message layouts with buttons, images, sections, and other UI components. The library offers two distinct approaches for Slack integration: legacy webhook-based messaging with attachments for backward compatibility, and modern Web API messaging with Block Kit for advanced features. It seamlessly integrates with Laravel's notification routing system, automatically selecting the appropriate channel based on how the notification route is configured. The package includes comprehensive support for message customization, threading, metadata, and rich formatting options. ## SlackMessage with Block Kit Builder Build rich Slack messages using Block Kit components for modern Slack integrations. ```php use Illuminate\Notifications\Slack\SlackMessage; use Illuminate\Notifications\Slack\BlockKit\Blocks\SectionBlock; use Illuminate\Notifications\Slack\BlockKit\Blocks\ActionsBlock; public function toSlack($notifiable) { return (new SlackMessage) ->text('Fallback text for notifications') ->to('#general') ->username('LaravelBot') ->emoji(':robot:') ->headerBlock('System Alert') ->sectionBlock(function (SectionBlock $section) { $section->text('Server load is *high* at 85%')->markdown(); $section->field('Status')->markdown()->text('*Critical*'); $section->field('Server')->text('web-01.example.com'); }) ->dividerBlock() ->actionsBlock(function (ActionsBlock $actions) { $actions->button('View Dashboard') ->url('https://dashboard.example.com') ->primary(); $actions->button('Acknowledge') ->value('ack_alert_001') ->id('ack_button'); }); } ``` ## SlackWebhookChannel via Webhook URL Send notifications to Slack using incoming webhooks without requiring OAuth tokens. ```php use Illuminate\Notifications\Notification; use Illuminate\Notifications\Messages\SlackMessage; class OrderShipped extends Notification { public function via($notifiable) { return ['slack']; } public function toSlack($notifiable) { return (new SlackMessage) ->success() ->content('Order #12345 has been shipped!') ->attachment(function ($attachment) { $attachment ->title('Order Details', 'https://example.com/orders/12345') ->fields([ 'Customer' => 'John Doe', 'Items' => '3 products', 'Total' => '$299.99' ]) ->color('#00ff00') ->footer('Laravel Store') ->timestamp(now()); }); } public function routeNotificationForSlack($notification) { return 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'; } } ``` ## SlackChannel with Web API Integration Send messages via Slack Web API with full Block Kit support and OAuth authentication. ```php use Illuminate\Notifications\Slack\SlackRoute; use Illuminate\Notifications\Slack\SlackMessage; class DeploymentNotification extends Notification { public function toSlack($notifiable) { return (new SlackMessage) ->text('Deployment completed successfully') ->metadata('deployment_event', [ 'environment' => 'production', 'version' => '2.1.0' ]) ->unfurlLinks(true) ->sectionBlock(function ($section) { $section->text('Production deployment *completed*')->markdown(); }) ->imageBlock('https://example.com/graphs/metrics.png', 'Performance metrics'); } public function routeNotificationForSlack($notification) { return SlackRoute::make('#deployments', config('services.slack.token')); } } // Configuration in config/services.php 'slack' => [ 'notifications' => [ 'bot_user_oauth_token' => env('SLACK_BOT_TOKEN'), 'channel' => env('SLACK_CHANNEL', '#general'), ], ], ``` ## Legacy SlackMessage with Attachments Create Slack messages using the legacy attachment format for backward compatibility. ```php use Illuminate\Notifications\Messages\SlackMessage; use Illuminate\Notifications\Messages\SlackAttachment; public function toSlack($notifiable) { return (new SlackMessage) ->from('Alert Bot', ':warning:') ->to('#alerts') ->content('System health check results') ->linkNames() ->unfurlLinks(true) ->attachment(function ($attachment) { $attachment ->title('Database Performance', 'https://db.example.com') ->pretext('Performance report generated') ->content('Query response times are within acceptable limits') ->color('good') ->author('Monitoring System', 'https://monitor.example.com', 'https://example.com/icon.png') ->field('Response Time', '125ms') ->field('Queries/sec', '1,247') ->field(function ($field) { $field->title('Status')->content('Healthy')->short(); }) ->image('https://example.com/chart.png') ->thumb('https://example.com/thumb.png') ->footer('Database Monitor') ->footerIcon('https://example.com/footer.png') ->timestamp(now()); }) ->attachment(function ($attachment) { $attachment ->title('Recommended Actions') ->content('Consider adding indexes to user_events table') ->color('warning') ->action('Review Query', 'https://example.com/query/123', 'primary') ->action('View Details', 'https://example.com/details', 'default'); }); } ``` ## Button Elements with Confirmation Add interactive buttons with optional confirmation dialogs to action blocks. ```php use Illuminate\Notifications\Slack\SlackMessage; use Illuminate\Notifications\Slack\BlockKit\Elements\ButtonElement; public function toSlack($notifiable) { return (new SlackMessage) ->headerBlock('Delete User Account') ->sectionBlock(function ($section) { $section->text('This action cannot be undone. Please confirm deletion of user account.'); }) ->actionsBlock(function ($actions) { $actions->button('Cancel') ->value('cancel') ->id('cancel_btn'); $actions->button('Delete Account') ->value('delete_user_123') ->id('delete_btn') ->danger() ->confirm('Are you absolutely sure?', function ($confirm) { $confirm ->title('Confirm Account Deletion') ->text('This will permanently delete the user account and all associated data.') ->confirm('Yes, Delete') ->deny('Cancel'); }); }); } ``` ## Thread Replies and Broadcasting Reply to existing Slack threads and broadcast thread replies to the channel. ```php use Illuminate\Notifications\Slack\SlackMessage; public function toSlack($notifiable) { return (new SlackMessage) ->text('Follow-up on the previous discussion') ->threadTimestamp('1503435956.000247') // Parent message timestamp ->broadcastReply(true) // Also post to main channel ->sectionBlock(function ($section) { $section->text('Update: The issue has been resolved'); }); } // For a simple thread reply without broadcasting public function toSlack($notifiable) { return (new SlackMessage) ->text('Internal thread reply, not visible in main channel') ->threadTimestamp('1503435956.000247') ->sectionBlock(function ($section) { $section->text('Additional details for the team'); }); } ``` ## Section Block with Accessory Elements Enhance section blocks with accessory elements like buttons or select menus. ```php use Illuminate\Notifications\Slack\SlackMessage; use Illuminate\Notifications\Slack\BlockKit\Elements\ButtonElement; public function toSlack($notifiable) { return (new SlackMessage) ->sectionBlock(function ($section) { $section ->text('*New feature request submitted*') ->markdown() ->field('Title')->text('Dark mode support') ->field('Priority')->text('High') ->field('Votes')->text('47') ->accessory(new ButtonElement('Review', function ($button) { $button ->url('https://features.example.com/123') ->primary(); })); }) ->sectionBlock(function ($section) { $section->text('Click the button above to review the feature request'); }); } ``` ## Image and Context Blocks Display images and contextual information with proper formatting. ```php use Illuminate\Notifications\Slack\SlackMessage; use Illuminate\Notifications\Slack\BlockKit\Blocks\ContextBlock; public function toSlack($notifiable) { return (new SlackMessage) ->headerBlock('Weekly Report') ->imageBlock( 'https://charts.example.com/weekly-stats.png', 'Weekly statistics chart', function ($image) { $image->id('weekly_chart')->title('Performance Metrics'); } ) ->contextBlock(function (ContextBlock $context) { $context ->image('https://example.com/icon.png')->alt('Report icon') ->text('Generated by Analytics Bot')->markdown() ->text('Last updated: ' . now()->format('M d, Y H:i')); }) ->dividerBlock() ->sectionBlock(function ($section) { $section->text('Download full report below'); }); } ``` ## Using Block Kit Templates Import pre-built Block Kit JSON templates from Slack's Block Kit Builder. ```php use Illuminate\Notifications\Slack\SlackMessage; public function toSlack($notifiable) { $message = new SlackMessage; // Add custom blocks first $message->headerBlock('Dashboard Update'); // Import blocks from Block Kit Builder $message->usingBlockKitTemplate(<<<'JSON' { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "Your metrics are looking *great* today! :chart_with_upwards_trend:" } }, { "type": "context", "elements": [ { "type": "image", "image_url": "https://api.example.com/avatar/user123.png", "alt_text": "User Avatar" }, { "type": "mrkdwn", "text": "Updated by *John Smith* at 2:30 PM" } ] } ] } JSON); // Add more blocks after template $message->dividerBlock(); return $message; } ``` ## Conditional Block Rendering Build messages dynamically with conditional block inclusion. ```php use Illuminate\Notifications\Slack\SlackMessage; public function toSlack($notifiable) { $hasErrors = true; $warningCount = 5; $isProduction = app()->environment('production'); return (new SlackMessage) ->headerBlock('Build Status Report') ->when($hasErrors, function ($message) { $message->sectionBlock(function ($section) { $section->text(':x: Build *failed* with errors')->markdown(); }); }) ->when($warningCount > 0, function ($message) use ($warningCount) { $message->sectionBlock(function ($section) use ($warningCount) { $section->text("Found {$warningCount} warnings")->markdown(); }); }, function ($message) { $message->sectionBlock(function ($section) { $section->text(':white_check_mark: No warnings found')->markdown(); }); }) ->when($isProduction, function ($message) { $message->contextBlock(function ($context) { $context->text(':warning: Production environment')->markdown(); }); }) ->dividerBlock() ->actionsBlock(function ($actions) { $actions->button('View Logs')->url('https://logs.example.com'); }); } ``` ## SlackNotificationRouterChannel Auto-Detection Automatically route notifications to webhook or Web API based on configuration. ```php use Illuminate\Notifications\Notification; use Illuminate\Notifications\Slack\SlackRoute; class FlexibleSlackNotification extends Notification { public function via($notifiable) { return ['slack']; // Uses SlackNotificationRouterChannel } public function toSlack($notifiable) { // Works with both webhook and Web API return (new \Illuminate\Notifications\Slack\SlackMessage) ->text('This notification works with any routing method') ->headerBlock('Flexible Notification'); } // Option 1: Route via webhook URL (uses SlackWebhookChannel) // public function routeNotificationForSlack($notification) // { // return 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'; // } // Option 2: Route via Web API with token (uses SlackChannel) public function routeNotificationForSlack($notification) { return SlackRoute::make('#general', 'xoxb-your-bot-token'); } // Option 3: Use channel name only (token from config) // public function routeNotificationForSlack($notification) // { // return '#general'; // } // Option 4: Disable notification for specific notifiable // public function routeNotificationForSlack($notification) // { // return false; // } } ``` ## Complete Notification Example Full-featured notification combining multiple block types and configuration options. ```php use Illuminate\Notifications\Notification; use Illuminate\Notifications\Slack\SlackMessage; use Illuminate\Notifications\Slack\SlackRoute; class ServerAlertNotification extends Notification { protected $server; protected $metric; protected $value; protected $threshold; public function __construct($server, $metric, $value, $threshold) { $this->server = $server; $this->metric = $metric; $this->value = $value; $this->threshold = $threshold; } public function via($notifiable) { return ['slack']; } public function toSlack($notifiable) { $severity = $this->value > ($this->threshold * 1.5) ? 'critical' : 'warning'; return (new SlackMessage) ->text("Server alert: {$this->metric} is {$this->value}% on {$this->server}") ->metadata('server_alert', [ 'server' => $this->server, 'metric' => $this->metric, 'severity' => $severity, 'timestamp' => now()->timestamp ]) ->unfurlLinks(false) ->headerBlock('🚨 Server Alert') ->sectionBlock(function ($section) { $section ->text("*{$this->metric}* has exceeded threshold on *{$this->server}*") ->markdown() ->field('Current Value')->markdown()->text("*{$this->value}%*") ->field('Threshold')->text("{$this->threshold}%") ->field('Server')->text($this->server) ->field('Status')->markdown()->text('*Active*'); }) ->when($this->value > ($this->threshold * 1.5), function ($message) { $message->contextBlock(function ($context) { $context->text('⚠️ Critical: Immediate action required')->markdown(); }); }) ->dividerBlock() ->imageBlock( "https://monitor.example.com/graph/{$this->server}/{$this->metric}.png", 'Performance graph' ) ->dividerBlock() ->actionsBlock(function ($actions) { $actions->button('View Dashboard') ->url("https://monitor.example.com/server/{$this->server}") ->primary(); $actions->button('SSH to Server') ->value("ssh_{$this->server}") ->id('ssh_button'); $actions->button('Acknowledge') ->value("ack_alert") ->id('ack_button') ->confirm('Acknowledge this alert?', function ($confirm) { $confirm ->title('Confirm Acknowledgment') ->text('Mark this alert as acknowledged?') ->confirm('Yes') ->deny('Cancel'); }); $actions->button('Silence for 1 hour') ->value('silence_3600') ->id('silence_button') ->danger(); }) ->contextBlock(function ($context) { $context ->text('Monitoring System') ->text('•') ->text(now()->format('M d, Y H:i:s')); }); } public function routeNotificationForSlack($notification) { return SlackRoute::make( '#ops-alerts', config('services.slack.notifications.bot_user_oauth_token') ); } } // Send the notification $admin->notify(new ServerAlertNotification('web-01', 'CPU Usage', 92, 80)); ``` ## Summary The Laravel Slack Notification Channel provides a comprehensive solution for sending sophisticated notifications to Slack workspaces through Laravel's notification system. It supports both modern Block Kit-based messages via the Slack Web API and legacy webhook-based messages with attachments, offering flexibility for various integration scenarios. The package automatically routes notifications through the appropriate channel based on how the notification route is configured, whether using webhook URLs, OAuth tokens, or configuration-based defaults. The library excels at creating rich, interactive messages with support for all major Block Kit components including sections, headers, images, dividers, contexts, and action blocks with buttons. Advanced features like thread replies, message broadcasting, metadata attachment, conditional rendering, markdown formatting, and confirmation dialogs enable developers to build production-ready alerting and notification systems. The fluent API design makes it straightforward to compose complex message layouts while maintaining clean, readable code, and the seamless integration with Laravel's notification infrastructure allows for consistent notification handling across multiple channels.