threadmeup/slack-sdk
A PHP SDK for interacting with the Slack API, offering a simple interface for sending messages, managing channels, and handling webhooks. Ideal for adding Slack notifications or bot integrations to Laravel and PHP applications.
This is a thin, single-purpose wrapper around Slack's Web API from the pre-Block-Kit era. Treat it as a small utility, not a framework.
Install and locate the entry point
composer require threadmeup/slack-sdk
Then read in this order: composer.json (PHP constraint and Guzzle version it pinned), README.md (the only usage examples you will get), and src/ (the entire public surface — it is small). The namespace is Threadmeup\Slack; the client is constructed with a Slack token and exposes Slack API methods on top of an HTTP client.
Provision a token
There is no OAuth install flow in this package. You supply a token yourself — a legacy API token or a bot token from a Slack app. Put it in config/services.php and never in code:
// config/services.php
'slack' => [
'token' => env('SLACK_TOKEN'),
],
First use case: a message from an Artisan command
The most common day-one use is "tell a channel something happened." From a controller or command:
use Threadmeup\Slack\Slack;
$slack = new Slack(config('services.slack.token'));
// Verify exact method names against src/ and the README —
// this SDK predates the current Slack docs.
$slack->getChannel('deployments')->send('Deploy finished: ' . $sha);
Get this working against a private test channel before wiring it into anything else. If the call returns without an exception but nothing appears in Slack, that is the single most important thing to debug first (see Gotchas).
Bind it once in a service provider. Don't new Slack(...) in a dozen places — resolve it from the container so tokens and the HTTP client stay in one spot.
// app/Providers/SlackServiceProvider.php
$this->app->singleton(\Threadmeup\Slack\Slack::class, function ($app) {
return new \Threadmeup\Slack\Slack($app['config']['services.slack.token']);
});
Put a gateway in front of it. The package is from 2014 and will not survive a Slack API change. Wrap it in a one-class adapter (App\Slack\Notifier) with methods like send(string $channel, string $text). When you eventually migrate to laravel/slack-notification-channel or slack-php/slack-php, you change one file, not forty call sites. This is the highest-value pattern for a package this old.
Always send off the request cycle. Message delivery is a network round trip to a third party; do it in a queued job:
dispatch(new NotifySlack($channel, $text));
Have the job take plain strings, not the SDK client, so it serialises cleanly.
Use it for notifications, not conversations. The realistic integrations are: deploy/CI announcements, error alerts from App\Exceptions\Handler, form-submission pings, and scheduled digests. Anything interactive (slash commands, buttons, modals) is out of scope — the API surface this wraps predates it.
For inbound/RTM work, run it as a long-lived command. If you use the real-time side, it belongs in an artisan slack:listen process under Supervisor, never in a web request.
Fake the gateway in tests. Bind a fake Notifier in the container and assert on recorded calls. Never let the test suite touch Slack; you'll get flaky failures and rate-limited CI.
php constraint and pinned Guzzle version are ancient. Expect to either run an old PHP image or add "platform" overrides / a replace entry. Check composer.json before you commit to it.{"ok": false, "error": "..."} for most failures. This family of SDKs frequently does not throw on those. Inspect every response, or wrap the client so ok === false becomes an exception in your code. This is the #1 source of "it silently doesn't work."chat.postMessage per channel. If you fan out to many channels, add a sleep or a queued job with backoff() — the SDK won't retry for you.mrkdwn (*bold*, <url|text>). Your **bold** and [text](url) will show as literal characters.curl against https://slack.com/api/... — that tells you instantly whether the problem is Slack, your token, or the SDK.missing_scope or not_in_channel, not an auth error. Never log the token, and rotate it if it ever lands in an exception trace.src/ takes an afternoon and is the best documentation you'll get.How can I help you explore Laravel packages today?