diff --git a/channel/dingtalk/dingtalk_message.py b/channel/dingtalk/dingtalk_message.py index ef9dc96..8a19cdc 100644 --- a/channel/dingtalk/dingtalk_message.py +++ b/channel/dingtalk/dingtalk_message.py @@ -32,13 +32,13 @@ class DingTalkMessage(ChatMessage): # 钉钉支持直接识别语音,所以此处将直接提取文字,当文字处理 self.content = event.extensions['content']['recognition'].strip() self.ctype = ContextType.TEXT - self.from_user_id = event.sender_id + if self.is_group: + self.from_user_id = event.conversation_id + self.actual_user_id = event.sender_id + else: + self.from_user_id = event.sender_id self.to_user_id = event.chatbot_user_id self.other_user_nickname = event.conversation_title user_id = event.sender_id nickname =event.sender_nick - - - - diff --git a/common/linkai_client.py b/common/linkai_client.py index ad7d213..8112f19 100644 --- a/common/linkai_client.py +++ b/common/linkai_client.py @@ -2,12 +2,13 @@ from bridge.context import Context, ContextType from bridge.reply import Reply, ReplyType from common.log import logger from linkai import LinkAIClient, PushMsg -from config import conf, pconf, plugin_config +from config import conf, pconf, plugin_config, load_config from plugins import PluginManager chat_client: LinkAIClient + class ChatClient(LinkAIClient): def __init__(self, api_key, host, channel): super().__init__(api_key, host) @@ -27,29 +28,65 @@ class ChatClient(LinkAIClient): def on_config(self, config: dict): if not self.client_id: return - logger.info(f"从控制台加载配置: {config}") + logger.info(f"[LinkAI] 从客户端管理加载远程配置: {config}") + if config.get("enabled") != "Y": + return + local_config = conf() for key in local_config.keys(): if config.get(key) is not None: local_config[key] = config.get(key) - if config.get("reply_voice_mode"): - if config.get("reply_voice_mode") == "voice_reply_voice": + + # 语音配置 + reply_voice_mode = config.get("reply_voice_mode") + if reply_voice_mode: + if reply_voice_mode == "voice_reply_voice": local_config["voice_reply_voice"] = True - elif config.get("reply_voice_mode") == "always_reply_voice": + elif reply_voice_mode == "always_reply_voice": local_config["always_reply_voice"] = True - # if config.get("admin_password") and plugin_config["Godcmd"]: - # plugin_config["Godcmd"]["password"] = config.get("admin_password") - # PluginManager().instances["Godcmd"].reload() - # if config.get("group_app_map") and pconf("linkai"): - # local_group_map = {} - # for mapping in config.get("group_app_map"): - # local_group_map[mapping.get("group_name")] = mapping.get("app_code") - # pconf("linkai")["group_app_map"] = local_group_map - # PluginManager().instances["linkai"].reload() + + if config.get("admin_password") and plugin_config["Godcmd"]: + plugin_config["Godcmd"]["password"] = config.get("admin_password") + PluginManager().instances["GODCMD"].reload() + + if config.get("group_app_map") and pconf("linkai"): + local_group_map = {} + for mapping in config.get("group_app_map"): + local_group_map[mapping.get("group_name")] = mapping.get("app_code") + pconf("linkai")["group_app_map"] = local_group_map + PluginManager().instances["LINKAI"].reload() def start(channel): global chat_client chat_client = ChatClient(api_key=conf().get("linkai_api_key"), host="link-ai.chat", channel=channel) + chat_client.config = _build_config() chat_client.start() + + +def _build_config(): + local_conf = conf() + config = { + "linkai_app_code": local_conf.get("linkai_app_code"), + "single_chat_prefix": local_conf.get("single_chat_prefix"), + "single_chat_reply_prefix": local_conf.get("single_chat_reply_prefix"), + "single_chat_reply_suffix": local_conf.get("single_chat_reply_suffix"), + "group_chat_prefix": local_conf.get("group_chat_prefix"), + "group_chat_reply_prefix": local_conf.get("group_chat_reply_prefix"), + "group_chat_reply_suffix": local_conf.get("group_chat_reply_suffix"), + "group_name_white_list": local_conf.get("group_name_white_list"), + "nick_name_black_list": local_conf.get("nick_name_black_list"), + "speech_recognition": "Y" if local_conf.get("speech_recognition") else "N", + "text_to_image": local_conf.get("text_to_image"), + "image_create_prefix": local_conf.get("image_create_prefix") + } + if local_conf.get("always_reply_voice"): + config["reply_voice_mode"] = "always_reply_voice" + elif local_conf.get("voice_reply_voice"): + config["reply_voice_mode"] = "voice_reply_voice" + if pconf("linkai"): + config["group_app_map"] = pconf("linkai").get("group_app_map") + if plugin_config.get("Godcmd"): + config["admin_password"] = plugin_config.get("Godcmd").get("password") + return config diff --git a/config.py b/config.py index 4bfcf26..71f79d0 100644 --- a/config.py +++ b/config.py @@ -258,6 +258,8 @@ def load_config(): config.load_user_datas() + + def get_root(): return os.path.dirname(os.path.abspath(__file__)) diff --git a/plugins/linkai/linkai.py b/plugins/linkai/linkai.py index 7978743..2411fb7 100644 --- a/plugins/linkai/linkai.py +++ b/plugins/linkai/linkai.py @@ -10,6 +10,7 @@ from common import const import os from .utils import Util + @plugins.register( name="linkai", desc="A plugin that supports knowledge base and midjourney drawing.", @@ -32,7 +33,6 @@ class LinkAI(Plugin): self.sum_config = self.config.get("summary") logger.info(f"[LinkAI] inited, config={self.config}") - def on_handle_context(self, e_context: EventContext): """ 消息处理逻辑 @@ -42,7 +42,8 @@ class LinkAI(Plugin): return context = e_context['context'] - if context.type not in [ContextType.TEXT, ContextType.IMAGE, ContextType.IMAGE_CREATE, ContextType.FILE, ContextType.SHARING]: + if context.type not in [ContextType.TEXT, ContextType.IMAGE, ContextType.IMAGE_CREATE, ContextType.FILE, + ContextType.SHARING]: # filter content no need solve return @@ -76,7 +77,8 @@ class LinkAI(Plugin): if not res: _set_reply_text("因为神秘力量无法获取文章内容,请稍后再试吧~", e_context, level=ReplyType.TEXT) return - _set_reply_text(res.get("summary") + "\n\n💬 发送 \"开启对话\" 可以开启与文章内容的对话", e_context, level=ReplyType.TEXT) + _set_reply_text(res.get("summary") + "\n\n💬 发送 \"开启对话\" 可以开启与文章内容的对话", e_context, + level=ReplyType.TEXT) USER_FILE_MAP[_find_user_id(context) + "-sum_id"] = res.get("summary_id") return @@ -99,7 +101,8 @@ class LinkAI(Plugin): _set_reply_text("开启对话失败,请稍后再试吧", e_context) return USER_FILE_MAP[_find_user_id(context) + "-file_id"] = res.get("file_id") - _set_reply_text("💡你可以问我关于这篇文章的任何问题,例如:\n\n" + res.get("questions") + "\n\n发送 \"退出对话\" 可以关闭与文章的对话", e_context, level=ReplyType.TEXT) + _set_reply_text("💡你可以问我关于这篇文章的任何问题,例如:\n\n" + res.get( + "questions") + "\n\n发送 \"退出对话\" 可以关闭与文章的对话", e_context, level=ReplyType.TEXT) return if context.type == ContextType.TEXT and context.content == "退出对话" and _find_file_id(context): @@ -117,12 +120,10 @@ class LinkAI(Plugin): e_context.action = EventAction.BREAK_PASS return - if self._is_chat_task(e_context): # 文本对话任务处理 self._process_chat_task(e_context) - # 插件管理功能 def _process_admin_cmd(self, e_context: EventContext): context = e_context['context'] @@ -177,7 +178,9 @@ class LinkAI(Plugin): tips_text = "关闭" is_open = False if not self.sum_config: - _set_reply_text(f"插件未启用summary功能,请参考以下链添加插件配置\n\nhttps://github.com/zhayujie/chatgpt-on-wechat/blob/master/plugins/linkai/README.md", e_context, level=ReplyType.INFO) + _set_reply_text( + f"插件未启用summary功能,请参考以下链添加插件配置\n\nhttps://github.com/zhayujie/chatgpt-on-wechat/blob/master/plugins/linkai/README.md", + e_context, level=ReplyType.INFO) else: self.sum_config["enabled"] = is_open _set_reply_text(f"文章总结功能{tips_text}", e_context, level=ReplyType.INFO) @@ -254,6 +257,9 @@ class LinkAI(Plugin): except Exception as e: logger.exception(e) + def reload(self): + self.config = super().load_config() + def _send_info(e_context: EventContext, content: str): reply = Reply(ReplyType.TEXT, content) @@ -273,15 +279,19 @@ def _set_reply_text(content: str, e_context: EventContext, level: ReplyType = Re e_context["reply"] = reply e_context.action = EventAction.BREAK_PASS + def _get_trigger_prefix(): return conf().get("plugin_trigger_prefix", "$") + def _find_sum_id(context): return USER_FILE_MAP.get(_find_user_id(context) + "-sum_id") + def _find_file_id(context): user_id = _find_user_id(context) if user_id: return USER_FILE_MAP.get(user_id + "-file_id") + USER_FILE_MAP = ExpiredDict(conf().get("expires_in_seconds") or 60 * 30)