---
# System prepended metadata

title: Discord Bot簡章：Discord 機器人結合 OpenAI GPT

---

### Discord Bot簡章：Discord 機器人結合 OpenAI GPT

這份簡章旨在詳細介紹如何利用 Python、OpenAI GPT API 以及 Discord API 建立一個智能聊天機器人，此機器人能夠自動回應用戶消息並進行互動。

#### 功能概述

1. **消息處理與回應**：
   - 機器人會監聽 Discord 服務器上的消息。
   - 當收到用戶消息時，機器人將該消息保存到本地 JSON 文件以記錄聊天歷史。
   - 利用 OpenAI GPT 產生回應並將回應發送給用戶。

2. **聊天歷史管理**：
   - 機器人將聊天歷史保存在本地 JSON 文件中。
   - 每當收到或發送消息時更新聊天歷史。
   - 定期清理超過 20 分鐘的舊消息以節省空間並保持歷史的相關性。

3. **自動重啟功能**：
   - 每 40 分鐘後自動重啟機器人，以確保系統穩定運行。
   - 重啟後重新連接 Discord 並繼續處理消息。

#### 主要程式碼段落

1. **初始化與設定**：
   - 設定 OpenAI API 鑰匙和 Discord 連接令牌。
   - 設定機器人的意圖，允許讀取和處理消息。

```python
openai_api_key = "your_openai_api_key"
discord_token = "your_discord_token"
openai.api_key = openai_api_key

intents = discord.Intents.default()
intents.messages = True
intents.message_content = True

bot = discord.Client(intents=intents)
```

2. **消息處理**：
   - 監聽來自 Discord 的消息。
   - 使用 OpenAI 的 GPT 模型生成回應。

```python
@bot.event
async def on_message(message):
    if message.author == bot.user:
        return
    save_message("user", str(message.author.id), message.content)
    # 構建消息列表供 OpenAI API 使用
    chat_history = load_chat_history()
    messages = [{"role": msg["role"], "content": msg["content"]} for msg in chat_history]
    try:
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=messages,
        )
        reply_text = response.choices[0].message['content'].strip()
        await message.channel.send(reply_text)
        save_message("assistant", "AI", reply_text)
    except Exception as e:
        print(f'發生錯誤：{e}')
        await message.channel.send("抱歉發生錯誤，無法處理您的消息。")
```

#### 使用與部署指南

1. **設定 API 鑰匙**：確保您已有有效的 OpenAI API 鑰匙和 Discord 機器人令牌。
2. **部署機器人**：將此程式碼部署到您的服務器或任何支持 Python 的運行環境。
3. **邀請機器人加入 Discord 服務器**：使用

 Discord 提供的機制將機器人加入到您的服務器中。

這個機器人展示了如何結合最新的 AI 技術與即時通訊工具來創建一個互動式聊天機器人，這種機器人可被應用於客服、娛樂或教育等多種場景。

```python


import discord
import openai
import json
import datetime
import asyncio

openai_api_key = "your_openai_api_key"
discord_token = "your_discord_token"

openai.api_key = openai_api_key

intents = discord.Intents.default()
intents.messages = True
intents.message_content = True

bot = discord.Client(intents=intents)
chat_history_file = "chat_history.json"

def load_chat_history():
    """從JSON文件中加載聊天歷史"""
    try:
        with open(chat_history_file, "r", encoding='utf-8') as file:
            return json.load(file)
    except FileNotFoundError:
        return []

def save_message(role, author_id, message_content):
    """將消息及其角色保存到JSON文件中，帶有時間戳"""
    chat_history = load_chat_history()
    chat_history.append({"role": role, "author_id": author_id, "content": message_content, "timestamp": datetime.datetime.now().isoformat()})
    with open(chat_history_file, "w", encoding='utf-8') as file:
        json.dump(chat_history, file, indent=4)

async def restart_bot(bot):
    """定時重啟機器人"""
    await bot.wait_until_ready()
    while not bot.is_closed():
        print("計劃在40分鐘後重啟...")
        await asyncio.sleep(2400)  # 等待40分鐘
        print("正在重啟機器人...")
        await bot.close()  # 關閉機器人連接
        await bot.start(discord_token)  # 重新啟動機器人
        print("機器人已重啟")

async def clean_old_messages():
    """定期清理超過20分鐘的消息，保留system消息"""
    while True:
        try:
            with open(chat_history_file, "r+", encoding='utf-8') as file:
                chat_history = json.load(file)
                current_time = datetime.datetime.now()
                # 過濾出含有 timestamp 字段且時間在20分鐘內的記錄，或者是系統消息
                filtered_history = [
                    msg for msg in chat_history
                    if ('timestamp' not in msg and msg.get('role') == 'system') or
                       ('timestamp' in msg and (current_time - datetime.datetime.fromisoformat(msg['timestamp'])) < datetime.timedelta(minutes=15))
                ]
                file.seek(0)
                file.truncate()
                json.dump(filtered_history, file, indent=4, ensure_ascii=False)
        except Exception as e:
            print(f"更新聊天歷史時出錯: {e}")
        await asyncio.sleep(60)  # 每分鐘檢查一次

@bot.event
async def on_ready():
    print(f'已登錄為 {bot.user.name}')
    try:
        with open(chat_history_file, "r", encoding='utf-8') as file:
            print("聊天歷史文件已存在。")
    except FileNotFoundError:
        with open(chat_history_file, "w", encoding='utf-8') as file:
            json.dump([], file)
            print("已創建聊天歷史文件。")
    bot.loop.create_task(restart_bot(bot))
    bot.loop.create_task(clean_old_messages())  # 開始執行定期清理任務

@bot.event
async def on_message(message):
    if message.author == bot.user:
        return

    # 保存用戶消息
    save_message("user", str(message.author.id), message.content)

    # 加載聊天歷史，為API調用準備消息列表
    chat_history = load_chat_history()
    messages = [{"role": msg["role"], "content": msg["content"]} for msg in chat_history if "role" in msg and "content" in msg]
    messages.append({"role": "user", "content": message.content})

    try:
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=messages,
        )
        reply_text = response.choices[0].message['content'].strip()
        # 保存機器人的回復
        save_message("assistant", "AI", reply_text)
    except Exception as e:
        print(f'發生錯誤：{e}')
        reply_text = "抱歉發生錯誤，無法處理您的消息。"

    await message.channel.send(reply_text)

bot.run(discord_token)

```