FishMem

Webhook

订阅带签名、可重试的记忆与来源变更事件。

控制台为每个项目配置 Webhook。FishMem 在成功变更后排队投递,并对准确请求体签名;搜索与读取不产生 Webhook。

事件触发时机
memory_add推理或原文写入提交
memory_update明确更新提交
memory_delete单条或作用域记忆删除
document_extract_queued已校验文件进入持久提取队列
document_ingest来源版本与召回投影提交
document_delete稳定来源族永久删除

新端点默认订阅五种提交/删除事件;document_extract_queued 需选择加入。

请求与签名

FishMem 使用 POST application/json,包含稳定事件 idtypecreated_at、项目标识和事件数据。响应头包括:

Header含义
x-fishmem-delivery稳定投递尝试记录 ID
x-fishmem-event事件类型
x-fishmem-timestamp参与签名的 Unix 时间
x-fishmem-signaturev1=<hex HMAC-SHA256>

端点密钥只在创建与轮换后显示,必须放入密钥管理器。对 <timestamp>.<raw request body> 计算 HMAC-SHA256,验证前不能解析后重新序列化请求体。

import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyFishMemWebhook(rawBody: string, timestamp: string, signature: string, secret: string) {
  const expected = `v1=${createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex")}`;
  const received = Buffer.from(signature);
  const wanted = Buffer.from(expected);
  return received.length === wanted.length && timingSafeEqual(received, wanted);
}

同时拒绝超出重放窗口的时间戳,并按顶层事件 id 去重。

投递与重试

任何 2xx 表示成功。网络错误或非 2xx 最多尝试 5 次,从 60 秒开始指数退避;第五次失败后标记为 dead。投递至少一次,接收方必须幂等,并应快速确认后再异步处理慢任务。轮换密钥影响后续尝试;停用或删除端点会停止待投递尝试。

On this page