## 插件化初衷
之前未插件化的代码耦合程度高,如果要定制一些个性化功能(如流量控制、接入`NovelAI`画图平台等),需要了解代码主体,避免影响到其他的功能。在实现多个功能后,不但无法调整功能的优先级顺序,功能的配置项也会变得非常混乱。
此时插件化应声而出。
**插件化**: 在保证主体功能是ChatGPT的前提下,我们推荐将主体功能外的功能利用插件的方式实现。
- [x] 可根据功能需要,下载不同插件。
- [x] 插件开发成本低,仅需了解插件触发事件,并按照插件定义接口编写插件。
- [x] 插件化能够自由开关和调整优先级。
- [x] 每个插件可在插件文件夹内维护独立的配置文件,方便代码的测试和调试,可以在独立的仓库开发插件。
PS: 插件目前仅支持`itchat`
## 插件化实现
插件化实现是在收到消息到发送回复的各个步骤之间插入触发事件实现的。
### 消息处理过程
在了解插件触发事件前,首先需要了解程序收到消息到发送回复的整个过程。
插件化版本中,消息处理过程可以分为4个步骤:
```
1.收到消息 ---> 2.产生回复 ---> 3.包装回复 ---> 4.发送回复
```
以下是它们的默认处理逻辑(太长不看,可跳过):
#### 1. 收到消息
负责接收用户消息,根据用户的配置,判断本条消息是否触发机器人。如果触发,则会判断该消息的类型(声音、文本、画图命令等),将消息包装成如下的`Context`交付给下一个步骤。
```python
class ContextType (Enum):
TEXT = 1 # 文本消息
VOICE = 2 # 音频消息
IMAGE_CREATE = 3 # 创建图片命令
class Context:
def __init__(self, type : ContextType = None , content = None, kwargs = dict()):
self.type = type
self.content = content
self.kwargs = kwargs
def __getitem__(self, key):
return self.kwargs[key]
```
`Context`中除了存放消息类型和内容外,还存放了一些与会话相关的参数。
例如,当收到用户私聊消息时,会存放以下的会话参数。
```python
context.kwargs = {'isgroup': False, 'msg': msg, 'receiver': other_user_id, 'session_id': other_user_id}
```
- `isgroup`: `Context`是否是群聊消息。
- `msg`: `itchat`中原始的消息对象。
- `receiver`: 需要回复消息的对象ID。
- `session_id`: 会话ID(一般是发送触发bot消息的用户ID,如果在群聊中并且`conf`里设置了`group_chat_in_one_session`,那么此处便是群聊ID)
#### 2. 产生回复
处理消息并产生回复。目前默认处理逻辑是根据`Context`的类型交付给对应的bot,并产生回复`Reply`。 如果本步骤没有产生任何回复,那么会跳过之后的所有步骤。
```python
if context.type == ContextType.TEXT or context.type == ContextType.IMAGE_CREATE:
reply = super().build_reply_content(context.content, context) #文字跟画图交付给chatgpt
elif context.type == ContextType.VOICE: # 声音先进行语音转文字后,修改Context类型为文字后,再交付给chatgpt
msg = context['msg']
file_name = TmpDir().path() + context.content
msg.download(file_name)
reply = super().build_voice_to_text(file_name)
if reply.type != ReplyType.ERROR and reply.type != ReplyType.INFO:
context.content = reply.content # 语音转文字后,将文字内容作为新的context
context.type = ContextType.TEXT
reply = super().build_reply_content(context.content, context)
if reply.type == ReplyType.TEXT:
if conf().get('voice_reply_voice'):
reply = super().build_text_to_voice(reply.content)
```
回复`Reply`的定义如下所示,它允许Bot可以回复多类不同的消息。同时也加入了`INFO`和`ERROR`消息类型区分系统提示和系统错误。
```python
class ReplyType(Enum):
TEXT = 1 # 文本
VOICE = 2 # 音频文件
IMAGE = 3 # 图片文件
IMAGE_URL = 4 # 图片URL
INFO = 9
ERROR = 10
class Reply:
def __init__(self, type : ReplyType = None , content = None):
self.type = type
self.content = content
```
#### 3. 装饰回复
根据`Context`和回复`Reply`的类型,对回复的内容进行装饰。目前的装饰有以下两种:
- `TEXT`文本回复,根据是否在群聊中来决定是艾特接收方还是添加回复的前缀。
- `INFO`或`ERROR`类型,会在消息前添加对应的系统提示字样。
如下是默认逻辑的代码:
```python
if reply.type == ReplyType.TEXT:
reply_text = reply.content
if context['isgroup']:
reply_text = '@' + context['msg']['ActualNickName'] + ' ' + reply_text.strip()
reply_text = conf().get("group_chat_reply_prefix", "")+reply_text
else:
reply_text = conf().get("single_chat_reply_prefix", "")+reply_text
reply.content = reply_text
elif reply.type == ReplyType.ERROR or reply.type == ReplyType.INFO:
reply.content = str(reply.type)+":\n" + reply.content
```
#### 4. 发送回复
根据`Reply`的类型,默认逻辑调用不同的发送函数发送回复给接收方`context["receiver"]`。
### 插件触发事件
主程序目前会在各个消息步骤间触发事件,监听相应事件的插件会按照优先级,顺序调用事件处理函数。
目前支持三类触发事件:
```
1.收到消息
---> `ON_HANDLE_CONTEXT`
2.产生回复
---> `ON_DECORATE_REPLY`
3.装饰回复
---> `ON_SEND_REPLY`
4.发送回复
```
触发事件会产生事件的上下文`EventContext`,它包含了以下信息:
`EventContext(Event事件类型, {'channel' : 消息channel, 'context': Context, 'reply': Reply})`
插件处理函数可通过修改`EventContext`中的`context`和`reply`来实现功能。
## 插件编写示例
以`plugins/hello`为例,其中编写了一个简单的`Hello`插件。
### 1. 创建插件
在`plugins`目录下创建一个插件文件夹`hello`。然后,在该文件夹中创建一个与文件夹同名的`.py`文件`hello.py`。
```
plugins/
└── hello
├── __init__.py
└── hello.py
```
### 2. 编写插件类
在`hello.py`文件中,创建插件类,它继承自`Plugin`。
在类定义之前需要使用`@plugins.register`装饰器注册插件,并填写插件的相关信息,其中`desire_priority`表示插件默认的优先级,越大优先级越高。初次加载插件后可在`plugins/plugins.json`中修改插件优先级。
并在`__init__`中绑定你编写的事件处理函数。
`Hello`插件为事件`ON_HANDLE_CONTEXT`绑定了一个处理函数`on_handle_context`,它表示之后每次生成回复前,都会由`on_handle_context`先处理。
PS: `ON_HANDLE_CONTEXT`是最常用的事件,如果要根据不同的消息来生成回复,就用它。
```python
@plugins.register(name="Hello", desc="A simple plugin that says hello", version="0.1", author="lanvent", desire_priority= -1)
class Hello(Plugin):
def __init__(self):
super().__init__()
self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context
logger.info("[Hello] inited")
```
### 3. 编写事件处理函数
#### 修改事件上下文
事件处理函数接收一个`EventContext`对象`e_context`作为参数。`e_context`包含了事件相关信息,利用`e_context['key']`来访问这些信息。
`EventContext(Event事件类型, {'channel' : 消息channel, 'context': Context, 'reply': Reply})`
处理函数中通过修改`e_context`对象中的事件相关信息来实现所需功能,比如更改`e_context['reply']`中的内容可以修改回复。
#### 决定是否交付给下个插件或�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
基于ChatGPT的微信聊天机器人,通过 ChatGPT 接口生成对话内容,使用 itchat 实现微信消息的接收和自动回复。已实现的特性如下: 文本对话: 接收私聊及群组中的微信消息,使用ChatGPT生成回复内容,完成自动回复。规则定制化: 支持私聊中按指定规则触发自动回复,支持对群组设置自动回复白名单。 图片生成: 支持根据描述生成图片,并自动发送至个人聊天或群聊。上下文记忆:支持多轮对话记忆,且为每个好友维护独立的上下会话。语音识别: 支持接收和处理语音消息,通过文字或语音回复。插件化: 支持个性化功能插件,提供角色扮演、文字冒险游戏等预设插件
资源推荐
资源详情
资源评论
收起资源包目录
这是从github上克隆的chatgpt 微信项目,调整为了API2D接口 (116个子文件)
Dockerfile.alpine 1KB
Dockerfile.alpine 392B
Dockerfile.debian 1KB
Dockerfile.debian 442B
.env 620B
.gitignore 108B
.gitignore 12B
image-create-sample.jpg 382KB
group-chat-sample.jpg 326KB
single-chat-sample.jpg 180KB
roles.json 26KB
config-template.json 736B
Dockerfile.latest 806B
LICENSE 1KB
Makefile 484B
README.md 10KB
readme.md 3KB
README.md 2KB
README.md 960B
ISSUE_TEMPLATE.md 697B
README.md 516B
README.md 418B
README.md 308B
Name 27B
messages.py 22KB
messages.py 22KB
contact.py 21KB
contact.py 20KB
core.py 20KB
wechat_channel.py 17KB
login.py 17KB
wechaty_channel.py 16KB
login.py 16KB
godcmd.py 13KB
templates.py 12KB
bdunit.py 10KB
WordsSearch.py 8KB
chat_gpt_bot.py 7KB
plugin_manager.py 7KB
utils.py 5KB
config.py 5KB
role.py 5KB
open_ai_bot.py 5KB
__init__.py 5KB
sdwebui.py 5KB
register.py 4KB
dungeon.py 4KB
hotreload.py 4KB
register.py 4KB
hotreload.py 4KB
chat_gpt_session.py 4KB
session_manager.py 3KB
__init__.py 3KB
baidu_voice.py 3KB
open_ai_session.py 3KB
banwords.py 3KB
returnvalues.py 2KB
sorted_dict.py 2KB
hello.py 2KB
time_check.py 2KB
bridge.py 2KB
open_ai_image.py 2KB
google_voice.py 2KB
event.py 2KB
audio_convert.py 1KB
token_bucket.py 1KB
log.py 1KB
config.py 1KB
baidu_unit_bot.py 1KB
expired_dict.py 1KB
context.py 1KB
pytts_voice.py 1KB
channel.py 1009B
messagequeue.py 986B
bot_factory.py 923B
openai_voice.py 855B
terminal_channel.py 839B
voice_factory.py 655B
app.py 615B
channel_factory.py 595B
reply.py 511B
tmp_dir.py 464B
log.py 458B
content.py 364B
bot.py 354B
voice.py 345B
__init__.py 319B
__init__.py 319B
__init__.py 268B
singleton.py 217B
plugin.py 140B
const.py 99B
__init__.py 0B
__init__.py 0B
__init__.py 0B
__init__.py 0B
__init__.py 0B
__init__.py 0B
__init__.py 0B
entrypoint.sh 4KB
共 116 条
- 1
- 2
资源评论
Java程序员-张凯
- 粉丝: 1w+
- 资源: 6746
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功