Skip to content

Documentation Sync

This page is auto-generated from plugins/adapters/slack/README.md. Please edit the in-package README and then run pnpm sync:adapter-docs.

@zhin.js/adapter-slack

Zhin.js Slack adapter (Plugin Runtime). Prefers Socket Mode; can also send and receive messages via the Runtime Host HTTP Events API.

Features

  • Socket Mode (default): persistent WebSocket connection, no public URL needed
  • HTTP Events API: httpHostToken POST (signature verification), not legacy host-router/Koa
  • Inbound via messageGatewayToken; outbound send({ target, payload }) -> chat.postMessage / Block Kit
  • Convention-based defineAdapter / definePlugin (no usePlugin needed)
  • Block Kit buttons, slash commands, message editing, emoji reactions, etc. (see agent/tools/)

Installation

bash
pnpm add @zhin.js/adapter-slack

Plugin Runtime

  • @zhin.js/adapter — convention-based adapters/slack.ts (defineAdapter)
  • @zhin.js/coremessageGatewayToken inbound/outbound
  • @zhin.js/host-http — only needed for HTTP mode to register Events route via httpHostToken
  • @zhin.js/plugin-runtimeplugin.ts (definePlugin)
  • Configuration goes to plugins.<instanceKey> via the plugin's schema.json

Inbound: gateway.receive({ adapter, target: channelId, content: text, sender, metadata }) Outbound: send({ target, payload }) -> Web API (target can be channel or channel:thread_ts)

Platform Permissions (platform permit)

  • plugin.ts has registered a checker. Runtime Tool permissions are uniformly enforced via Core's canAccessTool(). When Slack inbound does not have a reliable sender role, restricted tools are denied by fail-closed policy and will not silently pass through.

Mode Comparison

ModesocketModeUse CaseAdditional Fields
Socket Mode (default)trueLocal / intranet, no public URL neededappToken (xapp-...)
HTTP EventsfalseProduction with public HTTPSsigningSecret + Runtime Host

Minimal Configuration (Socket Mode)

yaml
# zhin.config.yml (Plugin Runtime)
plugins:
  slack:
    socketMode: true          # default true, can be omitted
    endpoints:
      - name: my-slack-bot
        token: ${SLACK_BOT_TOKEN}
        appToken: ${SLACK_APP_TOKEN}

Multiple workspaces: a single plugin instance can attach multiple endpoints (each item in the endpoints array overrides top-level fields; name is required):

yaml
plugins:
  slack:
    endpoints:
      - name: team-a
        token: ${SLACK_BOT_TOKEN_A}
        appToken: ${SLACK_APP_TOKEN_A}
      - name: team-b
        token: ${SLACK_BOT_TOKEN_B}
        appToken: ${SLACK_APP_TOKEN_B}

HTTP Events Configuration

yaml
plugins:
  slack:
    socketMode: false
    webhookPath: /slack/events   # optional, default /slack/events
    endpoints:
      - name: my-slack-bot
        token: ${SLACK_BOT_TOKEN}
        signingSecret: ${SLACK_SIGNING_SECRET}

The root plugin zhin.plugins (or project graph) must reference @zhin.js/adapter-slack (instanceKey: slack). In HTTP mode, the Runtime Host (http) must already be listening; the Slack App's Event Subscriptions / Interactivity / Slash Commands Request URL should point to https://your-domain/slack/events.

Environment Variables

VariableDescription
SLACK_BOT_TOKEN / SLACK_TOKENBot User OAuth Token (xoxb-...)
SLACK_APP_TOKENApp-Level Token (Socket Mode, xapp-...)
SLACK_SIGNING_SECRETSigning Secret (HTTP mode)
SLACK_BOT_NAMEOptional endpoint name

Message Format

Outbound (Markdown -> mrkdwn)

Common Markdown (e.g., **bold**) is converted to Slack mrkdwn and sent via Block Kit section.

Inbound (mrkdwn -> Markdown)

Slack mrkdwnCommon Markdown
*bold***bold**
_italic_*italic*
~strike~~~strike~~
<url|text>[text](url)

AI Tools

CategoryPath
Permit vocabularyagent/PERMITS.md
Platform toolsagent/tools/ (invite, topic, reactions, pin, edit, etc.)
Skill documentationagent/skills/slack.md

Limitations

  • Inbound mrkdwn -> Markdown conversion is heuristic
  • Modals / Select menus — not yet supported
  • OAuth installation flow — not yet supported
  • Old usePlugin / extends Adapter / host-router production entry points have been removed

License

MIT