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 Client Laravel Package

mpociot/slack-client

A Laravel-friendly PHP client for the Slack Web API. Send messages, manage channels and users, and post rich attachments or blocks using a simple, fluent interface with config-driven tokens and a facade for quick integration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a thin wrapper over Slack's Web API — a service provider, a facade alias, and a single token config key — which maps cleanly onto Laravel's container idiom. That part is architecturally unremarkable and low-friction. The problem is packaging: outbound message posting (a ~20-line HTTP call) is bundled with an RTM client built on ReactPHP, a long-running event-loop dependency. Adopting the package to send deploy alerts means inheriting an event loop, a WebSocket stack, and their transitive pins for a capability the roadmap almost certainly doesn't need. Treat the two capabilities as separately valued: outbound is viable, RTM is a retirement problem.

Integration feasibility. Entry cost is genuinely near-zero — composer require, auto-discovery on Laravel 5.5+, publish config, set SLACK_TOKEN. A spike lands in under a day. The real feasibility gate is dependency resolution, not API ergonomics: 2018-era pinning means Guzzle 6, old PSR versions, and old WebSocket/event-loop libraries. On Laravel 9+/PHP 8, assume conflicts until composer why-not says otherwise. Feasibility should be judged as "does this resolve against this host app," not "does this work."

Technical risk. Concentrated and structural, not incidental:

  • Unmaintained with no backstop. Last release October 2018, 51 stars, zero dependents, no vendor. There is no maintainer to file against, no community surface to lean on, and no CVE triage path. Every defect becomes internal work.
  • The differentiator is dead. Slack no longer grants RTM access to newly created apps. Any roadmap item promising live bot conversations or chat-driven workflows is unbuildable on this package regardless of code quality.
  • Failure detection is weak. RTM's classic half-open socket failure produces no exception — the bot simply stops responding. The package provides no application-level heartbeat.
  • Auth assumptions are dated. It presumes a legacy xoxb- bot-user token; modern granular scopes fail with not_allowed_token_type / missing_scope, which reads to a team as a package bug rather than a configuration mismatch.
  • Observability is thin. Failures surface little beyond an HTTP status in laravel.log; there is no first-class retry, backoff, or 429 handling we can verify against current Slack behavior.

Key questions for the decision.

  1. Does any committed roadmap item require inbound interactivity — buttons, modals, slash commands? If yes, this package is disqualified, full stop; that needs an owned HTTP endpoint, not this client.
  2. What PHP/Laravel version is the host app pinned to, and is that pin durable for the next 18 months?
  3. Is there an existing Slack app grandfathered into RTM, or would we be building RTM greenfield (impossible)?
  4. Who is the named owner for forks, PHP 8 deprecations, and Slack response-shape changes — and is that person's time actually allocated?
  5. What is the blast radius of a silently dropped message? Deploy notification: acceptable. Page-out for a Sev-1: not acceptable.
  6. What's the realistic message volume and latency expectation? This determines whether a queue is mandatory or merely good hygiene.

Integration Approach

Stack fit. Clean fit only when the host application is itself on PHP 7.x / Laravel ≤8, so the 2018 dependency graph doesn't collide with the main app. On anything newer, treat it as a foreign body: isolate it behind a service boundary rather than pulling its pins into the application's dependency graph. The package's own sendMessage / getChannelId / getUserId surface is small enough that the isolation boundary is cheap to draw.

Migration path — strangler fig, not rip-and-replace. The decision for an existing install is not "adopt or not," it's "isolate and replace, in what order."

  1. Inventory every Slack:: call site across jobs, listeners, controllers, and commands. This is the scope of the eventual exit.
  2. Introduce a SlackMessenger interface with a single implementation that internally calls the facade. No behavior change; this step exists purely to make call sites dependency-agnostic. One afternoon now, one sprint saved later.
  3. Move the implementation behind a boundary the application owns — its own class, ideally its own package or service — so the 2018 pins stop leaking into the app's composer.lock.
  4. Swap the implementation for laravel/slack-notification-channel or an owned Guzzle client. Only step 3's class changes.

Compatibility work that must happen up front, not later.

  • Cache getChannelId / getUserId with Cache::rememberForever — IDs are stable, and the API takes IDs, not #channel names.
  • Read config('slack.token') at call time rather than capturing it in a constructor, so token rotation doesn't require a code change.
  • Escape user-derived content: strip <!channel> / <!here> and escape </> unless a ping is explicitly intended.
  • Truncate against Slack's attachment ceilings (≈4,000 chars per attachment text, 20 fields, 100 attachments) and link out to full logs rather than pasting.

Sequencing. Outbound messaging first, inbound bot logic last — always. Outbound is where the value is, where the replacement path is cheapest, and where a botched migration is recoverable. RTM is the hardest piece with the smallest user-visible payoff; if it stalls a migration behind it, the migration doesn't ship. Concretely: interface and adapter → queue all sends with explicit 429/Retry-After handling → ID caching → migrate outbound to a supported channel → port or kill the RTM loop. Give the RTM step its own go/no-go against whether the bot is still worth its maintenance cost at all.

Operational Impact

Maintenance. This is a full-ownership asset, not a dependency. Any fix — a PHP 8 deprecation, a Slack response-shape change, a 401 after token rotation — is authored internally. There is no vendor, no maintainer, and negligible community surface. Budget an explicit recurring maintenance line item rather than treating it as free; the honest framing is "we are the maintainer now."

Support. None. No escalation path, no security advisories, no upgrade guides. When something breaks at 2am, the answer is your own engineers reading a 2018 codebase. That's acceptable for internal, non-critical alerting; it's disqualifying for anything compliance-, audit-, or availability-relevant.

Scaling. Adequate for internal, low-volume, low-stakes messaging — deploy notices, incident pings, admin notifications. It is not a throughput or availability commitment:

  • Every send is an HTTP round trip; never block a request or a synchronous job on it. Route through a queued job with retries and backoff. Treat 429s as retryable with the server-specified delay, not a fixed schedule.
  • RTM is a single long-running connection. Run it under Supervisor or systemd — never php artisan serve — with a restart policy and a liveness probe.
  • Explicitly out of scope: customer-facing integrations and high-throughput bot traffic.

Failure modes to design against, not discover.

  • Silent WebSocket drop. Half-open TCP, no exception, bot goes quiet. Needs an application-level heartbeat (periodic log line or ping task) plus a Supervisor restart policy.
  • Post-rotation 401s. Intermittent until the new token is injected and config cleared; mitigated by reading config at call time.
  • Auth/scope errors misread as package bugs (missing_scope, not_allowed_token_type).
  • Private-channel silence. The bot must be invited; there's no clear error.
  • Message loss with no retry when sends aren't queued.
  • Attachment truncation on long log dumps — silently rejected or clipped.
  • Accidental @channel pings from unescaped user content — the one failure mode with a social cost, not just an operational one.

Ramp-up. Shallow for the 80% case: Slack::sendMessage($channelId, 'text') with caching and queuing is hours of work for any Laravel-fluent engineer. Steep for the remainder — RTM debugging, dependency archaeology against PHP 8, and authoring fixes in an unowned codebase. Testing has one non-negotiable rule: bind a fake to your SlackMessenger interface (or mock the facade) and never hit Slack's API from CI; assert against the arguments you'd send, not against Slack's response shape. The single highest-leverage habit is keeping Slack:: calls out of jobs, listeners, and controllers entirely — the interface is what makes the eventual exit one afternoon instead of one sprint.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager