通过托管 OAuth 代理连接 Notion 工作区,支持搜索、数据库查询与读取,写入需用户确认。
集成
Slack
通过托管 OAuth 代理调用 Slack API,实现发消息、管频道、列用户和定时投递。
它能做什么
通过托管 OAuth 代理访问 Slack,自动注入认证令牌。提供 CLI 命令和 HTTP 接口,支持发送消息、回复帖子线程、定时消息、列出与管理频道、邀请用户、查看会话历史等操作。所有写入操作执行前需经用户明确同意。可同时接入多个 Slack 工作区,并通过 connection ID 区分请求目标。
什么时候用它
- 向频道发送消息或在帖子线程中回复
- 列出频道、成员并查看历史消息
- 设置定时消息,稍后自动投递
- 按需创建、重命名或归档频道
技能文档
Slack
Access the Slack API with managed OAuth authentication. Send messages, manage channels, list users, and automate Slack workflows.
Quick Start
CLI:
maton slack message send --channel C0123456789 --text 'Hello from Maton!'
maton api '/slack/api/chat.postMessage'
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'channel': 'C0123456789', 'text': 'Hello from Maton!'}).encode()
req = urllib.request.Request('https://api.maton.ai/slack/api/chat.postMessage', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://api.maton.ai/slack/{method}
Maton proxies requests to slack.com and automatically injects your OAuth token.
Installation
NPM:
npm install -g @maton/cli
Homebrew:
brew install maton-ai/cli/maton
Authentication
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
- Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Connection Management
Manage your Slack OAuth connections at https://api.maton.ai.
List Connections
CLI:
maton connection list slack --status ACTIVE
maton api -X GET /connections -f app=slack -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=slack&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
CLI:
maton connection create slack
maton api /connections -f app=slack
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'slack'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "slack",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Slack connections, specify which one to use:
CLI:
maton slack message send --channel C0123456789 --text 'Hello!' --connection {connection_id}
maton api /slack/api/chat.postMessage --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'channel': 'C0123456789', 'text': 'Hello!'}).encode()
req = urllib.request.Request('https://api.maton.ai/slack/api/chat.postMessage', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to messages, channels, users, files, and reactions within the connected Slack account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
Authentication
Auth Test
GET /slack/api/auth.test
Returns current user and team info.
Example:
maton slack whoami
Messages
Post Message
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"text": "Hello, world!"
}
Example:
maton slack message send --channel C0123456789 --text 'Hello, world!'
With blocks:
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"blocks": [
{"type": "section", "text": {"type": "mrkdwn", "text": "*Bold* and _italic_"}}
]
}
Example:
maton slack message send --channel C0123456789 --blocks '[{"type":"section","text":{"type":"mrkdwn","text":"*Bold* and _italic_"}}]'
Post /me-style Message
maton slack message me --channel C0123456789 --text 'is deploying'
Post Thread Reply
POST /slack/api/chat.postMessage
Content-Type: application/json
{
"channel": "C0123456789",
"thread_ts": "1234567890.123456",
"text": "This is a reply in a thread"
}
Example:
maton slack message reply --channel C0123456789 --thread-ts 1234567890.123456 --text 'This is a reply in a thread'
Update Message
POST /slack/api/chat.update
Content-Type: application/json
{
"channel": "C0123456789",
"ts": "1234567890.123456",
"text": "Updated message"
}
Example:
maton slack message update --channel C0123456789 --ts 1234567890.123456 --text 'Updated message'
Delete Message
POST /slack/api/chat.delete
Content-Type: application/json
{
"channel": "C0123456789",
"ts": "1234567890.123456"
}
Example:
maton slack message delete --channel C0123456789 --ts 1234567890.123456
Schedule Message
POST /slack/api/chat.scheduleMessage
Content-Type: application/json
{
"channel": "C0123456789",
"text": "Scheduled message",
"post_at": 1734567890
}
Example:
maton slack schedule create --channel C0123456789 --text 'Scheduled message' --post-at 1734567890
List Scheduled Messages
GET /slack/api/chat.scheduledMessages.list
Example:
maton slack schedule list
Delete Scheduled Message
POST /slack/api/chat.deleteScheduledMessage
Content-Type: application/json
{
"channel": "C0123456789",
"scheduled_message_id": "Q1234567890"
}
Example:
maton slack schedule delete --channel C0123456789 --id Q1234567890
Get Permalink
GET /slack/api/chat.getPermalink?channel=C0123456789&message_ts=1234567890.123456
Example:
maton slack message permalink --channel C0123456789 --message-ts 1234567890.123456
Conversations (Channels)
List Channels
GET /slack/api/conversations.list?types=public_channel,private_channel&limit=100
Types: public_channel, private_channel, im, mpim
Example:
maton slack channel list --types public_channel,private_channel --limit 100
Get Channel Info
GET /slack/api/conversations.info?channel=C0123456789
Example:
maton slack channel view C0123456789
Get Channel History
GET /slack/api/conversations.history?channel=C0123456789&limit=100
Example:
maton slack message list --channel C0123456789 --limit 100
With time range:
GET /slack/api/conversations.history?channel=C0123456789&oldest=1234567890&latest=1234567899
Example:
maton slack message list --channel C0123456789 --oldest 1234567890 --latest 1234567899
Get Thread Replies
GET /slack/api/conversations.replies?channel=C0123456789&ts=1234567890.123456
Example:
maton slack message replies --channel C0123456789 --ts 1234567890.123456
Get Channel Members
GET /slack/api/conversations.members?channel=C0123456789&limit=100
Example:
maton slack channel members C0123456789 --limit 100
Create Channel
POST /slack/api/conversations.create
Content-Type: application/json
{
"name": "new-channel-name",
"is_private": false
}
Example:
maton slack channel create --name new-channel-name
Join Channel
POST /slack/api/conversations.join
Content-Type: application/json
{
"channel": "C0123456789"
}
Example:
maton slack channel join C0123456789
Leave Channel
POST /slack/api/conversations.leave
Content-Type: application/json
{
"channel": "C0123456789"
}
Example:
maton slack channel leave C0123456789
Archive Channel
POST /slack/api/conversations.archive
Content-Type: application/json
{
"channel": "C0123456789"
}
Example:
maton slack channel archive C0123456789
Unarchive Channel
POST /slack/api/conversations.unarchive
Content-Type: application/json
{
"channel": "C0123456789"
}
Example:
maton slack channel unarchive C0123456789
Rename Channel
POST /slack/api/conversations.rename
Content-Type: application/json
{
"channel": "C0123456789",
"name": "new-name"
}
Example:
maton slack channel rename C0123456789 --name new-name
Set Channel Topic
POST /slack/api/conversations.setTopic
Content-Type: application/json
{
"channel": "C0123456789",
"topic": "Channel topic here"
}
Example:
maton slack channel set-topic C0123456789 --topic 'Channel topic here'
Set Channel Purpose
POST /slack/api/conversations.setPurpose
Content-Type: application/json
{
"channel": "C0123456789",
"purpose": "Channel purpose here"
}
Example:
maton slack channel set-purpose C0123456789 --purpose 'Channel purpose here'
Invite to Channel
POST /slack/api/conversations.invite
Content-Type: application/json
{
"channel": "C0123456789",
"users": "U0123456789,U9876543210"
}
Example:
maton slack channel invite C0123456789 --users U0123456789,U9876543210
Kick from Channel
POST /slack/api/conversations.kick
Content-Type: application/json
{
"channel": "C0123456789",
"user": "U0123456789"
}
Example:
maton slack channel kick C0123456789 --user U0123456789
Mark Channel Read
POST /slack/api/conversations.mark
Content-Type: application/json
{
"channel": "C0123456789",
"ts": "1234567890.123456"
}
Example:
maton slack channel mark C0123456789 --ts 1234567890.123456
Direct Messages
Open DM Conversation
POST /slack/api/conversations.open
Content-Type: application/json
{
"users": "U0123456789"
}
Example:
maton slack conversation open --users U0123456789
For group DM:
POST /slack/api/conversations.open
Content-Type: application/json
{
"users": "U0123456789,U9876543210"
}
Example:
maton slack conversation open --users U0123456789,U9876543210
List DM Channels
GET /slack/api/conversations.list?types=im
Example:
maton slack channel list --types im
List Group DM Channels
GET /slack/api/conversations.list?types=mpim
Example:
maton slack channel list --types mpim
My Conversations
GET /slack/api/users.conversations?limit=100
Example:
maton slack conversation list --limit 100
Users
List Users
GET /slack/api/users.list?limit=100
Example:
maton slack user list --limit 100
Get User Info
GET /slack/api/users.info?user=U0123456789
Example:
maton slack user view U0123456789
Get User Presence
GET /slack/api/users.getPresence?user=U0123456789
Example:
maton slack user presence U0123456789
Lookup User by Email
GET /slack/api/[email protected]
Example:
maton slack user lookup --email [email protected]
Reactions
Add Reaction
POST /slack/api/reactions.add
Content-Type: application/json
{
"channel": "C0123456789",
"name": "thumbsup",
"timestamp": "1234567890.123456"
}
Example:
maton slack reaction add --channel C0123456789 --ts 1234567890.123456 --emoji thumbsup
Remove Reaction
POST /slack/api/reactions.remove
Content-Type: application/json
{
"channel": "C0123456789",
"name": "thumbsup",
"timestamp": "1234567890.123456"
}
Example:
maton slack reaction remove --channel C0123456789 --ts 1234567890.123456 --emoji thumbsup
Get Reactions on Message
GET /slack/api/reactions.get?channel=C0123456789×tamp=1234567890.123456
Example:
maton slack reaction get --channel C0123456789 --ts 1234567890.123456
List My Reactions
GET /slack/api/reactions.list?limit=100
Example:
maton slack reaction list --limit 100
Stars
List Stars
GET /slack/api/stars.list?limit=100
Example:
maton slack star list --limit 100
Add Star
POST /slack/api/stars.add
Content-Type: application/json
{
"channel": "C0123456789",
"timestamp": "1234567890.123456"
}
Example:
maton slack star add --channel C0123456789 --ts 1234567890.123456
Remove Star
POST /slack/api/stars.remove
Content-Type: application/json
{
"channel": "C0123456789",
"timestamp": "1234567890.123456"
}
Example:
maton slack star remove --channel C0123456789 --ts 1234567890.123456
Pins
List Pins
GET /slack/api/pins.list?channel=C0123456789
Example:
maton slack pin list C0123456789
Add Pin
POST /slack/api/pins.add
Content-Type: application/json
{
"channel": "C0123456789",
"timestamp": "1234567890.123456"
}
Example:
maton slack pin add --channel C0123456789 --ts 1234567890.123456
Remove Pin
POST /slack/api/pins.remove
Content-Type: application/json
{
"channel": "C0123456789",
"timestamp": "1234567890.123456"
}
Example:
maton slack pin remove --channel C0123456789 --ts 1234567890.123456
Bookmarks
List Bookmarks
GET /slack/api/bookmarks.list?channel_id=C0123456789
Example:
maton slack bookmark list --channel C0123456789
Add Bookmark
POST /slack/api/bookmarks.add
Content-Type: application/json
{
"channel_id": "C0123456789",
"title": "Team Handbook",
"type": "link",
"link": "https://example.com/handbook"
}
Example:
maton slack bookmark add --channel C0123456789 --title 'Team Handbook' --type link --link https://example.com/handbook
Edit Bookmark
POST /slack/api/bookmarks.edit
Content-Type: application/json
{
"bookmark_id": "Bk0123456789",
"channel_id": "C0123456789",
"title": "Updated Title",
"link": "https://example.com/new"
}
Example:
maton slack bookmark edit --channel C0123456789 --bookmark-id Bk0123456789 --title 'Updated Title' --link https://example.com/new
Remove Bookmark
POST /slack/api/bookmarks.remove
Content-Type: application/json
{
"bookmark_id": "Bk0123456789",
"channel_id": "C0123456789"
}
Example:
maton slack bookmark remove --channel C0123456789 --bookmark-id Bk0123456789
Bots
Get Bot Info
GET /slack/api/bots.info?bot=B0123456789
Example:
maton slack bot view B0123456789
Note: this expects the B-prefixed bot ID (from bot_id on a message), not the bot's U-prefixed user ID. Passing a U… ID returns bot_not_found.
Files
List Files
GET /slack/api/files.list?count=100
Filter by channel, user, or file types:
GET /slack/api/files.list?channel=C0123456789&user=U0123456789&types=images,pdfs
Example:
maton slack file list --count 100
maton slack file list --channel C0123456789 --user U0123456789 --types images,pdfs
Upload File
POST /slack/api/files.upload
Content-Type: multipart/form-data
channels=C0123456789
content=file content here
filename=example.txt
title=Example File
Upload File v2 (Get Upload URL)
GET /slack/api/files.getUploadURLExternal?filename=example.txt&length=1024
Complete File Upload
POST /slack/api/files.completeUploadExternal
Content-Type: application/json
{
"files": [{"id": "F0123456789", "title": "My File"}],
"channel_id": "C0123456789"
}
Example:
maton slack file upload --file ./example.txt --channel C0123456789 --title 'My File'
Delete File
POST /slack/api/files.delete
Content-Type: application/json
{
"file": "F0123456789"
}
Example:
maton slack file delete F0123456789
Get File Info
GET /slack/api/files.info?file=F0123456789
Example:
maton slack file view F0123456789
Search
Search Messages
GET /slack/api/search.messages?query=keyword
Example:
maton slack search messages 'keyword'
Search Files
GET /slack/api/search.files?query=keyword
Note: search.files matches against filename and title, not file body content. Newly uploaded files may take a moment to appear in results due to indexing lag.
Code Examples
CLI
# Send a message to a channel
maton slack message send --channel C0123456789 --text 'Hello team'
# List channels
maton slack channel list --types public_channel,private_channel
# Look up a user by email
maton slack user lookup --email [email protected]
# Add a reaction to a message
maton slack reaction add --channel C012 --ts 1700000000.000100 --emoji thumbsup
JavaScript
const response = await fetch('https://api.maton.ai/slack/api/chat.postMessage', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
},
body: JSON.stringify({ channel: 'C0123456', text: 'Hello!' })
});
const result = await response.json();
console.log(result);
Python
import os
import requests
response = requests.post(
'https://api.maton.ai/slack/api/chat.postMessage',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
json={'channel': 'C0123456', 'text': 'Hello!'}
)
print(response.json())
Notes
- Channel IDs:
C(public),G(private/group),D(DM) - User IDs start with
U, Bot IDs start withB, Team IDs start withT - Message timestamps (
ts) are unique identifiers - Use
mrkdwntype for Slack-flavored markdown formatting - Thread replies use
thread_tsto reference the parent message - Cursor-based pagination: use
cursorfromresponse_metadata.next_cursor
Shell Notes
- IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets (fields[],sort[],records[]) to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing Slack connection |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from Slack API |
Missing Scope Errors: If you encounter missing_scope errors, contact Maton Support to request additional scopes for your connection.
Troubleshooting: API Key Issues
CLI:
- Check your auth state:
maton whoami
- Verify the API key is valid by listing connections:
maton connection list
Manual:
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
slack. For example:
- Correct:
https://api.maton.ai/slack/api/chat.postMessage - Incorrect:
https://api.maton.ai/api/chat.postMessage
Resources
常见问题
- Slack 凭证如何管理?
- 请求通过代理转发到 slack.com,OAuth 令牌由系统自动注入,用户只需通过 Maton CLI 登录流程或设置 MATON_API_KEY 环境变量完成一次认证。
- 能否接入多个 Slack 工作区?
- 可以,支持创建多个连接,每次请求通过 connection ID 指定目标工作区(HTTP 用 Maton-Connection 头,CLI 用 --connection 参数)。
- 写入操作是否需要用户确认?
- 是的,文档明确说明所有创建、更新、删除操作执行前都需获得用户明确同意。
相关技能
通过托管 OAuth 接入 GitHub REST API,覆盖仓库、Issue、PR、Commit、分支与用户等接口。
通过 OAuth 认证网关管理 Stripe 客户、订阅、发票、产品、价格和支付。
通过托管 OAuth 连接 Google Tasks,统一 API 完成任务列表与任务的读写管理。
通过托管 OAuth 调用 Google Docs API,实现文档创建、读写与样式管理。
通过托管 OAuth 调用 LinkedIn REST API,覆盖发文、个人资料、广告账户与广告库。