Skip to content

Slack Integration

Configuration

Add your Slack signing secret to .env:

env
SLACK_WEBHOOK_SECRET=your_slack_signing_secret_here

Get your signing secret:

  1. Go to Slack API
  2. Select your app
  3. Go to Basic InformationApp Credentials
  4. Copy the Signing Secret

Route Setup

php
// routes/web.php
use App\Http\Controllers\SlackWebhookController;

Route::post('/slack-webhook', [SlackWebhookController::class, 'handle'])
    ->middleware('validate-webhook:slack');

Controller Example

php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class SlackWebhookController extends Controller
{
    public function handle(Request $request): JsonResponse
    {
        $payload = json_decode($request->getContent(), true);

        // Handle URL verification challenge
        if (isset($payload['type']) && $payload['type'] === 'url_verification') {
            return response()->json(['challenge' => $payload['challenge']]);
        }

        $eventType = $payload['event']['type'] ?? $payload['type'] ?? 'unknown';

        match ($eventType) {
            'app_mention' => $this->handleAppMention($payload),
            'message' => $this->handleMessage($payload),
            'block_actions' => $this->handleBlockActions($payload),
            'view_submission' => $this->handleViewSubmission($payload),
            default => $this->handleUnknown($eventType),
        };

        return response()->json(['status' => 'success']);
    }

    private function handleAppMention(array $payload): void
    {
        $event = $payload['event'];

        Log::info('Slack: App mentioned', [
            'user' => $event['user'],
            'channel' => $event['channel'],
            'text' => $event['text'],
        ]);

        // Reply to the mention
        // $this->slackClient->chat->postMessage([
        //     'channel' => $event['channel'],
        //     'text' => "Hi <@{$event['user']}>! How can I help?",
        // ]);
    }

    private function handleMessage(array $payload): void
    {
        $event = $payload['event'];

        // Ignore bot messages to prevent loops
        if (isset($event['bot_id'])) {
            return;
        }

        Log::info('Slack: Message received', [
            'channel' => $event['channel'],
            'user' => $event['user'] ?? 'unknown',
        ]);
    }

    private function handleBlockActions(array $payload): void
    {
        $action = $payload['actions'][0] ?? [];

        Log::info('Slack: Block action triggered', [
            'action_id' => $action['action_id'] ?? 'unknown',
            'user' => $payload['user']['id'] ?? 'unknown',
        ]);
    }

    private function handleViewSubmission(array $payload): void
    {
        Log::info('Slack: View submitted', [
            'view_id' => $payload['view']['id'] ?? 'unknown',
            'user' => $payload['user']['id'] ?? 'unknown',
        ]);
    }

    private function handleUnknown(string $eventType): void
    {
        Log::warning('Slack: Unknown event', ['event_type' => $eventType]);
    }
}

Signature Validation

Slack sends two headers:

  • X-Slack-Signature: v0=HMAC_SHA256_SIGNATURE
  • X-Slack-Request-Timestamp: Unix timestamp

The signature is computed from: v0:timestamp:body

LaraWebhook automatically:

  1. Combines the timestamp and signature
  2. Validates the timestamp against tolerance
  3. Verifies the HMAC-SHA256 signature

URL Verification

When you first configure your webhook URL, Slack sends a verification challenge:

json
{
    "type": "url_verification",
    "challenge": "random_string"
}

The controller example above handles this automatically by returning the challenge.

Configure in Slack

Event Subscriptions

  1. Go to Slack API
  2. Select your app
  3. Navigate to Event Subscriptions
  4. Enable events
  5. Enter Request URL: https://your-domain.com/slack-webhook
  6. Subscribe to events (e.g., app_mention, message.channels)
  7. Save changes

Interactivity

For interactive components (buttons, modals):

  1. Navigate to Interactivity & Shortcuts
  2. Enable Interactivity
  3. Enter Request URL: https://your-domain.com/slack-webhook
  4. Save changes

Common Events

EventDescription
app_mentionBot mentioned in channel
messageMessage in channel
message.imDirect message to bot
block_actionsButton/menu clicked
view_submissionModal submitted
app_home_openedUser opened app home

Released under the MIT License.