From 20b71f206b79ddd9e752229116c6737ec85a6dd0 Mon Sep 17 00:00:00 2001 From: lanvent Date: Tue, 25 Apr 2023 23:58:46 +0800 Subject: [PATCH] feat: add subscribe_msg option for wechatmp, wechatmp_service, and wechatcom_app channels --- README.md | 7 +++++-- channel/wechatcom/wechatcomapp_channel.py | 22 ++++++---------------- channel/wechatmp/active_reply.py | 9 +++++---- channel/wechatmp/common.py | 18 ------------------ channel/wechatmp/passive_reply.py | 10 +++++----- config-template.json | 3 ++- config.py | 16 ++++++++++++++-- 7 files changed, 37 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 2fad81b..80004df 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ pip3 install azure-cognitiveservices-speech cp config-template.json config.json ``` -然后在`config.json`中填入配置,以下是对默认配置的说明,可根据需要进行自定义修改: +然后在`config.json`中填入配置,以下是对默认配置的说明,可根据需要进行自定义修改(请去掉注释): ```bash # config.json文件内容示例 @@ -115,7 +115,9 @@ pip3 install azure-cognitiveservices-speech "speech_recognition": false, # 是否开启语音识别 "group_speech_recognition": false, # 是否开启群组语音识别 "use_azure_chatgpt": false, # 是否使用Azure ChatGPT service代替openai ChatGPT service. 当设置为true时需要设置 open_ai_api_base,如 https://xxx.openai.azure.com/ - "character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", # 人格描述, + "character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", # 人格描述 + # 订阅消息,公众号和企业微信channel中请填写,当被订阅时会自动回复,可使用特殊占位符。目前支持的占位符有{trigger_prefix},在程序中它会自动替换成bot的触发词。 + "subscribe_msg": "感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持角色扮演和文字冒险等丰富插件。\n输入{trigger_prefix}#help 查看详细指令。" } ``` **配置说明:** @@ -150,6 +152,7 @@ pip3 install azure-cognitiveservices-speech + `clear_memory_commands`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。 + `hot_reload`: 程序退出后,暂存微信扫码状态,默认关闭。 + `character_desc` 配置中保存着你对机器人说的一段话,他会记住这段话并作为他的设定,你可以为他定制任何人格 (关于会话上下文的更多内容参考该 [issue](https://github.com/zhayujie/chatgpt-on-wechat/issues/43)) ++ `subscribe_msg`:订阅消息,公众号和企业微信channel中请填写,当被订阅时会自动回复, 可使用特殊占位符。目前支持的占位符有{trigger_prefix},在程序中它会自动替换成bot的触发词。 **所有可选的配置项均在该[文件](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py)中列出。** diff --git a/channel/wechatcom/wechatcomapp_channel.py b/channel/wechatcom/wechatcomapp_channel.py index 4d686eb..d4c090d 100644 --- a/channel/wechatcom/wechatcomapp_channel.py +++ b/channel/wechatcom/wechatcomapp_channel.py @@ -1,7 +1,6 @@ # -*- coding=utf-8 -*- import io import os -import textwrap import time import requests @@ -19,7 +18,7 @@ from channel.wechatcom.wechatcomapp_message import WechatComAppMessage from common.log import logger from common.singleton import singleton from common.utils import compress_imgfile, fsize, split_string_by_utf8_length -from config import conf +from config import conf, subscribe_msg from voice.audio_convert import any_to_amr MAX_UTF8_LEN = 2048 @@ -147,20 +146,11 @@ class Query: logger.debug("[wechatcom] receive message: {}, msg= {}".format(message, msg)) if msg.type == "event": if msg.event == "subscribe": - trigger_prefix = conf().get("single_chat_prefix", [""])[0] - reply_content = textwrap.dedent( - f"""\ - 感谢您的关注! - 这里是ChatGPT,可以自由对话。 - 支持语音对话。 - 支持通用表情输入。 - 支持图片输入输出。 - 支持角色扮演和文字冒险两种定制模式对话。 - 输入'{trigger_prefix}#help' 查看详细指令。""" - ) - reply = create_reply(reply_content, msg).render() - res = channel.crypto.encrypt_message(reply, nonce, timestamp) - return res + reply_content = subscribe_msg() + if reply_content: + reply = create_reply(reply_content, msg).render() + res = channel.crypto.encrypt_message(reply, nonce, timestamp) + return res else: try: wechatcom_msg = WechatComAppMessage(msg, client=channel.client) diff --git a/channel/wechatmp/active_reply.py b/channel/wechatmp/active_reply.py index 12975a5..10649cd 100644 --- a/channel/wechatmp/active_reply.py +++ b/channel/wechatmp/active_reply.py @@ -10,7 +10,7 @@ from channel.wechatmp.common import * from channel.wechatmp.wechatmp_channel import WechatMPChannel from channel.wechatmp.wechatmp_message import WeChatMPMessage from common.log import logger -from config import conf +from config import conf, subscribe_msg # This class is instantiated once per query @@ -66,13 +66,14 @@ class Query: logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) if msg.event in ["subscribe", "subscribe_scan"]: reply_text = subscribe_msg() - replyPost = create_reply(reply_text, msg) - return encrypt_func(replyPost.render()) + if reply_text: + replyPost = create_reply(reply_text, msg) + return encrypt_func(replyPost.render()) else: return "success" else: logger.info("暂且不处理") - return "success" + return "success" except Exception as exc: logger.exception(exc) return exc diff --git a/channel/wechatmp/common.py b/channel/wechatmp/common.py index be0b800..e1cbe7b 100644 --- a/channel/wechatmp/common.py +++ b/channel/wechatmp/common.py @@ -1,5 +1,3 @@ -import textwrap - import web from wechatpy.crypto import WeChatCrypto from wechatpy.exceptions import InvalidSignatureException @@ -27,19 +25,3 @@ def verify_server(data): raise web.Forbidden("Invalid signature") except Exception as e: raise web.Forbidden(str(e)) - - -def subscribe_msg(): - trigger_prefix = conf().get("single_chat_prefix", [""])[0] - msg = textwrap.dedent( - f"""\ - 感谢您的关注! - 这里是ChatGPT,可以自由对话。 - 资源有限,回复较慢,请勿着急。 - 支持语音对话。 - 支持图片输入。 - 支持图片输出,画字开头的消息将按要求创作图片。 - 支持tool、角色扮演和文字冒险等丰富的插件。 - 输入'{trigger_prefix}#帮助' 查看详细指令。""" - ) - return msg diff --git a/channel/wechatmp/passive_reply.py b/channel/wechatmp/passive_reply.py index 38fee6d..d926b2a 100644 --- a/channel/wechatmp/passive_reply.py +++ b/channel/wechatmp/passive_reply.py @@ -12,7 +12,7 @@ from channel.wechatmp.wechatmp_channel import WechatMPChannel from channel.wechatmp.wechatmp_message import WeChatMPMessage from common.log import logger from common.utils import split_string_by_utf8_length -from config import conf +from config import conf, subscribe_msg # This class is instantiated once per query @@ -200,14 +200,14 @@ class Query: logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) if msg.event in ["subscribe", "subscribe_scan"]: reply_text = subscribe_msg() - replyPost = create_reply(reply_text, msg) - return encrypt_func(replyPost.render()) + if reply_text: + replyPost = create_reply(reply_text, msg) + return encrypt_func(replyPost.render()) else: return "success" - else: logger.info("暂且不处理") - return "success" + return "success" except Exception as exc: logger.exception(exc) return exc diff --git a/config-template.json b/config-template.json index 864aa03..51187c4 100644 --- a/config-template.json +++ b/config-template.json @@ -27,5 +27,6 @@ "voice_reply_voice": false, "conversation_max_tokens": 1000, "expires_in_seconds": 3600, - "character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。" + "character_desc": "你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。", + "subcribe_msg": "感谢您的关注!\n这里是ChatGPT,可以自由对话。\n支持语音对话。\n支持图片输入。\n支持图片输出,画字开头的消息将按要求创作图片。\n支持tool、角色扮演和文字冒险等丰富的插件。\n输入{trigger_prefix}#help 查看详细指令。" } diff --git a/config.py b/config.py index b645ed3..ae1cfd7 100644 --- a/config.py +++ b/config.py @@ -8,6 +8,7 @@ import pickle from common.log import logger # 将所有可用的配置项写在字典里, 请使用小写字母 +# 此处的配置值无实际意义,程序不会读取此处的配置,仅用于提示格式,请将配置加入到config.json中 available_setting = { # openai api配置 "open_ai_api_key": "", # openai api key @@ -93,6 +94,7 @@ available_setting = { "clear_memory_commands": ["#清除记忆"], # 重置会话指令,必须以#开头 # channel配置 "channel_type": "wx", # 通道类型,支持:{wx,wxy,terminal,wechatmp,wechatmp_service,wechatcom_app} + "subscribe_msg": "", # 订阅消息, 支持: wechatmp, wechatmp_service, wechatcom_app "debug": False, # 是否开启debug模式,开启后会打印更多日志 "appdata_dir": "", # 数据目录 # 插件配置 @@ -101,8 +103,12 @@ available_setting = { class Config(dict): - def __init__(self, d: dict = {}): - super().__init__(d) + def __init__(self, d=None): + super().__init__() + if d is None: + d = {} + for k, v in d.items(): + self[k] = v # user_datas: 用户数据,key为用户名,value为用户数据,也是dict self.user_datas = {} @@ -210,3 +216,9 @@ def get_appdata_dir(): logger.info("[INIT] data path not exists, create it: {}".format(data_path)) os.makedirs(data_path) return data_path + + +def subscribe_msg(): + trigger_prefix = conf().get("single_chat_prefix", [""])[0] + msg = conf().get("subscribe_msg", "") + return msg.format(trigger_prefix=trigger_prefix)