Looking to hire Laravel developers? Try LaraJobs

laravel-slack maintained by labrodev

Description
Stateless Slack incoming-webhook client for Laravel with Block Kit message transport and webhook-URL validation.
Author
Last update
2026/07/22 13:43 (dev-main)
License
Downloads
0

Comments
comments powered by Disqus

Laravel Slack

Stateless Slack incoming-webhook client for Laravel with Block Kit message transport and webhook-URL validation. Slack incoming webhooks are self-contained bearer URLs — there is no OAuth flow, no bot token, and no app-level credential to configure. Each caller supplies its own webhook URL on every call, and the package stores nothing.

Installation

composer require labrodev/laravel-slack

Optionally publish the config file:

php artisan vendor:publish --tag=slack-config
SLACK_HTTP_TIMEOUT=10
SLACK_WEBHOOK_HOST=hooks.slack.com
SLACK_WEBHOOK_PATH_PREFIX=/services/

SLACK_WEBHOOK_HOST and SLACK_WEBHOOK_PATH_PREFIX only need overriding if Slack ever changes its incoming-webhook domain or path shape — the defaults match Slack's current URLs.

Sending a message

SlackClient::send() posts Block Kit blocks and a fallback text to the incoming-webhook URL you provide:

use Labrodev\Slack\Services\SlackClient;
use Labrodev\Slack\Exceptions\SlackRequestFailed;
use Labrodev\Slack\Exceptions\SlackWebhookRevoked;

$slackClient = new SlackClient();

$blocks = [
    [
        'type' => 'section',
        'text' => [
            'type' => 'mrkdwn',
            'text' => 'A new incident was reported.',
        ],
    ],
];

try {
    $slackClient->send(
        webhookUrl: $webhookUrl,
        blocks: $blocks,
        fallbackText: 'A new incident was reported.',
    );
} catch (SlackWebhookRevoked) {
    // the webhook was deleted or revoked on Slack's side
} catch (SlackRequestFailed) {
    // any other failed request
}

Validating a webhook URL

Use SlackWebhookUrl::validate() to check a pasted webhook URL before storing it. It checks the scheme, the host against slack.webhook_host, and the path against slack.webhook_path_prefix, without overfitting to the exact segment count — and throws a specific exception for whichever part failed:

use Labrodev\Slack\Support\SlackWebhookUrl;
use Labrodev\Slack\Exceptions\SlackWebhookUrlSchemeInvalid;
use Labrodev\Slack\Exceptions\SlackWebhookUrlHostInvalid;
use Labrodev\Slack\Exceptions\SlackWebhookUrlPathInvalid;

try {
    new SlackWebhookUrl()->validate($request->input('webhook_url'));
} catch (SlackWebhookUrlSchemeInvalid|SlackWebhookUrlHostInvalid|SlackWebhookUrlPathInvalid) {
    throw ValidationException::withMessages([
        'webhook_url' => 'That does not look like a Slack incoming-webhook URL.',
    ]);
}

Detecting a revoked webhook

Catch SlackWebhookRevoked to mark a stored webhook credential as dead instead of retrying it indefinitely:

use Labrodev\Slack\Exceptions\SlackWebhookRevoked;

try {
    $slackClient->send(webhookUrl: $channel->webhook_url, blocks: $blocks, fallbackText: $fallbackText);
} catch (SlackWebhookRevoked) {
    $channel->update(['webhook_url' => null]);
}

Exceptions

  • Labrodev\Slack\Exceptions\SlackWebhookRevoked — Slack returned 404 or 410: the webhook was deleted or revoked.
  • Labrodev\Slack\Exceptions\SlackRequestFailed — any other failed request.
  • Labrodev\Slack\Exceptions\SlackWebhookUrlSchemeInvalid — thrown by SlackWebhookUrl::validate() when the scheme isn't https.
  • Labrodev\Slack\Exceptions\SlackWebhookUrlHostInvalid — thrown by SlackWebhookUrl::validate() when the host doesn't match slack.webhook_host.
  • Labrodev\Slack\Exceptions\SlackWebhookUrlPathInvalid — thrown by SlackWebhookUrl::validate() when the path doesn't start with slack.webhook_path_prefix.

All carry fixed messages only. A Slack incoming-webhook URL is the bearer secret itself, so it is never interpolated into an exception message.

Testing

composer test      # pest
composer phpstan   # larastan, level 7
composer pint      # laravel preset
composer check     # all of the above

License

MIT. See LICENSE.md.