nonebot-plugin-llmchat/nonebot_plugin_llmchat/onebottools.py

215 lines
9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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表示解除禁言最大259200030天",
"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}"