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

Symfony Slack Bot Laravel Package

wow-apps/symfony-slack-bot

Symfony bundle for building Slack bots that handle slash commands, interactive components, and Slack events inside your app. Simplifies Slack API integration, routing, and replies so you can add workspace automation with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and first sanity check

composer require wow-apps/symfony-slack-bot

The package is archived and targets Symfony 3/4, so on a modern Laravel app expect a platform conflict. Read composer.json in the repo first:

  • PHP constraint (~7.1-ish) will not satisfy Laravel 10/11's ^8.1.
  • It pulls Symfony components (symfony/http-client/symfony/config/symfony/dependency-injection) that may collide with the versions Laravel already ships.

If you still want it, you have two realistic options: pin the app to an older PHP/Composer floor, or install with --ignore-platform-reqs only in a scratch environment to read the source. For production Laravel work, the practical answer is that you evaluate this package's ideas (a SlackMessage/SlackAttachment builder) rather than its runtime.

Where to look first

  1. src/WowAppsSlackBundle.php and src/Resources/config/services.yml — this is the Symfony bundle wiring. Laravel will not load this, so treat it as documentation of how SlackClient and SlackConfig are constructed.
  2. SlackClient / SlackClientInterface — the actual HTTP call to the incoming webhook.
  3. SlackMessage, SlackAttachment, and the block/field builder classes — the value of the package.
  4. The wowapps_slack configuration node (webhook URL, channel, bot name, icon) — mirror it in a Laravel config file.

First use case: a plain text ping from tinker

Because there is no Laravel service provider, construct the client yourself:

// config/slack.php
return [
    'webhook_url' => env('SLACK_WEBHOOK_URL'),
    'channel'     => env('SLACK_CHANNEL', '#general'),
    'bot_name'    => 'Laravel',
    'icon'        => ':robot_face:',
];
$config = new \WowApps\SlackBundle\Slack\SlackConfig(config('slack'));
$client = new \WowApps\SlackBundle\Slack\SlackClient($config);

$message = new \WowApps\SlackBundle\Slack\SlackMessage();
$message->setText('Deploy finished :white_check_mark:');

$client->sendMessage($message); // verify the exact method name against SlackClientInterface

If that round-trips to your test channel, everything else is ergonomics. If it throws on container/DI classes, the bundle is doing Symfony-specific work and you should stop and use laravel/slack-notification-channel instead.

Implementation Patterns

Bind a singleton, don't new in controllers

// app/Providers/SlackServiceProvider.php
public function register(): void
{
    $this->app->singleton(SlackClient::class, function ($app) {
        return new SlackClient(new SlackConfig($app['config']->get('slack')));
    });
}

Then inject SlackClient into whatever needs it. One client instance per webhook URL; if you route to different channels, prefer multiple webhook URLs over per-message channel overrides (see Gotchas).

Wrap sending in a queued job

A webhook is a synchronous network call. Never send inline in a request cycle:

class SendSlackMessage implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable;

    public int $tries = 3;
    public array $backoff = [5, 30];

    public function __construct(public SlackMessage $message) {}

    public function handle(SlackClient $client): void
    {
        $client->sendMessage($this->message);
    }
}

Note: SlackMessage must be serializable to survive the queue. The builder classes are plain objects, so this generally works — but if the client is injected into the message, use __sleep/__serialize or rebuild the message inside handle().

Message-building patterns that age well

  • Text only for quick ops pings (setText).
  • Attachments for legacy-style colored blocks. The package's SlackAttachment (title, text, color, fields) maps directly onto Slack's attachments array and is still supported.
  • Blocks (section, divider, actions, context) if the package version you have exposes them — this is the format Slack actually recommends. If the package doesn't have block support, build the payload array yourself and post it with Http::post($webhook, $payload); you lose nothing by mixing.

Where this earns its keep day-to-day

  • report() / exception handler hook — push production errors into a triage channel with SlackAttachment fields for exception class, route, and user ID.
  • Deployment / queue-backlog / health-check notifications from scheduled commands.
  • Alerting from Event::listen on domain events (order failed, refund issued), using Notifications-style message builders.

Testing without hitting Slack

You cannot easily Http::fake() a package that may use its own HTTP client. Two reliable approaches:

  1. Wrap SlackClient behind your own SlackNotifier interface and bind a NullNotifier/recording fake in tests.
  2. Use a local receiver (request bin, MailHog-equivalent like webhook.site) and assert on dispatch only.

Prefer (1). Asserting on the message object you built ($notifier->assertSent(fn ($m) => $m->getText() === '...')) is far more stable than asserting on JSON internals of a third-party builder.

Config-driven routing

Keep SLACK_WEBHOOK_URL per-environment and fail closed in local/testing — the classic mistake is local test runs spamming #alerts. A NullNotifier binding when app()->environment('local') avoids it cleanly.

Gotchas and Tips

Archived status is the headline risk. 21 stars, 0 dependents, last-touched in the Symfony 3/4 era. There will be no security fixes and no PHP 8.2+ / Laravel 11 compatibility patches. Treat any adoption as a vendored fork, not a dependency. If you need the builder ergonomics, copy the three or four message classes into app/Support/Slack/ (MIT license permits it) and own them.

The bundle will not boot in Laravel. WowAppsSlackBundle implements Symfony's Bundle interface and expects Kernel, services.yml autoloading, and a config tree. Skipping the bundle is not optional — you must instantiate SlackClient/SlackConfig manually. Anything that only works through the container (e.g. autowired config injection) is unavailable.

Check for Symfony-only dependencies in the hot path. If SlackClient type-hints a PSR-7/HttpFoundation/Validator class, you'll be pulling Symfony pieces into a Laravel app just to send a string. Read the constructor signature before committing.

Slack's incoming webhook returns the literal string ok, not JSON. The package may not check it. A 200 with invalid_payload still reads as success unless you inspect the body. Add your own assertion if delivery matters — especially for alerts, where silent failure is worse than a loud exception.

channel overrides are not free. A webhook bound to #general cannot post to #random unless the Slack app has been granted access to that channel; the override silently falls back. The reliable pattern is one webhook URL per channel, keyed in config.

Rate limit: ~1 message/second per webhook, HTTP 429 on burst. Retries with backoff (see the queued job above) are mandatory if you fan out notifications in a loop. Also consider batching multiple events into one message via fields/sections rather than N posts.

Escape untrusted text before setText/section blocks. Slack markdown treats <, >, & specially, and a raw <!channel> or <!here> in user-supplied content will page the whole team. Replace & → &amp;, < → &lt;, > → &gt;, and explicitly decide whether mentions are allowed.

Never log the webhook URL. It's a bearer credential — anyone with it can post as your bot. Store it in env(), and make sure it doesn't land in request/exception logs via the client's debug output.

Timeouts. The default HTTP timeout in older Symfony HTTP clients can be generous. Constrain it (2–5s) so a Slack outage doesn't stall a queue worker. Pair with $tries/$backoff and a failed() handler that logs locally rather than rethrowing into a loop.

Extension points worth knowing. SlackConfig (webhook, channel, bot name, icon) and SlackMessage are plain and subclassable — that's the sane customization surface. Extending SlackClient to add retries or body validation is also viable, and is probably the first thing you'll do.

Laravel-native alternative, for the record. If the goal is "send Slack messages from Laravel," laravel/slack-notification-channel (via Notifiable::routeNotificationForSlack) does this natively, is maintained, integrates with Notification::fake(), and supports block kit. This package only makes sense if you specifically want its builder classes and are willing to own them post-archive.

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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk