#!/bin/bash
# Slack Cookie-Auth Client
# Uses xoxc/xoxd session tokens to impersonate a user account
#
# Usage: ./slack-cookie-client.sh <command> [args]
#
# Environment:
# SLACK_TOKENS_FILE Path to cookie-tokens.env file
# SLACK_API_URL Full API URL override (e.g., https://wine-com.slack.com/api)
# SLACK_DOMAIN Slack domain (used if SLACK_API_URL not set)
# Or source the env file before running this script
set -e
# Load tokens if file specified, otherwise check relative path
if [[ -n "$SLACK_TOKENS_FILE" ]]; then
source "$SLACK_TOKENS_FILE"
elif [[ -f "$(dirname "$0")/../cookie-tokens.env" ]]; then
source "$(dirname "$0")/../cookie-tokens.env"
fi
# Validate required vars
if [[ -z "$SLACK_XOXC_TOKEN" || -z "$SLACK_XOXD_COOKIE" ]]; then
echo "Error: SLACK_XOXC_TOKEN and SLACK_XOXD_COOKIE must be set" >&2
echo "Either set SLACK_TOKENS_FILE or source your cookie-tokens.env" >&2
exit 1
fi
# Build API URL: prefer SLACK_API_URL, fallback to SLACK_DOMAIN, default to app.slack.com
if [[ -n "$SLACK_API_URL" ]]; then
SLACK_API="${SLACK_API_URL%/}" # Remove trailing slash if present
elif [[ -n "$SLACK_DOMAIN" ]]; then
SLACK_API="https://${SLACK_DOMAIN}/api"
else
SLACK_API="https://app.slack.com/api"
fi
slack_api() {
local endpoint="$1"
shift
curl -s "${SLACK_API}/${endpoint}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Cookie: d=${SLACK_XOXD_COOKIE}" \
-H "Origin: https://app.slack.com" \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
-d "token=${SLACK_XOXC_TOKEN}" \
"$@"
}
case "$1" in
auth)
slack_api "auth.test"
;;
channels)
slack_api "conversations.list" -d "&limit=${2:-20}&types=public_channel,private_channel"
;;
history)
# $2 = channel ID, $3 = limit (default 10)
if [[ -z "$2" ]]; then
echo "Usage: $0 history <channel_id> [limit]" >&2
exit 1
fi
slack_api "conversations.history" -d "&channel=$2&limit=${3:-10}"
;;
send)
# $2 = channel ID, $3 = message text
if [[ -z "$2" || -z "$3" ]]; then
echo "Usage: $0 send <channel_id> <message>" >&2
exit 1
fi
slack_api "chat.postMessage" -d "&channel=$2&text=$3"
;;
search)
# $2 = query
if [[ -z "$2" ]]; then
echo "Usage: $0 search <query>" >&2
exit 1
fi
slack_api "search.messages" -d "&query=$2&count=10"
;;
users)
slack_api "users.list" -d "&limit=${2:-50}"
;;
user)
# $2 = user ID
if [[ -z "$2" ]]; then
echo "Usage: $0 user <user_id>" >&2
exit 1
fi
slack_api "users.info" -d "&user=$2"
;;
dm)
# $2 = user ID, $3 = message
if [[ -z "$2" || -z "$3" ]]; then
echo "Usage: $0 dm <user_id> <message>" >&2
exit 1
fi
# Open DM channel first, parse with grep/sed if jq not available
response=$(slack_api "conversations.open" -d "&users=$2")
if command -v jq &>/dev/null; then
channel=$(echo "$response" | jq -r '.channel.id')
else
channel=$(echo "$response" | grep -o '"id":"[^"]*"' | head -1 | sed 's/"id":"//;s/"//')
fi
if [[ "$channel" != "null" && -n "$channel" ]]; then
slack_api "chat.postMessage" -d "&channel=$channel&text=$3"
else
echo "Failed to open DM channel" >&2
echo "$response" >&2
exit 1
fi
;;
*)
echo "Slack Cookie-Auth Client"
echo ""
echo "Usage: $0 <command> [args]"
echo ""
echo "Commands:"
echo " auth Test authentication"
echo " channels [limit] List channels (default: 20)"
echo " history <channel> [limit] Get channel history (default: 10)"
echo " send <channel> <text> Send a message to a channel"
echo " search <query> Search messages"
echo " users [limit] List users (default: 50)"
echo " user <user_id> Get user info"
echo " dm <user_id> <text> Send a direct message"
echo ""
echo "Environment:"
echo " SLACK_TOKENS_FILE Path to cookie-tokens.env file"
echo " SLACK_API_URL Full API URL (e.g., https://workspace.slack.com/api)"
echo " SLACK_DOMAIN Slack domain (fallback if SLACK_API_URL not set)"
echo " SLACK_XOXC_TOKEN xoxc token (if not using file)"
echo " SLACK_XOXD_COOKIE xoxd cookie (if not using file)"
echo ""
echo "Current API URL: $SLACK_API"
;;
esac