home / skills / atrislabs / atris / slack

slack skill

/atris/skills/slack

This skill helps you manage Slack conversations by reading messages, sending as yourself, and searching channels and DMs through AtrisOS.

npx playbooks add skill atrislabs/atris --skill slack

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
9.8 KB
---
name: slack
description: Slack integration via AtrisOS API. Read messages, send as yourself, search conversations, manage DMs. Use when user asks about Slack, messages, channels, or team communication.
version: 1.1.0
tags:
  - slack
  - backend
  - messaging
---

# Slack Agent

> Drop this in `~/.claude/skills/slack/SKILL.md` and Claude Code becomes your Slack assistant.

## Bootstrap (ALWAYS Run First)

Before any Slack operation, run this bootstrap to ensure everything is set up:

```bash
#!/bin/bash
set -e

# 1. Check if atris CLI is installed
if ! command -v atris &> /dev/null; then
  echo "Installing atris CLI..."
  npm install -g atris
fi

# 2. Check if logged in to AtrisOS
if [ ! -f ~/.atris/credentials.json ]; then
  echo "Not logged in to AtrisOS."
  echo ""
  echo "Option 1 (interactive): Run 'atris login' and follow prompts"
  echo "Option 2 (non-interactive): Get token from https://atris.ai/auth/cli"
  echo "                           Then run: atris login --token YOUR_TOKEN"
  echo ""
  exit 1
fi

# 3. Extract token
if command -v node &> /dev/null; then
  TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
elif command -v python3 &> /dev/null; then
  TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.atris/credentials.json')))['token'])")
elif command -v jq &> /dev/null; then
  TOKEN=$(jq -r '.token' ~/.atris/credentials.json)
else
  echo "Error: Need node, python3, or jq to read credentials"
  exit 1
fi

# 4. Check Slack connection status
STATUS=$(curl -s "https://api.atris.ai/api/integrations/slack/status" \
  -H "Authorization: Bearer $TOKEN")

if echo "$STATUS" | grep -q "Token expired\|Not authenticated"; then
  echo "Token expired. Please re-authenticate:"
  echo "  Run: atris login --force"
  exit 1
fi

if command -v node &> /dev/null; then
  CONNECTED=$(node -e "try{console.log(JSON.parse('$STATUS').connected||false)}catch(e){console.log(false)}")
elif command -v python3 &> /dev/null; then
  CONNECTED=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('connected', False))")
else
  CONNECTED=$(echo "$STATUS" | jq -r '.connected // false')
fi

if [ "$CONNECTED" != "true" ] && [ "$CONNECTED" != "True" ]; then
  echo "Slack not connected. Getting authorization URL..."
  AUTH=$(curl -s -X POST "https://api.atris.ai/api/integrations/slack/start" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"mode":"personal"}')

  if command -v node &> /dev/null; then
    URL=$(node -e "try{console.log(JSON.parse('$AUTH').auth_url||'')}catch(e){console.log('')}")
  elif command -v python3 &> /dev/null; then
    URL=$(echo "$AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('auth_url', ''))")
  else
    URL=$(echo "$AUTH" | jq -r '.auth_url // empty')
  fi

  echo ""
  echo "Open this URL to connect your Slack:"
  echo "$URL"
  echo ""
  echo "After authorizing, run your command again."
  exit 0
fi

echo "Ready. Slack is connected."
export ATRIS_TOKEN="$TOKEN"
```

---

## API Reference

Base: `https://api.atris.ai/api/integrations`

All requests require: `-H "Authorization: Bearer $TOKEN"`

### Get Token (after bootstrap)
```bash
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
```

---

## Personal Endpoints (send/read as yourself)

These use your personal Slack token. Messages appear as YOU, not a bot.

### List Your Channels & DMs
```bash
curl -s "https://api.atris.ai/api/integrations/slack/me/channels" \
  -H "Authorization: Bearer $TOKEN"
```

### List Your DMs
```bash
curl -s "https://api.atris.ai/api/integrations/slack/me/dms" \
  -H "Authorization: Bearer $TOKEN"
```

### Read Messages from a Channel or DM
```bash
curl -s "https://api.atris.ai/api/integrations/slack/me/messages/{channel_id}?limit=20" \
  -H "Authorization: Bearer $TOKEN"
```

### Send Message as Yourself
```bash
curl -s -X POST "https://api.atris.ai/api/integrations/slack/me/send" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123CHANNEL",
    "text": "Hey team, here is the update..."
  }'
```

**Reply in a thread:**
```bash
curl -s -X POST "https://api.atris.ai/api/integrations/slack/me/send" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123CHANNEL",
    "text": "Following up on this...",
    "thread_ts": "1234567890.123456"
  }'
```

### DM Someone as Yourself
```bash
curl -s -X POST "https://api.atris.ai/api/integrations/slack/me/dm" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "slack_user_id": "U0123USER",
    "text": "Hey, quick question about the project..."
  }'
```

### Search Messages
```bash
curl -s "https://api.atris.ai/api/integrations/slack/me/search?q=quarterly+report&count=20" \
  -H "Authorization: Bearer $TOKEN"
```

---

## Workspace Endpoints

### List Channels (bot view)
```bash
curl -s "https://api.atris.ai/api/integrations/slack/channels" \
  -H "Authorization: Bearer $TOKEN"
```

### List Users
```bash
curl -s "https://api.atris.ai/api/integrations/slack/users" \
  -H "Authorization: Bearer $TOKEN"
```

### Search Users
```bash
curl -s "https://api.atris.ai/api/integrations/slack/users/search?q=justin" \
  -H "Authorization: Bearer $TOKEN"
```

Searches by name, display name, or email. Much faster than pulling the full user list.

### Send as Bot
```bash
curl -s -X POST "https://api.atris.ai/api/integrations/slack/test-send" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C0123CHANNEL",
    "message": "Hello from Atris!"
  }'
```

### Check Connection Status
```bash
curl -s "https://api.atris.ai/api/integrations/slack/status" \
  -H "Authorization: Bearer $TOKEN"
```

### Disconnect Slack
```bash
curl -s -X DELETE "https://api.atris.ai/api/integrations/slack" \
  -H "Authorization: Bearer $TOKEN"
```

---

## Workflows

### "Check my Slack messages"
1. Run bootstrap
2. List DMs: `GET /slack/me/dms`
3. For each open DM, read recent messages: `GET /slack/me/messages/{channel_id}?limit=5`
4. Resolve user names: `GET /slack/users`
5. Display: who messaged, what they said, when

### "Send a message to someone"
1. Run bootstrap
2. Find the user: `GET /slack/users/search?q=NAME`
3. **Show user the draft for approval**
4. Send DM: `POST /slack/me/dm` with `{slack_user_id, text}`
5. Confirm: "Message sent!"

### "Reply in a channel"
1. Run bootstrap
2. List channels: `GET /slack/me/channels`
3. Find the right channel
4. Read recent messages: `GET /slack/me/messages/{channel_id}`
5. **Show user the draft for approval**
6. Send: `POST /slack/me/send` with `{channel, text}`

### "Find a conversation about X"
1. Run bootstrap
2. Search: `GET /slack/me/search?q=X`
3. Display matching messages with channel, sender, permalink

### "What did [person] say to me?"
1. Run bootstrap
2. Find user: `GET /slack/users/search?q=NAME` (get user ID)
3. List DMs: `GET /slack/me/dms` (find DM channel with that user)
4. Read messages: `GET /slack/me/messages/{channel_id}`
5. Display conversation

---

## Important Notes

- **Personal endpoints** (`/slack/me/*`) send messages as YOU, not a bot
- **Bot endpoints** (`/slack/channels`, `/slack/test-send`) use the bot token
- **Always get approval** before sending messages on behalf of the user
- **Thread replies**: include `thread_ts` to reply in a thread instead of creating a new message
- **User IDs**: Slack uses IDs like `U0123ABC`. Get them from `/slack/users` endpoint
- **Channel IDs**: Use IDs like `C0123ABC`. Get them from `/slack/me/channels`

---

## Error Handling

| Error | Meaning | Solution |
|-------|---------|----------|
| `Token expired` | AtrisOS session expired | Run `atris login` |
| `Slack not connected` | OAuth not completed | Re-run bootstrap |
| `Personal Slack not connected` | No user token | Re-connect Slack (needs re-auth for personal access) |
| `401 Unauthorized` | Invalid/expired token | Run `atris login` |
| `channel_not_found` | Invalid channel ID | Use `/slack/me/channels` to find correct ID |
| `not_in_channel` | User not in channel | Join the channel first |

---

## Security Model

1. **Local token** (`~/.atris/credentials.json`): Your AtrisOS auth token, stored locally.
2. **Slack credentials**: Bot token and user token stored **server-side** in AtrisOS encrypted vault.
3. **Two token types**: Bot token (xoxb-) for workspace operations, User token (xoxp-) for personal operations.
4. **Access control**: AtrisOS API enforces that you can only access your own Slack.
5. **HTTPS only**: All API communication encrypted in transit.

---

## Quick Reference

```bash
# Setup (one time)
npm install -g atris && atris login

# Get token
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")

# Check connection
curl -s "https://api.atris.ai/api/integrations/slack/status" -H "Authorization: Bearer $TOKEN"

# List your DMs
curl -s "https://api.atris.ai/api/integrations/slack/me/dms" -H "Authorization: Bearer $TOKEN"

# Read messages
curl -s "https://api.atris.ai/api/integrations/slack/me/messages/CHANNEL_ID" -H "Authorization: Bearer $TOKEN"

# Send as yourself
curl -s -X POST "https://api.atris.ai/api/integrations/slack/me/send" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"channel":"C0123","text":"Hello!"}'

# DM someone as yourself
curl -s -X POST "https://api.atris.ai/api/integrations/slack/me/dm" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"user_id":"U0123","text":"Hey!"}'

# Search messages
curl -s "https://api.atris.ai/api/integrations/slack/me/search?q=project+update" -H "Authorization: Bearer $TOKEN"

# List workspace users
curl -s "https://api.atris.ai/api/integrations/slack/users" -H "Authorization: Bearer $TOKEN"

# Search users by name
curl -s "https://api.atris.ai/api/integrations/slack/users/search?q=justin" -H "Authorization: Bearer $TOKEN"
```

Overview

This skill integrates Slack through the AtrisOS API to read messages, search conversations, and send messages as your user or as a bot. It automates connection checks and exposes endpoints for listing channels/DMs, reading threads, searching history, and sending or replying in threads. Use it to manage Slack workflows without manual API scripting.

How this skill works

Before any operation, run the provided bootstrap to ensure the Atris CLI is installed, your Atris token is available, and Slack is connected. The skill uses personal endpoints (/slack/me/*) to act as you and workspace endpoints (/slack/*) to act as the bot. All HTTP requests require the Atris bearer token and return channel lists, user lists, messages, search results, and allow sending messages or DMs.

When to use it

  • When you need to read recent DMs or channel threads quickly
  • When you want to send messages or reply in threads as yourself (not a bot)
  • When you must search Slack history for a topic or link
  • When you want to list workspace users or channels programmatically
  • When checking Slack connection status or automating reconnect flows

Best practices

  • Always run the bootstrap before making API calls to validate tokens and connection status
  • Request user approval before sending or drafting messages on their behalf
  • Use user endpoints (/slack/me/*) to send messages as the user and bot endpoints for workspace-level actions
  • Include thread_ts when replying in threads to avoid creating new top-level messages
  • Resolve user and channel IDs via /slack/users and /slack/me/channels to avoid channel_not_found errors

Example use cases

  • Check all open DMs and summarize unread messages with sender names and timestamps
  • Draft a DM to a colleague, show the draft for approval, then send it as the user
  • Search for mentions of a project across your Slack history and return matching messages with permalinks
  • Reply to a specific thread in a channel by including thread_ts so the reply stays in-thread
  • List workspace users to find a user ID, then start a direct message with that user

FAQ

What does bootstrap do and why run it first?

Bootstrap installs the Atris CLI if missing, verifies your Atris token, checks Slack connection status, and prints an authorization URL if Slack is not connected. It prevents failed requests from invalid or expired tokens.

Will messages sent with /slack/me/* appear as a bot?

No. Personal endpoints (/slack/me/*) send messages as you (your user token). Bot endpoints use the workspace bot token and appear as the bot.