Automated backup - 20250717_000001
This commit is contained in:
32
discord_bot/ai_bots/ai_bot_1/Dockerfile
Normal file
32
discord_bot/ai_bots/ai_bot_1/Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置环境变量
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制requirements文件
|
||||
COPY requirements.txt .
|
||||
|
||||
# 安装Python依赖
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制应用代码
|
||||
COPY chatgpt_bot.py .
|
||||
|
||||
# 创建utils目录(会通过volume挂载)
|
||||
RUN mkdir -p utils
|
||||
|
||||
# 设置健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD python3 -c "import sys; sys.exit(0)"
|
||||
|
||||
# 运行应用
|
||||
CMD ["python3", "chatgpt_bot.py"]
|
||||
241
discord_bot/ai_bots/ai_bot_1/chatgpt_bot.py
Normal file
241
discord_bot/ai_bots/ai_bot_1/chatgpt_bot.py
Normal file
@@ -0,0 +1,241 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
ChatGPT Discord Bot
|
||||
===================
|
||||
|
||||
这个bot使用OpenAI的ChatGPT API来提供AI对话功能。
|
||||
支持多种ChatGPT模型,包括GPT-4o、GPT-4等。
|
||||
|
||||
主要功能:
|
||||
- /chat - 与ChatGPT对话
|
||||
- /model - 切换ChatGPT模型
|
||||
- /help - 显示帮助信息
|
||||
"""
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import openai
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(str(Path(__file__).parent.parent.parent))
|
||||
from utils.token_reader import TokenReader
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ChatGPTBot:
|
||||
"""ChatGPT Discord Bot主类"""
|
||||
|
||||
def __init__(self, token_path: str):
|
||||
self.token_path = token_path
|
||||
self.token_reader = TokenReader(token_path)
|
||||
|
||||
# 设置Discord权限
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
intents.guild_messages = True
|
||||
|
||||
# 创建bot实例
|
||||
self.bot = commands.Bot(
|
||||
command_prefix='!',
|
||||
intents=intents,
|
||||
help_command=None
|
||||
)
|
||||
|
||||
# 初始化OpenAI客户端
|
||||
self.openai_client = None
|
||||
self.current_model = "gpt-4o-mini-2024-07-18"
|
||||
|
||||
# 可用模型列表
|
||||
self.available_models = [
|
||||
"gpt-4o-mini-2024-07-18",
|
||||
"gpt-4o",
|
||||
"gpt-4-turbo",
|
||||
"gpt-3.5-turbo"
|
||||
]
|
||||
|
||||
self.setup_events()
|
||||
self.setup_commands()
|
||||
|
||||
def setup_events(self):
|
||||
"""设置事件处理器"""
|
||||
|
||||
@self.bot.event
|
||||
async def on_ready():
|
||||
logger.info(f'{self.bot.user} (ChatGPT Bot) 已连接到Discord!')
|
||||
if self.bot.user:
|
||||
logger.info(f'Bot ID: {self.bot.user.id}')
|
||||
|
||||
# 初始化OpenAI客户端
|
||||
try:
|
||||
api_key = self.token_reader.get_token('chatgpt_API')
|
||||
if not api_key:
|
||||
raise ValueError("无法读取chatgpt_API")
|
||||
|
||||
self.openai_client = openai.OpenAI(api_key=api_key)
|
||||
logger.info("OpenAI客户端初始化成功")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"初始化OpenAI客户端失败: {e}")
|
||||
|
||||
@self.bot.event
|
||||
async def on_message(message):
|
||||
if message.author == self.bot.user:
|
||||
return
|
||||
|
||||
if self.bot.user.mentioned_in(message):
|
||||
content = message.content.replace(f'<@{self.bot.user.id}>', '').replace(f'<@!{self.bot.user.id}>', '').strip()
|
||||
|
||||
if not content:
|
||||
help_text = """🤖 **ChatGPT Bot 帮助**
|
||||
|
||||
**使用方法:**
|
||||
• @chatgpt_o4 你的问题 - 与ChatGPT对话
|
||||
• @chatgpt_o4 model gpt-4o - 切换模型
|
||||
• @chatgpt_o4 help - 显示帮助
|
||||
|
||||
**可用模型:**
|
||||
• gpt-4o-mini-2024-07-18 (默认)
|
||||
• gpt-4o
|
||||
• gpt-4-turbo
|
||||
• gpt-3.5-turbo
|
||||
|
||||
**当前模型:** {}
|
||||
**状态:** ✅ 在线""".format(self.current_model)
|
||||
await message.reply(help_text)
|
||||
return
|
||||
|
||||
if content.lower().startswith('help'):
|
||||
help_text = """🤖 **ChatGPT Bot 帮助**
|
||||
|
||||
**使用方法:**
|
||||
• @chatgpt_o4 你的问题 - 与ChatGPT对话
|
||||
• @chatgpt_o4 model gpt-4o - 切换模型
|
||||
• @chatgpt_o4 help - 显示帮助
|
||||
|
||||
**可用模型:**
|
||||
• gpt-4o-mini-2024-07-18 (默认)
|
||||
• gpt-4o
|
||||
• gpt-4-turbo
|
||||
• gpt-3.5-turbo
|
||||
|
||||
**当前模型:** {}
|
||||
**状态:** ✅ 在线""".format(self.current_model)
|
||||
await message.reply(help_text)
|
||||
return
|
||||
|
||||
if content.lower().startswith('model '):
|
||||
model = content[6:].strip()
|
||||
if model in self.available_models:
|
||||
old_model = self.current_model
|
||||
self.current_model = model
|
||||
await message.reply(f"✅ 模型已从 `{old_model}` 切换到 `{model}`")
|
||||
else:
|
||||
model_list = "\n".join([f"• {m}" for m in self.available_models])
|
||||
await message.reply(f"❌ 不支持的模型。可用模型:\n{model_list}")
|
||||
return
|
||||
|
||||
try:
|
||||
if not self.openai_client:
|
||||
await message.reply("❌ OpenAI客户端未初始化")
|
||||
return
|
||||
|
||||
typing_task = asyncio.create_task(self.start_typing(message.channel))
|
||||
|
||||
response = self.openai_client.chat.completions.create(
|
||||
model=self.current_model,
|
||||
messages=[
|
||||
{"role": "system", "content": "你是一个有用的AI助手。请用中文回答问题。"},
|
||||
{"role": "user", "content": content}
|
||||
],
|
||||
max_tokens=2000,
|
||||
temperature=0.7
|
||||
)
|
||||
|
||||
typing_task.cancel()
|
||||
|
||||
ai_response = response.choices[0].message.content
|
||||
await self.send_long_message(message, f"🤖 **ChatGPT ({self.current_model})**\n\n{ai_response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"ChatGPT调用错误: {e}")
|
||||
await message.reply(f"❌ ChatGPT API调用失败: {str(e)}")
|
||||
|
||||
@self.bot.event
|
||||
async def on_command_error(ctx, error):
|
||||
logger.error(f"命令错误: {error}")
|
||||
await ctx.send(f"执行命令时出错: {str(error)}")
|
||||
|
||||
async def start_typing(self, channel):
|
||||
"""持续显示正在输入状态"""
|
||||
try:
|
||||
while True:
|
||||
async with channel.typing():
|
||||
await asyncio.sleep(5)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
def setup_commands(self):
|
||||
"""保留slash commands作为备用"""
|
||||
pass
|
||||
|
||||
async def send_long_message(self, message, response: str):
|
||||
"""分段发送长回复到消息"""
|
||||
max_length = 2000
|
||||
|
||||
if len(response) <= max_length:
|
||||
await message.reply(response)
|
||||
return
|
||||
|
||||
# 分段处理
|
||||
parts = []
|
||||
current_part = ""
|
||||
|
||||
for line in response.split('\n'):
|
||||
if len(current_part) + len(line) + 1 > max_length:
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
current_part = line
|
||||
else:
|
||||
if current_part:
|
||||
current_part += '\n' + line
|
||||
else:
|
||||
current_part = line
|
||||
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
|
||||
# 发送所有部分
|
||||
if parts:
|
||||
await message.reply(parts[0])
|
||||
for part in parts[1:]:
|
||||
await message.channel.send(part)
|
||||
|
||||
async def start(self):
|
||||
"""启动bot"""
|
||||
try:
|
||||
token = self.token_reader.get_token('chatgpt_discord_token')
|
||||
if not token:
|
||||
raise ValueError("无法读取chatgpt_discord_token")
|
||||
|
||||
logger.info("启动ChatGPT Bot...")
|
||||
await self.bot.start(token)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"启动Bot失败: {e}")
|
||||
raise
|
||||
|
||||
async def main():
|
||||
"""主函数"""
|
||||
bot = ChatGPTBot("/home/will/docker/tokens.txt")
|
||||
await bot.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
4
discord_bot/ai_bots/ai_bot_1/requirements.txt
Normal file
4
discord_bot/ai_bots/ai_bot_1/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
discord.py>=2.3.0
|
||||
openai>=1.0.0
|
||||
asyncio
|
||||
pathlib
|
||||
32
discord_bot/ai_bots/ai_bot_2/Dockerfile
Normal file
32
discord_bot/ai_bots/ai_bot_2/Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置环境变量
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制requirements文件
|
||||
COPY requirements.txt .
|
||||
|
||||
# 安装Python依赖
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制应用代码
|
||||
COPY deepseek_bot.py .
|
||||
|
||||
# 创建utils目录(会通过volume挂载)
|
||||
RUN mkdir -p utils
|
||||
|
||||
# 设置健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD python3 -c "import sys; sys.exit(0)"
|
||||
|
||||
# 运行应用
|
||||
CMD ["python3", "deepseek_bot.py"]
|
||||
253
discord_bot/ai_bots/ai_bot_2/deepseek_bot.py
Normal file
253
discord_bot/ai_bots/ai_bot_2/deepseek_bot.py
Normal file
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
DeepSeek Discord Bot
|
||||
====================
|
||||
|
||||
这个bot使用DeepSeek的AI API来提供智能对话功能。
|
||||
DeepSeek是一个优秀的中文AI模型,特别擅长代码和推理任务。
|
||||
|
||||
主要功能:
|
||||
- /deepseek - 与DeepSeek AI对话
|
||||
- /code - 代码相关问题(DeepSeek的强项)
|
||||
- /help - 显示帮助信息
|
||||
"""
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import httpx
|
||||
import asyncio
|
||||
import logging
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(str(Path(__file__).parent.parent.parent))
|
||||
from utils.token_reader import TokenReader
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DeepSeekBot:
|
||||
"""DeepSeek Discord Bot主类"""
|
||||
|
||||
def __init__(self, token_path: str):
|
||||
self.token_path = token_path
|
||||
self.token_reader = TokenReader(token_path)
|
||||
|
||||
# 设置Discord权限
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
intents.guild_messages = True
|
||||
|
||||
# 创建bot实例
|
||||
self.bot = commands.Bot(
|
||||
command_prefix='!',
|
||||
intents=intents,
|
||||
help_command=None
|
||||
)
|
||||
|
||||
# DeepSeek API配置
|
||||
self.api_key = None
|
||||
self.base_url = "https://api.deepseek.com/v1/chat/completions"
|
||||
self.model = "deepseek-chat"
|
||||
|
||||
self.setup_events()
|
||||
self.setup_commands()
|
||||
|
||||
def setup_events(self):
|
||||
"""设置事件处理器"""
|
||||
|
||||
@self.bot.event
|
||||
async def on_ready():
|
||||
logger.info(f'{self.bot.user} (DeepSeek Bot) 已连接到Discord!')
|
||||
if self.bot.user:
|
||||
logger.info(f'Bot ID: {self.bot.user.id}')
|
||||
|
||||
# 初始化API密钥
|
||||
try:
|
||||
self.api_key = self.token_reader.get_token('deepseek_API')
|
||||
if not self.api_key:
|
||||
raise ValueError("无法读取deepseek_API")
|
||||
|
||||
logger.info("DeepSeek API密钥加载成功")
|
||||
|
||||
# 同步slash commands
|
||||
synced = await self.bot.tree.sync()
|
||||
logger.info(f"同步了 {len(synced)} 个slash commands")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"初始化DeepSeek API失败: {e}")
|
||||
|
||||
@self.bot.event
|
||||
async def on_command_error(ctx, error):
|
||||
logger.error(f"命令错误: {error}")
|
||||
if isinstance(error, commands.CommandNotFound):
|
||||
await ctx.send("未知命令,请使用 /help 查看可用命令")
|
||||
else:
|
||||
await ctx.send(f"执行命令时出错: {str(error)}")
|
||||
|
||||
def setup_commands(self):
|
||||
"""设置slash commands"""
|
||||
|
||||
@self.bot.tree.command(name="deepseek", description="与DeepSeek AI对话")
|
||||
async def deepseek_command(interaction: discord.Interaction, message: str):
|
||||
"""处理DeepSeek聊天命令"""
|
||||
try:
|
||||
await interaction.response.defer(thinking=True)
|
||||
|
||||
if not self.api_key:
|
||||
await interaction.followup.send("❌ DeepSeek API未初始化")
|
||||
return
|
||||
|
||||
# 调用DeepSeek API
|
||||
response = await self.call_deepseek_api(message)
|
||||
|
||||
# 分段发送长回复
|
||||
await self.send_long_response(interaction, f"🧠 **DeepSeek AI**\\n\\n{response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"DeepSeek命令错误: {e}")
|
||||
await interaction.followup.send(f"❌ DeepSeek API调用失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="code", description="向DeepSeek请教代码问题")
|
||||
async def code_command(interaction: discord.Interaction, question: str):
|
||||
"""处理代码相关问题"""
|
||||
try:
|
||||
await interaction.response.defer(thinking=True)
|
||||
|
||||
if not self.api_key:
|
||||
await interaction.followup.send("❌ DeepSeek API未初始化")
|
||||
return
|
||||
|
||||
# 为代码问题添加特殊提示
|
||||
code_prompt = f"""你是一个专业的程序员和代码导师。请帮我解答以下代码相关的问题,提供清晰的解释和示例代码:
|
||||
|
||||
{question}
|
||||
|
||||
请用中文回答,并在适当的地方提供代码示例。"""
|
||||
|
||||
response = await self.call_deepseek_api(code_prompt)
|
||||
|
||||
# 分段发送长回复
|
||||
await self.send_long_response(interaction, f"💻 **DeepSeek Code Expert**\\n\\n{response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Code命令错误: {e}")
|
||||
await interaction.followup.send(f"❌ DeepSeek Code API调用失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="help", description="显示DeepSeek Bot帮助信息")
|
||||
async def help_command(interaction: discord.Interaction):
|
||||
"""显示帮助信息"""
|
||||
help_text = """🧠 **DeepSeek Bot 帮助**
|
||||
|
||||
**主要命令:**
|
||||
• `/deepseek <message>` - 与DeepSeek AI对话
|
||||
• `/code <question>` - 向DeepSeek请教代码问题
|
||||
• `/help` - 显示此帮助信息
|
||||
|
||||
**DeepSeek特色:**
|
||||
• 🧠 强大的推理能力
|
||||
• 💻 优秀的代码理解和生成
|
||||
• 🔍 深度思考和分析
|
||||
• 🇨🇳 优秀的中文理解
|
||||
|
||||
**使用示例:**
|
||||
• `/deepseek 请解释一下量子计算的基本原理`
|
||||
• `/code 如何在Python中实现单例模式?`
|
||||
• `/deepseek 帮我分析这个算法的时间复杂度`
|
||||
|
||||
**模型:** `deepseek-chat`
|
||||
**状态:** ✅ 在线"""
|
||||
|
||||
await interaction.response.send_message(help_text)
|
||||
|
||||
async def call_deepseek_api(self, message: str) -> str:
|
||||
"""调用DeepSeek API"""
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
payload = {
|
||||
"model": self.model,
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "你是DeepSeek AI,一个有用、无害、诚实的人工智能助手。请用中文回答问题,提供准确和有帮助的信息。"
|
||||
},
|
||||
{"role": "user", "content": message}
|
||||
],
|
||||
"max_tokens": 2000,
|
||||
"temperature": 0.7,
|
||||
"stream": False
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(
|
||||
self.base_url,
|
||||
headers=headers,
|
||||
json=payload,
|
||||
timeout=60.0
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
result = response.json()
|
||||
return result["choices"][0]["message"]["content"]
|
||||
|
||||
async def send_long_response(self, interaction: discord.Interaction, response: str):
|
||||
"""分段发送长响应"""
|
||||
max_length = 2000
|
||||
|
||||
if len(response) <= max_length:
|
||||
await interaction.followup.send(response)
|
||||
return
|
||||
|
||||
# 分段处理
|
||||
parts = []
|
||||
current_part = ""
|
||||
|
||||
for line in response.split('\\n'):
|
||||
if len(current_part) + len(line) + 1 > max_length:
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
current_part = line
|
||||
else:
|
||||
if current_part:
|
||||
current_part += '\\n' + line
|
||||
else:
|
||||
current_part = line
|
||||
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
|
||||
# 发送所有部分
|
||||
if parts:
|
||||
await interaction.followup.send(parts[0])
|
||||
for part in parts[1:]:
|
||||
await interaction.followup.send(part)
|
||||
|
||||
async def start(self):
|
||||
"""启动bot"""
|
||||
try:
|
||||
token = self.token_reader.get_token('deepseek_discord_token')
|
||||
if not token:
|
||||
raise ValueError("无法读取deepseek_discord_token")
|
||||
|
||||
logger.info("启动DeepSeek Bot...")
|
||||
await self.bot.start(token)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"启动Bot失败: {e}")
|
||||
raise
|
||||
|
||||
async def main():
|
||||
"""主函数"""
|
||||
bot = DeepSeekBot("/home/will/docker/tokens.txt")
|
||||
await bot.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
4
discord_bot/ai_bots/ai_bot_2/requirements.txt
Normal file
4
discord_bot/ai_bots/ai_bot_2/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
discord.py>=2.3.0
|
||||
httpx>=0.25.0
|
||||
asyncio
|
||||
pathlib
|
||||
32
discord_bot/ai_bots/ai_bot_3/Dockerfile
Normal file
32
discord_bot/ai_bots/ai_bot_3/Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置环境变量
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# 安装系统依赖
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 复制requirements文件
|
||||
COPY requirements.txt .
|
||||
|
||||
# 安装Python依赖
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# 复制应用代码
|
||||
COPY claude_bot.py .
|
||||
|
||||
# 创建utils目录(会通过volume挂载)
|
||||
RUN mkdir -p utils
|
||||
|
||||
# 设置健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD python3 -c "import sys; sys.exit(0)"
|
||||
|
||||
# 运行应用
|
||||
CMD ["python3", "claude_bot.py"]
|
||||
316
discord_bot/ai_bots/ai_bot_3/claude_bot.py
Normal file
316
discord_bot/ai_bots/ai_bot_3/claude_bot.py
Normal file
@@ -0,0 +1,316 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Claude Discord Bot
|
||||
==================
|
||||
|
||||
这个bot使用Anthropic的Claude API来提供AI对话功能。
|
||||
Claude以其安全性、有用性和诚实性而闻名。
|
||||
|
||||
主要功能:
|
||||
- /claude - 与Claude AI对话
|
||||
- /analyze - 深度分析问题(Claude的强项)
|
||||
- /creative - 创意写作和头脑风暴
|
||||
- /help - 显示帮助信息
|
||||
"""
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import asyncio
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
from anthropic import Anthropic
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(str(Path(__file__).parent.parent.parent))
|
||||
from utils.token_reader import TokenReader
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ClaudeBot:
|
||||
"""Claude Discord Bot主类"""
|
||||
|
||||
def __init__(self, token_path: str):
|
||||
self.token_path = token_path
|
||||
self.token_reader = TokenReader(token_path)
|
||||
|
||||
# 设置Discord权限
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
intents.guild_messages = True
|
||||
|
||||
# 创建bot实例
|
||||
self.bot = commands.Bot(
|
||||
command_prefix='!',
|
||||
intents=intents,
|
||||
help_command=None
|
||||
)
|
||||
|
||||
# 初始化Claude客户端
|
||||
self.claude_client = None
|
||||
self.current_model = "claude-3-sonnet-20240229"
|
||||
|
||||
# 可用模型列表
|
||||
self.available_models = [
|
||||
"claude-3-sonnet-20240229",
|
||||
"claude-3-haiku-20240307",
|
||||
"claude-3-opus-20240229"
|
||||
]
|
||||
|
||||
self.setup_events()
|
||||
self.setup_commands()
|
||||
|
||||
def setup_events(self):
|
||||
"""设置事件处理器"""
|
||||
|
||||
@self.bot.event
|
||||
async def on_ready():
|
||||
logger.info(f'{self.bot.user} (Claude Bot) 已连接到Discord!')
|
||||
if self.bot.user:
|
||||
logger.info(f'Bot ID: {self.bot.user.id}')
|
||||
|
||||
# 初始化Claude客户端
|
||||
try:
|
||||
api_key = self.token_reader.get_token('claude_API')
|
||||
if not api_key:
|
||||
raise ValueError("无法读取claude_API")
|
||||
|
||||
self.claude_client = Anthropic(api_key=api_key)
|
||||
logger.info("Claude客户端初始化成功")
|
||||
|
||||
# 同步slash commands
|
||||
synced = await self.bot.tree.sync()
|
||||
logger.info(f"同步了 {len(synced)} 个slash commands")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"初始化Claude客户端失败: {e}")
|
||||
|
||||
@self.bot.event
|
||||
async def on_command_error(ctx, error):
|
||||
logger.error(f"命令错误: {error}")
|
||||
if isinstance(error, commands.CommandNotFound):
|
||||
await ctx.send("未知命令,请使用 /help 查看可用命令")
|
||||
else:
|
||||
await ctx.send(f"执行命令时出错: {str(error)}")
|
||||
|
||||
def setup_commands(self):
|
||||
"""设置slash commands"""
|
||||
|
||||
@self.bot.tree.command(name="claude", description="与Claude AI对话")
|
||||
async def claude_command(interaction: discord.Interaction, message: str):
|
||||
"""处理Claude聊天命令"""
|
||||
try:
|
||||
await interaction.response.defer(thinking=True)
|
||||
|
||||
if not self.claude_client:
|
||||
await interaction.followup.send("❌ Claude客户端未初始化")
|
||||
return
|
||||
|
||||
# 调用Claude API
|
||||
response = await asyncio.to_thread(
|
||||
self.claude_client.messages.create,
|
||||
model=self.current_model,
|
||||
max_tokens=2000,
|
||||
messages=[
|
||||
{"role": "user", "content": message}
|
||||
]
|
||||
)
|
||||
|
||||
ai_response = response.content[0].text
|
||||
|
||||
# 分段发送长回复
|
||||
await self.send_long_response(interaction, f"🎭 **Claude ({self.current_model})**\\n\\n{ai_response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Claude命令错误: {e}")
|
||||
await interaction.followup.send(f"❌ Claude API调用失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="analyze", description="使用Claude进行深度分析")
|
||||
async def analyze_command(interaction: discord.Interaction, topic: str):
|
||||
"""处理分析命令"""
|
||||
try:
|
||||
await interaction.response.defer(thinking=True)
|
||||
|
||||
if not self.claude_client:
|
||||
await interaction.followup.send("❌ Claude客户端未初始化")
|
||||
return
|
||||
|
||||
# 分析提示词
|
||||
analysis_prompt = f"""请对以下主题进行深度分析:
|
||||
|
||||
{topic}
|
||||
|
||||
请从多个角度进行分析,包括但不限于:
|
||||
1. 背景和现状
|
||||
2. 关键要素和影响因素
|
||||
3. 潜在的机会和挑战
|
||||
4. 可能的解决方案或建议
|
||||
5. 未来的发展趋势
|
||||
|
||||
请提供详细、有条理的分析。"""
|
||||
|
||||
response = await asyncio.to_thread(
|
||||
self.claude_client.messages.create,
|
||||
model=self.current_model,
|
||||
max_tokens=3000,
|
||||
messages=[
|
||||
{"role": "user", "content": analysis_prompt}
|
||||
]
|
||||
)
|
||||
|
||||
ai_response = response.content[0].text
|
||||
|
||||
# 分段发送长回复
|
||||
await self.send_long_response(interaction, f"🔍 **Claude 深度分析**\\n\\n{ai_response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"分析命令错误: {e}")
|
||||
await interaction.followup.send(f"❌ Claude 分析失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="creative", description="使用Claude进行创意写作")
|
||||
async def creative_command(interaction: discord.Interaction, prompt: str):
|
||||
"""处理创意写作命令"""
|
||||
try:
|
||||
await interaction.response.defer(thinking=True)
|
||||
|
||||
if not self.claude_client:
|
||||
await interaction.followup.send("❌ Claude客户端未初始化")
|
||||
return
|
||||
|
||||
# 创意写作提示词
|
||||
creative_prompt = f"""作为一个富有创意的作家,请根据以下提示进行创意写作:
|
||||
|
||||
{prompt}
|
||||
|
||||
请发挥你的想象力,创作出有趣、引人入胜的内容。可以是故事、诗歌、对话、或任何其他创意形式。注重创意性、情感表达和文学性。"""
|
||||
|
||||
response = await asyncio.to_thread(
|
||||
self.claude_client.messages.create,
|
||||
model=self.current_model,
|
||||
max_tokens=2500,
|
||||
messages=[
|
||||
{"role": "user", "content": creative_prompt}
|
||||
]
|
||||
)
|
||||
|
||||
ai_response = response.content[0].text
|
||||
|
||||
# 分段发送长回复
|
||||
await self.send_long_response(interaction, f"✨ **Claude 创意工坊**\\n\\n{ai_response}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创意命令错误: {e}")
|
||||
await interaction.followup.send(f"❌ Claude 创意写作失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="model", description="切换Claude模型")
|
||||
async def model_command(interaction: discord.Interaction, model: str):
|
||||
"""切换模型命令"""
|
||||
try:
|
||||
if model not in self.available_models:
|
||||
model_list = "\\n".join([f"• {m}" for m in self.available_models])
|
||||
await interaction.response.send_message(
|
||||
f"❌ 不支持的模型。可用模型:\\n{model_list}"
|
||||
)
|
||||
return
|
||||
|
||||
old_model = self.current_model
|
||||
self.current_model = model
|
||||
|
||||
await interaction.response.send_message(
|
||||
f"✅ 模型已从 `{old_model}` 切换到 `{model}`"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"模型切换错误: {e}")
|
||||
await interaction.response.send_message(f"❌ 切换模型失败: {str(e)}")
|
||||
|
||||
@self.bot.tree.command(name="help", description="显示Claude Bot帮助信息")
|
||||
async def help_command(interaction: discord.Interaction):
|
||||
"""显示帮助信息"""
|
||||
help_text = """🎭 **Claude Bot 帮助**
|
||||
|
||||
**主要命令:**
|
||||
• `/claude <message>` - 与Claude AI对话
|
||||
• `/analyze <topic>` - 深度分析主题
|
||||
• `/creative <prompt>` - 创意写作
|
||||
• `/model <model_name>` - 切换Claude模型
|
||||
• `/help` - 显示此帮助信息
|
||||
|
||||
**可用模型:**
|
||||
• `claude-3-sonnet-20240229` (默认,平衡性能)
|
||||
• `claude-3-haiku-20240307` (快速响应)
|
||||
• `claude-3-opus-20240229` (最强推理)
|
||||
|
||||
**Claude特色:**
|
||||
• 🎭 安全、有用、诚实
|
||||
• 🔍 强大的分析能力
|
||||
• ✨ 出色的创意写作
|
||||
• 🧠 逻辑推理和问题解决
|
||||
|
||||
**使用示例:**
|
||||
• `/claude 你好,请介绍一下你自己`
|
||||
• `/analyze 人工智能的发展趋势`
|
||||
• `/creative 写一个关于时间旅行的短故事`
|
||||
|
||||
**当前模型:** `{}`
|
||||
**状态:** ✅ 在线""".format(self.current_model)
|
||||
|
||||
await interaction.response.send_message(help_text)
|
||||
|
||||
async def send_long_response(self, interaction: discord.Interaction, response: str):
|
||||
"""分段发送长响应"""
|
||||
max_length = 2000
|
||||
|
||||
if len(response) <= max_length:
|
||||
await interaction.followup.send(response)
|
||||
return
|
||||
|
||||
# 分段处理
|
||||
parts = []
|
||||
current_part = ""
|
||||
|
||||
for line in response.split('\\n'):
|
||||
if len(current_part) + len(line) + 1 > max_length:
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
current_part = line
|
||||
else:
|
||||
if current_part:
|
||||
current_part += '\\n' + line
|
||||
else:
|
||||
current_part = line
|
||||
|
||||
if current_part:
|
||||
parts.append(current_part)
|
||||
|
||||
# 发送所有部分
|
||||
if parts:
|
||||
await interaction.followup.send(parts[0])
|
||||
for part in parts[1:]:
|
||||
await interaction.followup.send(part)
|
||||
|
||||
async def start(self):
|
||||
"""启动bot"""
|
||||
try:
|
||||
token = self.token_reader.get_token('claude_discord_token')
|
||||
if not token:
|
||||
raise ValueError("无法读取claude_discord_token")
|
||||
|
||||
logger.info("启动Claude Bot...")
|
||||
await self.bot.start(token)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"启动Bot失败: {e}")
|
||||
raise
|
||||
|
||||
async def main():
|
||||
"""主函数"""
|
||||
bot = ClaudeBot("/home/will/docker/tokens.txt")
|
||||
await bot.start()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
4
discord_bot/ai_bots/ai_bot_3/requirements.txt
Normal file
4
discord_bot/ai_bots/ai_bot_3/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
discord.py>=2.3.0
|
||||
anthropic>=0.28.0
|
||||
asyncio
|
||||
pathlib
|
||||
76
discord_bot/ai_bots/docker-compose.yml
Normal file
76
discord_bot/ai_bots/docker-compose.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# ChatGPT Bot - OpenAI AI对话机器人
|
||||
chatgpt-bot:
|
||||
build:
|
||||
context: ./ai_bot_1
|
||||
dockerfile: Dockerfile
|
||||
container_name: chatgpt-discord-bot
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../../tokens.txt:/home/will/docker/tokens.txt:ro
|
||||
- ../utils:/app/utils:ro
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
networks:
|
||||
- ai-bots-network
|
||||
depends_on:
|
||||
- deepseek-bot
|
||||
healthcheck:
|
||||
test: ["CMD", "python3", "-c", "import sys; sys.exit(0)"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
# DeepSeek Bot - DeepSeek AI对话机器人
|
||||
deepseek-bot:
|
||||
build:
|
||||
context: ./ai_bot_2
|
||||
dockerfile: Dockerfile
|
||||
container_name: deepseek-discord-bot
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../../tokens.txt:/home/will/docker/tokens.txt:ro
|
||||
- ../utils:/app/utils:ro
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
networks:
|
||||
- ai-bots-network
|
||||
healthcheck:
|
||||
test: ["CMD", "python3", "-c", "import sys; sys.exit(0)"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
# Claude Bot - Claude AI对话机器人
|
||||
claude-bot:
|
||||
build:
|
||||
context: ./ai_bot_3
|
||||
dockerfile: Dockerfile
|
||||
container_name: claude-discord-bot
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ../../tokens.txt:/home/will/docker/tokens.txt:ro
|
||||
- ../utils:/app/utils:ro
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
networks:
|
||||
- ai-bots-network
|
||||
depends_on:
|
||||
- deepseek-bot
|
||||
healthcheck:
|
||||
test: ["CMD", "python3", "-c", "import sys; sys.exit(0)"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
|
||||
networks:
|
||||
ai-bots-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
ai_bots_logs:
|
||||
65
discord_bot/ai_bots/test_bots.py
Normal file
65
discord_bot/ai_bots/test_bots.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
测试AI Bots状态
|
||||
"""
|
||||
import asyncio
|
||||
import discord
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 添加项目根目录到Python路径
|
||||
sys.path.append(str(Path(__file__).parent.parent))
|
||||
from utils.token_reader import TokenReader
|
||||
|
||||
async def test_bot_connection(token, bot_name):
|
||||
"""测试bot连接状态"""
|
||||
try:
|
||||
intents = discord.Intents.default()
|
||||
client = discord.Client(intents=intents)
|
||||
|
||||
@client.event
|
||||
async def on_ready():
|
||||
print(f"✅ {bot_name} 连接成功!")
|
||||
print(f" Bot名称: {client.user}")
|
||||
print(f" Bot ID: {client.user.id}")
|
||||
print(f" 在 {len(client.guilds)} 个服务器中")
|
||||
|
||||
for guild in client.guilds:
|
||||
print(f" - {guild.name} (ID: {guild.id})")
|
||||
|
||||
await client.close()
|
||||
|
||||
await client.start(token)
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ {bot_name} 连接失败: {e}")
|
||||
|
||||
async def main():
|
||||
"""主函数"""
|
||||
token_reader = TokenReader("/home/will/docker/tokens.txt")
|
||||
|
||||
print("🤖 测试AI Bots连接状态...")
|
||||
print("=" * 50)
|
||||
|
||||
# 测试ChatGPT Bot
|
||||
chatgpt_token = token_reader.get_token('chatgpt_discord_token')
|
||||
if chatgpt_token:
|
||||
await test_bot_connection(chatgpt_token, "ChatGPT Bot")
|
||||
|
||||
print()
|
||||
|
||||
# 测试DeepSeek Bot
|
||||
deepseek_token = token_reader.get_token('deepseek_discord_token')
|
||||
if deepseek_token:
|
||||
await test_bot_connection(deepseek_token, "DeepSeek Bot")
|
||||
|
||||
print()
|
||||
|
||||
# 测试Claude Bot
|
||||
claude_token = token_reader.get_token('claude_discord_token')
|
||||
if claude_token:
|
||||
await test_bot_connection(claude_token, "Claude Bot")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Binary file not shown.
Reference in New Issue
Block a user