新增大量WhatsApp适配器相关代码,包括账号管理、会话处理、消息收发、验证授权、媒体处理、互动命令、审批流程、健康检测等完整功能模块,搭建基础的Baileys协议WhatsApp接入能力
70 lines
2.3 KiB
Python
70 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from enum import StrEnum
|
|
from typing import Any
|
|
|
|
from yuxi.utils.logging_config import logger
|
|
|
|
|
|
class PipelineAction(StrEnum):
|
|
ACCEPT = "accept"
|
|
DROP = "drop"
|
|
DEFER = "defer"
|
|
|
|
|
|
@dataclass
|
|
class PipelineResult:
|
|
action: PipelineAction
|
|
reason: str | None = None
|
|
metadata: dict[str, Any] = field(default_factory=dict)
|
|
|
|
@property
|
|
def is_accepted(self) -> bool:
|
|
return self.action == PipelineAction.ACCEPT
|
|
|
|
@property
|
|
def is_dropped(self) -> bool:
|
|
return self.action == PipelineAction.DROP
|
|
|
|
|
|
class InboundPipeline:
|
|
def __init__(self):
|
|
self._steps: list = []
|
|
|
|
def add_step(self, handler, name: str | None = None) -> None:
|
|
self._steps.append((handler, name or handler.__name__))
|
|
|
|
async def process(self, message: dict) -> PipelineResult:
|
|
ctx = dict(message)
|
|
meta = {}
|
|
for handler, step_name in self._steps:
|
|
try:
|
|
result = handler(ctx)
|
|
if hasattr(result, "__await__"):
|
|
result = await result
|
|
if isinstance(result, PipelineResult):
|
|
if not result.is_accepted:
|
|
logger.debug(f"InboundPipeline: step '{step_name}' → {result.action.value} ({result.reason})")
|
|
result.metadata.update(meta)
|
|
return result
|
|
meta.update(result.metadata)
|
|
elif result is False:
|
|
logger.debug(f"InboundPipeline: step '{step_name}' → DROP")
|
|
return PipelineResult(
|
|
action=PipelineAction.DROP,
|
|
reason=f"blocked_by_{step_name}",
|
|
metadata=meta,
|
|
)
|
|
elif isinstance(result, dict):
|
|
ctx.update(result)
|
|
meta.update(result.get("_meta", {}))
|
|
except Exception:
|
|
logger.exception(f"InboundPipeline: step '{step_name}' failed")
|
|
return PipelineResult(
|
|
action=PipelineAction.DROP,
|
|
reason=f"exception_in_{step_name}",
|
|
metadata=meta,
|
|
)
|
|
return PipelineResult(action=PipelineAction.ACCEPT, reason="ok", metadata=meta)
|