Loading...
Loading...
Emulated Slack API for local development and testing. Use when the user needs to interact with Slack API endpoints locally, test Slack integrations, emulate channels/messages/users, set up Slack OAuth flows, test incoming webhooks, or work with the Slack Web API without hitting the real Slack API. Triggers include "Slack API", "emulate Slack", "mock Slack", "test Slack OAuth", "Slack bot", "incoming webhook", "local Slack", or any task requiring a local Slack API.
npx skill4agent add vercel-labs/emulate slackevent_callback# Slack only
npx emulate --service slack
# Default port (when run alone)
# http://localhost:4000import { createEmulator } from 'emulate'
const slack = await createEmulator({ service: 'slack', port: 4003 })
// slack.url === 'http://localhost:4003'Authorization: Bearer <token>curl -X POST http://localhost:4003/api/auth.test \
-H "Authorization: Bearer test_token_admin"SLACK_EMULATOR_URL=http://localhost:4003import { WebClient } from '@slack/web-api'
const client = new WebClient(token, {
slackApiUrl: `${process.env.SLACK_EMULATOR_URL}/api/`,
})| Real Slack URL | Emulator URL |
|---|---|
| |
| |
{
id: 'slack',
name: 'Slack',
type: 'oauth',
authorization: {
url: `${process.env.SLACK_EMULATOR_URL}/oauth/v2/authorize`,
params: { scope: 'chat:write,channels:read,users:read' },
},
token: {
url: `${process.env.SLACK_EMULATOR_URL}/api/oauth.v2.access`,
},
clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
}slack:
team:
name: My Workspace
domain: my-workspace
users:
- name: developer
real_name: Developer
email: dev@example.com
is_admin: true
- name: designer
real_name: Designer
email: designer@example.com
channels:
- name: general
topic: General discussion
- name: engineering
topic: Engineering discussions
is_private: true
bots:
- name: my-bot
oauth_apps:
- client_id: "12345.67890"
client_secret: example_client_secret
name: My Slack App
redirect_uris:
- http://localhost:3000/api/auth/callback/slack
incoming_webhooks:
- channel: general
label: CI Notifications
signing_secret: my_signing_secretclient_idclient_idclient_secretredirect_uri# Test authentication
curl -X POST http://localhost:4003/api/auth.test \
-H "Authorization: Bearer $TOKEN"# Post message
curl -X POST http://localhost:4003/api/chat.postMessage \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "text": "Hello from the emulator!"}'
# Post threaded reply
curl -X POST http://localhost:4003/api/chat.postMessage \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "text": "Thread reply", "thread_ts": "1234567890.123456"}'
# Update message
curl -X POST http://localhost:4003/api/chat.update \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "ts": "1234567890.123456", "text": "Updated message"}'
# Delete message
curl -X POST http://localhost:4003/api/chat.delete \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "ts": "1234567890.123456"}'
# /me message
curl -X POST http://localhost:4003/api/chat.meMessage \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "text": "is thinking..."}'# List channels (cursor pagination)
curl -X POST http://localhost:4003/api/conversations.list \
-H "Authorization: Bearer $TOKEN"
# Get channel info
curl -X POST http://localhost:4003/api/conversations.info \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001"}'
# Create channel
curl -X POST http://localhost:4003/api/conversations.create \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "new-channel", "is_private": false}'
# Channel history (top-level messages only)
curl -X POST http://localhost:4003/api/conversations.history \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001"}'
# Thread replies
curl -X POST http://localhost:4003/api/conversations.replies \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "ts": "1234567890.123456"}'
# Join / leave channel
curl -X POST http://localhost:4003/api/conversations.join \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001"}'
# List members
curl -X POST http://localhost:4003/api/conversations.members \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001"}'# List users (cursor pagination)
curl -X POST http://localhost:4003/api/users.list \
-H "Authorization: Bearer $TOKEN"
# Get user info
curl -X POST http://localhost:4003/api/users.info \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"user": "U000000001"}'
# Lookup by email
curl -X POST http://localhost:4003/api/users.lookupByEmail \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com"}'# Add reaction
curl -X POST http://localhost:4003/api/reactions.add \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "timestamp": "1234567890.123456", "name": "thumbsup"}'
# Remove reaction
curl -X POST http://localhost:4003/api/reactions.remove \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "timestamp": "1234567890.123456", "name": "thumbsup"}'
# Get reactions
curl -X POST http://localhost:4003/api/reactions.get \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "timestamp": "1234567890.123456"}'# Get workspace info
curl -X POST http://localhost:4003/api/team.info \
-H "Authorization: Bearer $TOKEN"# Get bot info
curl -X POST http://localhost:4003/api/bots.info \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"bot": "B000000001"}'# Post via incoming webhook
curl -X POST http://localhost:4003/services/T000000001/B000000001/X000000001 \
-H "Content-Type: application/json" \
-d '{"text": "Deployment complete!"}'
# Post to a specific channel
curl -X POST http://localhost:4003/services/T000000001/B000000001/X000000001 \
-H "Content-Type: application/json" \
-d '{"text": "Alert!", "channel": "C000000002"}'
# Post threaded webhook message
curl -X POST http://localhost:4003/services/T000000001/B000000001/X000000001 \
-H "Content-Type: application/json" \
-d '{"text": "Thread update", "thread_ts": "1234567890.123456"}'# Authorize (browser flow, shows user picker)
# GET /oauth/v2/authorize?client_id=...&redirect_uri=...&scope=...&state=...
# Token exchange
curl -X POST http://localhost:4003/api/oauth.v2.access \
-H "Content-Type: application/json" \
-d '{"client_id": "12345.67890", "client_secret": "example_client_secret", "code": "<code>"}'{
"ok": true,
"access_token": "xoxb-...",
"token_type": "bot",
"bot_user_id": "B000000001",
"team": { "id": "T000000001", "name": "Emulate" },
"authed_user": { "id": "U000000001" }
}event_callbackmessagechat.postMessagechat.updatechat.deletereaction_addedreaction_removedreactions.addreactions.removemessagesubtype: bot_messageTOKEN="test_token_admin"
BASE="http://localhost:4003"
# Post a message
curl -X POST $BASE/api/chat.postMessage \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "text": "Hello!"}'
# React to it (use the ts from the response)
curl -X POST $BASE/api/reactions.add \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel": "C000000001", "timestamp": "<ts>", "name": "wave"}'$SLACK_EMULATOR_URL/oauth/v2/authorize?client_id=...&redirect_uri=...&scope=chat:write,channels:read&state=...?code=...&state=...POST /api/oauth.v2.accessxoxb-# Use the default incoming webhook
curl -X POST http://localhost:4003/services/T000000001/B000000001/X000000001 \
-H "Content-Type: application/json" \
-d '{"text": "Build passed on main"}'