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 Slack Slash Command Laravel Package

spatie/laravel-slack-slash-command

Build Slack slash commands in Laravel. Define handlers to validate and process incoming Slack requests, reply within 3 seconds or dispatch jobs for longer work, and send structured responses back to Slack. Includes request/response helpers and simple routing of commands.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-slack-slash-command
    

    Publish the config file:

    php artisan vendor:publish --provider="Spatie\SlackSlashCommand\SlackSlashCommandServiceProvider"
    
  2. Configure Slack:

    • Register a slash command in your Slack app settings (e.g., /mycommand).
    • Set the Request URL to your Laravel endpoint (e.g., https://your-app.test/slack/mycommand).
    • Add the Signing Secret from Slack to .env:
      SLACK_SIGNING_SECRET=your_signing_secret_here
      
  3. Define a Command Handler: Create a handler class (e.g., app/Slack/Commands/MyCommandHandler.php):

    namespace App\Slack\Commands;
    
    use Spatie\SlackSlashCommand\SlackCommand;
    
    class MyCommandHandler
    {
        public function handle(SlackCommand $slackCommand): string
        {
            return "Hello, {$slackCommand->user->name}! Your input: {$slackCommand->body('text')}";
        }
    }
    
  4. Register the Handler: Bind the handler in AppServiceProvider:

    public function boot()
    {
        SlackCommand::macro('mycommand', function () {
            return new \App\Slack\Commands\MyCommandHandler();
        });
    }
    
  5. Route the Command: Add a route in routes/web.php:

    use Spatie\SlackSlashCommand\SlackCommand;
    
    Route::post('/slack/mycommand', function () {
        return SlackCommand::mycommand()->handle();
    });
    
  6. Test Locally: Use Slack's Socket Mode or tools like ngrok to test locally.


First Use Case: Simple User Greeting

Create a /greet command that responds with a personalized message:

// app/Slack/Commands/GreetHandler.php
public function handle(SlackCommand $slackCommand): string
{
    $name = $slackCommand->body('text') ?: $slackCommand->user->name;
    return "Hi {$name}! Welcome to our app. 🎉";
}
  • Slack Command: /greet @user or /greet John.
  • Output: "Hi John! Welcome to our app. 🎉".

Implementation Patterns

Workflow: Building a Multi-Step Command

  1. Validate Input:

    public function handle(SlackCommand $slackCommand): string
    {
        $text = $slackCommand->body('text');
        if (empty($text)) {
            return "Please provide a task name. Example: `/todo Add laundry`";
        }
        // ...
    }
    
  2. Interact with Laravel Services: Inject dependencies (e.g., repositories, services) into the handler:

    use App\Services\TodoService;
    
    public function __construct(private TodoService $todoService) {}
    
    public function handle(SlackCommand $slackCommand): string
    {
        $task = $this->todoService->create($slackCommand->body('text'));
        return "Added task: *{$task->name}* (ID: {$task->id})";
    }
    
  3. Attachments and Interactive Responses: Return rich messages with attachments:

    public function handle(SlackCommand $slackCommand): string
    {
        return response()->json([
            'text' => 'Your task was created!',
            'attachments' => [
                [
                    'title' => 'Task Details',
                    'fields' => [
                        ['title' => 'Name', 'value' => $task->name, 'short' => true],
                        ['title' => 'Due', 'value' => $task->due_date, 'short' => true],
                    ],
                ],
            ],
        ]);
    }
    
  4. Error Handling: Use Laravel's exception handling or return user-friendly errors:

    try {
        $this->todoService->create($text);
    } catch (\Exception $e) {
        return "❌ Error: {$e->getMessage()}";
    }
    

Integration Tips

  1. Authentication: Verify the Slack user or team before processing:

    if ($slackCommand->team->id !== config('slack.allowed_team_id')) {
        return "This command is restricted to our team.";
    }
    
  2. Rate Limiting: Use Laravel's throttle middleware to limit command frequency:

    Route::post('/slack/todo', function () {
        return SlackCommand::todo()->handle();
    })->middleware('throttle:5,1'); // 5 requests per minute
    
  3. Logging: Log command executions for debugging:

    \Log::info('Slack command executed', [
        'command' => $slackCommand->command,
        'user' => $slackCommand->user->name,
        'input' => $slackCommand->body(),
    ]);
    
  4. Testing: Use SlackCommand facade in tests:

    public function test_greet_command()
    {
        $response = $this->post('/slack/greet', [
            'text' => 'John',
            'token' => 'valid_token',
            'team_id' => 'T123',
            'user_id' => 'U456',
            'user_name' => 'john_doe',
        ]);
    
        $response->assertJson(['response_type' => 'ephemeral', 'text' => 'Hi John! Welcome...']);
    }
    

Gotchas and Tips

Pitfalls

  1. Signing Secret Mismatch:

    • Ensure the SLACK_SIGNING_SECRET in .env matches Slack's app settings.
    • Debug: If requests fail silently, check Laravel logs for InvalidSlackRequestException.
  2. Missing response_type:

    • Slack expects response_type in the JSON response (e.g., in_channel, ephemeral).
    • Fix: Always return a JSON response with response_type:
      return response()->json(['response_type' => 'in_channel', 'text' => '...']);
      
  3. CORS Issues:

    • Slack sends requests to your Laravel app from its domain. Ensure CORS is configured if using APIs:
      // config/cors.php
      'paths' => ['api/*', 'slack/*'],
      'allowed_methods' => ['*'],
      'allowed_origins' => ['https://your-slack-app.slack.com'],
      
  4. Command Not Triggering:

    • Verify the Request URL in Slack matches your Laravel route exactly (including trailing slashes).
    • Test: Use php artisan route:list to confirm the route exists.
  5. Large Payloads:


Debugging Tips

  1. Inspect Raw Request: Dump the $slackCommand->body() to verify incoming data:

    \Log::debug('Raw body:', $slackCommand->body()->all());
    
  2. Enable Slack Debugging: Add this to your handler to log the full request:

    \Log::debug('Slack request:', [
        'command' => $slackCommand->command,
        'body' => $slackCommand->body()->all(),
        'user' => $slackCommand->user,
        'team' => $slackCommand->team,
    ]);
    
  3. Verify Webhook URL: Use Slack's Socket Mode for local testing or tools like RequestBin to inspect incoming requests.


Extension Points

  1. Custom Validation: Extend the SlackCommand class to add validation rules:

    use Spatie\SlackSlashCommand\SlackCommand as BaseSlackCommand;
    
    class SlackCommand extends BaseSlackCommand
    {
        public function validate(array $rules)
        {
            return validator($this->body->all(), $rules);
        }
    }
    
  2. Middleware: Add middleware to the route for pre-processing:

    Route::post('/slack/admin-command', function () {
        return SlackCommand::admin()->handle();
    })->middleware(\App\Http\Middleware\CheckAdmin::class);
    
  3. Dynamic Command Registration: Register commands dynamically based on user roles or config:

    if (config('slack.enable_todo_command')) {
        SlackCommand::macro('todo', function () {
            return new \App\Slack\Commands\Todo
    
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