@@ -97,7 +97,7 @@ pip3 install azure-cognitiveservices-speech | |||||
cp config-template.json config.json | cp config-template.json config.json | ||||
``` | ``` | ||||
然后在`config.json`中填入配置,以下是对默认配置的说明,可根据需要进行自定义修改: | |||||
然后在`config.json`中填入配置,以下是对默认配置的说明,可根据需要进行自定义修改(请去掉注释): | |||||
```bash | ```bash | ||||
# config.json文件内容示例 | # config.json文件内容示例 | ||||
@@ -115,7 +115,9 @@ pip3 install azure-cognitiveservices-speech | |||||
"speech_recognition": false, # 是否开启语音识别 | "speech_recognition": false, # 是否开启语音识别 | ||||
"group_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/ | "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`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。 | + `clear_memory_commands`: 对话内指令,主动清空前文记忆,字符串数组可自定义指令别名。 | ||||
+ `hot_reload`: 程序退出后,暂存微信扫码状态,默认关闭。 | + `hot_reload`: 程序退出后,暂存微信扫码状态,默认关闭。 | ||||
+ `character_desc` 配置中保存着你对机器人说的一段话,他会记住这段话并作为他的设定,你可以为他定制任何人格 (关于会话上下文的更多内容参考该 [issue](https://github.com/zhayujie/chatgpt-on-wechat/issues/43)) | + `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)中列出。** | **所有可选的配置项均在该[文件](https://github.com/zhayujie/chatgpt-on-wechat/blob/master/config.py)中列出。** | ||||
@@ -1,7 +1,6 @@ | |||||
# -*- coding=utf-8 -*- | # -*- coding=utf-8 -*- | ||||
import io | import io | ||||
import os | import os | ||||
import textwrap | |||||
import time | import time | ||||
import requests | import requests | ||||
@@ -19,7 +18,7 @@ from channel.wechatcom.wechatcomapp_message import WechatComAppMessage | |||||
from common.log import logger | from common.log import logger | ||||
from common.singleton import singleton | from common.singleton import singleton | ||||
from common.utils import compress_imgfile, fsize, split_string_by_utf8_length | 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 | from voice.audio_convert import any_to_amr | ||||
MAX_UTF8_LEN = 2048 | MAX_UTF8_LEN = 2048 | ||||
@@ -147,20 +146,11 @@ class Query: | |||||
logger.debug("[wechatcom] receive message: {}, msg= {}".format(message, msg)) | logger.debug("[wechatcom] receive message: {}, msg= {}".format(message, msg)) | ||||
if msg.type == "event": | if msg.type == "event": | ||||
if msg.event == "subscribe": | 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: | else: | ||||
try: | try: | ||||
wechatcom_msg = WechatComAppMessage(msg, client=channel.client) | wechatcom_msg = WechatComAppMessage(msg, client=channel.client) | ||||
@@ -10,7 +10,7 @@ from channel.wechatmp.common import * | |||||
from channel.wechatmp.wechatmp_channel import WechatMPChannel | from channel.wechatmp.wechatmp_channel import WechatMPChannel | ||||
from channel.wechatmp.wechatmp_message import WeChatMPMessage | from channel.wechatmp.wechatmp_message import WeChatMPMessage | ||||
from common.log import logger | from common.log import logger | ||||
from config import conf | |||||
from config import conf, subscribe_msg | |||||
# This class is instantiated once per query | # This class is instantiated once per query | ||||
@@ -66,13 +66,14 @@ class Query: | |||||
logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) | logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) | ||||
if msg.event in ["subscribe", "subscribe_scan"]: | if msg.event in ["subscribe", "subscribe_scan"]: | ||||
reply_text = subscribe_msg() | 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: | else: | ||||
return "success" | return "success" | ||||
else: | else: | ||||
logger.info("暂且不处理") | logger.info("暂且不处理") | ||||
return "success" | |||||
return "success" | |||||
except Exception as exc: | except Exception as exc: | ||||
logger.exception(exc) | logger.exception(exc) | ||||
return exc | return exc |
@@ -1,5 +1,3 @@ | |||||
import textwrap | |||||
import web | import web | ||||
from wechatpy.crypto import WeChatCrypto | from wechatpy.crypto import WeChatCrypto | ||||
from wechatpy.exceptions import InvalidSignatureException | from wechatpy.exceptions import InvalidSignatureException | ||||
@@ -27,19 +25,3 @@ def verify_server(data): | |||||
raise web.Forbidden("Invalid signature") | raise web.Forbidden("Invalid signature") | ||||
except Exception as e: | except Exception as e: | ||||
raise web.Forbidden(str(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 |
@@ -12,7 +12,7 @@ from channel.wechatmp.wechatmp_channel import WechatMPChannel | |||||
from channel.wechatmp.wechatmp_message import WeChatMPMessage | from channel.wechatmp.wechatmp_message import WeChatMPMessage | ||||
from common.log import logger | from common.log import logger | ||||
from common.utils import split_string_by_utf8_length | 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 | # This class is instantiated once per query | ||||
@@ -200,14 +200,14 @@ class Query: | |||||
logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) | logger.info("[wechatmp] Event {} from {}".format(msg.event, msg.source)) | ||||
if msg.event in ["subscribe", "subscribe_scan"]: | if msg.event in ["subscribe", "subscribe_scan"]: | ||||
reply_text = subscribe_msg() | 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: | else: | ||||
return "success" | return "success" | ||||
else: | else: | ||||
logger.info("暂且不处理") | logger.info("暂且不处理") | ||||
return "success" | |||||
return "success" | |||||
except Exception as exc: | except Exception as exc: | ||||
logger.exception(exc) | logger.exception(exc) | ||||
return exc | return exc |
@@ -27,5 +27,6 @@ | |||||
"voice_reply_voice": false, | "voice_reply_voice": false, | ||||
"conversation_max_tokens": 1000, | "conversation_max_tokens": 1000, | ||||
"expires_in_seconds": 3600, | "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 查看详细指令。" | |||||
} | } |
@@ -8,6 +8,7 @@ import pickle | |||||
from common.log import logger | from common.log import logger | ||||
# 将所有可用的配置项写在字典里, 请使用小写字母 | # 将所有可用的配置项写在字典里, 请使用小写字母 | ||||
# 此处的配置值无实际意义,程序不会读取此处的配置,仅用于提示格式,请将配置加入到config.json中 | |||||
available_setting = { | available_setting = { | ||||
# openai api配置 | # openai api配置 | ||||
"open_ai_api_key": "", # openai api key | "open_ai_api_key": "", # openai api key | ||||
@@ -93,6 +94,7 @@ available_setting = { | |||||
"clear_memory_commands": ["#清除记忆"], # 重置会话指令,必须以#开头 | "clear_memory_commands": ["#清除记忆"], # 重置会话指令,必须以#开头 | ||||
# channel配置 | # channel配置 | ||||
"channel_type": "wx", # 通道类型,支持:{wx,wxy,terminal,wechatmp,wechatmp_service,wechatcom_app} | "channel_type": "wx", # 通道类型,支持:{wx,wxy,terminal,wechatmp,wechatmp_service,wechatcom_app} | ||||
"subscribe_msg": "", # 订阅消息, 支持: wechatmp, wechatmp_service, wechatcom_app | |||||
"debug": False, # 是否开启debug模式,开启后会打印更多日志 | "debug": False, # 是否开启debug模式,开启后会打印更多日志 | ||||
"appdata_dir": "", # 数据目录 | "appdata_dir": "", # 数据目录 | ||||
# 插件配置 | # 插件配置 | ||||
@@ -101,8 +103,12 @@ available_setting = { | |||||
class Config(dict): | 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 | # user_datas: 用户数据,key为用户名,value为用户数据,也是dict | ||||
self.user_datas = {} | self.user_datas = {} | ||||
@@ -210,3 +216,9 @@ def get_appdata_dir(): | |||||
logger.info("[INIT] data path not exists, create it: {}".format(data_path)) | logger.info("[INIT] data path not exists, create it: {}".format(data_path)) | ||||
os.makedirs(data_path) | os.makedirs(data_path) | ||||
return 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) |