Sfoglia il codice sorgente

feat: add subscribe_msg option for wechatmp, wechatmp_service, and wechatcom_app channels

lanvent 2 anni fa
parent
commit
20b71f206b

+ 5 - 2
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)中列出。**
 

+ 6 - 16
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)

+ 5 - 4
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

+ 0 - 18
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

+ 5 - 5
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

+ 2 - 1
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 查看详细指令。"
 }

+ 14 - 2
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)