Integrating Slack API with Website (Notifications, Bots)
Slack integration allows sending website event notifications to team channels, creating interactive bots for site management from Slack, and receiving commands from staff without leaving the messenger.
Incoming Webhooks (Simple Notifications)
The quickest method is using an Incoming Webhook URL, created in Slack App settings:
class SlackNotifier
{
public function send(string $channel, array $message): void
{
Http::post(config('services.slack.webhook_url'), [
'channel' => $channel,
'text' => $message['text'] ?? '',
'attachments' => $message['attachments'] ?? [],
'blocks' => $message['blocks'] ?? [],
]);
}
public function notifyNewOrder(Order $order): void
{
$this->send('#orders', [
'blocks' => [
[
'type' => 'section',
'text' => ['type' => 'mrkdwn', 'text' => "*New Order #{$order->number}*"],
],
[
'type' => 'section',
'fields' => [
['type' => 'mrkdwn', 'text' => "*Customer:*\n{$order->customer_name}"],
['type' => 'mrkdwn', 'text' => "*Amount:*\n{$order->formatted_total}"],
],
],
[
'type' => 'actions',
'elements' => [[
'type' => 'button',
'text' => ['type' => 'plain_text', 'text' => 'View Order'],
'url' => route('admin.orders.show', $order),
]],
],
],
]);
}
}
Slash Commands
// Handler for /check-order {order_id}
Route::post('/slack/commands/check-order', function (Request $request) {
// Slack signature verification
$signature = $request->header('X-Slack-Signature');
$timestamp = $request->header('X-Slack-Request-Timestamp');
$sigBase = "v0:{$timestamp}:" . $request->getContent();
$expected = 'v0=' . hash_hmac('sha256', $sigBase, config('services.slack.signing_secret'));
if (!hash_equals($expected, $signature)) abort(401);
$orderId = $request->input('text');
$order = Order::find($orderId);
if (!$order) {
return response()->json(['text' => "Order #{$orderId} not found"]);
}
return response()->json([
'response_type' => 'in_channel',
'text' => "Order #{$orderId}: {$order->status}, {$order->formatted_total}",
]);
});
Events API (Slack → Website)
Bots receive events (new message, reaction, channel join) via Events API:
Route::post('/slack/events', function (Request $request) {
// Challenge verification during initial setup
if ($request->has('challenge')) {
return response()->json(['challenge' => $request->input('challenge')]);
}
$event = $request->input('event');
if ($event['type'] === 'message' && str_contains($event['text'], 'deploy')) {
TriggerDeploy::dispatch($event['user']);
}
return response('ok');
});
Timeline
Notifications via Incoming Webhooks: 1 day. Slash Commands + Events API: 3–4 days.







