Weave 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

Slack Bundle Laravel Package

slowhop/slack-bundle

A Symfony bundle that simplifies Slack integration, providing configuration and services for webhooks, notifications, and Slack API connectivity so your PHP app can send messages with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Step 0 — run the gate before you write any code. This is a Symfony bundle (CL\SlackBundle) being evaluated from a Laravel codebase, so the first command is not require, it's the dry run:

composer require slowhop/slack-bundle --dry-run

If it won't resolve against PHP 8.1+ and Laravel 10/11 without --ignore-platform-reqs, stop here. Ignoring platform requirements to install a zero-adoption, unmaintained package is the trade you don't make. Record the result and move to the replacement path.

Where to look first (30-minute read, in this order):

  1. composer.json — PHP and symfony/* constraints tell you the era. Expect ^2.x/^3.x and ~5.5|~7.0.
  2. DependencyInjection/CLSlackExtension.php + Configuration.php — this is the entire config surface. Translate each key to a .env var; this is your future config/slack.php.
  3. The service classes (Service/Client.php, API wrappers) — enumerate exactly which Slack methods are called and which auth model they assume. This is the only information the package uniquely gives you.
  4. Grep for attachments, chat.postMessage, rtm, oauth, X-Slack-Signature. That tells you whether it's webhook-era, Web API v1-era, or has any modern coverage.

First use case — one outbound message, in isolation. Do not register the bundle in config/app.php or bootstrap/providers.php. Instead, prove the capability with the maintained path:

composer require laravel/slack-notification-channel
// app/Notifications/DeployFinished.php
public function via($notifiable) { return [SlackChannel::class]; }

public function toSlack($notifiable): SlackMessage
{
    return (new SlackMessage)
        ->text('Deploy finished')            // fallback, required
        ->headerBlock('production')
        ->contextBlock(fn ($b) => $b->text("commit `abc1234`"));
}

Point SLACK_WEBHOOK_URL at a test channel. If that closes the ticket — and for the "notify a channel when X happens" requirement it usually does — slowhop/slack-bundle is evaluated-and-declined, and you never owe it a maintenance commitment.

Implementation Patterns

Bind behind an interface, always. Even when you vendor the bundle's logic directly, call sites should never see vendor classes:

// app/Contracts/SlackClient.php
interface SlackClient { public function post(string $channel, SlackMessage $m): void; }

// app/Providers/SlackServiceProvider.php
$this->app->bind(SlackClient::class, SlackWebApiClient::class);

This is the pattern that makes the "we adopted an unmaintained package" decision reversible instead of permanent.

Vendor-and-rewrite (only if the source contains logic you must preserve). Treat it as a rewrite, not a port: copy the useful classes into app/Support/Slack/, delete the Bundle subclass and the DI Extension, rewrite Configuration.php as config/slack.php + a service provider, add declare(strict_types=1), type every signature, and write tests around each method you kept. Expect original test coverage to be thin or absent — budget accordingly.

Queue every outbound call. Slack enforces per-method, per-workspace tiered limits and returns 429 with Retry-After. Inline synchronous Guzzle in a request worker blocks the worker and, under load, converts a slow Slack into a slow app.

class SendSlackAlert implements ShouldQueue
{
    public int $tries = 5;
    public array $backoff = [1, 5, 15, 60, 300]; // survives Retry-After
}

Inbound webhooks — write this yourself, don't inherit it. If the bundle predates Slack signing secrets it either trusts unsigned payloads or verifies nothing:

$base = "v0:{$request->header('X-Slack-Request-Timestamp')}:{$request->getContent()}";
abort_unless(hash_equals('v0='.hash_hmac('sha256', $base, config('slack.signing_secret')),
                        $request->header('X-Slack-Signature')), 401);
abort_if(abs(time() - $request->header('X-Slack-Request-Timestamp')) > 300, 401);

Contract tests against a fake transport. Snapshot the JSON payload you send and assert on it with Http::fake(). Slack's API drifts; a CI test on payload shape catches drift before production does — the thing no upstream is going to do for you.

Gotchas and Tips

A Symfony Bundle is not a Laravel package. It assumes a kernel, bundles.php, an Extension with a Configuration tree, and Symfony's event dispatcher. There is no package discovery. Registering it means bootstrapping Symfony's DI inside Laravel — a permanent tax on every engineer who touches it, with zero payoff.

Slack returns HTTP 200 on logical failure. Every chat.postMessage response must be inspected for "ok": false and the error field (channel_not_found, not_in_channel, invalid_auth, ratelimited). Wrappers of this vintage frequently check only the status code — so "messages silently not arriving" is the most likely bug you'll debug.

Auth model mismatch. Legacy workspace tokens and the RTM API are retired; granular scopes, OAuth v2, and Block Kit post-date this code. If it only speaks attachments and not blocks, you're shipping a deprecated message format.

Payload limits bite in prod, not dev. 50 blocks per message, 3,000 characters per text block, 150 for header, and a top-level text fallback is required or push notifications render empty.

Don't be the silent sole dependent. Zero stars and zero dependents means no issue history to search and no third party who hit your bug first. Pin by commit SHA, note the provenance in an ADR, and keep the vendor surface thin so removal is a day, not a quarter.

Debugging loop: log the exact outgoing JSON and the full Slack response body together, correlation-ID'd. When something fails, that pair answers "did we send the wrong shape, or does the token lack scope?" — the only two questions that matter here.

Extension point that actually exists: your own SlackClient interface. Because the package has no upstream, the interface is the abstraction layer; it's what lets you swap to slack-php/slack-php-api or a Saloon connector later without hunting call sites.

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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment