ErisPulse 2.3.1__py3-none-any.whl → 2.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ErisPulse/Core/Bases/__init__.pyi +14 -0
- ErisPulse/Core/Bases/adapter.py +13 -1
- ErisPulse/Core/Bases/adapter.pyi +140 -0
- ErisPulse/Core/Bases/module.pyi +52 -0
- ErisPulse/Core/Event/__init__.py +3 -1
- ErisPulse/Core/Event/__init__.pyi +26 -0
- ErisPulse/Core/Event/base.py +5 -0
- ErisPulse/Core/Event/base.pyi +62 -0
- ErisPulse/Core/Event/command.py +66 -17
- ErisPulse/Core/Event/command.pyi +113 -0
- ErisPulse/Core/Event/exceptions.pyi +43 -0
- ErisPulse/Core/Event/message.pyi +93 -0
- ErisPulse/Core/Event/meta.pyi +92 -0
- ErisPulse/Core/Event/notice.pyi +108 -0
- ErisPulse/Core/Event/request.pyi +76 -0
- ErisPulse/Core/Event/wrapper.py +592 -0
- ErisPulse/Core/Event/wrapper.pyi +404 -0
- ErisPulse/Core/__init__.py +16 -8
- ErisPulse/Core/__init__.pyi +17 -0
- ErisPulse/Core/_self_config.pyi +72 -0
- ErisPulse/Core/adapter.pyi +229 -0
- ErisPulse/Core/config.pyi +70 -0
- ErisPulse/Core/exceptions.pyi +60 -0
- ErisPulse/Core/lifecycle.py +6 -1
- ErisPulse/Core/lifecycle.pyi +92 -0
- ErisPulse/Core/logger.pyi +168 -0
- ErisPulse/Core/module.pyi +178 -0
- ErisPulse/Core/router.pyi +120 -0
- ErisPulse/Core/storage.pyi +273 -0
- ErisPulse/Core/ux.pyi +94 -0
- ErisPulse/__init__.py +10 -5
- ErisPulse/__init__.pyi +310 -0
- ErisPulse/__main__.py +0 -5
- ErisPulse/__main__.pyi +24 -0
- ErisPulse/sdk_protocol.py +150 -0
- ErisPulse/sdk_protocol.pyi +100 -0
- ErisPulse/utils/__init__.pyi +16 -0
- ErisPulse/utils/cli.py +9 -4
- ErisPulse/utils/cli.pyi +145 -0
- ErisPulse/utils/console.pyi +20 -0
- ErisPulse/utils/package_manager.pyi +224 -0
- ErisPulse/utils/reload_handler.pyi +64 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Bases/__init__.pyi +14 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Bases/adapter.pyi +140 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Bases/module.pyi +52 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/__init__.pyi +26 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/base.pyi +62 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/command.pyi +113 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/exceptions.pyi +43 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/message.pyi +93 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/meta.pyi +92 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/notice.pyi +108 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/request.pyi +76 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/Event/wrapper.pyi +404 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/__init__.pyi +17 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/_self_config.pyi +72 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/adapter.pyi +229 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/config.pyi +70 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/exceptions.pyi +60 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/lifecycle.pyi +92 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/logger.pyi +168 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/module.pyi +178 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/router.pyi +120 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/storage.pyi +273 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/Core/ux.pyi +94 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/__init__.pyi +310 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/__main__.pyi +24 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/sdk_protocol.pyi +100 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/utils/__init__.pyi +16 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/utils/cli.pyi +145 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/utils/console.pyi +20 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/utils/package_manager.pyi +224 -0
- erispulse-2.3.3.data/data/ErisPulse-stubs/ErisPulse/utils/reload_handler.pyi +64 -0
- {erispulse-2.3.1.dist-info → erispulse-2.3.3.dist-info}/METADATA +1 -3
- erispulse-2.3.3.dist-info/RECORD +98 -0
- erispulse-2.3.1.dist-info/RECORD +0 -34
- {erispulse-2.3.1.dist-info → erispulse-2.3.3.dist-info}/WHEEL +0 -0
- {erispulse-2.3.1.dist-info → erispulse-2.3.3.dist-info}/entry_points.txt +0 -0
- {erispulse-2.3.1.dist-info → erispulse-2.3.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ErisPulse 事件包装类
|
|
3
|
+
|
|
4
|
+
提供便捷的事件访问方法
|
|
5
|
+
|
|
6
|
+
{!--< tips >!--}
|
|
7
|
+
1. 继承自dict,完全兼容字典访问
|
|
8
|
+
2. 提供便捷方法简化事件处理
|
|
9
|
+
3. 支持点式访问 event.platform
|
|
10
|
+
{!--< /tips >!--}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Any, Dict, List, Optional, Callable, Awaitable, Union
|
|
14
|
+
from .. import adapter, logger
|
|
15
|
+
import asyncio
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Event(dict):
|
|
19
|
+
"""
|
|
20
|
+
事件包装类
|
|
21
|
+
|
|
22
|
+
提供便捷的事件访问方法
|
|
23
|
+
|
|
24
|
+
{!--< tips >!--}
|
|
25
|
+
所有方法都是可选的,不影响原有字典访问方式
|
|
26
|
+
{!--< /tips >!--}
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, event_data: Dict[str, Any]):
|
|
30
|
+
"""
|
|
31
|
+
初始化事件包装器
|
|
32
|
+
|
|
33
|
+
:param event_data: 原始事件数据
|
|
34
|
+
"""
|
|
35
|
+
super().__init__(event_data)
|
|
36
|
+
self._event_data = event_data
|
|
37
|
+
|
|
38
|
+
# ==================== 核心必填字段方法 ====================
|
|
39
|
+
|
|
40
|
+
def get_id(self) -> str:
|
|
41
|
+
"""
|
|
42
|
+
获取事件ID
|
|
43
|
+
|
|
44
|
+
:return: 事件ID
|
|
45
|
+
"""
|
|
46
|
+
return self.get("id", "")
|
|
47
|
+
|
|
48
|
+
def get_time(self) -> int:
|
|
49
|
+
"""
|
|
50
|
+
获取事件时间戳
|
|
51
|
+
|
|
52
|
+
:return: Unix时间戳(秒级)
|
|
53
|
+
"""
|
|
54
|
+
return self.get("time", 0)
|
|
55
|
+
|
|
56
|
+
def get_type(self) -> str:
|
|
57
|
+
"""
|
|
58
|
+
获取事件类型
|
|
59
|
+
|
|
60
|
+
:return: 事件类型(message/notice/request/meta等)
|
|
61
|
+
"""
|
|
62
|
+
return self.get("type", "")
|
|
63
|
+
|
|
64
|
+
def get_detail_type(self) -> str:
|
|
65
|
+
"""
|
|
66
|
+
获取事件详细类型
|
|
67
|
+
|
|
68
|
+
:return: 事件详细类型(private/group/friend等)
|
|
69
|
+
"""
|
|
70
|
+
return self.get("detail_type", "")
|
|
71
|
+
|
|
72
|
+
def get_platform(self) -> str:
|
|
73
|
+
"""
|
|
74
|
+
获取平台名称
|
|
75
|
+
|
|
76
|
+
:return: 平台名称
|
|
77
|
+
"""
|
|
78
|
+
return self.get("platform", "")
|
|
79
|
+
|
|
80
|
+
# ==================== 机器人信息方法 ====================
|
|
81
|
+
|
|
82
|
+
def get_self_platform(self) -> str:
|
|
83
|
+
"""
|
|
84
|
+
获取机器人平台
|
|
85
|
+
|
|
86
|
+
:return: 机器人平台名称
|
|
87
|
+
"""
|
|
88
|
+
return self.get("self", {}).get("platform", "")
|
|
89
|
+
|
|
90
|
+
def get_self_user_id(self) -> str:
|
|
91
|
+
"""
|
|
92
|
+
获取机器人用户ID
|
|
93
|
+
|
|
94
|
+
:return: 机器人用户ID
|
|
95
|
+
"""
|
|
96
|
+
return self.get("self", {}).get("user_id", "")
|
|
97
|
+
|
|
98
|
+
def get_self_info(self) -> Dict[str, Any]:
|
|
99
|
+
"""
|
|
100
|
+
获取机器人完整信息
|
|
101
|
+
|
|
102
|
+
:return: 机器人信息字典
|
|
103
|
+
"""
|
|
104
|
+
return self.get("self", {})
|
|
105
|
+
|
|
106
|
+
# ==================== 消息事件专用方法 ====================
|
|
107
|
+
|
|
108
|
+
def get_message(self) -> List[Dict[str, Any]]:
|
|
109
|
+
"""
|
|
110
|
+
获取消息段数组
|
|
111
|
+
|
|
112
|
+
:return: 消息段数组
|
|
113
|
+
"""
|
|
114
|
+
return self.get("message", [])
|
|
115
|
+
|
|
116
|
+
def get_alt_message(self) -> str:
|
|
117
|
+
"""
|
|
118
|
+
获取消息备用文本
|
|
119
|
+
|
|
120
|
+
:return: 消息备用文本
|
|
121
|
+
"""
|
|
122
|
+
return self.get("alt_message", "")
|
|
123
|
+
|
|
124
|
+
def get_text(self) -> str:
|
|
125
|
+
"""
|
|
126
|
+
获取纯文本内容
|
|
127
|
+
|
|
128
|
+
:return: 纯文本内容
|
|
129
|
+
"""
|
|
130
|
+
return self.get_alt_message()
|
|
131
|
+
|
|
132
|
+
def get_message_text(self) -> str:
|
|
133
|
+
"""
|
|
134
|
+
获取纯文本内容(别名)
|
|
135
|
+
|
|
136
|
+
:return: 纯文本内容
|
|
137
|
+
"""
|
|
138
|
+
return self.get_alt_message()
|
|
139
|
+
|
|
140
|
+
def has_mention(self) -> bool:
|
|
141
|
+
"""
|
|
142
|
+
是否包含@消息
|
|
143
|
+
|
|
144
|
+
:return: 是否包含@消息
|
|
145
|
+
"""
|
|
146
|
+
message_segments = self.get_message()
|
|
147
|
+
self_id = self.get_self_user_id()
|
|
148
|
+
|
|
149
|
+
for segment in message_segments:
|
|
150
|
+
if segment.get("type") == "mention":
|
|
151
|
+
if segment.get("data", {}).get("user_id") == self_id:
|
|
152
|
+
return True
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
def get_mentions(self) -> List[str]:
|
|
156
|
+
"""
|
|
157
|
+
获取所有被@的用户ID列表
|
|
158
|
+
|
|
159
|
+
:return: 被@的用户ID列表
|
|
160
|
+
"""
|
|
161
|
+
message_segments = self.get_message()
|
|
162
|
+
mentions = []
|
|
163
|
+
|
|
164
|
+
for segment in message_segments:
|
|
165
|
+
if segment.get("type") == "mention":
|
|
166
|
+
user_id = segment.get("data", {}).get("user_id")
|
|
167
|
+
if user_id:
|
|
168
|
+
mentions.append(user_id)
|
|
169
|
+
|
|
170
|
+
return mentions
|
|
171
|
+
|
|
172
|
+
def get_user_id(self) -> str:
|
|
173
|
+
"""
|
|
174
|
+
获取发送者ID
|
|
175
|
+
|
|
176
|
+
:return: 发送者用户ID
|
|
177
|
+
"""
|
|
178
|
+
return self.get("user_id", "")
|
|
179
|
+
|
|
180
|
+
def get_user_nickname(self) -> str:
|
|
181
|
+
"""
|
|
182
|
+
获取发送者昵称
|
|
183
|
+
|
|
184
|
+
:return: 发送者昵称
|
|
185
|
+
"""
|
|
186
|
+
return self.get("user_nickname", "")
|
|
187
|
+
|
|
188
|
+
def get_group_id(self) -> str:
|
|
189
|
+
"""
|
|
190
|
+
获取群组ID
|
|
191
|
+
|
|
192
|
+
:return: 群组ID(群聊消息)
|
|
193
|
+
"""
|
|
194
|
+
return self.get("group_id", "")
|
|
195
|
+
|
|
196
|
+
def get_sender(self) -> Dict[str, Any]:
|
|
197
|
+
"""
|
|
198
|
+
获取发送者信息字典
|
|
199
|
+
|
|
200
|
+
:return: 发送者信息字典
|
|
201
|
+
"""
|
|
202
|
+
return {
|
|
203
|
+
"user_id": self.get_user_id(),
|
|
204
|
+
"nickname": self.get_user_nickname(),
|
|
205
|
+
"group_id": self.get_group_id() if self.is_group_message() else None
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
# ==================== 消息类型判断 ====================
|
|
209
|
+
|
|
210
|
+
def is_message(self) -> bool:
|
|
211
|
+
"""
|
|
212
|
+
是否为消息事件
|
|
213
|
+
|
|
214
|
+
:return: 是否为消息事件
|
|
215
|
+
"""
|
|
216
|
+
return self.get_type() == "message"
|
|
217
|
+
|
|
218
|
+
def is_private_message(self) -> bool:
|
|
219
|
+
"""
|
|
220
|
+
是否为私聊消息
|
|
221
|
+
|
|
222
|
+
:return: 是否为私聊消息
|
|
223
|
+
"""
|
|
224
|
+
return self.is_message() and self.get_detail_type() == "private"
|
|
225
|
+
|
|
226
|
+
def is_group_message(self) -> bool:
|
|
227
|
+
"""
|
|
228
|
+
是否为群聊消息
|
|
229
|
+
|
|
230
|
+
:return: 是否为群聊消息
|
|
231
|
+
"""
|
|
232
|
+
return self.is_message() and self.get_detail_type() == "group"
|
|
233
|
+
|
|
234
|
+
def is_at_message(self) -> bool:
|
|
235
|
+
"""
|
|
236
|
+
是否为@消息
|
|
237
|
+
|
|
238
|
+
:return: 是否为@消息
|
|
239
|
+
"""
|
|
240
|
+
return self.has_mention()
|
|
241
|
+
|
|
242
|
+
# ==================== 通知事件专用方法 ====================
|
|
243
|
+
|
|
244
|
+
def get_operator_id(self) -> str:
|
|
245
|
+
"""
|
|
246
|
+
获取操作者ID
|
|
247
|
+
|
|
248
|
+
:return: 操作者ID
|
|
249
|
+
"""
|
|
250
|
+
return self.get("operator_id", "")
|
|
251
|
+
|
|
252
|
+
def get_operator_nickname(self) -> str:
|
|
253
|
+
"""
|
|
254
|
+
获取操作者昵称
|
|
255
|
+
|
|
256
|
+
:return: 操作者昵称
|
|
257
|
+
"""
|
|
258
|
+
return self.get("operator_nickname", "")
|
|
259
|
+
|
|
260
|
+
# ==================== 通知类型判断 ====================
|
|
261
|
+
|
|
262
|
+
def is_notice(self) -> bool:
|
|
263
|
+
"""
|
|
264
|
+
是否为通知事件
|
|
265
|
+
|
|
266
|
+
:return: 是否为通知事件
|
|
267
|
+
"""
|
|
268
|
+
return self.get_type() == "notice"
|
|
269
|
+
|
|
270
|
+
def is_group_member_increase(self) -> bool:
|
|
271
|
+
"""
|
|
272
|
+
群成员增加
|
|
273
|
+
|
|
274
|
+
:return: 是否为群成员增加事件
|
|
275
|
+
"""
|
|
276
|
+
return self.is_notice() and self.get_detail_type() == "group_member_increase"
|
|
277
|
+
|
|
278
|
+
def is_group_member_decrease(self) -> bool:
|
|
279
|
+
"""
|
|
280
|
+
群成员减少
|
|
281
|
+
|
|
282
|
+
:return: 是否为群成员减少事件
|
|
283
|
+
"""
|
|
284
|
+
return self.is_notice() and self.get_detail_type() == "group_member_decrease"
|
|
285
|
+
|
|
286
|
+
def is_friend_add(self) -> bool:
|
|
287
|
+
"""
|
|
288
|
+
好友添加
|
|
289
|
+
|
|
290
|
+
:return: 是否为好友添加事件
|
|
291
|
+
"""
|
|
292
|
+
return self.is_notice() and self.get_detail_type() == "friend_add"
|
|
293
|
+
|
|
294
|
+
def is_friend_delete(self) -> bool:
|
|
295
|
+
"""
|
|
296
|
+
好友删除
|
|
297
|
+
|
|
298
|
+
:return: 是否为好友删除事件
|
|
299
|
+
"""
|
|
300
|
+
return self.is_notice() and self.get_detail_type() == "friend_delete"
|
|
301
|
+
|
|
302
|
+
# ==================== 请求事件专用方法 ====================
|
|
303
|
+
|
|
304
|
+
def get_comment(self) -> str:
|
|
305
|
+
"""
|
|
306
|
+
获取请求附言
|
|
307
|
+
|
|
308
|
+
:return: 请求附言
|
|
309
|
+
"""
|
|
310
|
+
return self.get("comment", "")
|
|
311
|
+
|
|
312
|
+
# ==================== 请求类型判断 ====================
|
|
313
|
+
|
|
314
|
+
def is_request(self) -> bool:
|
|
315
|
+
"""
|
|
316
|
+
是否为请求事件
|
|
317
|
+
|
|
318
|
+
:return: 是否为请求事件
|
|
319
|
+
"""
|
|
320
|
+
return self.get_type() == "request"
|
|
321
|
+
|
|
322
|
+
def is_friend_request(self) -> bool:
|
|
323
|
+
"""
|
|
324
|
+
是否为好友请求
|
|
325
|
+
|
|
326
|
+
:return: 是否为好友请求
|
|
327
|
+
"""
|
|
328
|
+
return self.is_request() and self.get_detail_type() == "friend"
|
|
329
|
+
|
|
330
|
+
def is_group_request(self) -> bool:
|
|
331
|
+
"""
|
|
332
|
+
是否为群组请求
|
|
333
|
+
|
|
334
|
+
:return: 是否为群组请求
|
|
335
|
+
"""
|
|
336
|
+
return self.is_request() and self.get_detail_type() == "group"
|
|
337
|
+
|
|
338
|
+
# ==================== 回复功能 ====================
|
|
339
|
+
|
|
340
|
+
def _get_adapter_and_target(self) -> tuple:
|
|
341
|
+
"""
|
|
342
|
+
获取适配器实例和目标信息
|
|
343
|
+
|
|
344
|
+
:return: (适配器实例, 详细类型, 目标ID)
|
|
345
|
+
"""
|
|
346
|
+
platform = self.get_platform()
|
|
347
|
+
if not platform:
|
|
348
|
+
raise ValueError("平台信息缺失")
|
|
349
|
+
|
|
350
|
+
adapter_instance = getattr(adapter, platform, None)
|
|
351
|
+
if not adapter_instance:
|
|
352
|
+
raise ValueError(f"找不到平台 {platform} 的适配器")
|
|
353
|
+
|
|
354
|
+
group_id = self.get_group_id()
|
|
355
|
+
user_id = self.get_user_id()
|
|
356
|
+
|
|
357
|
+
if group_id:
|
|
358
|
+
detail_type = "group"
|
|
359
|
+
target_id = group_id
|
|
360
|
+
else:
|
|
361
|
+
detail_type = "user"
|
|
362
|
+
target_id = user_id
|
|
363
|
+
|
|
364
|
+
return adapter_instance, detail_type, target_id
|
|
365
|
+
|
|
366
|
+
async def reply(self,
|
|
367
|
+
content: str,
|
|
368
|
+
method: str = "Text",
|
|
369
|
+
**kwargs) -> Any:
|
|
370
|
+
"""
|
|
371
|
+
通用回复方法
|
|
372
|
+
|
|
373
|
+
基于适配器的Text方法,但可以通过method参数指定其他发送方法
|
|
374
|
+
|
|
375
|
+
:param content: 发送内容(文本、URL等,取决于method参数)
|
|
376
|
+
:param method: 适配器发送方法,默认为"Text"
|
|
377
|
+
可选值: "Text", "Image", "Voice", "Video", "File" 等
|
|
378
|
+
:param kwargs: 额外参数,例如Mention方法的user_id
|
|
379
|
+
:return: 适配器发送方法的返回值
|
|
380
|
+
|
|
381
|
+
:example:
|
|
382
|
+
>>> await event.reply("你好") # 发送文本
|
|
383
|
+
>>> await event.reply("http://example.com/image.jpg", method="Image") # 发送图片
|
|
384
|
+
>>> await event.reply("回复内容", method="Mention", user_id="123456") # @用户并发送
|
|
385
|
+
>>> await event.reply("http://example.com/voice.mp3", method="Voice") # 发送语音
|
|
386
|
+
"""
|
|
387
|
+
adapter_instance, detail_type, target_id = self._get_adapter_and_target()
|
|
388
|
+
|
|
389
|
+
# 构建发送链
|
|
390
|
+
send_chain = adapter_instance.Send.To(detail_type, target_id)
|
|
391
|
+
|
|
392
|
+
# 处理特殊方法
|
|
393
|
+
if method == "Mention":
|
|
394
|
+
user_id = kwargs.get("user_id")
|
|
395
|
+
if user_id is None:
|
|
396
|
+
user_id = self.get_user_id()
|
|
397
|
+
send_chain = send_chain.Mention(user_id)
|
|
398
|
+
method = "Text"
|
|
399
|
+
|
|
400
|
+
# 调用指定方法
|
|
401
|
+
send_method = getattr(send_chain, method, None)
|
|
402
|
+
if not send_method or not callable(send_method):
|
|
403
|
+
raise ValueError(f"适配器不支持方法: {method}")
|
|
404
|
+
|
|
405
|
+
return await send_method(content)
|
|
406
|
+
|
|
407
|
+
async def forward_to_group(self, group_id: str):
|
|
408
|
+
"""
|
|
409
|
+
转发到群组
|
|
410
|
+
|
|
411
|
+
:param group_id: 目标群组ID
|
|
412
|
+
"""
|
|
413
|
+
adapter_instance = getattr(adapter, self.get_platform(), None)
|
|
414
|
+
if not adapter_instance:
|
|
415
|
+
raise ValueError(f"找不到平台 {self.get_platform()} 的适配器")
|
|
416
|
+
await adapter_instance.Forward.To("group", group_id).Event(self)
|
|
417
|
+
|
|
418
|
+
async def forward_to_user(self, user_id: str):
|
|
419
|
+
"""
|
|
420
|
+
转发给用户
|
|
421
|
+
|
|
422
|
+
:param user_id: 目标用户ID
|
|
423
|
+
"""
|
|
424
|
+
adapter_instance = getattr(adapter, self.get_platform(), None)
|
|
425
|
+
if not adapter_instance:
|
|
426
|
+
raise ValueError(f"找不到平台 {self.get_platform()} 的适配器")
|
|
427
|
+
await adapter_instance.Forward.To("user", user_id).Event(self)
|
|
428
|
+
|
|
429
|
+
# ==================== 等待回复功能 ====================
|
|
430
|
+
|
|
431
|
+
async def wait_reply(self,
|
|
432
|
+
prompt: str = None,
|
|
433
|
+
timeout: float = 60.0,
|
|
434
|
+
callback: Callable[[Dict[str, Any]], Awaitable[Any]] = None,
|
|
435
|
+
validator: Callable[[Dict[str, Any]], bool] = None) -> Optional['Event']:
|
|
436
|
+
"""
|
|
437
|
+
等待用户回复
|
|
438
|
+
|
|
439
|
+
:param prompt: 提示消息,如果提供会发送给用户
|
|
440
|
+
:param timeout: 等待超时时间(秒)
|
|
441
|
+
:param callback: 回调函数,当收到回复时执行
|
|
442
|
+
:param validator: 验证函数,用于验证回复是否有效
|
|
443
|
+
:return: 用户回复的事件数据,如果超时则返回None
|
|
444
|
+
"""
|
|
445
|
+
platform = self.get_platform()
|
|
446
|
+
user_id = self.get_user_id()
|
|
447
|
+
group_id = self.get_group_id()
|
|
448
|
+
target_id = group_id or user_id
|
|
449
|
+
detail_type = "group" if group_id else "private"
|
|
450
|
+
|
|
451
|
+
# 导入command处理器以复用等待逻辑
|
|
452
|
+
from .command import command as command_handler
|
|
453
|
+
|
|
454
|
+
# 发送提示消息(如果提供)
|
|
455
|
+
if prompt:
|
|
456
|
+
try:
|
|
457
|
+
adapter_instance = getattr(adapter, platform)
|
|
458
|
+
await adapter_instance.Send.To(detail_type, target_id).Text(prompt)
|
|
459
|
+
except Exception as e:
|
|
460
|
+
logger.warning(f"发送提示消息失败: {e}")
|
|
461
|
+
|
|
462
|
+
# 使用command处理器的wait_reply方法
|
|
463
|
+
result = await command_handler.wait_reply(
|
|
464
|
+
self,
|
|
465
|
+
prompt=None, # 已经发送过提示了
|
|
466
|
+
timeout=timeout,
|
|
467
|
+
callback=callback,
|
|
468
|
+
validator=validator
|
|
469
|
+
)
|
|
470
|
+
|
|
471
|
+
# 将结果转换为Event对象
|
|
472
|
+
if result:
|
|
473
|
+
return Event(result)
|
|
474
|
+
return None
|
|
475
|
+
|
|
476
|
+
# ==================== 原始数据和元信息 ====================
|
|
477
|
+
|
|
478
|
+
def get_raw(self) -> Dict[str, Any]:
|
|
479
|
+
"""
|
|
480
|
+
获取原始事件数据
|
|
481
|
+
|
|
482
|
+
:return: 原始事件数据
|
|
483
|
+
"""
|
|
484
|
+
platform = self.get_platform()
|
|
485
|
+
raw_key = f"{platform}_raw" if platform else "raw"
|
|
486
|
+
return self.get(raw_key, {})
|
|
487
|
+
|
|
488
|
+
def get_raw_type(self) -> str:
|
|
489
|
+
"""
|
|
490
|
+
获取原始事件类型
|
|
491
|
+
|
|
492
|
+
:return: 原始事件类型
|
|
493
|
+
"""
|
|
494
|
+
platform = self.get_platform()
|
|
495
|
+
raw_type_key = f"{platform}_raw_type" if platform else "raw_type"
|
|
496
|
+
return self.get(raw_type_key, "")
|
|
497
|
+
|
|
498
|
+
# ==================== 命令信息 ====================
|
|
499
|
+
|
|
500
|
+
def get_command_name(self) -> str:
|
|
501
|
+
"""
|
|
502
|
+
获取命令名称
|
|
503
|
+
|
|
504
|
+
:return: 命令名称
|
|
505
|
+
"""
|
|
506
|
+
return self.get("command", {}).get("name", "")
|
|
507
|
+
|
|
508
|
+
def get_command_args(self) -> List[str]:
|
|
509
|
+
"""
|
|
510
|
+
获取命令参数
|
|
511
|
+
|
|
512
|
+
:return: 命令参数列表
|
|
513
|
+
"""
|
|
514
|
+
return self.get("command", {}).get("args", [])
|
|
515
|
+
|
|
516
|
+
def get_command_raw(self) -> str:
|
|
517
|
+
"""
|
|
518
|
+
获取命令原始文本
|
|
519
|
+
|
|
520
|
+
:return: 命令原始文本
|
|
521
|
+
"""
|
|
522
|
+
return self.get("command", {}).get("raw", "")
|
|
523
|
+
|
|
524
|
+
def get_command_info(self) -> Dict[str, Any]:
|
|
525
|
+
"""
|
|
526
|
+
获取完整命令信息
|
|
527
|
+
|
|
528
|
+
:return: 命令信息字典
|
|
529
|
+
"""
|
|
530
|
+
return self.get("command", {})
|
|
531
|
+
|
|
532
|
+
def is_command(self) -> bool:
|
|
533
|
+
"""
|
|
534
|
+
是否为命令
|
|
535
|
+
|
|
536
|
+
:return: 是否为命令
|
|
537
|
+
"""
|
|
538
|
+
return "command" in self and bool(self.get("command"))
|
|
539
|
+
|
|
540
|
+
# ==================== 工具方法 ====================
|
|
541
|
+
|
|
542
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
543
|
+
"""
|
|
544
|
+
转换为字典
|
|
545
|
+
|
|
546
|
+
:return: 事件数据字典
|
|
547
|
+
"""
|
|
548
|
+
return dict(self)
|
|
549
|
+
|
|
550
|
+
def is_processed(self) -> bool:
|
|
551
|
+
"""
|
|
552
|
+
是否已被处理
|
|
553
|
+
|
|
554
|
+
:return: 是否已被处理
|
|
555
|
+
"""
|
|
556
|
+
return self.get("_processed", False)
|
|
557
|
+
|
|
558
|
+
def mark_processed(self):
|
|
559
|
+
"""
|
|
560
|
+
标记为已处理
|
|
561
|
+
"""
|
|
562
|
+
self["_processed"] = True
|
|
563
|
+
|
|
564
|
+
# ==================== 魔术方法 ====================
|
|
565
|
+
|
|
566
|
+
def __getattr__(self, name: str) -> Any:
|
|
567
|
+
"""
|
|
568
|
+
支持点式访问字典键
|
|
569
|
+
|
|
570
|
+
:param name: 属性名
|
|
571
|
+
:return: 属性值
|
|
572
|
+
"""
|
|
573
|
+
try:
|
|
574
|
+
return self[name]
|
|
575
|
+
except KeyError:
|
|
576
|
+
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
|
|
577
|
+
|
|
578
|
+
def __repr__(self) -> str:
|
|
579
|
+
"""
|
|
580
|
+
字符串表示
|
|
581
|
+
|
|
582
|
+
:return: 字符串表示
|
|
583
|
+
"""
|
|
584
|
+
event_type = self.get_type()
|
|
585
|
+
detail_type = self.get_detail_type()
|
|
586
|
+
platform = self.get_platform()
|
|
587
|
+
return f"Event(type={event_type}, detail_type={detail_type}, platform={platform})"
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
__all__ = [
|
|
591
|
+
"Event"
|
|
592
|
+
]
|