import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk";
import type { ResolvedBotAccount } from "../types/index.js";
import type { WecomInboundMessage } from "../types.js";
/**
* **WecomRuntimeEnv (运行时环境)**
*
* 包含基础的日志和错误报告接口,用于解耦对 PluginRuntime 的直接依赖。
*/
export type WecomRuntimeEnv = {
log?: (message: string) => void;
error?: (message: string) => void;
};
/**
* **WecomWebhookTarget (Webhook 目标上下文)**
*
* 描述一个注册的 Bot 接收端点。包含处理该端点所需的所有上下文信息。
*
* @property account 解析后的 Bot 账号信息 (Token, AESKey 等)
* @property config 插件全局配置
* @property runtime 运行时环境 (日志)
* @property core OpenClaw 插件核心运行时
* @property path 该 Target 注册的 Webhook 路径
* @property statusSink 用于上报最后收发消息时间的回调
*/
export type WecomWebhookTarget = {
account: ResolvedBotAccount;
config: OpenClawConfig;
runtime: WecomRuntimeEnv;
core: PluginRuntime;
path: string;
/** 反馈最后接收/发送时间 */
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
};
/**
* **StreamState (流式会话状态)**
*
* 记录一个流式请求的生命周期状态。
*
* @property streamId 唯一会话 ID
* @property msgid 关联的企业微信消息 ID (用于去重)
* @property createdAt 创建时间
* @property updatedAt 最后更新时间 (用于 Prune)
* @property started 是否已开始处理 (Agent 已介入)
* @property finished 是否已完成 (Agent 输出完毕或出错)
* @property error 错误信息 (如有)
* @property content 已积累的响应内容 (用于长轮询返回)
* @property images 过程中生成的图片 (Base64 + MD5)
*/
export type StreamState = {
streamId: string;
msgid?: string;
/** 会话键(同一人同一会话,用于队列/批次) */
conversationKey?: string;
/** 批次键(conversationKey + 批次序号) */
batchKey?: string;
/** 触发者 userid(用于 Agent 私信兜底) */
userId?: string;
/** 会话类型(用于群聊兜底逻辑) */
chatType?: "group" | "direct";
/** 群聊 chatid(用于日志/提示,不用于 Agent 发群) */
chatId?: string;
/** 智能机器人 aibotid(用于 taskKey 生成与日志) */
aibotid?: string;
/** Bot 回调幂等键(用于最终交付幂等) */
taskKey?: string;
createdAt: number;
updatedAt: number;
started: boolean;
finished: boolean;
error?: string;
content: string;
images?: { base64: string; md5: string }[];
/** 兜底模式(仅作为内部状态,不暴露给企微) */
fallbackMode?: "media" | "timeout" | "error";
/** 群内兜底提示是否已发送(用于防重复刷屏) */
fallbackPromptSentAt?: number;
/** Agent 私信最终交付是否已完成(用于防重复发送) */
finalDeliveredAt?: number;
/** 用于私信兜底的完整内容(不受 STREAM_MAX_BYTES 限制,但仍需上限保护) */
dmContent?: string;
/** 已通过 Agent 私信发送过的媒体标识(防重复发送附件) */
agentMediaKeys?: string[];
};
/**
* **PendingInbound (待处理/防抖消息)**
*
* 暂存在队列中的消息,等待防抖计时器结束进行聚合。
*
* @property streamId 预分配的流 ID
* @property target 目标 Webhook 上下文
* @property msg 原始消息对象 (如果聚合,通常指第一条)
* @property contents 聚合的消息内容列表
* @property media 附带的媒体文件 (如果有)
* @property msgids 聚合的所有消息 ID (用于去重)
* @property timeout 防抖定时器句柄
*/
export type PendingInbound = {
streamId: string;
conversationKey: string;
batchKey: string;
target: WecomWebhookTarget;
msg: WecomInboundMessage;
contents: string[];
media?: { buffer: Buffer; contentType: string; filename: string };
msgids: string[];
nonce: string;
timestamp: string;
timeout: ReturnType<typeof setTimeout> | null;
/** 已到达防抖截止时间,但因前序批次仍在处理中而暂存 */
readyToFlush?: boolean;
createdAt: number;
};
/**
* **ActiveReplyState (主动回复地址状态)**
*
* 存储企业微信回调中提供的 `response_url`,用于后续将流式响应转为主动推送(template_card)等。
*
* @property response_url 企业微信提供的回调回复 URL
* @property proxyUrl 如果配置了代理,存储代理地址
* @property createdAt 创建时间
* @property usedAt 使用时间 (仅当 policy="once" 时有意义)
* @property lastError 最后一次发送失败的错误信息
*/
export type ActiveReplyState = {
response_url: string;
proxyUrl?: string;
createdAt: number;
usedAt?: number;
lastError?: string;
};