Slack
Send messages via Slack Web API
The Slack transport is included in @betternotify/slack. It calls the Slack Web API via fetch — no external HTTP dependencies required (Node 22+ / Bun built-in).
It is a thin delivery adapter. Better-Notify handles rendering and validation upstream; slackTransport() posts the rendered message to chat.postMessage.
Install
npm install @betternotify/slackUsage
import { slackTransport } from '@betternotify/slack';
const transport = slackTransport({
token: process.env.SLACK_BOT_TOKEN!,
defaultChannel: '#notifications',
});Pass it to createClient via transportsByChannel:
import { createClient } from '@betternotify/core';
import { slackChannel, slackTransport } from '@betternotify/slack';
const notify = createClient({
catalog,
transportsByChannel: {
slack: slackTransport({ token: process.env.SLACK_BOT_TOKEN! }),
},
});Standalone usage
The transport can be used directly without the full pipeline:
import { slackTransport } from '@betternotify/slack';
const transport = slackTransport({ token: process.env.SLACK_BOT_TOKEN! });
const result = await transport.send(
{ text: 'Deploy complete!', to: '#releases' },
{ route: 'manual', messageId: 'msg-1', attempt: 1 },
);
console.log(result.data.ts); // Slack message timestampOptions
Prop
Type
Block Kit
Use the blocks slot to send rich messages with Block Kit:
const catalog = rpc.catalog({
deploy: rpc
.slack()
.input(z.object({ service: z.string(), version: z.string() }))
.text(({ input }) => `${input.service} deployed ${input.version}`)
.blocks(({ input }) => [
{ type: 'header', text: { type: 'plain_text', text: `Deploy: ${input.service}` } },
{
type: 'section',
text: { type: 'mrkdwn', text: `Version *${input.version}* is now live.` },
},
]),
});The text field is always required — Slack uses it as the notification preview and fallback for clients that don't render blocks.
Threading
Reply in a thread by passing threadTs:
await notify.deploy.send({
to: '#releases',
threadTs: '1234567890.123456',
input: { service: 'api', version: 'v2.1.0' },
});Verifying the bot token
Call verify() at startup to confirm the token is valid:
const transport = slackTransport({ token: process.env.SLACK_BOT_TOKEN! });
const { ok, details } = await transport.verify!();
if (!ok) {
throw new Error('Invalid Slack bot token');
}
console.log('Bot:', details); // { url, team, user, ... }Error handling
Slack API errors throw NotifyRpcError with a mapped error code:
| Slack error | Code | Meaning |
|---|---|---|
invalid_auth, token_revoked, not_authed, account_inactive, missing_scope | CONFIG | Token/auth issue |
channel_not_found, no_text, invalid_blocks, invalid_arguments, msg_too_long | VALIDATION | Bad request data |
ratelimited, others | PROVIDER | Server/rate limit issue |
import { NotifyRpcError } from '@betternotify/core';
try {
await notify.alert.send({ to: '#ops', input });
} catch (err) {
if (err instanceof NotifyRpcError && err.code === 'CONFIG') {
console.error('Check your SLACK_BOT_TOKEN');
}
}