第一個機器人
本指南會從頭帶你建立 Discord 應用程式、邀請機器人加入伺服器,並建立一個會回音訊息的工作代理。完成後你會有一個 Python 腳本,透過 discli serve 監聽訊息並自動回覆。
前置作業
- 已安裝 discli
- Discord 帳號
- 你有管理權限的 Discord 伺服器(必要時建立測試伺服器)
設定 Discord 機器人
建立 Discord 應用程式
建立機器人並複製 Token
在左側導覽列點選 Bot。
點選 Reset Token(如果尚未建立則先點 Add Bot)產生機器人 Token,並立刻複製,關閉後無法再次查看。
請不要外流機器人 Token。 任何拿到 Token 的人都能完整控制你的機器人。若不慎外洩,請立即到開發者平台重設。
啟用 MESSAGE CONTENT 供即時訊息事件使用
在同一個 Bot 設定頁面,往下捲到 Privileged Gateway Intents。
若你將使用 discli listen、discli serve 或其他會消費即時訊息事件的功能,請啟用 MESSAGE CONTENT INTENT。單次 REST 指令不會開啟 Gateway 連線,但 Discord 仍可能在 HTTP 回應中限制 content 欄位。
點選 Save Changes。
未開啟 MESSAGE CONTENT INTENT 時,機器人仍可收到事件但 content 會是空值,這是新機器人「看起來沒回應」最常見原因。
邀請機器人到伺服器
在左側導覽點選 OAuth2。
在 OAuth2 URL Generator 下方:
- 在 Scopes 勾選 bot
- 在 Bot Permissions 勾選:
- Send Messages(傳送訊息)
- Read Message History(讀取訊息歷史)
- View Channels(檢視頻道)
複製頁面底部產生的 URL 並在瀏覽器開啟,選擇測試伺服器後點 Authorize。
若你要做完整功能代理,之後可再補足更多權限(管理訊息、加上表情、建立公開討論串等)。建議先以最小權限起步,依需求逐步擴充。
用 discli 設定 Token
回到終端機,儲存機器人 Token:
discli config set token YOUR_BOT_TOKENSet token.將 YOUR_BOT_TOKEN 換成你在步驟 2 複製的實際值。
測試連線
驗證 discli 是否能使用你的 Token 連到 Discord:
discli server list我的測試伺服器(ID: 1234567890123456789)— 5 位成員你應該會看到剛才邀請機器人到的伺服器。若有錯誤,請用 discli config show 再確認一次 Token。
建立第一個代理
接著進入核心:建立一個會監聽訊息並回覆的機器人。這會使用 discli serve,透過 stdin/stdout 開啟持續 JSONL(JSON Lines)連線。
建立代理腳本
建立 my_bot.py,內容如下:
import jsonimport subprocess
# 以 JSON 輸出啟動 discli 的 serve 模式proc = subprocess.Popen( ["discli", "--json", "serve"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True,)
# 從 stdout 逐列讀取 JSON 物件事件for line in proc.stdout: event = json.loads(line)
# 只回應非機器人訊息 if event.get("event") == "message" and not event.get("is_bot"): # 建立回覆動作 cmd = json.dumps({ "action": "reply", "channel_id": event["channel_id"], "message_id": event["message_id"],"content": f"你剛才說:{event['content']}", })
# 經由 stdin 傳送動作給 discli proc.stdin.write(cmd + "\n") proc.stdin.flush()這段程式只用 15 行邏輯,沒有 Discord 函式庫樣板、沒有額外事件迴圈設定,也不需要你自己管理 Gateway 連線,全部由 discli 接管。
執行代理
python my_bot.py程式會啟動並等待 Discord 事件,初始可能看不到輸出,這是正常現象。
測試
到 Discord 伺服器中找一個機器人可讀取的頻道,傳送一則訊息:
你:你好,bot!My discli Bot:你剛才說:你好,bot!機器人應在一秒內回覆,請再多送幾則訊息確認流程正常。
在終端機按 Ctrl+C 可停止代理。
程式碼運作方式
先把代理程式拆開解讀:
啟動 serve 流程
proc = subprocess.Popen( ["discli", "--json", "serve"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True,)這會以子進程方式啟動 discli serve。--json 旗標讓 discli 以 JSON 輸出事件,stdin 與 stdout 形成雙向通訊管道:
- stdout — discli 會將事件(訊息、表情、成員加入等)以 JSON 列輸出
- stdin — 你的代理將動作(傳訊息、回覆、加表情等)以 JSON 列輸入
讀取事件
for line in proc.stdout: event = json.loads(line)stdout 的每列都是完整 JSON 物件,代表一則 Discord 事件。event 欄位指示事件種類。訊息事件範例如下:
{ "event": "message", "channel_id": "1111111111111111111", "message_id": "2222222222222222222", "author": "Alice", "author_id": "3333333333333333333", "content": "你好,bot!", "is_bot": false, "guild_id": "4444444444444444444"}過濾事件
if event.get("event") == "message" and not event.get("is_bot"):這行邏輯會檢查兩件事:
- 事件是訊息而非表情、成員加入等
- 訊息不是機器人自己傳的(避免機器人自我回覆形成無限循環)
傳送動作
cmd = json.dumps({ "action": "reply", "channel_id": event["channel_id"], "message_id": event["message_id"], "content": f"你剛才說:{event['content']}",})proc.stdin.write(cmd + "\n")proc.stdin.flush()要讓機器人執行動作,就將 JSON 動作寫進 stdin。reply 會回覆指定訊息;其他動作還有 send(傳訊息)、react(加表情)、thread_create(建立討論串)與更多。
flush() 非常重要,否則 Python 可能暫存輸出,導致動作無法即時送到 discli。
疑難排解
機器人沒有回應訊息嗎? 請檢查以下常見情況:
MESSAGE CONTENT INTENT 未啟用。 到開發者平台的 Bot 設定確認此開關已開啟,否則
event['content']會是空字串。機器人不在測試頻道。 確認機器人在測試頻道有「檢視頻道」權限。
Token 錯誤或已過期。 執行
discli server list驗證。若失敗,請在開發者平台重設 token,並執行discli config set token NEW_TOKEN。防火牆或網路問題。
discli serve需要連到 Discord 的 WebSocket 外傳連線,請確認網路允許該連線。
Windows: 若 stdin 顯示停住,這是 Python subprocess 在 Windows 上的已知情況。discli 內部有用執行緒式 stdin 讀取器處理,請確認使用 discli v0.5.0 以上版本(pip install --upgrade discord-cli-agent)。
擴充代理
你可以在這個基礎上再做:
- 加入 AI 模型。 不必只回音,改為把訊息內容送進 LLM(Claude、GPT 等)再以 AI 回覆。
- 讀取對話歷史。 用
message_list取得先前訊息,補齊 AI 需要的上下文。 - 建立討論串。 用
thread_create幫每個對話各建一個專用討論串。 - 加入斜線指令。 設定使用者可透過
/呼叫的自訂指令。 - 限制權限。 用
discli permission set chat把可執行操作縮小到必要範圍。