4 releases (2 stable)
| new 1.0.1 | Mar 3, 2026 |
|---|---|
| 0.2.0 | Feb 22, 2026 |
| 0.1.0 | Feb 21, 2026 |
#487 in Command line utilities
84KB
2K
SLoC
slafling
Fling messages and files to Slack. Sends text or uploads files to a configured Slack channel via Bot Token. Supports stdin for both text and file input.
Concept
slafling is a safety-first Slack CLI tool. Messages always go to pre-configured destinations — there is no ad-hoc channel override flag. This design prevents accidental messages to wrong channels caused by typos or copy-paste mistakes.
Use profiles to manage multiple channels. Each profile explicitly maps to a destination, making message routing deliberate and reviewable.
Install
Homebrew
brew install td72/tap/slafling
From crates.io
cargo install slafling
From GitHub Releases
Download a prebuilt binary from Releases.
Available targets:
x86_64-unknown-linux-gnuaarch64-unknown-linux-gnuaarch64-apple-darwinx86_64-apple-darwin
From source
cargo install --path .
Setup
Quick Start
slafling init
This creates ~/.config/slafling/config.toml and stores your Bot Token securely (macOS Keychain on macOS, token file on other platforms).
Token Management
Tokens are not stored in config.toml. They are resolved from the backend specified by token_store — Keychain ("keychain", default on macOS) or token file ("file", default on other platforms).
In headless mode, SLAFLING_TOKEN environment variable is used instead.
Token storage location: <data_dir>/slafling/tokens/<profile> (file) or macOS Keychain service slafling (keychain). <data_dir> is ~/Library/Application Support on macOS, ~/.local/share on Linux.
# Store a token
slafling token set
# Store a token for a specific profile
slafling token set -p work
# Show where the token is resolved from
slafling token show
# Remove a stored token
slafling token delete
Manual Setup
Create ~/.config/slafling/config.toml:
[default]
channel = "#general"
max_file_size = "100MB" # optional (default: 100MB, Slack API max: 1GB)
confirm = true # optional: prompt before sending (default: false)
output = "table" # optional: search output format — table, tsv, json (default: auto-detect)
search_types = ["public_channel", "private_channel"] # optional (default: public_channel) — public_channel, private_channel, im, mpim
# token_store = "keychain" # optional: keychain or file (default: keychain on macOS, file on other platforms)
[profiles.random]
channel = "#random"
[profiles.dm-alice]
channel = "D0123456789" # Conversation ID for DM (not User ID)
[profiles.other-workspace]
channel = "#alerts" # Use `slafling token set -p other-workspace` to store a different token
Bot Token Scopes
| Scope | Required for |
|---|---|
chat:write |
Send text messages (-t) — bot must be invited to the channel |
chat:write.public |
Send to public channels without being invited |
files:write |
Upload files (-f) — bot must be invited to the channel |
channels:read |
Search public channels (search) |
groups:read |
Search private channels (search --types private_channel) |
im:read |
Search DMs (search --types im) |
mpim:read |
Search group DMs (search --types mpim) |
chat:write and files:write work for all conversation types (channels, DMs, group DMs). The *:read scopes are only needed for search. Only add the scopes you need.
Usage
Send (default)
# Send a text message
slafling -t "hello world"
# Pipe text from stdin
echo "piped message" | slafling -t
# Upload a file
slafling -f image.png
# Upload from stdin with a filename
cat report.csv | slafling -f -n report.csv
# File upload with a comment
slafling -f error.log -t "Check this log"
# Use a profile
slafling -p random -t "hello random"
# Use a profile via environment variable
export SLAFLING_PROFILE=random
slafling -t "hello random"
# Confirm before sending (when confirm = true in config)
slafling -t "important message" # prompts: Send? [y/N]
slafling -t "skip prompt" -y # skip confirmation with --yes
Search
# Search for channels by name
slafling search general
# Override output format via environment variable
export SLAFLING_OUTPUT=json
slafling search general
# Search specific channel types
slafling search general --types public_channel,private_channel
# Search with a profile (uses that profile's token)
slafling -p work search deploy
# Output as JSON
slafling search general -o json
# Pick a channel with fzf and copy its ID
slafling search dev | fzf | cut -f3 | pbcopy
Init
# Create config file interactively
slafling init
Token
-p/--profile and SLAFLING_PROFILE work for all subcommands including token.
# Store token interactively
slafling token set
# Store token for a profile
slafling token set -p work
# Show token source
slafling token show
slafling token show -p work
# Delete stored token
slafling token delete
slafling token delete -p work
Validate
# Validate config file
slafling validate
Environment Variables
| Variable | Description | Available in |
|---|---|---|
SLAFLING_PROFILE |
Profile selection | Normal |
SLAFLING_TOKEN |
Bot token | Headless |
SLAFLING_OUTPUT |
Search output format (table, tsv, json) |
Normal, Headless |
SLAFLING_HEADLESS |
Enable headless mode (1, true, yes) |
— |
SLAFLING_CHANNEL |
Channel to send to (#channel or C01ABCDEF) |
Headless |
SLAFLING_MAX_FILE_SIZE |
File size limit (100MB, 1GB, etc.) |
Normal, Headless |
SLAFLING_CONFIRM |
Prompt before sending (true, 1, yes) |
Normal, Headless |
SLAFLING_SEARCH_TYPES |
Channel types for search (comma-separated) | Normal, Headless |
Headless Mode
Run without a config file — all settings come from environment variables (see above). Useful for CI/CD, Docker, cron, and other non-interactive environments.
Enable with --headless flag or SLAFLING_HEADLESS=1. Requires SLAFLING_TOKEN and SLAFLING_CHANNEL (for send).
# Send a message
SLAFLING_TOKEN=xoxb-... SLAFLING_CHANNEL="#deploy" slafling --headless -t "deploy complete"
# Pipe from stdin
echo "build log" | SLAFLING_TOKEN=xoxb-... SLAFLING_CHANNEL="#ci" slafling --headless -t
# Search channels
SLAFLING_TOKEN=xoxb-... slafling --headless search general
# Using SLAFLING_HEADLESS env var (no --headless flag needed)
export SLAFLING_HEADLESS=1
export SLAFLING_TOKEN=xoxb-...
export SLAFLING_CHANNEL="#alerts"
slafling -t "alert message"
--profile is ignored in headless mode (with a warning). init, token, and validate subcommands are not available in headless mode.
License
MIT
Dependencies
~15–26MB
~433K SLoC