【免费下载链接】openclaw-weixin项目地址https://gitcode.com/gh_mirrors/op/openclaw-weixin点击查看免费下载一句话看懂openclaw-weixin 是什么引用缓存解决什么问题openclaw-weixin 是 OpenClaw 的微信Weixin渠道插件通过扫码登录接入 OpenClaw Gateway让 Agent 收发微信文本、图片、语音、文件和视频。其中引用缓存Quote Cache负责解决一个隐蔽的问题新版微信客户端发起引用时往往只带上被引用消息的服务端 IDsvr_id不再附带原文内容——Agent 看到的引用就空了。插件的方案很朴素平时把每条消息的文本和媒体元数据悄悄存进本地 SQLite 数据库等引用消息带着 ID 到来时再按 ID 把原文查出来还原给 Agent。全程使用 Node.js 内置模块node:sqlite不需要任何第三方数据库依赖。背景为什么引用里可能只剩一个消息 ID在微信协议里引用消息通过ref_msg字段下发见 types.ts{ ref_msg: { svr_id: 18446744073709551615 } }新版客户端的引用载荷里ref_msg可能只有svr_id这一个字段——没有标题、没有摘要、没有正文。更坑的是这个 ID 是 64 位无符号整数uint64最大能到18446744073709551615远超 JavaScript 的安全整数范围直接JSON.parse会丢精度。为此插件在 api.ts 中实现了parseWeixinApiJson在解析前先扫描原文把message_id、msg_id、svr_id这三个字段的数字改写为字符串保证 ID 全程无损。这是引用缓存能按 ID 命中的前提。 所以引用缓存要回答两个问题存什么、存哪里以及取不到时怎么体面降级。存储层node:sqlite 与 ref-messages.sqlite 设计引用缓存的全部实现集中在 quote-store.ts 的QuoteStore类L152。建库一个库文件 一套权限约定数据库文件位于状态目录stateDir/openclaw-weixin/ref-messages.sqliteL191-L206目录权限0o700、库文件权限0o600——只有当前用户可读媒体是隐私数据权限收紧是刻意的打开时设置WAL日志模式与synchronous NORMAL兼顾并发读与写入性能initializeSchema媒体文件不入库单独放在受管目录stateDir/media/inbound/openclaw-weixin-quotes/账号目录/下库里只存路径L138-L145表结构按「账号 会话 消息ID」定位核心表quote_messages的主键是(account_id, conversation_id, message_id)L226-L238外加两条加速清理与媒体反查的索引。每条记录包含字段作用direction区分入站inbound/出站outbound消息body消息文本正文media_path/media_mime/media_name/media_size媒体元数据图片、视频、语音、附件created_at消息时间戳用于过期清理按账号、会话做隔离意味着多账号登录时不同账号、不同会话之间不会串引用数据。写入策略幂等 upsert 媒体去重put() 使用INSERT ... ON CONFLICT ... DO UPDATE同一条消息重复入库时更新而非报错媒体字段用COALESCE保留先写入的值天然幂等。媒体注册registerManagedMedia前会做路径规范化校验拒绝受管目录之外的文件且单文件超过 25 MiB 直接不保留。写入时机入站和出站消息如何入缓存缓存是旁路的——不影响消息主流程只是顺手存一份。入站鉴权通过后立刻缓存在 process-message.ts 中消息通过发送者鉴权后resolveStoredQuoteContext()先尝试还原这条消息本身的引用然后调用getQuoteStore()?.put(...)把本条消息方向inbound连同文本、媒体路径写入缓存写入失败只记警告不阻断投递。出站Bot 的回复同样可被引用Agent 发出的回复也可能被用户引用。send.ts 的cacheOutboundMessage()在拿到服务端返回的serverMessageId后以方向outbound写入同一条记录通道保证引用 Bot 的话也能还原。生命周期启动、关闭与账号注销账号上线时调用 initializeQuoteStorechannel.ts L515初始化单例存储配置变更会热更新策略所有账号注销时 deactivateQuoteStoreAccount 关闭数据库删除账号时 deleteQuoteCacheForAccount 同步清除该账号的引用记录和保留媒体。还原流程一条 svr_id 如何变回原文这是整个特性最精彩的一段实现在 inbound.ts 的resolveStoredQuoteContext()提取引用 ID优先取ref_msg.svr_id兼容message_item.msg_idL346查库按「账号 会话 消息 ID」三要素精确查询命中ctx.ReplyToBody被填回原文文本Agent 就能看到完整的引用上下文未命中填入占位文案[引用消息内容未缓存]L353-L355早于缓存启动的历史消息就属于这种情况。部分引用用 MD5 校验还原选中的那句话微信还支持只引用一句话里的一个片段。协议里的partial_text结构为types.ts L156-L162{ start: 片段开头, end: 片段结尾, startindex: 2, endindex: 5, quotemd5: ... }partial-quote.ts 的resolvePartialQuote()会同时按全局下标和相对下标两种解释各算一次候选片段如果协议带了quotemd5就用 MD5 哈希校验候选片段命中才返回校验失败绝不伪造引用内容L54-L61。媒体引用文件路径 工具访问提示引用的是图片、视频或文件时还原逻辑inbound.ts L364-L402文件仍存在把受管路径追加进ctx.MediaPaths并生成附件访问信息原始文件名、受管源路径、工作区media/inbound/目录提示方便 file/PDF 类工具直接读取文件已过期被清理返回[引用的图片已过期]之类的友好标签expiredMediaLabel而不是报错。配置项与数据生命周期缓存多久、占多大空间配置入口是channels.openclaw-weixin.quoteCache完整说明见官方文档 docs/quote-cache_zh_CN.md配置项默认值说明enabledtrue是否启用本地引用还原retentionDays30文本及元数据保留天数maxMessagesPerAccount10000每账号最多保留的记录数mediaRetentionDays7引用媒体文件保留天数maxMediaBytesPerAccount268435456256 MiB每账号媒体总空间上限maxSingleMediaBytes2621440025 MiB单个可保留媒体的大小上限修改配置后重启 Gateway 生效openclaw gateway restartGC 清理节奏runGc() 触发时机有四种启动时、每小时定时器、每写入 100 条记录、媒体空间超限时命中已过期记录时也会惰性清理。清理策略包括超过retentionDays的记录直接删除超出每账号条数上限时按时间淘汰最旧的记录媒体超 7 天或超 256 MiB 预算时先解绑media_path再删孤儿文件pruneOrphanMediaFiles当前消息与后续引用复用同一份媒体文件不会重复占空间。兼容性设计与优雅降级依赖 Node.js ≥ 22.13.0该版本起node:sqlite不再需要实验性启动参数即可使用package.json 中已声明无内存兜底当前 Node.js 不提供node:sqlite或数据库打不开时插件记录警告并整体关闭引用缓存也不用内存缓存替代——缓存故障绝不影响正常收发QuoteStore.openID 全程字符串化规避 uint64 精度丢失部分引用做 MD5 校验校验失败宁可降级也不伪造内容。验证如何确认引用缓存工作正常文档推荐的重点单元测试docs/quote-cache_zh_CN.mdnpx vitest run --coveragefalse src/messaging/quote-store.test.ts src/messaging/partial-quote.test.ts手工验证至少覆盖 5 个场景文本引用还原、媒体引用还原、Gateway 重启后仍可还原、多账号/多会话数据隔离、缓存关闭时消息收发不受影响。总结openclaw-weixin 的引用缓存用很小的代价补齐了新版微信协议留下的坑存入站/出站消息随手写入node:sqlite的旁路数据库零外部依赖查引用消息带svr_id到来时按「账号会话ID」精确还原文本与媒体删多重 GC 策略控制条数与空间隐私数据权限收紧稳缓存故障静默降级正常消息收发永远是最高优先级。想深入了解实现细节可以从 src/messaging/quote-store.ts 和 docs/quote-cache_zh_CN.md 入手。赞分享【免费下载链接】openclaw-weixin项目地址https://gitcode.com/gh_mirrors/op/openclaw-weixin点击查看免费下载相关推荐Smol Vision模型部署终极指南使用Optimum ONNX Runtime优化DETR的完整教程Smol Vision模型部署终极指南使用Optimum ONNX Runtime优化DETR的完整教程 Smol Vision模型部署 是AI开发者面临的关终极英语学习指南如何用科学方法快速提升英语能力终极英语学习指南如何用科学方法快速提升英语能力 你是否曾经下定决心要学好英语却总是在单词、语法、听力和口语中反复挣扎你是否收藏了无数英语学习资源却始终找文档教程教育LLOneBot 消息引用回复功能解析与实现LLOneBot 消息引用回复功能解析与实现 在即时通讯机器人开发中消息引用回复是一个常见的功能需求。本文将以LLOneBot项目为例深入分析消息引用回复功后端即时通讯上一篇aiogram 中的 replaceManagedBotToken 方法安全轮换托管机器人令牌的完整指南下一篇Listen gem与现代Web框架集成Rails、Sinatra等项目的完整配置方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?