diff --git a/plugins/jd_sign_token/__init__.py b/plugins/jd_sign_token/__init__.py new file mode 100644 index 0000000..be4b20a --- /dev/null +++ b/plugins/jd_sign_token/__init__.py @@ -0,0 +1,7 @@ +# 从当前包的main模块导入JDTokenPlugin类 +from .main import JDTokenPlugin + +# 提供get_plugin函数,返回插件实例 +def get_plugin(): + """获取插件实例""" + return JDTokenPlugin() \ No newline at end of file diff --git a/plugins/jd_sign_token/config.toml b/plugins/jd_sign_token/config.toml new file mode 100644 index 0000000..6fdbe96 --- /dev/null +++ b/plugins/jd_sign_token/config.toml @@ -0,0 +1,7 @@ +[JD_Token] +enable = true +command = ["设置京东"] +command-format = """ +🔑京东签到Token设置指令: +设置京东 token内容 备注名称 +""" \ No newline at end of file diff --git a/plugins/jd_sign_token/config.yaml b/plugins/jd_sign_token/config.yaml new file mode 100644 index 0000000..297fe4e --- /dev/null +++ b/plugins/jd_sign_token/config.yaml @@ -0,0 +1,4 @@ +# 青龙面板配置 +QL_HOST: "http://192.168.2.32:5800" # 青龙面板地址,请根据实际情况修改 +CLIENT_ID: "g_jH014_iQhW" # 青龙面板应用ID,请填写实际值 +CLIENT_SECRET: "lSRhT-1Xs0lOEZ5YfKMMCkbl" # 青龙面板应用密钥,请填写实际值 \ No newline at end of file diff --git a/plugins/jd_sign_token/main.py b/plugins/jd_sign_token/main.py new file mode 100644 index 0000000..c5245b2 --- /dev/null +++ b/plugins/jd_sign_token/main.py @@ -0,0 +1,281 @@ +from loguru import logger +import requests +import re +import os +import yaml +from json import dumps as jsonDumps +from typing import Dict, Any, List, Optional, Tuple + +from plugin_common.message_plugin_interface import MessagePluginInterface +from plugin_common.plugin_interface import PluginStatus +from utils.decorator.plugin_decorators import plugin_stats_decorator +from utils.robot_cmd.robot_command import Feature, PermissionStatus, GroupBotManager +from utils.decorator.points_decorator import plugin_points_cost +from wechat_ipad import WechatAPIClient + + +class QL: + def __init__(self, address: str, id: str, secret: str) -> None: + """ + 初始化 + """ + self.address = address + self.id = id + self.secret = secret + self.valid = True + self.login() + + def log(self, content: str) -> None: + """ + 日志 + """ + print(content) + + def login(self) -> None: + """ + 登录 + """ + url = f"{self.address}/open/auth/token?client_id={self.id}&client_secret={self.secret}" + try: + rjson = requests.get(url).json() + if (rjson['code'] == 200): + self.auth = f"{rjson['data']['token_type']} {rjson['data']['token']}" + else: + self.log(f"登录失败:{rjson['message']}") + except Exception as e: + self.valid = False + self.log(f"登录失败:{str(e)}") + + def getEnvs(self) -> list: + """ + 获取环境变量 + """ + url = f"{self.address}/open/envs?searchValue=" + headers = {"Authorization": self.auth} + try: + rjson = requests.get(url, headers=headers).json() + if (rjson['code'] == 200): + return rjson['data'] + else: + self.log(f"获取环境变量失败:{rjson['message']}") + except Exception as e: + self.log(f"获取环境变量失败:{str(e)}") + + def deleteEnvs(self, ids: list) -> bool: + """ + 删除环境变量 + """ + url = f"{self.address}/open/envs" + headers = {"Authorization": self.auth, "content-type": "application/json"} + try: + rjson = requests.delete(url, headers=headers, data=jsonDumps(ids)).json() + if (rjson['code'] == 200): + self.log(f"删除环境变量成功:{len(ids)}") + return True + else: + self.log(f"删除环境变量失败:{rjson['message']}") + return False + except Exception as e: + self.log(f"删除环境变量失败:{str(e)}") + return False + + def addEnvs(self, envs: list) -> bool: + """ + 新建环境变量 + """ + url = f"{self.address}/open/envs" + headers = {"Authorization": self.auth, "content-type": "application/json"} + try: + rjson = requests.post(url, headers=headers, data=jsonDumps(envs)).json() + if (rjson['code'] == 200): + self.log(f"新建环境变量成功:{len(envs)}") + return True + else: + self.log(f"新建环境变量失败:{rjson['message']}") + return False + except Exception as e: + self.log(f"新建环境变量失败:{str(e)}") + return False + + def updateEnv(self, env: dict) -> bool: + """ + 更新环境变量 + """ + url = f"{self.address}/open/envs" + headers = {"Authorization": self.auth, "content-type": "application/json"} + try: + rjson = requests.put(url, headers=headers, data=jsonDumps(env)).json() + if (rjson['code'] == 200): + self.log(f"更新环境变量成功") + return True + else: + self.log(f"更新环境变量失败:{rjson['message']}") + return False + except Exception as e: + self.log(f"更新环境变量失败:{str(e)}") + return False + + +class JDTokenPlugin(MessagePluginInterface): + """京东签到Token设置插件""" + + @property + def name(self) -> str: + return "京东签到Token设置" + + @property + def version(self) -> str: + return "1.0.0" + + @property + def description(self) -> str: + return "提供京东签到Token设置功能,支持添加和更新Token" + + @property + def author(self) -> str: + return "Trae AI" + + @property + def command_prefix(self) -> Optional[str]: + return "" # 不需要前缀,直接匹配命令 + + @property + def commands(self) -> List[str]: + return self._commands + + def __init__(self): + super().__init__() + self.plugin_dir = os.path.dirname(os.path.abspath(__file__)) + self.config_path = os.path.join(self.plugin_dir, "config.yaml") + + def initialize(self, context: Dict[str, Any]) -> bool: + """初始化插件""" + self.LOG = logger + self.LOG.info(f"正在初始化 {self.name} 插件...") + + # 保存上下文对象 + self.event_system = context.get("event_system") + self.message_util = context.get("message_util") + + self._commands = self._config.get("JD_Token", {}).get("command", ["设置京东"]) + self.command_format = self._config.get("JD_Token", {}).get("command-format", "设置京东 token内容 备注名称") + self.enable = self._config.get("JD_Token", {}).get("enable", True) + + # 加载青龙面板配置 + self.load_config() + self.ql = QL(self.ql_config.get("QL_HOST"), self.ql_config.get("CLIENT_ID"), self.ql_config.get("CLIENT_SECRET")) + + self.LOG.info(f"[{self.name}] 插件初始化完成,指令:{self._commands}") + return True + + def load_config(self): + """加载配置""" + if os.path.exists(self.config_path): + with open(self.config_path, 'r', encoding='utf-8') as f: + self.ql_config = yaml.safe_load(f) + else: + # 默认配置 + self.ql_config = { + "QL_HOST": "http://localhost:5700", + "CLIENT_ID": "", + "CLIENT_SECRET": "" + } + # 保存默认配置 + with open(self.config_path, 'w', encoding='utf-8') as f: + yaml.dump(self.ql_config, f, default_flow_style=False, allow_unicode=True) + + def start(self) -> bool: + """启动插件""" + self.LOG.info(f"[{self.name}] 插件已启动") + self.status = PluginStatus.RUNNING + return True + + def stop(self) -> bool: + """停止插件""" + self.LOG.info(f"[{self.name}] 插件已停止") + self.status = PluginStatus.STOPPED + return True + + def can_process(self, message: Dict[str, Any]) -> bool: + """检查是否可以处理该消息""" + if not self.enable: + return False + + content = str(message.get("content", "")).strip() + command = content.split(" ")[0] + + return command in self._commands + + @plugin_stats_decorator(plugin_name="京东签到Token设置") + async def process_message(self, message: Dict[str, Any]) -> Tuple[bool, Optional[str]]: + """处理消息""" + content = str(message.get("content", "")).strip() + self.LOG.info(f"插件执行: {self.name}:{content}") + command = content.split(" ")[0] + sender = message.get("sender") + roomid = message.get("roomid", "") + gbm: GroupBotManager = message.get("gbm") + bot: WechatAPIClient = message.get("bot") + + # 检查命令格式 + pattern = r'^设置京东\s+([^\s]+)\s+(.+)$' + match = re.match(pattern, content) + + if not match: + await bot.send_text_message((roomid if roomid else sender), f"❌命令格式错误!\n{self.command_format}" + , sender) + return False, "命令格式错误" + + # 检查权限 + if roomid and gbm.get_group_permission(roomid, Feature.UTILITY) == PermissionStatus.DISABLED: + return False, "没有权限" + + # 提取token和备注 + token = match.group(1) + remark = match.group(2) + + try: + # 设置京东Token + result = self.set_jd_token(token, remark) + await bot.send_text_message((roomid if roomid else sender), result, sender) + return True, "处理成功" + + except Exception as e: + self.LOG.error(f"处理京东Token设置请求出错: {e}") + await bot.send_text_message((roomid if roomid else sender), f"❌处理出错: {str(e)}", sender) + return False, f"处理出错: {e}" + + def set_jd_token(self, token: str, remark: str) -> str: + """设置京东Token""" + if not self.ql.valid: + return f"❌ 青龙面板连接失败,请检查配置" + + # 检查是否已存在相同备注的环境变量 + envs = self.ql.getEnvs() + if not envs: + return f"❌ 获取环境变量失败" + + # 查找是否有相同备注的JD_COOKIE + existing_env = None + for env in envs: + if env.get('name') == 'JD_COOKIE' and env.get('remarks') == remark: + existing_env = env + break + + result = False + if existing_env: + # 更新已存在的环境变量 + existing_env['value'] = token + result = self.ql.updateEnv(existing_env) + if result: + return f"✅ 已成功更新京东账号 [{remark}] 的Token" + else: + return f"❌ 更新京东账号 [{remark}] 的Token失败" + else: + # 添加新的环境变量 + new_env = [{"name": "JD_COOKIE", "value": token, "remarks": remark}] + result = self.ql.addEnvs(new_env) + if result: + return f"✅ 已成功添加京东账号 [{remark}] 的Token" + else: + return f"❌ 添加京东账号 [{remark}] 的Token失败" \ No newline at end of file