mirror of
https://github.com/FuQuan233/nonebot-plugin-llmchat.git
synced 2026-02-05 19:48:06 +00:00
215 lines
9 KiB
Python
215 lines
9 KiB
Python
import json
|
||
import time
|
||
from typing import Any, cast
|
||
|
||
from nonebot import get_bot, logger
|
||
from nonebot.adapters.onebot.v11 import Bot
|
||
|
||
|
||
class OneBotTools:
|
||
"""内置的OneBot群操作工具类"""
|
||
|
||
def __init__(self):
|
||
self.tools = [
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__mute_user",
|
||
"description": "禁言指定用户一段时间。需要机器人有管理员权限。不能随便禁言成员,你应该听从管理员的指令。",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"user_id": {"type": "string", "description": "要禁言的用户QQ号"},
|
||
"duration": {
|
||
"type": "integer",
|
||
"description": "禁言时长(秒),0表示解除禁言,最大2592000(30天)",
|
||
"minimum": 0,
|
||
"maximum": 2592000,
|
||
},
|
||
},
|
||
"required": ["user_id", "duration"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__get_group_info",
|
||
"description": "获取群信息,包括群成员数量、群名称等。",
|
||
"parameters": {"type": "object", "properties": {}, "required": []},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__get_group_member_info",
|
||
"description": "获取指定群成员的信息。",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {"user_id": {"type": "string", "description": "要查询的用户QQ号"}},
|
||
"required": ["user_id"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__get_group_member_list",
|
||
"description": "获取群成员列表。",
|
||
"parameters": {"type": "object", "properties": {}, "required": []},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__poke_user",
|
||
"description": "戳一戳指定用户。",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {"user_id": {"type": "string", "description": "要戳一戳的用户QQ号"}},
|
||
"required": ["user_id"],
|
||
},
|
||
},
|
||
},
|
||
{
|
||
"type": "function",
|
||
"function": {
|
||
"name": "ob__recall_message",
|
||
"description": "撤回指定消息。需要机器人有管理员权限或者是消息发送者。",
|
||
"parameters": {
|
||
"type": "object",
|
||
"properties": {"message_id": {"type": "integer", "description": "要撤回的消息ID"}},
|
||
"required": ["message_id"],
|
||
},
|
||
},
|
||
},
|
||
]
|
||
|
||
def get_friendly_name(self, tool_name: str) -> str:
|
||
"""获取工具的友好名称"""
|
||
friendly_names = {
|
||
"ob__mute_user": "OneBot - 禁言用户",
|
||
"ob__get_group_info": "OneBot - 获取群信息",
|
||
"ob__get_group_member_info": "OneBot - 获取成员信息",
|
||
"ob__get_group_member_list": "OneBot - 获取成员列表",
|
||
"ob__poke_user": "OneBot - 戳一戳用户",
|
||
"ob__recall_message": "OneBot - 撤回消息",
|
||
}
|
||
return friendly_names.get(tool_name, tool_name)
|
||
|
||
def get_available_tools(self) -> list[dict[str, Any]]:
|
||
"""获取可用的工具列表"""
|
||
return self.tools
|
||
|
||
async def call_tool(self, tool_name: str, tool_args: dict[str, Any], group_id: int, bot_id: str) -> str:
|
||
"""调用指定的工具"""
|
||
try:
|
||
bot = cast(Bot, get_bot(bot_id))
|
||
|
||
if tool_name == "ob__mute_user":
|
||
return await self._mute_user(bot, group_id, tool_args)
|
||
elif tool_name == "ob__get_group_info":
|
||
return await self._get_group_info(bot, group_id, tool_args)
|
||
elif tool_name == "ob__get_group_member_info":
|
||
return await self._get_group_member_info(bot, group_id, tool_args)
|
||
elif tool_name == "ob__get_group_member_list":
|
||
return await self._get_group_member_list(bot, group_id, tool_args)
|
||
elif tool_name == "ob__poke_user":
|
||
return await self._poke_user(bot, group_id, tool_args)
|
||
elif tool_name == "ob__recall_message":
|
||
return await self._recall_message(bot, group_id, tool_args)
|
||
else:
|
||
return f"未知的工具: {tool_name}"
|
||
|
||
except Exception as e:
|
||
logger.error(f"调用OneBot工具 {tool_name} 时出错: {e}")
|
||
return f"执行失败: {e!s}"
|
||
|
||
async def _mute_user(self, bot: Bot, group_id: int, args: dict[str, Any]) -> str:
|
||
"""禁言用户"""
|
||
user_id = int(args["user_id"])
|
||
duration = args["duration"]
|
||
|
||
try:
|
||
await bot.set_group_ban(group_id=group_id, user_id=user_id, duration=duration)
|
||
if duration > 0:
|
||
return f"成功禁言用户 {user_id},时长 {duration} 秒"
|
||
else:
|
||
return f"成功解除用户 {user_id} 的禁言"
|
||
except Exception as e:
|
||
return f"禁言操作失败: {e!s}"
|
||
|
||
async def _get_group_info(self, bot: Bot, group_id: int, _args: dict[str, Any]) -> str:
|
||
"""获取群信息"""
|
||
try:
|
||
group_info = await bot.get_group_info(group_id=group_id)
|
||
info = {
|
||
"群号": group_info["group_id"],
|
||
"群名称": group_info["group_name"],
|
||
"群成员数": group_info["member_count"],
|
||
"群上限": group_info["max_member_count"],
|
||
}
|
||
return json.dumps(info, ensure_ascii=False, indent=2)
|
||
except Exception as e:
|
||
return f"获取群信息失败: {e!s}"
|
||
|
||
async def _get_group_member_info(self, bot: Bot, group_id: int, args: dict[str, Any]) -> str:
|
||
"""获取群成员信息"""
|
||
user_id = int(args["user_id"])
|
||
|
||
try:
|
||
member_info = await bot.get_group_member_info(group_id=group_id, user_id=user_id)
|
||
info = {
|
||
"用户QQ": member_info["user_id"],
|
||
"昵称": member_info["nickname"],
|
||
"群名片": member_info["card"],
|
||
"性别": member_info["sex"],
|
||
"年龄": member_info["age"],
|
||
"地区": member_info["area"],
|
||
"加群时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(member_info["join_time"])),
|
||
"最后发言时间": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(member_info["last_sent_time"])),
|
||
"群内等级": member_info["level"],
|
||
"角色": member_info["role"],
|
||
"专属头衔": member_info["title"],
|
||
}
|
||
return json.dumps(info, ensure_ascii=False, indent=2)
|
||
except Exception as e:
|
||
return f"获取成员信息失败: {e!s}"
|
||
|
||
async def _get_group_member_list(self, bot: Bot, group_id: int, _args: dict[str, Any]) -> str:
|
||
"""获取群成员列表"""
|
||
try:
|
||
member_list = await bot.get_group_member_list(group_id=group_id)
|
||
members = []
|
||
for member in member_list:
|
||
members.append(
|
||
{"QQ": member["user_id"], "昵称": member["nickname"], "群名片": member["card"], "角色": member["role"]}
|
||
)
|
||
|
||
result = {"群成员总数": len(members), "成员列表": members}
|
||
return json.dumps(result, ensure_ascii=False, indent=2)
|
||
except Exception as e:
|
||
return f"获取群成员列表失败: {e!s}"
|
||
|
||
async def _poke_user(self, bot: Bot, group_id: int, args: dict[str, Any]) -> str:
|
||
"""戳一戳用户"""
|
||
user_id = int(args["user_id"])
|
||
|
||
try:
|
||
# 使用OneBot的戳一戳API
|
||
await bot.call_api("group_poke", group_id=group_id, user_id=user_id)
|
||
return f"成功戳了戳用户 {user_id}"
|
||
except Exception as e:
|
||
return f"戳一戳失败: {e!s}"
|
||
|
||
async def _recall_message(self, bot: Bot, group_id: int, args: dict[str, Any]) -> str:
|
||
"""撤回消息"""
|
||
message_id = int(args["message_id"])
|
||
|
||
try:
|
||
await bot.delete_msg(message_id=message_id)
|
||
return f"成功撤回消息 {message_id}"
|
||
except Exception as e:
|
||
return f"撤回消息失败: {e!s}"
|
||
|
||
|