ErisPulse 1.1.15__py3-none-any.whl → 1.2.0__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/__init__.py CHANGED
@@ -36,10 +36,13 @@ sdk.logger.info("SDK已初始化")
36
36
 
37
37
  """
38
38
 
39
- import types
40
- sdk = types.SimpleNamespace()
41
39
  import os
42
40
  import sys
41
+
42
+ # 依赖类型
43
+ import types
44
+
45
+ # BaseModules: SDK核心模块
43
46
  from . import util
44
47
  from .raiserr import raiserr
45
48
  from .logger import logger
@@ -50,177 +53,254 @@ from .adapter import adapter, BaseAdapter, SendDSL
50
53
  # 这里不能删,确保windows下的shell能正确显示颜色
51
54
  os.system('')
52
55
 
53
- setattr(sdk, "env", env)
54
- setattr(sdk, "mods", mods)
55
- setattr(sdk, "util", util)
56
- setattr(sdk, "raiserr", raiserr)
57
- setattr(sdk, "logger", logger)
58
- setattr(sdk, "adapter", adapter)
59
- setattr(sdk, "SendDSL", SendDSL)
60
- setattr(sdk, "BaseAdapter", BaseAdapter)
61
-
62
- # 注册 ErrorHook 并预注册常用错误类型
63
- raiserr.register("CaughtExternalError" , doc="捕获的非SDK抛出的异常")
64
- raiserr.register("InitError" , doc="SDK初始化错误")
65
- raiserr.register("MissingDependencyError" , doc="缺少依赖错误")
66
- raiserr.register("InvalidDependencyError" , doc="依赖无效错误")
67
- raiserr.register("CycleDependencyError" , doc="依赖循环错误")
68
- raiserr.register("ModuleLoadError" , doc="模块加载错误")
69
-
70
- def init() -> None:
56
+ sdk = types.SimpleNamespace()
57
+
58
+ BaseModules = {
59
+ "util" : util,
60
+ "logger" : logger,
61
+ "env" : env,
62
+ "mods" : mods,
63
+ "adapter" : adapter,
64
+ "SendDSL" : SendDSL, # 链式发送基类 - 兼容原 sdk.SendDSL | 待弃用, 需要在 Adapter继承类中手动创建嵌套类并集成 super().SendDSL()
65
+ "AdapterFather" : BaseAdapter,
66
+ "BaseAdapter" : BaseAdapter
67
+ }
68
+
69
+ BaseErrors = {
70
+ "ExternalError" : "外部捕获异常",
71
+ "CaughtExternalError" : "捕获的非SDK抛出的异常",
72
+ "InitError" : "SDK初始化错误",
73
+ "MissingDependencyError" : "缺少依赖错误",
74
+ "InvalidDependencyError" : "依赖无效错误",
75
+ "CycleDependencyError" : "依赖循环错误",
76
+ "ModuleLoadError" : "模块加载错误"
77
+ }
78
+
79
+ for module, moduleObj in BaseModules.items():
80
+ try:
81
+ setattr(sdk, module, moduleObj)
82
+ except Exception as e:
83
+ raise e
84
+
85
+ for error, doc in BaseErrors.items():
71
86
  try:
72
- logger.info("[Init] SDK 正在初始化...")
73
- if env.create_env_file_if_not_exists():
87
+ raiserr.register(error, doc=doc)
88
+ except Exception as e:
89
+ raise e
90
+ def init_progress():
91
+ from pathlib import Path
92
+ env_file = Path("env.py")
93
+ main_file = Path("main.py")
94
+
95
+ if not env_file.exists():
96
+ content = '''# env.py
97
+ # ErisPulse 环境配置文件
98
+ # 本文件由 SDK 自动创建,请勿随意删除
99
+ # 配置项可通过 sdk.env.get(key, default) 获取,或使用 sdk.env.set(key, value) 设置
100
+ # 你也可以像写普通变量一样直接定义配置项,例如:
101
+ #
102
+ # MY_CONFIG = "value"
103
+ # MY_CONFIG_2 = {"key": "value"}
104
+ # MY_CONFIG_3 = [1, 2, 3]
105
+ #
106
+ # sdk.env.set("MY_CONFIG", "value")
107
+ # sdk.env.set("MY_CONFIG_2", {"key": "value"})
108
+ # sdk.env.set("MY_CONFIG_3", [1, 2, 3])
109
+ #
110
+ # 这些变量会自动被加载到 SDK 的配置系统中,可通过 sdk.env.MY_CONFIG 或 sdk.env.get("MY_CONFIG") 访问。
111
+
112
+ from ErisPulse import sdk
113
+ '''
114
+ if not main_file.exists():
115
+ content += '''# main.py
116
+ # ErisPulse 主程序文件
117
+ # 本文件由 SDK 自动创建,您可随意修改
118
+
119
+ from ErisPulse import sdk
120
+
121
+ async def main():
122
+ try:
123
+ sdk.init()
124
+ await sdk.adapter.startup()
125
+
126
+ except Exception as e:
127
+ sdk.logger.error(e)
128
+ except KeyboardInterrupt:
129
+ sdk.logger.info("正在停止程序")
130
+ finally:
131
+ await sdk.shutdown()
132
+
133
+ if __name__ == "__main__":
134
+ asyncio.run(main())
135
+ '''
136
+ try:
137
+ with open(env_file, "w", encoding="utf-8") as f:
138
+ f.write(content)
139
+ return True
140
+ except Exception as e:
141
+ from . import sdk
142
+ sdk.logger.error(f"无法初始化项目环境: {e}")
143
+ return False
144
+ return False
145
+
146
+ def _prepare_environment() -> bool:
147
+ # 检查环境
148
+ logger.info("[Init] 准备初始化环境...")
149
+ try:
150
+ if init_progress():
74
151
  logger.info("[Init] 项目首次初始化,建议先配置环境变量")
75
152
  if input("是否立即退出?(y/n): ").strip().lower() == "y":
76
- sys.exit(0)
153
+ return False
77
154
  env.load_env_file()
78
-
79
- sdkModulePath = os.path.join(os.path.dirname(__file__), "modules")
80
-
81
- if not os.path.exists(sdkModulePath):
82
- os.makedirs(sdkModulePath)
83
-
84
- sys.path.append(sdkModulePath)
85
-
86
- TempModules = [
87
- x for x in os.listdir(sdkModulePath)
88
- if os.path.isdir(os.path.join(sdkModulePath, x))
89
- ]
90
-
91
- sdkInstalledModuleNames: list[str] = []
92
- disabledModules: list[str] = []
93
-
94
- # ==== 扫描模块并收集基本信息 ====
95
- module_objs = {} # {module_name: moduleObj}
96
- for module_name in TempModules:
97
- try:
98
- moduleObj = __import__(module_name)
99
- if not hasattr(moduleObj, "moduleInfo") or not isinstance(moduleObj.moduleInfo, dict):
100
- logger.warning(f"模块 {module_name} 缺少有效的 'moduleInfo' 字典.")
101
- continue
102
- if "name" not in moduleObj.moduleInfo.get("meta", {}):
103
- logger.warning(f"模块 {module_name} 的 'moduleInfo' 字典 缺少必要 'name' 键.")
104
- continue
105
- if not hasattr(moduleObj, "Main"):
106
- logger.warning(f"模块 {module_name} 缺少 'Main' 类.")
107
- continue
108
-
109
- meta_name = moduleObj.moduleInfo["meta"]["name"]
110
- module_info = mods.get_module(meta_name)
111
- if module_info is None:
112
- module_info = {
113
- "status": True,
114
- "info": moduleObj.moduleInfo
115
- }
116
- mods.set_module(meta_name, module_info)
117
- logger.info(f"模块 {meta_name} 信息已初始化并存储到数据库")
118
-
119
- if not module_info.get('status', True):
120
- disabledModules.append(module_name)
121
- logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
122
- continue
123
-
124
- required_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
125
- missing_required_deps = [dep for dep in required_deps if dep not in TempModules]
126
- if missing_required_deps:
127
- logger.error(f"模块 {module_name} 缺少必需依赖: {missing_required_deps}")
128
- raiserr.MissingDependencyError(f"模块 {module_name} 缺少必需依赖: {missing_required_deps}")
129
-
130
- optional_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
131
- available_optional_deps = []
132
- for dep in optional_deps:
133
- if isinstance(dep, list):
134
- available_deps = [d for d in dep if d in TempModules]
135
- if available_deps:
136
- available_optional_deps.extend(available_deps)
137
- elif dep in TempModules:
138
- available_optional_deps.append(dep)
139
-
140
- if optional_deps and not available_optional_deps:
141
- logger.warning(f"模块 {module_name} 缺少所有可选依赖: {optional_deps}")
142
-
143
- module_objs[module_name] = moduleObj
144
- sdkInstalledModuleNames.append(module_name)
145
-
146
- except Exception as e:
147
- logger.warning(f"模块 {module_name} 加载失败: {e}")
155
+ return True
156
+ except Exception as e:
157
+ logger.error(f"环境准备失败: {e}")
158
+ return False
159
+ def _scan_modules(module_path: str) -> tuple[dict, list, list]:
160
+ # 扫描并验证模块
161
+ module_objs = {}
162
+ enabled_modules = []
163
+ disabled_modules = []
164
+
165
+ if not os.path.exists(module_path):
166
+ os.makedirs(module_path)
167
+ sys.path.append(module_path)
168
+
169
+ for module_name in os.listdir(module_path):
170
+ if not os.path.isdir(os.path.join(module_path, module_name)):
171
+ continue
172
+
173
+ try:
174
+ moduleObj = __import__(module_name)
175
+ if not _validate_module(moduleObj, module_name):
148
176
  continue
149
-
150
- # ==== 构建依赖图并进行拓扑排序 ====
151
- sdkModuleDependencies = {}
152
- for module_name in sdkInstalledModuleNames:
153
- moduleObj = module_objs[module_name]
177
+
154
178
  meta_name = moduleObj.moduleInfo["meta"]["name"]
155
-
156
- req_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
157
- opt_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
158
-
159
- available_optional_deps = [dep for dep in opt_deps if dep in sdkInstalledModuleNames]
160
- deps = req_deps + available_optional_deps
161
-
162
- for dep in deps:
163
- if dep in disabledModules:
164
- logger.warning(f"模块 {meta_name} 的依赖模块 {dep} 已禁用,跳过加载")
165
- continue
166
-
167
- if not all(dep in sdkInstalledModuleNames for dep in deps):
168
- raiserr.InvalidDependencyError(f"模块 {meta_name} 的依赖无效: {deps}")
169
- sdkModuleDependencies[module_name] = deps
170
-
171
- sdkInstalledModuleNames: list[str] = sdk.util.topological_sort(
172
- sdkInstalledModuleNames, sdkModuleDependencies, raiserr.CycleDependencyError
173
- )
174
- # 存储模块依赖关系到env
175
- env.set('module_dependencies', {
176
- 'modules': sdkInstalledModuleNames,
177
- 'dependencies': sdkModuleDependencies
178
- })
179
-
180
- # ==== 注册适配器 ====
181
- logger.debug("[Init] 开始注册适配器...")
182
- for module_name in sdkInstalledModuleNames:
183
- moduleObj = module_objs[module_name]
184
- meta_name = moduleObj.moduleInfo["meta"]["name"]
185
-
186
- try:
187
- if hasattr(moduleObj, "adapterInfo") and isinstance(moduleObj.adapterInfo, dict):
188
- for platform_name, adapter_class in moduleObj.adapterInfo.items():
189
- sdk.adapter.register(platform_name, adapter_class)
190
- logger.info(f"模块 {meta_name} 注册了适配器: {platform_name}")
191
- except Exception as e:
192
- logger.error(f"模块 {meta_name} 注册适配器失败: {e}")
193
-
194
- # ==== 存储模块信息到数据库 ====
195
- all_modules_info = {}
196
- for module_name in sdkInstalledModuleNames:
197
- moduleObj = module_objs[module_name]
198
- moduleInfo: dict = moduleObj.moduleInfo
199
-
200
- meta_name = moduleInfo.get("meta", {}).get("name", None)
201
- module_info = mods.get_module(meta_name)
202
- mods.set_module(meta_name, {
179
+ module_info = mods.get_module(meta_name) or {
203
180
  "status": True,
204
- "info": moduleInfo
205
- })
206
- logger.debug("所有模块信息已加载并存储到数据库")
207
-
208
- # ==== 实例化 Main 类并挂载到 sdk ====
209
- logger.debug("[Init] 开始实例化模块 Main 类...")
210
- for module_name in sdkInstalledModuleNames:
211
- moduleObj = module_objs[module_name]
212
- meta_name = moduleObj.moduleInfo["meta"]["name"]
213
-
214
- module_status = mods.get_module_status(meta_name)
215
- if not module_status:
181
+ "info": moduleObj.moduleInfo
182
+ }
183
+ mods.set_module(meta_name, module_info)
184
+
185
+ if not module_info.get('status', True):
186
+ disabled_modules.append(module_name)
187
+ logger.warning(f"模块 {meta_name} 已禁用,跳过加载")
216
188
  continue
217
-
218
- moduleMain = moduleObj.Main(sdk)
219
- setattr(moduleMain, "moduleInfo", moduleObj.moduleInfo)
220
- setattr(sdk, meta_name, moduleMain)
221
- logger.debug(f"模块 {meta_name} 正在初始化")
189
+
190
+ _check_dependencies(moduleObj, module_name, os.listdir(module_path))
191
+ module_objs[module_name] = moduleObj
192
+ enabled_modules.append(module_name)
193
+
194
+ except Exception as e:
195
+ logger.warning(f"模块 {module_name} 加载失败: {e}")
196
+
197
+ return module_objs, enabled_modules, disabled_modules
198
+
199
+ def _validate_module(moduleObj, module_name: str) -> bool:
200
+ # 验证模块基本结构
201
+ if not hasattr(moduleObj, "moduleInfo") or not isinstance(moduleObj.moduleInfo, dict):
202
+ logger.warning(f"模块 {module_name} 缺少有效的 'moduleInfo' 字典")
203
+ return False
204
+ if "name" not in moduleObj.moduleInfo.get("meta", {}):
205
+ logger.warning(f"模块 {module_name} 缺少必要 'name' 键")
206
+ return False
207
+ if not hasattr(moduleObj, "Main"):
208
+ logger.warning(f"模块 {module_name} 缺少 'Main' 类")
209
+ return False
210
+ return True
211
+
212
+ def _check_dependencies(moduleObj, module_name: str, available_modules: list):
213
+ # 检查模块依赖关系
214
+ required_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
215
+ if missing := [dep for dep in required_deps if dep not in available_modules]:
216
+ logger.error(f"模块 {module_name} 缺少必需依赖: {missing}")
217
+ raiserr.MissingDependencyError(f"模块 {module_name} 缺少必需依赖: {missing}")
218
+
219
+ optional_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
220
+ available_optional = [
221
+ dep for dep in optional_deps
222
+ if (isinstance(dep, list) and any(d in available_modules for d in dep))
223
+ or (not isinstance(dep, list) and dep in available_modules)
224
+ ]
225
+ if optional_deps and not available_optional:
226
+ logger.warning(f"模块 {module_name} 缺少所有可选依赖: {optional_deps}")
227
+
228
+ def _resolve_dependencies(modules: list, module_objs: dict) -> list:
229
+ # 解析模块依赖关系并进行拓扑排序
230
+ dependencies = {}
231
+ for module_name in modules:
232
+ moduleObj = module_objs[module_name]
233
+ req_deps = moduleObj.moduleInfo.get("dependencies", {}).get("requires", [])
234
+ opt_deps = moduleObj.moduleInfo.get("dependencies", {}).get("optional", [])
235
+ available_opt = [dep for dep in opt_deps if dep in modules]
236
+ dependencies[module_name] = req_deps + available_opt
237
+
238
+ sorted_modules = sdk.util.topological_sort(modules, dependencies, raiserr.CycleDependencyError)
239
+ env.set('module_dependencies', {
240
+ 'modules': sorted_modules,
241
+ 'dependencies': dependencies
242
+ })
243
+ return sorted_modules
244
+
245
+ def _register_adapters(modules: list, module_objs: dict) -> bool:
246
+ # 注册适配器
247
+ success = True
248
+ logger.debug("[Init] 开始注册适配器...")
249
+ for module_name in modules:
250
+ moduleObj = module_objs[module_name]
251
+ meta_name = moduleObj.moduleInfo["meta"]["name"]
252
+
253
+ try:
254
+ if hasattr(moduleObj, "adapterInfo") and isinstance(moduleObj.adapterInfo, dict):
255
+ for platform, adapter_class in moduleObj.adapterInfo.items():
256
+ sdk.adapter.register(platform, adapter_class)
257
+ logger.info(f"模块 {meta_name} 注册适配器: {platform}")
258
+ except Exception as e:
259
+ logger.error(f"模块 {meta_name} 适配器注册失败: {e}")
260
+ success = False
261
+ return success
262
+
263
+ def _initialize_modules(modules: list, module_objs: dict) -> bool:
264
+ # 初始化模块
265
+ success = True
266
+ logger.debug("[Init] 开始实例化模块...")
267
+ for module_name in modules:
268
+ moduleObj = module_objs[module_name]
269
+ meta_name = moduleObj.moduleInfo["meta"]["name"]
270
+
271
+ try:
272
+ if mods.get_module_status(meta_name):
273
+ moduleMain = moduleObj.Main(sdk)
274
+ setattr(moduleMain, "moduleInfo", moduleObj.moduleInfo)
275
+ setattr(sdk, meta_name, moduleMain)
276
+ logger.debug(f"模块 {meta_name} 初始化完成")
277
+ except Exception as e:
278
+ logger.error(f"模块 {meta_name} 初始化失败: {e}")
279
+ success = False
280
+ return success
281
+
282
+ def init() -> bool:
283
+ logger.info("[Init] SDK 正在初始化...")
284
+ try:
285
+ if not _prepare_environment():
286
+ return False
287
+
288
+ module_path = os.path.join(os.path.dirname(__file__), "modules")
289
+ module_objs, enabled_modules, _ = _scan_modules(module_path)
290
+
291
+ if not enabled_modules:
292
+ logger.warning("没有找到可用的模块")
293
+ return True
294
+
295
+ sorted_modules = _resolve_dependencies(enabled_modules, module_objs)
296
+ if not _register_adapters(sorted_modules, module_objs):
297
+ return False
298
+
299
+ return _initialize_modules(sorted_modules, module_objs)
300
+
222
301
  except Exception as e:
302
+ logger.critical(f"SDK初始化严重错误: {e}")
223
303
  raiserr.InitError(f"sdk初始化失败: {e}", exit=True)
304
+ return False
224
305
 
225
-
226
- sdk.init = init
306
+ sdk.init = init
ErisPulse/__main__.py CHANGED
@@ -44,6 +44,7 @@ epsdk origin add https://example.com/map.json
44
44
  """
45
45
 
46
46
  import argparse
47
+ import importlib
47
48
  import os
48
49
  import sys
49
50
  import time
@@ -550,29 +551,27 @@ def install_pip_dependencies(dependencies):
550
551
  return False
551
552
 
552
553
  def install_local_module(module_path, force=False):
553
- """安装本地目录中的模块"""
554
- module_path = os.path.abspath(module_path)
555
- if not os.path.exists(module_path):
556
- shellprint.panel(f"路径不存在: {module_path}", "错误", "error")
557
- return False
558
-
559
- # 尝试从目录名获取模块名
560
- module_name = os.path.basename(module_path.rstrip('/\\'))
561
-
562
- # 检查是否是有效的模块目录
563
- init_py = os.path.join(module_path, '__init__.py')
564
- if not os.path.exists(init_py):
565
- shellprint.panel(f"目录 {module_path} 不是一个有效的Python模块", "错误", "error")
566
- return False
567
-
568
- # 尝试导入模块获取moduleInfo
569
554
  try:
570
- spec = importlib.util.spec_from_file_location(module_name, init_py)
571
- module = importlib.util.module_from_spec(spec)
572
- spec.loader.exec_module(module)
573
- if not hasattr(module, 'moduleInfo'):
574
- shellprint.panel(f"模块 {module_name} 缺少 moduleInfo 定义", "错误", "error")
555
+ module_path = os.path.abspath(module_path)
556
+ if not os.path.exists(module_path):
557
+ shellprint.panel(f"路径不存在: {module_path}", "错误", "error")
575
558
  return False
559
+
560
+ module_name = os.path.basename(module_path.rstrip('/\\'))
561
+ init_py = os.path.join(module_path, '__init__.py')
562
+
563
+ if not os.path.exists(init_py):
564
+ shellprint.panel(f"目录 {module_path} 不是一个有效的Python模块", "错误", "error")
565
+ return False
566
+ import sys
567
+ sys.path.insert(0, os.path.dirname(module_path))
568
+ try:
569
+ module = importlib.import_module(module_name)
570
+ if not hasattr(module, 'moduleInfo'):
571
+ shellprint.panel(f"模块 {module_name} 缺少 moduleInfo 定义", "错误", "error")
572
+ return False
573
+ finally:
574
+ sys.path.remove(os.path.dirname(module_path))
576
575
  except Exception as e:
577
576
  shellprint.panel(f"导入模块 {module_name} 失败: {e}", "错误", "error")
578
577
  return False
@@ -992,7 +991,6 @@ def list_modules(module_name=None):
992
991
 
993
992
  def main():
994
993
  parser = argparse.ArgumentParser(
995
-
996
994
  prog="epsdk",
997
995
  formatter_class=argparse.RawTextHelpFormatter
998
996
  )
ErisPulse/adapter.py CHANGED
@@ -3,13 +3,6 @@
3
3
 
4
4
  提供平台适配器基类、消息发送DSL和适配器管理功能。支持多平台消息处理、事件驱动和生命周期管理。
5
5
 
6
- ## 核心功能
7
- 1. 适配器基类定义
8
- 2. 链式消息发送DSL
9
- 3. 适配器注册和管理
10
- 4. 事件处理系统
11
- 5. 中间件支持
12
-
13
6
  ## API 文档
14
7
 
15
8
  ### 适配器基类 (BaseAdapter)
@@ -229,124 +222,6 @@ import atexit
229
222
  atexit.register(lambda: asyncio.run(sdk.adapter.shutdown()))
230
223
  ```
231
224
 
232
- ## 最佳实践
233
-
234
- 1. 适配器实现
235
- ```python
236
- class MyPlatformAdapter(sdk.BaseAdapter):
237
- class Send(sdk.BaseAdapter.Send):
238
- # 实现基本消息类型
239
- def Text(self, text: str):
240
- return asyncio.create_task(
241
- self._adapter.call_api(
242
- endpoint="/send",
243
- content=text,
244
- recvId=self._target_id,
245
- recvType=self._target_type
246
- )
247
- )
248
-
249
- # 添加自定义消息类型
250
- def Image(self, file: bytes):
251
- return asyncio.create_task(
252
- self._adapter.call_api(
253
- endpoint="/send_image",
254
- file=file,
255
- recvId=self._target_id,
256
- recvType=self._target_type
257
- )
258
- )
259
-
260
- async def call_api(self, endpoint: str, **params):
261
- # 实现API调用逻辑
262
- async with aiohttp.ClientSession() as session:
263
- async with session.post(
264
- f"{self.api_base}{endpoint}",
265
- json=params
266
- ) as response:
267
- return await response.json()
268
-
269
- async def start(self):
270
- # 初始化连接
271
- self.client = await self._create_client()
272
- # 启动事件监听
273
- asyncio.create_task(self._listen_events())
274
-
275
- async def shutdown(self):
276
- # 清理资源
277
- if self.client:
278
- await self.client.close()
279
- ```
280
-
281
- 2. 事件处理
282
- ```python
283
- # 注册事件处理器
284
- adapter = MyPlatformAdapter()
285
-
286
- @adapter.on("message")
287
- async def handle_message(data):
288
- # 消息处理逻辑
289
- if data["type"] == "text":
290
- await process_text_message(data)
291
- elif data["type"] == "image":
292
- await process_image_message(data)
293
-
294
- # 使用中间件
295
- @adapter.middleware
296
- async def auth_middleware(data):
297
- if not verify_token(data.get("token")):
298
- return None
299
- return data
300
-
301
- @adapter.middleware
302
- async def log_middleware(data):
303
- sdk.logger.info(f"处理事件: {data}")
304
- return data
305
- ```
306
-
307
- 3. 消息发送
308
- ```python
309
- # 基本消息发送
310
- async def send_welcome(user_id: str):
311
- await sdk.adapter.Platform.Send.To("user", user_id).Text("欢迎!")
312
-
313
- # 复杂消息处理
314
- async def process_group_notification(group_id: str, event: dict):
315
- # 发送格式化消息
316
- message = format_notification(event)
317
- await sdk.adapter.Platform.Send.To("group", group_id).Text(message)
318
-
319
- # 发送附加文件
320
- if event.get("has_attachment"):
321
- file_data = await get_attachment(event["attachment_id"])
322
- await sdk.adapter.Platform.Send.To("group", group_id).File(file_data)
323
- ```
324
-
325
- ## 注意事项
326
-
327
- 1. 适配器实现
328
- - 确保正确实现所有抽象方法
329
- - 处理所有可能的异常情况
330
- - 实现适当的重试机制
331
- - 注意资源的正确释放
332
-
333
- 2. 事件处理
334
- - 避免在事件处理器中执行长时间操作
335
- - 使用适当的错误处理
336
- - 考虑事件处理的顺序性
337
- - 合理使用中间件过滤机制
338
-
339
- 3. 消息发送
340
- - 实现消息发送的限流机制
341
- - 处理发送失败的情况
342
- - 注意消息格式的平台兼容性
343
- - 大文件传输时考虑分片
344
-
345
- 4. 生命周期管理
346
- - 确保适配器正确启动和关闭
347
- - 处理意外断开的情况
348
- - 实现自动重连机制
349
- - 注意资源泄漏问题
350
225
  """
351
226
 
352
227
  import functools