npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@aarekaz/switchboard-slack

v0.3.5

Published

Slack adapter for Switchboard SDK

Downloads

138

Readme

@aarekaz/switchboard-slack

Slack adapter for Switchboard SDK.

Build chat bots once, deploy everywhere. This adapter enables your Switchboard bot to work seamlessly with Slack.

Installation

pnpm add @aarekaz/switchboard-slack

Quick Start

import { createBot } from '@aarekaz/switchboard-core';
import '@aarekaz/switchboard-slack';

const bot = createBot({
  platform: 'slack',
  credentials: {
    botToken: process.env.SLACK_BOT_TOKEN,
    appToken: process.env.SLACK_APP_TOKEN,  // For Socket Mode
  },
});

bot.onMessage(async (message) => {
  if (message.text.includes('hello')) {
    await bot.reply(message, 'Hello from Slack! 👋');
  }
});

await bot.start();

Setup Guide

1. Create a Slack App

  1. Go to https://api.slack.com/apps
  2. Click "Create New App" → "From scratch"
  3. Name your app and select your workspace

2. Configure Bot Token Scopes

In your app settings, go to OAuth & Permissions and add these scopes:

Required scopes:

  • chat:write - Send messages
  • channels:read - View channels
  • groups:read - View private channels
  • im:read - View direct messages
  • mpim:read - View group direct messages
  • users:read - View users

Optional scopes (for additional features):

  • chat:write.customize - Customize message appearance
  • reactions:write - Add reactions
  • files:write - Upload files
  • channels:history - Read channel messages
  • groups:history - Read private channel messages
  • im:history - Read DM messages

3. Install App to Workspace

  1. In OAuth & Permissions, click "Install to Workspace"
  2. Copy the Bot User OAuth Token (starts with xoxb-)
  3. Save it as SLACK_BOT_TOKEN

4. Enable Socket Mode (Recommended for Development)

  1. Go to Socket Mode in your app settings
  2. Enable Socket Mode
  3. Generate an app-level token with connections:write scope
  4. Copy the token (starts with xapp-)
  5. Save it as SLACK_APP_TOKEN

Note: Socket Mode is great for development but for production, consider using the Events API instead.

5. Subscribe to Events

  1. Go to Event Subscriptions
  2. Enable Events
  3. If using Socket Mode, events will be delivered through the socket
  4. If using Events API (production), provide your server URL
  5. Subscribe to these bot events:
    • message.channels
    • message.groups
    • message.im
    • message.mpim
    • reaction_added
    • reaction_removed

Authentication Modes

The Slack adapter supports two authentication modes:

Socket Mode (Development)

Best for development and testing. No public URL required.

const bot = createBot({
  platform: 'slack',
  credentials: {
    botToken: process.env.SLACK_BOT_TOKEN,    // xoxb-...
    appToken: process.env.SLACK_APP_TOKEN,    // xapp-...
  },
});

Events API (Production)

Best for production deployments.

const bot = createBot({
  platform: 'slack',
  credentials: {
    botToken: process.env.SLACK_BOT_TOKEN,
    signingSecret: process.env.SLACK_SIGNING_SECRET,
  },
});

The adapter automatically detects which mode to use based on the credentials provided.

Usage

Basic Message Operations

// Send a message
await bot.sendMessage('C1234567890', 'Hello, Slack!');

// Reply to a message
bot.onMessage(async (message) => {
  await bot.reply(message, 'Got your message!');
});

// Edit a message
const result = await bot.sendMessage('C1234567890', 'Original');
if (result.ok) {
  await bot.editMessage(result.value, 'Edited!');
}

// Delete a message
await bot.deleteMessage(message);

Reactions

bot.onMessage(async (message) => {
  // Add reaction
  await bot.addReaction(message, '👍');

  // Remove reaction
  await bot.removeReaction(message, '👍');
});

Threads

bot.onMessage(async (message) => {
  // Create a thread
  await bot.createThread(message, 'Starting a thread!');

  // Reply in existing thread
  await bot.sendMessage(message.channelId, 'Thread reply', {
    threadId: message.threadId,
  });
});

Platform-Specific Features

Use Slack's Block Kit for rich messages:

await bot.sendMessage('C1234567890', 'Hello!', {
  slack: {
    blocks: [
      {
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: '*Hello* from Slack Block Kit!',
        },
      },
      {
        type: 'actions',
        elements: [
          {
            type: 'button',
            text: {
              type: 'plain_text',
              text: 'Click Me',
            },
            action_id: 'button_click',
          },
        ],
      },
    ],
  },
});

Important: MessageRef Pattern

Slack requires channel context for message operations (edit, delete, reactions). The adapter uses a cache to store this context, but for guaranteed reliability, always pass the full message object:

// ✅ RECOMMENDED: Always works
bot.onMessage(async (message) => {
  await bot.editMessage(message, 'Updated');
  await bot.addReaction(message, '👍');
});

// ⚠️ Works if message is in cache (last 1000 messages, 1 hour)
await bot.editMessage(messageId, 'Updated');

How the Cache Works

  • Capacity: Stores last 1000 messages
  • TTL: Messages expire after 1 hour
  • Hit Rate: ~95% for typical interactive bots
  • When it fails:
    • Message older than 1 hour
    • Bot restarted
    • Message sent by another instance

Error Messages Guide You

If cache lookup fails, you'll get a helpful error:

Cannot edit message: channel context not found.

This happens when:
1. The message is older than 1 hour (cache expired)
2. The bot restarted since the message was sent
3. The message was sent by another bot instance

Solution: Pass the full message object instead:
  bot.editMessage(message, "text")  // ✅ Works reliably
  bot.editMessage(message.id, "text")  // ❌ May fail on Slack

Known Limitations

1. Message Context Requirement

Unlike Discord, Slack requires both channel ID and message timestamp for operations. This is handled transparently via caching, but long-lived message references should use the full message object.

2. Timestamps as IDs

Slack uses timestamps as message IDs (e.g., "1503435956.000247"). These are unique but may look unusual compared to typical IDs.

3. File Uploads

File uploads are not yet implemented in this version. Coming in Phase 5.

4. Message Formatting

Slack uses mrkdwn (their own Markdown variant), not standard Markdown. The adapter does minimal conversion. For rich formatting, use Block Kit.

Configuration

Cache Settings

import { SlackAdapter } from '@aarekaz/switchboard-slack';

const adapter = new SlackAdapter({
  cacheSize: 5000,              // Store more messages
  cacheTTL: 1000 * 60 * 60 * 2, // 2 hour TTL
});

const bot = createBot({
  platform: 'slack',
  adapter,
  credentials: { ... },
});

Events API Port

const adapter = new SlackAdapter({
  socketMode: false,
  port: 3000,  // Custom port for Events API
});

Monitoring

The adapter logs cache hit rates every 1000 operations:

📊 Slack cache hit rate: 96.8% (968/1000)

High hit rates (>90%) indicate good performance. Lower rates suggest:

  • Long-lived message references (consider using message objects)
  • Frequent bot restarts (consider persistent cache in production)
  • Multi-instance deployment (consider Redis cache)

Examples

See the examples directory for complete examples:

  • hello-world/slack.ts - Basic Slack bot
  • hello-world/one-line-swap.ts - Demonstrates platform switching

API Reference

See @aarekaz/switchboard-core for the full API reference. The Slack adapter implements the complete PlatformAdapter interface.

License

MIT