事件工厂111
This commit is contained in:
33
core/bot.py
33
core/bot.py
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .ws import WS
|
||||
from ..models.event import Event
|
||||
from models import OneBotEvent
|
||||
|
||||
|
||||
class Bot:
|
||||
@@ -33,40 +33,53 @@ class Bot:
|
||||
"""
|
||||
return await self.ws.call_api(action, params)
|
||||
|
||||
async def send_group_msg(self, group_id: int, message: str) -> dict:
|
||||
async def send_group_msg(self, group_id: int, message: str, auto_escape: bool = False) -> dict:
|
||||
"""
|
||||
发送群消息
|
||||
|
||||
:param group_id: 群号
|
||||
:param message: 消息内容
|
||||
:param auto_escape: 是否自动转义
|
||||
:return: API 响应结果
|
||||
"""
|
||||
return await self.call_api(
|
||||
"send_group_msg", {"group_id": group_id, "message": message}
|
||||
"send_group_msg", {"group_id": group_id, "message": message, "auto_escape": auto_escape}
|
||||
)
|
||||
|
||||
async def send_private_msg(self, user_id: int, message: str) -> dict:
|
||||
async def send_private_msg(self, user_id: int, message: str, auto_escape: bool = False) -> dict:
|
||||
"""
|
||||
发送私聊消息
|
||||
|
||||
:param user_id: 用户 QQ 号
|
||||
:param message: 消息内容
|
||||
:param auto_escape: 是否自动转义
|
||||
:return: API 响应结果
|
||||
"""
|
||||
return await self.call_api(
|
||||
"send_private_msg", {"user_id": user_id, "message": message}
|
||||
"send_private_msg", {"user_id": user_id, "message": message, "auto_escape": auto_escape}
|
||||
)
|
||||
|
||||
async def send(self, event: "Event", message: str) -> dict:
|
||||
async def send(self, event: "OneBotEvent", message: str, auto_escape: bool = False) -> dict:
|
||||
"""
|
||||
智能发送消息,根据事件类型自动选择发送方式
|
||||
|
||||
:param event: 触发事件对象
|
||||
:param message: 消息内容
|
||||
:param auto_escape: 是否自动转义
|
||||
:return: API 响应结果
|
||||
"""
|
||||
if event.message_type == "group" and event.group_id:
|
||||
return await self.send_group_msg(event.group_id, message)
|
||||
elif event.user_id:
|
||||
return await self.send_private_msg(event.user_id, message)
|
||||
# 如果是消息事件,直接调用 reply
|
||||
if hasattr(event, "reply"):
|
||||
await event.reply(message, auto_escape)
|
||||
return {"status": "ok", "msg": "Replied via event.reply()"}
|
||||
|
||||
# 尝试从事件中获取 user_id 或 group_id
|
||||
user_id = getattr(event, "user_id", None)
|
||||
group_id = getattr(event, "group_id", None)
|
||||
|
||||
if group_id:
|
||||
return await self.send_group_msg(group_id, message, auto_escape)
|
||||
elif user_id:
|
||||
return await self.send_private_msg(user_id, message, auto_escape)
|
||||
|
||||
return {"status": "failed", "msg": "Unknown message target"}
|
||||
|
||||
@@ -73,6 +73,23 @@ class CommandManager:
|
||||
|
||||
return decorator
|
||||
|
||||
# --- 统一事件分发入口 ---
|
||||
async def handle_event(self, bot, event):
|
||||
"""
|
||||
统一事件分发入口
|
||||
|
||||
:param bot: Bot 实例
|
||||
:param event: 事件对象
|
||||
"""
|
||||
post_type = event.post_type
|
||||
|
||||
if post_type == 'message':
|
||||
await self.handle_message(bot, event)
|
||||
elif post_type == 'notice':
|
||||
await self.handle_notice(bot, event)
|
||||
elif post_type == 'request':
|
||||
await self.handle_request(bot, event)
|
||||
|
||||
# --- 消息分发逻辑 ---
|
||||
async def handle_message(self, bot, event):
|
||||
"""
|
||||
|
||||
44
core/ws.py
44
core/ws.py
@@ -11,7 +11,7 @@ from datetime import datetime
|
||||
|
||||
import websockets
|
||||
|
||||
from models import Event
|
||||
from models import EventFactory
|
||||
|
||||
from .bot import Bot
|
||||
from .command_manager import matcher
|
||||
@@ -76,6 +76,7 @@ class WS:
|
||||
data = json.loads(message)
|
||||
|
||||
# 1. 处理 API 响应
|
||||
# 如果消息中包含 echo 字段,说明是 API 调用的响应
|
||||
echo_id = data.get("echo")
|
||||
if echo_id and echo_id in self._pending_requests:
|
||||
future = self._pending_requests.pop(echo_id)
|
||||
@@ -84,12 +85,14 @@ class WS:
|
||||
continue
|
||||
|
||||
# 2. 处理上报事件
|
||||
# 如果消息中包含 post_type 字段,说明是 OneBot 上报的事件
|
||||
if "post_type" in data:
|
||||
# 使用 create_task 异步执行,避免阻塞
|
||||
# 使用 create_task 异步执行,避免阻塞 WebSocket 接收循环
|
||||
asyncio.create_task(self.on_event(data))
|
||||
|
||||
except Exception as e:
|
||||
print(f" 解析消息异常: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
async def on_event(self, raw_data: dict):
|
||||
"""
|
||||
@@ -98,40 +101,25 @@ class WS:
|
||||
:param raw_data: 原始事件数据字典
|
||||
"""
|
||||
try:
|
||||
# 解析为 Event 对象
|
||||
event = Event.from_dict(raw_data)
|
||||
event.bot = self.bot
|
||||
# 使用工厂创建事件对象
|
||||
event = EventFactory.create_event(raw_data)
|
||||
event.bot = self.bot # 注入 Bot 实例
|
||||
|
||||
# 格式化时间用于打印
|
||||
# 打印日志
|
||||
t = datetime.fromtimestamp(event.time).strftime("%H:%M:%S")
|
||||
|
||||
# --- 分流处理 ---
|
||||
|
||||
# A. 消息事件 (Message)
|
||||
if event.post_type == "message":
|
||||
print(
|
||||
f" [{t}] [消息] {event.message_type} | {event.user_id}: {event.raw_message}"
|
||||
)
|
||||
await matcher.handle_message(self.bot, event)
|
||||
|
||||
# B. 通知事件 (Notice)
|
||||
sender_name = event.sender.nickname if event.sender else "Unknown"
|
||||
print(f" [{t}] [消息] {event.message_type} | {event.user_id}({sender_name}): {event.raw_message}")
|
||||
elif event.post_type == "notice":
|
||||
print(
|
||||
f" [{t}] [通知] {event.notice_type} | 来自: {event.group_id or '私聊'}"
|
||||
)
|
||||
await matcher.handle_notice(self.bot, event)
|
||||
|
||||
# C. 请求事件 (Request)
|
||||
print(f" [{t}] [通知] {event.notice_type}")
|
||||
elif event.post_type == "request":
|
||||
print(f" [{t}] [请求] {event.request_type} | 内容: {event.comment}")
|
||||
await matcher.handle_request(self.bot, event)
|
||||
print(f" [{t}] [请求] {event.request_type}")
|
||||
|
||||
# D. 元事件 (Meta Event) - 通常用来心跳检测,可不处理
|
||||
elif event.post_type == "meta_event":
|
||||
pass
|
||||
# 分发事件
|
||||
await matcher.handle_event(self.bot, event)
|
||||
|
||||
except Exception as e:
|
||||
print(f"事件分发失败: {e}")
|
||||
print(f" 事件处理异常: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
async def call_api(self, action: str, params: dict = None):
|
||||
|
||||
Reference in New Issue
Block a user