- name
- slack-latest
- description
- Gather recent Slack messages, read threads, send replies, and upload/download files. Use when the user asks about Slack activity or wants to interact with Slack.
# Slack: gather, read, send, file upload/download
`slack.py` is a self-contained Python script (no dependencies beyond
the standard library) at `{baseDir}/slack.py`.
## Authentication
**ํ๊ฒฝ๋ณ์ ๋ฐฉ์** (๊ถ์ฅ โ `~/.env.local`์ ์ค์ ):
```bash
export SLACK_WORKSPACE_URL="https://WORKSPACE.slack.com"
export SLACK_TOKEN="xoxc-..."
export SLACK_COOKIE="xoxd-..."
```
ํ๊ฒฝ๋ณ์๊ฐ ์์ผ๋ฉด `~/.config/skills/slack-latest/credentials.json` ํ์ผ์ ์ฝ์.
### ํ ํฐ ๋ฐ๊ธ (๋ธ๋ผ์ฐ์ cURL ๋ณต์ฌ)
1. Slack **์น ๋ธ๋ผ์ฐ์ **์์ F12 โ Network ํญ
2. ํํฐ์ `api/` ์
๋ ฅ โ `*.slack.com/api/` ์์ฒญ ์ฐพ๊ธฐ
3. ์ฐํด๋ฆญ โ **Copy as cURL**
4. ํ ํฐ ์ ์ฅ:
```bash
pbpaste | python3 {baseDir}/slack.py auth
```
**ํ ํฐ ์๋ช
:** ๋ธ๋ผ์ฐ์ ๋ก๊ทธ์์ ์ ๋ง๋ฃ. ์ธ์ฆ ์๋ฌ ๋ฐ์ํ๋ฉด ์ฌ์ค์ .
๊ฒ์ฆ:
```bash
python3 {baseDir}/slack.py auth-test
```
## Gather recent messages
์ฑ๋ ๋ฉ์์ง ์์ง. **๊ธฐ๋ณธ์ ์ผ๋ก `--no-dm`์ ์ฌ์ฉ**ํ์ฌ ๊ฐ์ธ DM์ ์ ์ธํ๋ค.
```bash
# ์ฑ๋๋ง (DM ์ ์ธ) โ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
python3 {baseDir}/slack.py gather --days 3 --no-dm --out ~/tmp/slack-recent.json
# DM ํฌํจ (์ฌ์ฉ์๊ฐ ๋ช
์์ ์ผ๋ก ์์ฒญํ ๊ฒฝ์ฐ๋ง)
python3 {baseDir}/slack.py gather --days 3 --out ~/tmp/slack-recent.json
```
Output: JSON array grouped by channel (most recently active first).
### Options
| Flag | Description |
|------|-------------|
| `--days N` | time window (default: 3) |
| `--no-dm` | **DM/group DM ์ ์ธ** (์ฑ๋๋ง) |
| `--max-text N` | truncate message text in chars (default: 500) |
| `--include-ids` | add `_id`, `_uid`, `_ts` for follow-up API calls |
| `--compact` | single-line JSON (saves ~25% size) |
| `--out PATH` | output file path (default: ~/tmp/slack-recent.json) |
### Output format
```json
[
{
"channel": "#general",
"messages": [
{
"from": "ํ๊ธธ๋", "at": "2026-03-07 12:18 KST",
"text": "๋ฐฐํฌ ์๋ฃํ์ต๋๋ค",
"replies": [
{"from": "๊น์ํฌ", "at": "2026-03-07 12:20 KST", "text": "ํ์ธ!"}
]
}
]
}
]
```
- Messages: oldest-first (narrative order)
- Thread replies expanded inline under `replies`
- `older_replies: N` when replies fall outside time window
- Timestamps in KST (UTC+9, suffix `KST`)
## Read one channel's history (bot alert ํ์ โ "๋ฌธ์ ์๋?!")
`gather` ๋ bot_message ๋ฅผ noise ๋ก ๋ฒ๋ ค์, **๋ด์ด ์๋ alert ์ฑ๋**(์๋ฒ์๋ต์ฒดํฌ / cube alerts ๋ฑ)์
ํต์งธ ๋๋ฝํ๋ค. `history` ๋ ๋จ์ผ ์ฑ๋์ ์ฝ๋ `--include-bot` ์ผ๋ก bot alert ๋ฅผ ์ด๋ฆฌ๊ณ ,
alert ๋ณธ๋ฌธ์ด `attachments`/`blocks` ์๋ง ์์ ๋๋ `text` ๋ก ๋ณต์ํ๋ค. read-only.
์ด๊ฒ์ด ์ด์ ์ ๊ฒ("๋ฌธ์ ์๋?!")์์ **P0 bot alert ํ์ ๊ฒฝ๋ก**๋ค.
```bash
# bot alert ์ฑ๋ โ --include-bot ํ์
python3 {baseDir}/slack.py history --channel C095PQMMW9J \
--days 14 --include-ids --include-bot --out /tmp/noti-server-history.json
```
์ถ๋ ฅ์ `gather` ํธํ `[{"channel","_id","messages":[...]}]` ๋ผ์ incidentcli
`slack_alert` ingest ๊ฐ ๋ฐ๋ก ๋จน๋๋ค:
```bash
cd ~/repos/work/incidentcli
./run.sh ingest --from slack_alert --input /tmp/noti-server-history.json \
--incident-id <DENOTE_ID> --window FROM..UNTIL --out /tmp/envelope.json
./run.sh validate-output /tmp/envelope.json
```
| Flag | Description |
|------|-------------|
| `--channel` | Channel ID (required) |
| `--include-bot` | **bot_message alert ํฌํจ** (๊ธฐ๋ณธ ์ ์ธ โ alert ์ฑ๋์ ํ์) |
| `--days N` | time window (default: 1). ๋น๋ฉด 7/14 ๋ก ๋ํ๋ ๋จ โ **๋น ๊ฒฐ๊ณผ๋ ์ ์์ผ ์ ์์** |
| `--channel-name` | ํ์ ์ด๋ฆ override (๊ธฐ๋ณธ: conversations.info ๋ก ํด์) |
| `--include-ids` | `_uid` ์ถ๊ฐ (`_ts`/`_id` ๋ ํญ์ ํฌํจ) |
| `--max-text N` | message text truncate (default: 800) |
| `--compact` / `--out` | gather ์ ๋์ผ |
- DM ์ ๋์์ด ์๋๋ค(๋จ์ผ ์ฑ๋ ID ๋ง). gather ์ DM ๊ธฐ๋ณธ ์ ์ธ ์์น๊ณผ send ์ ํ์ธ ์์น์ ๊ทธ๋๋ก ์ ์ง.
- ์ง์ง ์์คํ
noise(`channel_join` ๋ฑ)๋ง ํญ์ skip, bot alert ๋ `--include-bot` ๋ก ์ ์ด.
## Read a single thread
```bash
python3 {baseDir}/slack.py thread --channel C0123456789 --ts 1700000000.000001
```
## Send (text, file, or both)
`send` ๋ ํ
์คํธ๋ง / ํ์ผ๋ง / ํ
์คํธ+ํ์ผ ์ฒจ๋ถ ๋ชจ๋ ์ง์. ์ค๋ ๋ ๋ต๊ธ๋ ๊ฐ๋ฅ.
```bash
# ํ
์คํธ๋ง (chat.postMessage)
python3 {baseDir}/slack.py send --channel C0123456789 --text "Hello"
# ์ค๋ ๋ ๋ต๊ธ
python3 {baseDir}/slack.py send --channel C0123456789 \
--thread-ts 1700000000.000001 --text "Got it"
# ํ์ผ๋ง ์
๋ก๋ (files.upload v2 โ getUploadURLExternal + complete)
python3 {baseDir}/slack.py send --channel D09336BAYF7 \
--file ~/Documents/report.pdf
# ํ์ผ + ๋ฉ์์ง (--text ๊ฐ initial_comment ๋ก ๋ค์ด๊ฐ)
python3 {baseDir}/slack.py send --channel D09336BAYF7 \
--file ~/report.pdf \
--text "์ด์ฌ๋, ๊ฒํ ์์ฒญ๋๋ฆฝ๋๋ค."
# ์ค๋ ๋ ์์ ํ์ผ ์ฒจ๋ถ
python3 {baseDir}/slack.py send --channel C0123456789 \
--thread-ts 1700000000.000001 \
--file ~/snapshot.png --text "๋ฐฉ๊ธ ์บก์ณ"
```
์ต์
:
| Flag | Description |
|------|-------------|
| `--channel` | Channel/DM ID (required) |
| `--text` | ๋ฉ์์ง ๋ณธ๋ฌธ. `--file` ๊ณผ ํจ๊ป ์ฐ๋ฉด ์ฒจ๋ถ ์ฝ๋ฉํธ๋ก ๋ค์ด๊ฐ |
| `--file` | ์
๋ก๋ํ ํ์ผ ๊ฒฝ๋ก |
| `--title` | ํ์ผ ์ ๋ชฉ (๊ธฐ๋ณธ: ํ์ผ๋ช
). `--file` ์์ผ๋ฉด ๋ฌด์ |
| `--thread-ts` | ์ค๋ ๋ ๋ต๊ธ timestamp |
`--text` ์ `--file` ๋ ๋ค ๋น์ด ์์ผ๋ฉด ์๋ฌ.
## Download a file
```bash
# ํ์ผ ID ๋ก ๋ค์ด๋ก๋ (ํ์ฌ ๋๋ ํ ๋ฆฌ์ ์๋ณธ ํ์ผ๋ช
์ผ๋ก ์ ์ฅ)
python3 {baseDir}/slack.py get-file --file-id F0B529622S3
# Permalink URL ๋ก๋ ๊ฐ๋ฅ (URL ์์์ F<ID> ์๋ ์ถ์ถ)
python3 {baseDir}/slack.py get-file \
--url "https://team.slack.com/files/U092.../F0B5.../report.doc"
# ์ถ๋ ฅ ๊ฒฝ๋ก/๋๋ ํ ๋ฆฌ ์ง์
python3 {baseDir}/slack.py get-file --file-id F0B529622S3 --out /tmp/report.doc
python3 {baseDir}/slack.py get-file --file-id F0B529622S3 --out ~/Downloads/
```
ํ์ผ ID ๋ `gather --include-ids` ๊ฒฐ๊ณผ์ ๋ฉ์์ง์ ๋ณด์ด๋ `files[].id`, ๋๋
์
๋ก๋ ํ ์๋ต์ `permalink` URL ์์ ์ป์ ์ ์๋ค.
## ์์ด์ ํธ ๊ท์น
1. **DM์ ๊ธฐ๋ณธ ์ ์ธ**: gather ์ ํญ์ `--no-dm` ์ฌ์ฉ. ์ฌ์ฉ์๊ฐ ๋ช
์์ ์ผ๋ก DM ์์ฒญ ์์๋ง ์๋ต
2. **๋ฉ์์ง/ํ์ผ ์ ์ก ์ ํ์ธ**: `send` ์คํ ์ ๋ฐ๋์ ์ฌ์ฉ์ ํ์ธ (ํ์ผ ์ฒจ๋ถ๋ ๋์ผ)
3. **๋ค์ด๋ก๋ ํ์ผ ์์น ๋ณด๊ณ **: `get-file` ๊ฒฐ๊ณผ์ `saved` ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉ์์๊ฒ ์๋ฆผ
4. **๊ฐ์ธ์ ๋ณด ์ฃผ์**: ์์ง๋ ๋ฉ์์ง์ ๋ค์ด๋ก๋ํ ํ์ผ์ ์ธ๋ถ์ ๋
ธ์ถํ์ง ์์
Ver en GitHub