symfony/slack-notifier
Symfony Slack Notifier integrates Slack messaging into Symfony's Notifier component. Send chat messages via a simple DSN with your bot token and channel, and add interactive Block Kit elements like buttons, sections, images, and dividers using SlackOptions.
Framing note (read first): despite being filed here as a "Laravel/PHP package," symfony/slack-notifier is a Symfony Notifier bridge, not a Laravel package. It is a read-only split of the symfony/symfony monorepo and ships one transport (SlackTransport) plus a Block Kit builder DSL. Any assessment of "fit" has to start there, because for a Laravel shop this is not a drop-in — it is the adoption of a second, parallel notification abstraction next to Illuminate\Notifications.
Architecture fit
SlackTransport implements Symfony's ChatTransportInterface, consumes a ChatMessage + SlackOptions, and POSTs to chat.postMessage/chat.update over symfony/http-client. It is useless without symfony/notifier, symfony/options-resolver, symfony/contracts, and an HTTP client — roughly 4–6 transitive production dependencies in a Laravel app that already has Guzzle.SlackOptions / Block Kit layer, not the transport. The README documents section/header/context/divider/actions blocks, button confirm dialogs, accessory() elements, field() with markdown/verbatim/emoji flags, threadTs(), postAt() scheduling, UpdateMessageSlackOptions, and SlackSentMessage::getMessageId()/getChannelId() for later edits. That is materially more than Laravel's built-in SlackMessage (which supports basic blocks, not threaded replies, scheduled posts, message updates, or confirm dialogs).signing_secret), and route yourself. Nothing in this package receives or parses those payloads. Any "approval workflow" use case is therefore 2 packages of work, not 1.symfony/symfony, not in this repo. Do not read the GitHub metrics at face value.Integration feasibility
SlackNotifier wrapper. It is not "install and configure a channel."slack://xoxb-...@default?channel=name or channel=@user is valid; channel=#name and bare channel=user are invalid. Most engineers will instinctively paste #channel and get a confusing failure.Technical risk
no significant changes across many point releases). Boring is good here.Chatter/ChatMessage concept alongside Laravel's Notification system. Two ways to send a Slack message means two sets of credentials, two retry policies, two test doubles, and inevitable drift.->id('contribute_block); — unterminated string), which suggests examples are copied, not executed. Treat the snippets as illustrative, not verified.Key questions to resolve before committing
chat.update, postAt), or would Laravel's native SlackMessage + incoming webhook cover 80% of the need?xoxb-) or webhook? This package requires a bot token with chat:write (plus chat:write.public for public channels the bot isn't in). Webhook-only governance models are incompatible.symfony/http-client alongside Guzzle, or do we standardize on one?Stack fit
Migration path
SlackTransport behind a Laravel-native SlackNotifier interface; prove one non-critical flow end-to-end (e.g., a nightly digest). Success criteria: message delivered, SlackSentMessage IDs captured, failure surfaces as a Laravel exception.Illuminate\Notifications Slack/webhook channels untouched. New flows go through the bridge only.Compatibility
Illuminate\Notifications is fine mechanically (different namespaces, different config keys) — the risk is conceptual drift, not autoloading.composer.json with a caret on the minor (^7.4) rather than floating, since the 6.4/7.x/8.x lines have different floor requirements.SlackTransport from a singleton binding; do not resolve it ad hoc, or you will re-instantiate the HTTP client per call.Sequencing (dependency order)
.env in prod).Maintenance
no significant changes releases. Budget for a once-per-major review (6.4 → 7.4 → 8.x), not ongoing maintenance.chat.postMessage payload changes). That is your problem, not Symfony's — the bridge is a thin pass-through and will happily send a payload Slack has since deprecated.Support
symfony/symfony. Sympathy is available, SLA is not. If you need a vendor to call, you do not have one — plan for internal ownership.Scaling
ShouldQueue / dedicated job) with a rate limiter keyed by channel, and treat 429 with Retry-After as first-class.Failure modes to instrument
#channel, bare username) — fails at transport construction or first send; validate at boot, fail fast.chat:write.public for a channel the bot hasn't joined — surfaces as a Slack API error mid-incident, i.e., the worst time.chat.update on a stale ts or wrong channel ID silently no-ops or edits the wrong message — persist both IDs together, never just one.postAt is Slack-side; a deleted/archived channel leaves the scheduled message in limbo with no local record unless you persist the intent.ok/error code; alert on error-rate, not on send count.Ramp-up
Chatter/ChatMessage/Options model, which is a genuinely different mental model from Notification::route('slack', ...).Bottom line for a TPM: treat this as a capability purchase, not a library purchase. Approve it only if the roadmap needs threaded replies, message updates, scheduling, or confirm dialogs — the things Laravel's native Slack channel cannot do. If the requirement is "post a formatted message to a channel," the correct decision is to decline and stay on Illuminate\Notifications + webhooks. If approved, budget for the Slack app governance, the queue/rate-limit layer, and the interaction receiver; the composer install is the easy 10%.
How can I help you explore Laravel packages today?