接入event
This commit is contained in:
14
plugins/napcat_adapter_plugin/event_types.py
Normal file
14
plugins/napcat_adapter_plugin/event_types.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
class NapcatEvent:
|
||||||
|
# napcat插件事件枚举类
|
||||||
|
ON_RECEIVED_TEXT = "napcat_on_received_text"
|
||||||
|
ON_RECEIVED_FACE = "napcat_on_received_face"
|
||||||
|
ON_RECEIVED_REPLY = "napcat_on_received_reply"
|
||||||
|
ON_RECEIVED_IMAGE = "napcat_on_received_image"
|
||||||
|
ON_RECEIVED_RECORD = "napcat_on_received_record"
|
||||||
|
ON_RECEIVED_VIDEO = "napcat_on_received_video"
|
||||||
|
ON_RECEIVED_AT = "napcat_on_received_at"
|
||||||
|
ON_RECEIVED_DICE = "napcat_on_received_dice"
|
||||||
|
ON_RECEIVED_SHAKE = "napcat_on_received_shake"
|
||||||
|
ON_RECEIVED_JSON = "napcat_on_received_json"
|
||||||
|
ON_RECEIVED_RPS = "napcat_on_received_rps"
|
||||||
|
ON_FRIEND_INPUT = "napcat_on_friend_input"
|
||||||
@@ -35,6 +35,7 @@ class NoticeType: # 通知事件
|
|||||||
|
|
||||||
class Notify:
|
class Notify:
|
||||||
poke = "poke" # 戳一戳
|
poke = "poke" # 戳一戳
|
||||||
|
input_status = "input_status" # 正在输入
|
||||||
|
|
||||||
class GroupBan:
|
class GroupBan:
|
||||||
ban = "ban" # 禁言
|
ban = "ban" # 禁言
|
||||||
@@ -56,6 +57,7 @@ class RealMessageType: # 实际消息分类
|
|||||||
reply = "reply" # 回复消息
|
reply = "reply" # 回复消息
|
||||||
forward = "forward" # 转发消息
|
forward = "forward" # 转发消息
|
||||||
node = "node" # 转发消息节点
|
node = "node" # 转发消息节点
|
||||||
|
json = "json" # json消息
|
||||||
|
|
||||||
|
|
||||||
class MessageSentType:
|
class MessageSentType:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from ...event_types import NapcatEvent
|
||||||
|
from src.plugin_system.core.event_manager import event_manager
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
logger = get_logger("napcat_adapter")
|
logger = get_logger("napcat_adapter")
|
||||||
|
|
||||||
@@ -327,12 +329,14 @@ class MessageHandler:
|
|||||||
case RealMessageType.text:
|
case RealMessageType.text:
|
||||||
ret_seg = await self.handle_text_message(sub_message)
|
ret_seg = await self.handle_text_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_TEXT,message_seg=ret_seg)
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
else:
|
else:
|
||||||
logger.warning("text处理失败")
|
logger.warning("text处理失败")
|
||||||
case RealMessageType.face:
|
case RealMessageType.face:
|
||||||
ret_seg = await self.handle_face_message(sub_message)
|
ret_seg = await self.handle_face_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_FACE,message_seg=ret_seg)
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
else:
|
else:
|
||||||
logger.warning("face处理失败或不支持")
|
logger.warning("face处理失败或不支持")
|
||||||
@@ -340,6 +344,7 @@ class MessageHandler:
|
|||||||
if not in_reply:
|
if not in_reply:
|
||||||
ret_seg = await self.handle_reply_message(sub_message)
|
ret_seg = await self.handle_reply_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_REPLY,message_seg=ret_seg)
|
||||||
seg_message += ret_seg
|
seg_message += ret_seg
|
||||||
else:
|
else:
|
||||||
logger.warning("reply处理失败")
|
logger.warning("reply处理失败")
|
||||||
@@ -347,6 +352,7 @@ class MessageHandler:
|
|||||||
logger.debug(f"开始处理图片消息段")
|
logger.debug(f"开始处理图片消息段")
|
||||||
ret_seg = await self.handle_image_message(sub_message)
|
ret_seg = await self.handle_image_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_IMAGE,message_seg=ret_seg)
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
logger.debug(f"图片处理成功,添加到消息段")
|
logger.debug(f"图片处理成功,添加到消息段")
|
||||||
else:
|
else:
|
||||||
@@ -355,6 +361,7 @@ class MessageHandler:
|
|||||||
case RealMessageType.record:
|
case RealMessageType.record:
|
||||||
ret_seg = await self.handle_record_message(sub_message)
|
ret_seg = await self.handle_record_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_RECORD,message_seg=ret_seg)
|
||||||
seg_message.clear()
|
seg_message.clear()
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
break # 使得消息只有record消息
|
break # 使得消息只有record消息
|
||||||
@@ -363,6 +370,7 @@ class MessageHandler:
|
|||||||
case RealMessageType.video:
|
case RealMessageType.video:
|
||||||
ret_seg = await self.handle_video_message(sub_message)
|
ret_seg = await self.handle_video_message(sub_message)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_VIDEO,message_seg=ret_seg)
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
else:
|
else:
|
||||||
logger.warning("video处理失败")
|
logger.warning("video处理失败")
|
||||||
@@ -373,17 +381,33 @@ class MessageHandler:
|
|||||||
raw_message.get("group_id"),
|
raw_message.get("group_id"),
|
||||||
)
|
)
|
||||||
if ret_seg:
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_AT,message_seg=ret_seg)
|
||||||
seg_message.append(ret_seg)
|
seg_message.append(ret_seg)
|
||||||
else:
|
else:
|
||||||
logger.warning("at处理失败")
|
logger.warning("at处理失败")
|
||||||
case RealMessageType.rps:
|
case RealMessageType.rps:
|
||||||
logger.warning("暂时不支持猜拳魔法表情解析")
|
ret_seg = await self.handle_rps_message(sub_message)
|
||||||
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_RPS,message_seg=ret_seg)
|
||||||
|
seg_message.append(ret_seg)
|
||||||
|
else:
|
||||||
|
logger.warning("rps处理失败")
|
||||||
case RealMessageType.dice:
|
case RealMessageType.dice:
|
||||||
logger.warning("暂时不支持骰子表情解析")
|
ret_seg = await self.handle_dice_message(sub_message)
|
||||||
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_DICE,message_seg=ret_seg)
|
||||||
|
seg_message.append(ret_seg)
|
||||||
|
else:
|
||||||
|
logger.warning("dice处理失败")
|
||||||
case RealMessageType.shake:
|
case RealMessageType.shake:
|
||||||
# 预计等价于戳一戳
|
ret_seg = await self.handle_shake_message(sub_message)
|
||||||
logger.warning("暂时不支持窗口抖动解析")
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_SHAKE,message_seg=ret_seg)
|
||||||
|
seg_message.append(ret_seg)
|
||||||
|
else:
|
||||||
|
logger.warning("shake处理失败")
|
||||||
case RealMessageType.share:
|
case RealMessageType.share:
|
||||||
|
print("\n\n哦哦哦噢噢噢哦哦你收到了一个超级无敌SHARE消息,快速速把你刚刚收到的消息截图发到MoFox-Bot群里!!!!\n\n")
|
||||||
logger.warning("暂时不支持链接解析")
|
logger.warning("暂时不支持链接解析")
|
||||||
case RealMessageType.forward:
|
case RealMessageType.forward:
|
||||||
messages = await self._get_forward_message(sub_message)
|
messages = await self._get_forward_message(sub_message)
|
||||||
@@ -396,7 +420,15 @@ class MessageHandler:
|
|||||||
else:
|
else:
|
||||||
logger.warning("转发消息处理失败")
|
logger.warning("转发消息处理失败")
|
||||||
case RealMessageType.node:
|
case RealMessageType.node:
|
||||||
|
print("\n\n哦哦哦噢噢噢哦哦你收到了一个超级无敌NODE消息,快速速把你刚刚收到的消息截图发到MoFox-Bot群里!!!!\n\n")
|
||||||
logger.warning("不支持转发消息节点解析")
|
logger.warning("不支持转发消息节点解析")
|
||||||
|
case RealMessageType.json:
|
||||||
|
ret_seg = await self.handle_json_message(sub_message)
|
||||||
|
if ret_seg:
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_RECEIVED_JSON,message_seg=ret_seg)
|
||||||
|
seg_message.append(ret_seg)
|
||||||
|
else:
|
||||||
|
logger.warning("json处理失败")
|
||||||
case _:
|
case _:
|
||||||
logger.warning(f"未知消息类型: {sub_message_type}")
|
logger.warning(f"未知消息类型: {sub_message_type}")
|
||||||
|
|
||||||
@@ -643,25 +675,49 @@ class MessageHandler:
|
|||||||
processed_message: Seg
|
processed_message: Seg
|
||||||
if image_count < 5 and image_count > 0:
|
if image_count < 5 and image_count > 0:
|
||||||
# 处理图片数量小于5的情况,此时解析图片为base64
|
# 处理图片数量小于5的情况,此时解析图片为base64
|
||||||
logger.trace("图片数量小于5,开始解析图片为base64")
|
logger.info("图片数量小于5,开始解析图片为base64")
|
||||||
processed_message = await self._recursive_parse_image_seg(
|
processed_message = await self._recursive_parse_image_seg(
|
||||||
handled_message, True
|
handled_message, True
|
||||||
)
|
)
|
||||||
elif image_count > 0:
|
elif image_count > 0:
|
||||||
logger.trace("图片数量大于等于5,开始解析图片为占位符")
|
logger.info("图片数量大于等于5,开始解析图片为占位符")
|
||||||
# 处理图片数量大于等于5的情况,此时解析图片为占位符
|
# 处理图片数量大于等于5的情况,此时解析图片为占位符
|
||||||
processed_message = await self._recursive_parse_image_seg(
|
processed_message = await self._recursive_parse_image_seg(
|
||||||
handled_message, False
|
handled_message, False
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# 处理没有图片的情况,此时直接返回
|
# 处理没有图片的情况,此时直接返回
|
||||||
logger.trace("没有图片,直接返回")
|
logger.info("没有图片,直接返回")
|
||||||
processed_message = handled_message
|
processed_message = handled_message
|
||||||
|
|
||||||
# 添加转发消息提示
|
# 添加转发消息提示
|
||||||
forward_hint = Seg(type="text", data="这是一条转发消息:\n")
|
forward_hint = Seg(type="text", data="这是一条转发消息:\n")
|
||||||
return Seg(type="seglist", data=[forward_hint, processed_message])
|
return Seg(type="seglist", data=[forward_hint, processed_message])
|
||||||
|
|
||||||
|
async def handle_dice_message(self, raw_message: dict) -> Seg:
|
||||||
|
message_data: dict = raw_message.get("data",{})
|
||||||
|
res = message_data.get("result","")
|
||||||
|
return Seg(type="text", data=f"[扔了一个骰子,点数是{res}]")
|
||||||
|
|
||||||
|
async def handle_shake_message(self, raw_message: dict) -> Seg:
|
||||||
|
return Seg(type="text", data="[向你发送了窗口抖动,现在你的屏幕猛烈地震了一下!]")
|
||||||
|
|
||||||
|
async def handle_json_message(self, raw_message: dict) -> Seg:
|
||||||
|
message_data: str = raw_message.get("data","").get("data","")
|
||||||
|
res = json.loads(message_data)
|
||||||
|
return Seg(type="json", data=res)
|
||||||
|
|
||||||
|
async def handle_rps_message(self, raw_message: dict) -> Seg:
|
||||||
|
message_data: dict = raw_message.get("data",{})
|
||||||
|
res = message_data.get("result","")
|
||||||
|
if res == "1":
|
||||||
|
shape = "布"
|
||||||
|
elif res == "2":
|
||||||
|
shape = "剪刀"
|
||||||
|
else:
|
||||||
|
shape = "石头"
|
||||||
|
return Seg(type="text", data=f"[发送了一个魔法猜拳表情,结果是:{shape}]")
|
||||||
|
|
||||||
async def _recursive_parse_image_seg(self, seg_data: Seg, to_image: bool) -> Seg:
|
async def _recursive_parse_image_seg(self, seg_data: Seg, to_image: bool) -> Seg:
|
||||||
# sourcery skip: merge-else-if-into-elif
|
# sourcery skip: merge-else-if-into-elif
|
||||||
if to_image:
|
if to_image:
|
||||||
@@ -688,7 +744,7 @@ class MessageHandler:
|
|||||||
return Seg(type="text", data="[表情包]")
|
return Seg(type="text", data="[表情包]")
|
||||||
return Seg(type="emoji", data=encoded_image)
|
return Seg(type="emoji", data=encoded_image)
|
||||||
else:
|
else:
|
||||||
logger.trace(f"不处理类型: {seg_data.type}")
|
logger.info(f"不处理类型: {seg_data.type}")
|
||||||
return seg_data
|
return seg_data
|
||||||
else:
|
else:
|
||||||
if seg_data.type == "seglist":
|
if seg_data.type == "seglist":
|
||||||
@@ -702,7 +758,7 @@ class MessageHandler:
|
|||||||
elif seg_data.type == "emoji":
|
elif seg_data.type == "emoji":
|
||||||
return Seg(type="text", data="[动画表情]")
|
return Seg(type="text", data="[动画表情]")
|
||||||
else:
|
else:
|
||||||
logger.trace(f"不处理类型: {seg_data.type}")
|
logger.info(f"不处理类型: {seg_data.type}")
|
||||||
return seg_data
|
return seg_data
|
||||||
|
|
||||||
async def _handle_forward_message(self, message_list: list, layer: int) -> Tuple[Seg, int] | Tuple[None, int]:
|
async def _handle_forward_message(self, message_list: list, layer: int) -> Tuple[Seg, int] | Tuple[None, int]:
|
||||||
|
|||||||
@@ -115,6 +115,10 @@ class NoticeHandler:
|
|||||||
handled_message, user_info = await self.handle_poke_notify(raw_message, group_id, user_id)
|
handled_message, user_info = await self.handle_poke_notify(raw_message, group_id, user_id)
|
||||||
else:
|
else:
|
||||||
logger.warning("戳一戳消息被禁用,取消戳一戳处理")
|
logger.warning("戳一戳消息被禁用,取消戳一戳处理")
|
||||||
|
case NoticeType.Notify.input_status:
|
||||||
|
from src.plugin_system.core.event_manager import event_manager
|
||||||
|
from ...event_types import NapcatEvent
|
||||||
|
await event_manager.trigger_event(NapcatEvent.ON_FRIEND_INPUT)
|
||||||
case _:
|
case _:
|
||||||
logger.warning(f"不支持的notify类型: {notice_type}.{sub_type}")
|
logger.warning(f"不支持的notify类型: {notice_type}.{sub_type}")
|
||||||
case NoticeType.group_ban:
|
case NoticeType.group_ban:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ response_time_dict: Dict = {}
|
|||||||
async def get_response(request_id: str, timeout: int = 10) -> dict:
|
async def get_response(request_id: str, timeout: int = 10) -> dict:
|
||||||
response = await asyncio.wait_for(_get_response(request_id), timeout)
|
response = await asyncio.wait_for(_get_response(request_id), timeout)
|
||||||
_ = response_time_dict.pop(request_id)
|
_ = response_time_dict.pop(request_id)
|
||||||
logger.trace(f"响应信息id: {request_id} 已从响应字典中取出")
|
logger.info(f"响应信息id: {request_id} 已从响应字典中取出")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
async def _get_response(request_id: str) -> dict:
|
async def _get_response(request_id: str) -> dict:
|
||||||
@@ -28,7 +28,7 @@ async def put_response(response: dict):
|
|||||||
now_time = time.time()
|
now_time = time.time()
|
||||||
response_dict[echo_id] = response
|
response_dict[echo_id] = response
|
||||||
response_time_dict[echo_id] = now_time
|
response_time_dict[echo_id] = now_time
|
||||||
logger.trace(f"响应信息id: {echo_id} 已存入响应字典")
|
logger.info(f"响应信息id: {echo_id} 已存入响应字典")
|
||||||
|
|
||||||
|
|
||||||
async def check_timeout_response() -> None:
|
async def check_timeout_response() -> None:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
# TODO List:
|
||||||
|
|
||||||
[x] logger使用主程序的
|
[x] logger使用主程序的
|
||||||
[ ] 使用插件系统的config系统
|
[ ] 使用插件系统的config系统
|
||||||
[ ] 接收从napcat传递的所有信息
|
[ ] 接收从napcat传递的所有信息
|
||||||
@@ -5,3 +7,83 @@
|
|||||||
[ ] 单独一个模块负责与主程序通信
|
[ ] 单独一个模块负责与主程序通信
|
||||||
[ ] 使用event系统完善接口api
|
[ ] 使用event系统完善接口api
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
Event分为两种,一种是对外输出的event,由napcat插件自主触发并传递参数,另一种是接收外界输入的event,由外部插件触发并向napcat传递参数
|
||||||
|
|
||||||
|
|
||||||
|
## 例如,
|
||||||
|
|
||||||
|
### 对外输出的event:
|
||||||
|
|
||||||
|
napcat_on_received_text -> (message_seg: Seg) 接受到qq的文字消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_face -> (message_seg: Seg) 接受到qq的表情消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_reply -> (message_seg: Seg) 接受到qq的回复消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_image -> (message_seg: Seg) 接受到qq的图片消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_image -> (message_seg: Seg) 接受到qq的图片消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_record -> (message_seg: Seg) 接受到qq的语音消息,会向handler传递一个Seg
|
||||||
|
napcat_on_received_rps -> (message_seg: Seg) 接受到qq的猜拳魔法表情,会向handler传递一个Seg
|
||||||
|
napcat_on_received_friend_invitation -> (user_id: str) 接受到qq的好友请求,会向handler传递一个user_id
|
||||||
|
...
|
||||||
|
|
||||||
|
此类event不接受外部插件的触发,只能由napcat插件统一触发。
|
||||||
|
|
||||||
|
外部插件需要编写handler并订阅此类事件。
|
||||||
|
```python
|
||||||
|
from src.plugin_system.core.event_manager import event_manager
|
||||||
|
from src.plugin_system.base.base_event import HandlerResult
|
||||||
|
|
||||||
|
class MyEventHandler(BaseEventHandler):
|
||||||
|
handler_name = "my_handler"
|
||||||
|
handler_description = "我的自定义事件处理器"
|
||||||
|
weight = 10 # 权重,越大越先执行
|
||||||
|
intercept_message = False # 是否拦截消息
|
||||||
|
init_subscribe = ["napcat_on_received_text"] # 初始订阅的事件
|
||||||
|
|
||||||
|
async def execute(self, params: dict) -> HandlerResult:
|
||||||
|
"""处理事件"""
|
||||||
|
try:
|
||||||
|
message = params.get("message_seg")
|
||||||
|
print(f"收到消息: {message.data}")
|
||||||
|
|
||||||
|
# 业务逻辑处理
|
||||||
|
# ...
|
||||||
|
|
||||||
|
return HandlerResult(
|
||||||
|
success=True,
|
||||||
|
continue_process=True, # 是否继续让其他处理器处理
|
||||||
|
message="处理成功",
|
||||||
|
handler_name=self.handler_name
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return HandlerResult(
|
||||||
|
success=False,
|
||||||
|
continue_process=True,
|
||||||
|
message=f"处理失败: {str(e)}",
|
||||||
|
handler_name=self.handler_name
|
||||||
|
)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 接收外界输入的event:
|
||||||
|
|
||||||
|
napcat_kick_group <- (user_id, group_id) 踢出某个群组中的某个用户
|
||||||
|
napcat_mute_user <- (user_id, group_id, time) 禁言某个群组中的某个用户
|
||||||
|
napcat_unmute_user <- (user_id, group_id) 取消禁言某个群组中的某个用户
|
||||||
|
napcat_mute_group <- (user_id, group_id) 禁言某个群组
|
||||||
|
napcat_unmute_group <- (user_id, group_id) 取消禁言某个群组
|
||||||
|
napcat_add_friend <- (user_id) 向某个用户发出好友请求
|
||||||
|
napcat_accept_friend <- (user_id) 接收某个用户的好友请求
|
||||||
|
napcat_reject_friend <- (user_id) 拒绝某个用户的好友请求
|
||||||
|
...
|
||||||
|
此类事件只由外部插件触发并传递参数,由napcat完成请求任务。
|
||||||
|
|
||||||
|
外部插件需要触发此类的event并传递正确的参数。
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src.plugin_system.core.event_manager import event_manager
|
||||||
|
|
||||||
|
# 触发事件
|
||||||
|
await event_manager.trigger_event("napcat_accept_friend", user_id = 1234123)
|
||||||
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user