简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

ErisPulse.Core.Bases.adapter_patterns 模块


模块概述

ErisPulse 适配器通信模式基类

为最常见的两类平台连接模式提供「半成品」基类,子类只实现拉取/转换钩子, start / shutdown 的生命周期编排(后台任务归属、路由注册与按 owner 清理)全部由基类完成:

提示

  1. 两个基类都不需要子类实现 start / shutdown(基类已管)
  2. epsdk create adapter --template polling / webhook 可直接生成对应骨架
  3. 平台协议为 WebSocket 时请直接继承 :class:BaseAdapter(见 ws-server 模板)

类列表

class PollingAdapter(BaseAdapter)

HTTP 轮询型适配器基类(抽象)

适用于"客户端定时拉取事件"的平台(Telegram getUpdates 型)。基类以 spawn-返回式实现 start():经 :meth:BaseAdapter.spawn_client_loop 拉起轮询循环后立即返回;循环内拉取失败自动留痕并指数退避(基数 POLLING_ADAPTER_BACKOFF_BASE_SECS 秒、上限 POLLING_ADAPTER_BACKOFF_MAX_SECS 秒),成功后归零重计。

子类最小实现面:

提示

  1. 轮询间隔默认取类属性 poll_interval(5 秒);声明了含 poll_interval 字段的 ConfigClass 时自动改用配置值
  2. shutdown() 无需子类处理:轮询循环经 owner(平台名)归属, 适配器停止时框架自动取消
  3. 拉取与转换异常由基类统一捕获退避,循环内无需写 try/except

示例:

class TelegramAdapter(PollingAdapter):
    poll_interval = 3.0

    async def fetch_events(self):
        resp = await self.sdk.client.get(f"{self.cfg.endpoint}/getUpdates")
        data = await resp.json()
        return data.get("result", [])

    def convert_one(self, raw):
        return MyConverter().convert(raw)

方法列表

async start() -> None

启动轮询适配器(spawn-返回式)

拉起归属本平台的轮询循环后立即返回:启动即成功,平台不可达等 拉取失败由循环内的指数退避处理,不阻塞框架启动链。

子类通常无需覆写;需要一次性初始化(如登录)时可覆写并在 await super().start() 前后补充逻辑。


async _poll_loop() -> None

常驻轮询循环:拉取 → 逐条转换上报 → 休眠

内部方法 拉取/转换异常统一捕获:WARNING 留痕 + 指数退避后重试; asyncio.CancelledError 原样上抛(owner 取消即停止)。


_resolve_poll_interval() -> float

解析生效的轮询间隔

优先取 ConfigClass 声明的 poll_interval 配置值(实时读取, 热更新生效);未声明或值非法(非正数)时回退类属性默认值。

返回值: 生效的轮询间隔(秒)


async fetch_events() -> list[Any]

拉取一批平台原生事件(抽象,子类必须实现)

建议实现为一次平台 API 调用(如 getUpdates),返回本轮全部 原生事件;无新事件时返回空列表。抛出的异常由基类统一退避处理。

返回值: 平台原生事件列表


convert_one(raw: Any) -> dict[str, Any] | None

单条原生事件转 OneBot12 标准格式(抽象,子类必须实现)

返回值 (OneBot12): 事件字典;无法识别的事件返回 None(跳过不上报)


async shutdown() -> None

关闭轮询适配器(默认空实现)

轮询循环经 owner(平台名)归属:适配器停止时框架按归属自动取消, 子类无需管理任务句柄;有平台侧会话需要显式登出时可覆写本方法。


class WebhookAdapter(BaseAdapter)

HTTP 回调型适配器基类(抽象)

适用于"平台主动推送回调"的平台。基类的 start() 在框架 router 上 注册接收路由(最终路径 /{平台名}/webhook,与 ws-server 模板的 /{平台名}/ws 同一命名空间约定),注册包在 owner_scope 中使 适配器卸载时按 owner 自动清理;回调处理器完成「校验 → 解析 → 转换 → 上报」的固定编排。

子类最小实现面:

提示

  1. shutdown() 无需子类处理:路由经 owner 归属自动清理
  2. 回调地址可经 sdk.adapter.get_connection_info(platform) 或 sdk.router.get_module_urls(platform) 查询后填到平台后台
  3. 校验失败的请求返回 403,载荷解析失败返回 400

示例:

class DiscordAdapter(WebhookAdapter):
    def verify_request(self, request) -> bool:
        return request.headers.get("x-signature") == self._sign()

    def convert(self, payload):
        return MyConverter().convert(payload)

方法列表

async start() -> None

启动回调适配器:注册接收路由后返回

路由注册在 owner_scope(平台名) 下进行(框架在启动链上本已注入 owner,此处显式包住以保证脱离管理器直接调用 start() 时归属 同样正确),适配器停止/卸载时按 owner 自动清理,无需子类注销。

子类通常无需覆写;需要同时拉起辅助任务(如心跳)时可覆写并在 await super().start() 前后补充逻辑。


async _webhook_handler(request: HttpRequest) -> Any

回调接收处理器:校验 → 解析 → 转换 → 上报

内部方法 固定编排不允许子类干预顺序;自定义逻辑分别经 verify_request / convert 两个钩子注入。校验失败返回 (denied, 403),载荷非法返回 (bad request, 400),正常返回 {"status": "ok"}(转换返回 None 的 载荷视为已忽略,同样返回 ok)。

返回值 (HTTP): 响应(dict 或 (body, status) 元组)


verify_request(request: HttpRequest) -> bool

回调请求校验钩子(可选覆写,默认放行)

用于签名 / Token 校验:返回 False 时基类直接以 403 回绝且不进入 事件转换。默认实现恒放行(平台无校验要求时无需覆写)。

返回值: 是否放行

示例:

def verify_request(self, request) -> bool:
    cfg = self.cfg
    if not cfg.token:
        return True  # 未配置 Token 时放行
    auth = request.headers.get("authorization", "")
    return auth == f"Bearer {cfg.token}"

convert(payload: Any) -> dict[str, Any] | None

回调载荷转 OneBot12 标准格式(抽象,子类必须实现)

返回值 (OneBot12): 事件字典;无法识别的载荷返回 None(跳过上报)


async shutdown() -> None

关闭回调适配器(默认空实现)

接收路由经 owner(平台名)归属:适配器停止/卸载时框架按 owner 自动清理,子类无需手动注销路由。