discli 是標準 Unix CLI,會從環境變數讀取 token、輸出結構化 JSON,並以有意義的退出碼結束。這使它很適合放進 shell 腳本、cron 任務與 CI/CD pipeline。
Bash 單行指令
可直接在終端機或腳本中執行的快速操作:
discli message send "#general" "從終端機發送訊息到 Discord"discli --json channel list --server "My Server" | jq -r '.[].name'discli --json member list "My Server" --limit 1000 | jq 'length'discli --json message search "#general" "" --author "alice#1234" --after "$(date -u +%Y-%m-%d)" | jq 'length'discli --json message history "#general" --days 7 | jq -r '.[] | [.timestamp, .author, .content] | @csv' > history.csvLATEST=$(discli --json message list "#general" --limit 1 | jq -r '.[0].id')discli reaction add "#general" "$LATEST" "👍"頻道紀錄腳本
將某個頻道所有訊息記錄到檔案並自動輪替。
#!/usr/bin/env bashset -euo pipefail
CHANNEL="${1:?用法:$0 <channel> [log_dir]}"LOG_DIR="${2:-./logs}"mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/$(date -u +%Y-%m-%d).jsonl"
echo "正在記錄 $CHANNEL 到 $LOG_FILE(按 Ctrl+C 可停止)" >&2
discli --json listen --channel "$CHANNEL" --events messages >> "$LOG_FILE"使用方式:
# 將 #support 記到 ./logs/./channel-logger.sh "#support"
# 指定輸出目錄./channel-logger.sh "#support" /var/log/discord
# 背景執行nohup ./channel-logger.sh "#support" /var/log/discord &Tip
日誌會依日期輪替,每一行都是完整 JSON,能直接交給 jq、匯入資料庫或導入日誌匯流服務。
分析已記錄資料
# 今日每位作者訊息數cat logs/$(date -u +%Y-%m-%d).jsonl | jq -r '.author' | sort | uniq -c | sort -rn
# 找含有「error」的訊息cat logs/*.jsonl | jq -r 'select(.content | test("error"; "i")) | "\(.timestamp) \(.author): \(.content)"'
# 每小時訊息數cat logs/$(date -u +%Y-%m-%d).jsonl | jq -r '.timestamp[:13]' | sort | uniq -c以反應建立投票
可先發一則訊息,再加上反應選項:
#!/usr/bin/env bashset -euo pipefail
CHANNEL="${1:?用法:$0 <channel> <question> <emoji1> <emoji2> [emoji3...]}"QUESTION="${2:?}"shift 2EMOJIS=("$@")
if [ ${#EMOJIS[@]} -lt 2 ]; then echo "至少需要 2 個表情選項" >&2 exit 1fi
# 建立投票訊息MESSAGE="📊 **投票:** $QUESTION\n\n"for emoji in "${EMOJIS[@]}"; do MESSAGE+="$emoji — 點擊後可投票\n"done
# 發送訊息並取得 IDMSG_ID=$(discli --json message send "$CHANNEL" "$(echo -e "$MESSAGE")" | jq -r '.id')
if [ -z "$MSG_ID" ] || [ "$MSG_ID" = "null" ]; then echo "無法發送投票訊息" >&2 exit 1fi
# 新增投票表情for emoji in "${EMOJIS[@]}"; do discli reaction add "$CHANNEL" "$MSG_ID" "$emoji" sleep 0.5 # 避免速率限制done
echo "投票已建立,訊息 ID:$MSG_ID"用法:
./reaction-poll.sh "#general" "你最推薦的程式語言是?" "🐍" "🦀" "🟨"Cron 任務範例
排程執行 Discord 自動化流程。
每日頻道摘要
#!/usr/bin/env bashset -euo pipefail
CHANNEL="#daily-summary"SOURCE="#general"
# 取得昨日訊息數YESTERDAY=$(date -u -d "yesterday" +%Y-%m-%d 2>/dev/null || date -u -v-1d +%Y-%m-%d)COUNT=$(discli --json message history "$SOURCE" --days 1 | jq 'length')
# 取得前五名活躍作者TOP_AUTHORS=$(discli --json message history "$SOURCE" --days 1 \ | jq -r '[group_by(.author) | .[] | {author: .[0].author, count: length}] | sort_by(-.count) | .[:5] | .[] | " \(.author): \(.count) messages"')
discli message send "$CHANNEL" "📊 **#general 每日摘要**($YESTERDAY)
訊息數:$COUNT主要貢獻者:$TOP_AUTHORS"Crontab 設定(每日 09:00 UTC):
0 9 * * * /path/to/daily-summary.sh排程公告
# 每週一 09:00:晨會提醒0 9 * * 1 discli message send "#engineering" "🔔 早安,開始晨會!上週你們都在做什麼?"
# 每月 1 號 10:00:帳務提醒0 10 1 * * discli message send "#billing" "📅 本月帳務週期今天開始,請檢查儀表板。"
# 週一到週五 09:00–17:00 每小時:狀態檢查0 9-17 * * 1-5 discli --json server list | jq -r '.[].name' | while read server; do echo "$(date): $server 線上"; done >> /var/log/discord-status.logWarning
cron 的環境較為精簡。請確認 discli 在 PATH 中,或直接用絕對路徑;在 crontab 要設 DISCORD_BOT_TOKEN,或改用 ~/.discli/config.json 解析 token。
Cron 環境設定
# 方式 1:在 crontab 設 tokenDISCORD_BOT_TOKEN=your-token-here0 9 * * * /path/to/daily-summary.sh
# 方式 2:載入 token 檔0 9 * * * . /path/to/.env && /path/to/daily-summary.sh
# 方式 3:用 config.json(不需環境變數)# 確認 ~/.discli/config.json 含 {"token": "your-token"}0 9 * * * /usr/local/bin/discli message send "#general" "早安,大家!"GitHub 動作:部署通知
在 CI/CD pipeline 內發送部署通知。
name: Deploy and Notify
on: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Deploy run: | # 在此加入你的部署步驟 echo "部署中..."
- name: Install discli run: pip install discord-cli-agent
- name: Notify Discord env: DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} run: | COMMIT_MSG=$(git log -1 --pretty=%s) COMMIT_AUTHOR=$(git log -1 --pretty=%an) COMMIT_SHA=$(git log -1 --pretty=%h)
discli message send "#deploys" "🚀 **已部署至正式環境**
提交:\`$COMMIT_SHA\` — $COMMIT_MSG 作者:$COMMIT_AUTHOR 分支:${{ github.ref_name }} 執行:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"以 embed 發送部署狀態
- name: Notify Discord (with embed) env: DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} run: | discli message send "#deploys" "部署完成" \ --embed-title "v$(cat VERSION) 已部署" \ --embed-desc "所有檢查都通過。[查看執行](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"失敗通知
- name: Notify failure if: failure() env: DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} run: | discli message send "#deploys" "❌ **部署失敗**
分支:${{ github.ref_name }} 執行:${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} 請盡快排查。"JSON 與 jq 實作模式
訊息分析
# 最近一週每日訊息數discli --json message history "#general" --days 7 \ | jq 'group_by(.timestamp[:10]) | map({date: .[0].timestamp[:10], count: length})'
# 平均訊息長度discli --json message list "#general" --limit 100 \ | jq '[.[].content | length] | add / length'
# 常用字詞(前 20)discli --json message list "#general" --limit 500 \ | jq -r '.[].content' \ | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' \ | sort | uniq -c | sort -rn | head -20伺服器健康檢查
#!/usr/bin/env bashset -euo pipefail
STATUS_CHANNEL="#bot-status"
# 檢查機器人是否能連線並取得伺服器列表SERVERS=$(discli --json server list 2>&1) || { echo "重大異常:無法連線到 Discord" >&2 exit 1}
SERVER_COUNT=$(echo "$SERVERS" | jq 'length')TOTAL_MEMBERS=$(echo "$SERVERS" | jq '[.[].member_count] | add')
discli message send "$STATUS_CHANNEL" "✅ **健康檢查通過**伺服器總數:$SERVER_COUNT總成員數:$TOTAL_MEMBERS時間戳記:$(date -u +%Y-%m-%dT%H:%M:%SZ)"批次操作
# 對指定伺服器所有文字頻道發訊息discli --json channel list --server "My Server" \ | jq -r '.[] | select(.type == "text") | .id' \ | while read channel_id; do discli message send "$channel_id" "重要公告:今夜 2:00 UTC 進行伺服器維護" sleep 1 # 避免速率限制 done
# 匯出所有文字頻道近期歷史discli --json channel list --server "My Server" \ | jq -r '.[] | select(.type == "text") | "\(.id) \(.name)"' \ | while read channel_id channel_name; do echo "正在匯出 #$channel_name..." >&2 discli --json message list "$channel_id" --limit 100 > "export-${channel_name}.json" sleep 2 done腳本中的錯誤處理
退出碼
discli 成功為 0,失敗為非 0。可用標準 Bash 錯誤控制:
#!/usr/bin/env bashset -euo pipefail # 遇到錯誤、未定義變數或管線失敗就退出
# 方法 1:set -e(第一個錯誤直接退出)discli message send "#general" "你好"
# 方法 2:明確檢查錯誤if ! discli message send "#general" "你好" 2>/dev/null; then echo "訊息發送失敗" >&2 # 可加上備援或警示fi
# 方法 3:接收輸出後檢查OUTPUT=$(discli --json message send "#general" "你好" 2>&1) || { echo "發送失敗:$OUTPUT" >&2 exit 1} MSG_ID=$(echo "$OUTPUT" | jq -r '.id')echo "已發送訊息 $MSG_ID"重試邏輯
#!/usr/bin/env bash
send_with_retry() { local channel="$1" local message="$2" local max_attempts="${3:-3}" local attempt=1
while [ $attempt -le $max_attempts ]; do if discli message send "$channel" "$message" 2>/dev/null; then return 0 fi echo "第 $attempt/$max_attempts 次嘗試失敗,將於 ${attempt} 秒後重試…" >&2 sleep "$attempt" attempt=$((attempt + 1)) done
echo "已重試 $max_attempts 次仍然失敗" >&2 return 1}
# 用法send_with_retry "#deploys" "部署完成" 3Token 驗證
# 快速驗證 token 是否有效if ! discli server list >/dev/null 2>&1; then echo "錯誤:Discord token 無效,或機器人尚未加入任何伺服器" >&2 echo "請設定 DISCORD_BOT_TOKEN,或用 discli config set token YOUR_TOKEN 設定" >&2 exit 1fi與其他工具結合
將 webhook 資料轉發到 Discord
# 轉發 GitHub webhook 負載curl -s "https://api.github.com/repos/owner/repo/releases/latest" \ | jq -r '"新版本發布:\(.tag_name) — \(.html_url)"' \ | xargs -I{} discli message send "#releases" "{}"監控日誌檔
# 監控日誌並轉發錯誤到 Discordtail -F /var/log/app/error.log | while read line; do discli message send "#alerts" "🚨 錯誤:$line" sleep 1 # 避免速率限制done資料庫查詢結果推播
# 將查詢結果以格式化訊息發送RESULT=$(psql -t -c "SELECT count(*) FROM users WHERE created_at > now() - interval '1 day'")discli message send "#metrics" "📊 今日新增使用者:**$RESULT**"腳本安全性
Danger
請勿在腳本內硬編碼 token。應使用環境變數、密鑰管理服務,或 ~/.discli/config.json。
# 不建議:token 寫在腳本內discli --token "mfa.abc123..." message send "#general" "你好"
# 建議:使用環境變數export DISCORD_BOT_TOKEN="$VAULT_TOKEN"discli message send "#general" "你好"
# 建議:用 config 檔(一次設定)discli config set token "$VAULT_TOKEN"discli message send "#general" "你好"CI/CD 請一律使用加密機密:
env: DISCORD_BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}自動化腳本請使用最小必要的權限設定檔:
# CI 通知只需發送訊息discli --profile chat message send "#deploys" "已部署"