Skip to content

Releases: fanyuantaier/wechatbot-new

2.2.8.4 仅文档:离线包链接换成 2.2.8.3 那份(2.2.8.1 的包带同一连接泄漏)

Choose a tag to compare

@fanyuantaier fanyuantaier released this 17 Oct 11:35

仅文档版

代码与 2.2.8.3 零改动。 这一版只换 PyPI 描述里的离线包链接。

2.2.8.3 的描述里链接的还是 2.2.8.1 的离线包,而那份包里带着同一个连接泄漏(就是 2.2.8.3 修的、让控制台刷 PermissionError(13) 的那个)。用离线包的人会踩同一个坑。

免安装离线包(不用装 Python)

wechatbot-new-offline-2.2.8.3.zip — 142.8 MB,解压后 394 MB,4704 个文件 + 890 个目录条目;包内嵌入式 Python 3.12.9 + 全部依赖(含 wechatauto-replica 1.2.6.1),解压即用,不需要装 Python、不需要联网、不需要管理员权限。

https://livefile.xesimg.com/programme/python_assets/8e4a588d4a7c4dbbeceada4b418fec0e.zip

出包后对解压出来的副本重跑验收闸门:58 项、0 失败(含真实取密钥、DPI awareness、包内 wechatauto 版本下限与 _msg_conns 分片接口)。zip 上传后回读核对:ETag == 本地 md5、长度一致。

装什么

pip install -U wechatbot-new
  • 已在 2.2.8 / 2.2.8.1 / 2.2.8.2 上的:先重启一次进程(释放泄漏的句柄、立刻恢复收消息),再升级到本版。
  • 完整修复清单见 CHANGELOG。

2.2.8.3 修 status_votes 漏关连接:监听/防撤回不再刷 PermissionError(13)

Choose a tag to compare

@fanyuantaier fanyuantaier released this 17 Oct 11:28

修:控制台刷 PermissionError(13, '拒绝访问。') 且收不到新消息

线上表现:listener poll error: PermissionError(13, '拒绝访问。') 和 recall scan error: ... 刷满控制台,同时监听停摆(新消息进不来,机器人看起来"不回了")。

根因是 2.2.8 引入的连接泄漏:新加的 status_votes()(判「我」时读 status 列)没有关闭 WeChatDB._msg_conns() 返回的分片连接,而那个函数的 docstring 明写「调用方负责 close 连接(避免 Windows 下删除缓存被占用)」。这些句柄一直占着解密缓存,wechatauto 每次重建缓存时 os.replace(tmp, message_N.db) 被 Windows 拒绝 —— WinError 5 被 Python 包成 PermissionError(13)。监听轮询和防撤回扫描都会触发重建,于是两边一起刷屏,且不会自愈。

复现与验证(本机真实库):

泄漏一个连接 → _invalidate_cache() → get_messages()
→ PermissionError [WinError 5] ... .tmp -> message__message_0.db
关掉连接后再试 → 成功
  • 修复:status_votes() 用 try/finally 关闭全部分片连接,包含「表名不合规」「execute 抛错」这两条提前返回的路径;tools/style_profile.py 里同一段代码一并修了。
  • 回归:test_wxbot.py 新增 4 项(用假连接断言 close() 一定被调用:正常 / 表名不合规 / execute 抛错),现共 24 项,全过。
  • 真实库验证:判完「我」之后强制 _invalidate_cache() 再读,修复前抛异常、修复后正常返回。

已经装了 2.2.8 / 2.2.8.1 / 2.2.8.2 的

先重启一次进程(重启会释放泄漏的句柄,立刻恢复收消息),然后升级到本版才是根治:

pip install -U wechatbot-new

其它

  • 本版只改 wxbot.py 的一个函数和测试,其余与 2.2.8.2 相同(real_sender_id 那套「我」的判定、合并转发解析、超时、eval→literal_eval、config 写锁等都在 2.2.8 里)。
  • 真机端到端:这次用真实库复现并验证了缓存重建这一段;没有开着微信发一条真实消息跑完整回信链路。

2.2.8.2 仅文档:离线包直链换成 2.2.8.1 那份(代码同 2.2.8.1)

Choose a tag to compare

@fanyuantaier fanyuantaier released this 03 Oct 12:26

仅文档版

代码、依赖、配置项与 2.2.8.1 零改动。 发这个号只为一件事:让 PyPI 的项目描述指向新的免安装离线包。

2.2.8.1 的描述里那条离线包链接还指着 2.2.7 的包(readme 是在那次构建之后才改的,而 PyPI 不允许改已发布版本的描述,所以只能再占一个版本号)。

免安装离线包(不用装 Python)

wechatbot-new-offline-2.2.8.1.zip — 142.6 MB,解压后 393 MB,4700 个文件 + 889 个目录条目。
包内是官方嵌入式 Python 3.12.9 + 全部依赖(含 wechatauto-replica 1.2.4.4),解压即用:不需要装 Python、不需要联网、不需要管理员权限,入口 start.bat。

https://livefile.xesimg.com/programme/python_assets/38b0312752cece199400864abf0f67aa.zip

离线包本身是 2.2.8.1 的代码,与本版本只差这两行文档。出包后对解压出来的副本重跑过验收闸门:58 项、0 失败(含真实取密钥、DPI awareness、包内 wechatauto 版本下限与 _msg_conns 分片接口)。zip 上传后回读核对过:远端 ETag == 本地 md5、长度一致。

装什么

pip install -U wechatbot-new

这一系列版本修了什么

real_sender_id 是微信本地库里分片内的短编号,同一个人换个分片就换个号。本机实测同一会话里 2025-07 ~ 2026-02 自己是 4、2026-06 之后是 2,而代码里写的是 sender_id == 2。后果不是"数字不准":那一段历史里你发的每一条都被标成"对方说的",风格档案于是描述的是对方的口吻——而这份档案会替代该用户的 Prompt。

现在只认两条正向证据:status == 2(微信给自己发出的消息打的标,跨分片稳定)与表情/图片 XML 里的 fromusername == 本机 wxid;整场都没有正向证据才退回 == 2,判得出「我」之后剩下的 id 一律算对方。历史与实时两条路共用同一套判定,实时那条在订阅会话时算一次(只看最近 400 条)。sender_username 不再用来认人(全局 rowid 跨分片串号):单聊用会话昵称,群里用正文前缀的 wxid,认不出的标成「群成员」。

同时修掉:合并转发内容不再永远为空、同秒连发不再可能倒序、识图接口补 timeout、读不到聊天记录时的提示不再自己抛 NameError、重试耗尽不再一律报「api余额不足」、eval → ast.literal_eval、机器人写 config.py 与配置编辑器共用文件锁且只认 True/False 现值、ENABLE_URL_FETCHING 补上界面开关。依赖下限抬到 wechatauto-replica>=1.2.4.4。

  • v2.2.8 已作废:它的 wheel/sdist 里打进了打包机当时的真实 config.py(2 个联系人昵称,无密钥无令牌),详见该版本 Release 页与 CHANGELOG。文件需在 pypi.org 网页端撤回(用户项目的 API token 没有删除权限)。
  • 完整清单见 CHANGELOG。

验证与未验证

  • test_wxbot.py 20 项桩测试全过(每条判据配正反两例)。
  • 真实库只读跑过两个会话:单聊 179 行里「我」96 行(旧年代 59 行中有 21 行以前全挂在对方名下)、裸 wxid 0 行;11 人群 532 行里「我」10 行,与该会话 status=2 的实际条数一致。
  • 真机端到端仍未测:没有开着微信收过一条真实消息。

2.2.8.1 撤回重发(代码同 2.2.8):2.2.8 的发布物带出了本机 config.py 的 2 个昵称

Choose a tag to compare

@fanyuantaier fanyuantaier released this 03 Oct 11:56

这一版只是撤回重发

代码与 v2.2.8 一字未改。 v2.2.8 的 wheel / sdist 里打进了打包机上当时的真实 config.py:LISTEN_LIST 一个联系人昵称 + 角色位、HISTORY_STYLE_USERS 两个名字。逐类扫过发布物——没有 API Key、没有令牌、没有 URL、没有手机号、没有 wxid、没有账号目录哈希,只有这 2 个键的昵称。GitHub 这边(提交、tag、Release 正文)一直是干净的,用的就是占位版。

原因是我的流程顺序错了:python -m build 取的是工作目录当前状态。第一次构建时 config.py 是占位版(当时也验过输出);随后我发现 sdist 漏了 test_wxbot.py,就先把真实 config.py 还原回去、又重跑了一次构建,上传的是第二次的产物。"PyPI 的 sha256 与本地一致"只能证明传对了文件,证明不了本地那份是占位的——这句我上一轮当成通过项报出去了,是我漏的。

  • 2.2.8 的两个文件正在从 PyPI 撤回(用户项目的 API token 没有删除权限,需网页端登录操作),版本号 2.2.8 作废。
  • 发布链路加了 check_release_config.py:构建前查工作副本、构建后查产物,判据是 LISTEN_LIST 必须为占位串、HISTORY_STYLE_USERS 必须为空、且与 git show HEAD:config.py 一致。先对着这次的坏状态跑过,pre/post 都正确报错,再用的这次构建。

装什么

pip install -U "wechatbot-new==2.2.8.1"

2.2.8 修了什么(本版内容完全相同)

real_sender_id 是微信本地库里分片内的短编号,同一个人换个分片就换个号。本机实测同一会话里 2025-07 ~ 2026-02 自己是 4、2026-06 之后是 2,而代码里写的是 sender_id == 2。后果不是"数字不准":那一段历史里你发的每一条都被标成"对方说的",风格档案于是描述的是对方的口吻——而这份档案会替代该用户的 Prompt。

现在只认两条正向证据:status == 2(微信给自己发出的消息打的标,跨分片稳定)与表情/图片 XML 里的 fromusername == 本机 wxid;整场都没有正向证据才退回 == 2,判得出「我」之后剩下的 id 一律算对方。历史与实时两条路共用同一套判定,实时那条在订阅会话时算一次(只看最近 400 条),不在每条消息回调里扫全表。sender_username 不再用来认人(全局 rowid 跨分片串号):单聊用会话昵称,群里用正文前缀的 wxid,认不出的标成「群成员」。

同时修掉:合并转发内容不再永远为空(_merge 从没被赋过值)、同秒连发不再可能倒序、识图接口补 timeout、读不到聊天记录时的提示不再自己抛 NameError、重试耗尽不再一律报「api余额不足」、eval → ast.literal_eval、机器人写 config.py 与配置编辑器共用文件锁且只认 True/False 现值、ENABLE_URL_FETCHING 补上界面开关。依赖下限抬到 wechatauto-replica>=1.2.4.4(读 status 要用它的分片接口;低版本不崩,但会退回旧判法)。

详细清单见 CHANGELOG 的 v2.2.8 一节。

验证与未验证

  • test_wxbot.py 20 项桩测试全过(每条判据配正反两例)。
  • 真实库只读跑过两个会话:单聊 179 行里「我」96 行(旧年代 59 行中有 21 行以前全挂在对方名下)、裸 wxid 0 行;11 人群 532 行里「我」10 行,与该会话 status=2 的实际条数一致。
  • 真机端到端仍未测:没有开着微信收过一条真实消息。

免安装离线包(不用装 Python)

wechatbot-new-offline-2.2.8.1.zip — 142.6 MB,解压后 393 MB,4700 个文件 + 889 个目录条目;包内是官方嵌入式 Python 3.12.9 + 全部依赖(含 wechatauto-replica 1.2.4.4),解压即用,不需要装 Python、不需要联网、不需要管理员权限,入口是 start.bat。

https://livefile.xesimg.com/programme/python_assets/38b0312752cece199400864abf0f67aa.zip

出包后对解压出来的副本重跑过验收闸门:58 项、0 失败(含真实取密钥、DPI awareness、包内 wechatauto 版本下限与 _msg_conns 分片接口)。

2.2.8(已作废,请装 2.2.8.1)

Choose a tag to compare

@fanyuantaier fanyuantaier released this 03 Oct 11:23

⚠ 这个版本请别装

2.2.8 的 wheel / sdist 里打进了打包机当时的真实 config.py:LISTEN_LIST 一个联系人昵称 + 角色位、HISTORY_STYLE_USERS 两个名字。逐类扫过发布物:没有 API Key、没有令牌、没有 URL、没有手机号、没有 wxid。GitHub 的提交与 tag 是干净的(用的是占位版)。

代码与 2.2.8.1 完全相同,请改装:pip install -U wechatbot-new==2.2.8.1。 2.2.8 的两个文件因用户项目的 API token 没有删除权限,需在 pypi.org 网页端撤回;版本号 2.2.8 作废。


这版修的是什么

一句话:读历史消息时"这条是不是我发的"判错了,导致风格档案可能照着对方学。

real_sender_id 是微信本地库里分片内的短编号,同一个人换个分片就换个号。本机实测同一个会话里:2025-07 ~ 2026-02 自己是 4,2026-06 之后是 2。而代码里写的是 sender_id == 2。

后果不是"数字不准":那一段历史里你发的每一条都被标成"对方说的",风格档案于是描述的是对方的口吻——而这份档案会替代该用户的 Prompt(开了「聊天记录风格模仿」就生效)。

现在怎么判

只认两条正向证据:

  1. status == 2 —— 微信给自己发出的消息打的标,跨分片稳定(实测自己是 43/43 与 44/53,对方两个编号都是 0/N);
  2. 表情/图片 XML 里的 fromusername == 本机 wxid。

整场都没有正向证据才退回 == 2;只要判得出「我」,剩下的 id 一律算对方——群里十几个成员编号,不该有一个靠 == 2 混进来(这条假阳性是在一个 11 人的群里实测出来的)。

历史文本和实时监听两条路共用同一套判定;实时那条在订阅会话时算一次(只看该会话最近 400 条),不放在每条消息的回调里,几万条的群不做全表扫描。

sender_username 不再用来认人:它取自 message_resource.db 的全局 rowid,跨分片会串号(实测把本机自己的 2 号解析成了陌生人的 wxid)。现在单聊用会话昵称,群聊用正文前缀里的 wxid,群里解析不出的(图片/表情这类没有前缀)标成「群成员」,不再输出裸 wxid。

同时修掉的

  • 合并转发的内容永远是空的:_merge 只在构造时赋过 None、从没被填过,msg.get_messages() 因此恒返回 None。现在按 <record>/<item> 解析成 [[发送者, 内容, 时间], ...]。
  • 同秒连发可能倒序:get_messages() 是"新的在前",只按 create_time 稳定排序会把同一秒内保持成倒序,现在统一先按 sort_seq 正序。
  • 识图接口没有 timeout:requests.post 不传就是永远等,一个不响应的端点能把线程挂死。补 180 秒(不复用 REQUESTS_TIMEOUT=10,多模态调用比抓网页慢得多)。
  • 诊断信息自己先崩:读不到聊天记录时那句提示引用了变量 username,函数里的叫 _uname,于是抛 NameError 被上层当成"预读失败",写给用户的"昵称和微信显示名不一致"永远看不到。
  • 重试耗尽一律报「api余额不足」:超时、上下文超长、本地代码抛错都会被说成"你去充值"。现在带上最后一次真实原因。
  • get_dynamic_config 用 eval() 解析 config.py 的值——那文件里写什么就会被执行什么。换成 ast.literal_eval。
  • 机器人写 config.py 没和配置编辑器共用文件锁(开关指令那条路),两边同时保存会互相覆盖;现在锁同一个 config.py.lock。它的正则原本带 |.+$:键的值要是写成跨行列表,只替换第一行会把续行留下变成语法错误——现在只认 True/False,现值不是布尔就拒绝改写并报错。
  • ENABLE_URL_FETCHING(抓取消息里的网页链接)此前只有默认值、没有界面开关,只能手改文件。

升级

pip install -U "wechatbot-new>=2.2.8"
pip install -U "wechatauto-replica[guia]>=1.2.4.4"

依赖下限抬到 wechatauto-replica>=1.2.4.4(读 status 要用 1.2.4.4 的分片接口,顺带把 1.2.4.3 里朋友圈发送的修复纳进下限)。低版本不会崩,但会退回旧的 == 2 判法。

老 config.py 用户不用手动补:新增配置项会自动补进旧文件。本次没有新增配置项。

验证与未验证

  • 新增 test_wxbot.py:20 项桩测试,不启动微信、不碰界面,每条判据都配了正反两例(含"群里 id=2 不许冒充我""名片里的 username 不算自证""同秒按 sort_seq 正序")。
  • 真实库只读跑过两个会话:单聊 179 行里 96 行归"我"(旧年代 59 行里 21 行以前全挂在对方名下)、裸 wxid 0 行;11 人群 532 行里"我" 10 行,与该会话 status=2 的实际条数一致。
  • 真机端到端仍未测:没有开着微信收过一条真实消息。按仓库惯例,任何真机操作都走 rhythm(默认 natural)。

免安装离线包目前还是 2.2.7 那一份,尚未按本版本重出。

v2.2.7.1(文档:免安装离线包)

Choose a tag to compare

@fanyuantaier fanyuantaier released this 02 Oct 02:46

仅文档版:代码、依赖、配置项与 v2.2.7 完全一致,发版只是为了让离线包链接出现在 PyPI 的项目页上(PyPI 不允许给已发布版本改描述或补文件)。

免安装离线包(自带 Python)

  • wechatbot-new-offline-2.2.7.zip — 142.5 MB(解压后 406 MB / 4696 个文件),md5 cf1b5c02b7c200b6da614e373b7ed475
  • 直链:https://livefile.xesimg.com/programme/python_assets/cf1b5c02b7c200b6da614e373b7ed475.zip
  • 里面是官方嵌入式 Python 3.12.9 + 本项目全部依赖 + 项目源码,解压即用:目标机不需要装 Python、不需要联网、不需要管理员权限。
  • start.bat 打开配置网页;wx.bat 你的脚本.py 用包内解释器跑脚本;diagnose.bat / check_env.py 自检;详见包内 README-offline.md。
  • 前提:64 位 Win10/11 + 微信 4.1.12 及以上已登录;不要「以管理员身份运行」。
  • 出厂 config.py 是占位内容,包内不含任何人的昵称、聊天记录或密钥缓存。

本版改动

  • readme.md 新增「免安装离线包(不用装 Python)」一节
  • CHANGELOG.md 新增 v2.2.7.1 条目
  • pyproject.toml 加 Download-offline 链接(会显示在 PyPI 页面右侧 Links)
  • config_editor.py 启动横幅版本号 -> 2.2.7.1

v2.2.7 聊天记录风格档案 + 消息识别层重整

Choose a tag to compare

@fanyuantaier fanyuantaier released this 01 Oct 13:22

v2.2.7(2026年10月01日)

这一版主要是把你反馈的三件事在真机上查清并修掉了,另外把消息识别层重做了一遍。

新增:用聊天记录生成「模仿我」的风格档案

  • 用户列表每行新增 读聊天记录 勾选与 读取聊天记录 按钮:读该会话在本机的聊天记录,让模型提炼**「我」这一方的说话风格**与近期上下文,存成 HistoryProfiles/<昵称>.md。
  • 启用后该用户不再使用他原来的 Prompt 文件,记忆功能照旧。
  • 生成即启用:档案写成功的同时就把该昵称记入启用名单并落盘,不用再手动勾选+保存。机器人正在运行时,下一条消息起改用档案。
  • 新增 档案生成模型:可以让风格档案交给另一个模型生成(Chat 挂本地慢模型、档案用快模型),API 地址与 Key 仍沿用 Chat 那一套;留空就是跟 Chat 一致。
  • 新配置项:HISTORY_STYLE_USERS、HISTORY_PROFILE_DIR、HISTORY_READ_LIMIT、HISTORY_PROFILE_MAX_CHARS、HISTORY_PROFILE_MODEL。

新增:按需读取聊天上下文

  • 开关 ENABLE_CONTEXT_FETCH(默认关):启动时先给每个监听用户预读一次背景;之后每条消息先让模型判断「这条需不需要更多上下文」,判要时才重新读库(拿到此刻最新的记录)。
  • 群聊也能读到:以前按群名解析不到会话,监听群时上下文一直是空的;现在解析不到会按会话表反查群名。读不到时日志会点名说明,不再静默。
  • 可调 CONTEXT_MESSAGE_LIMIT(默认 30 条)、CONTEXT_MAX_CHARS(默认 2500 字)。

新增:模型可自定义 + 一键获取可用模型

  • Chat / 辅助 / 识图 / 联网四个模型区都有 获取可用模型:按你填的地址与 Key 调 /models 列出来直接选;列表里没有当前已保存的名字时会自动切到「其它」并保留原名,不会把 custom 模型弄丢。

修复:消息识别层(真机日志自查得出)

  • 正文不再输出整段 XML。此前约 15% 的消息(表情、视频号卡片、红包、位置、合并转发)把原始 XML 当正文交给模型,5307 行样本里有 462 行带着微信资源地址。现在按类型折成一行可读文本,复检后正文含 URL 的行从 462 降到 14(剩下 14 行是用户真的在发网盘/会议/文章链接),XML 残片 0 行。
  • 「莫名识别到链接」的根因:那是表情与视频号卡片里的 CDN 下载地址(vweixinf.tc.qq.com、wxapp.tc.qq.com 的 stodownload),不是网页。现在只把卡片 <url> 里的网页地址当链接,抓取前再过一道资源域名黑名单,被拦下时日志会说明,不再变成一句「提取不到有效文本」。
  • 链接 / 引用 / 合并转发的判据第一次真正生效:get_message_row() 返回的原始列是 zstd 压缩帧(实测 336/336 行),而判据没解压就读,等于这段代码一直是死的。补上解压后,同一批真库数据里判出 52 条文章链接、131 条引用、59 条合并转发,且资源地址 0 条。
  • 联网失败不再伪装成搜索结果:在线 API 出错时原本返回一句「抱歉,在线搜索功能暂时出错了。」,而这句话会被当成「搜索到的参考信息」塞进主模型提示词,表现就像联网结果经常是空的。现在鉴权/欠费类错误单独报一行原因(含地址),并回退到常规回复。
  • 配置界面不再丢掉「没选 Prompt 的用户行」:用风格档案的人本来就不需要选 Prompt,而旧逻辑是 Prompt 为空就整行不写入 LISTEN_LIST——结果保存一次用户就从监听列表里消失。真被丢弃的行现在会留一条 warning 点名。
  • 配置界面会把新增配置项补进旧 config.py:以前 update_config() 只改写文件里已有的键,升级用户(config.py 还是旧那份)在网页里填的新字段会静默丢失。
  • 按需上下文不再新开第二条 system 消息:本地模型(llama.cpp / Ollama 系)的 GGUF chat template 见到非首位 system 会直接报错返回 500,机器人当场不回话。现在合并进首条 system。

启动自检

  • 每个监听用户会打印人设来源(风格档案:大小/路径/生成时间,或所用 Prompt 文件)。
  • 档案文件在、但名字不在启用名单里时,会明确警告并给出开启方法。

关于默认模型地址(重要)

config.py 出厂预置的是 https://opencode.ai/zen/v1 + 模型 space-bunny-free,API Key 填 public(该端点不校验 Key)。它是免费的,但不保证一直可用——随时可能下线、改名或改成收费,届时表现为模型调用报错、机器人不回。要稳定请自备服务商 Key,或在配置页把地址改成 DeepSeek 官方 / 硅基流动 / WeAPIs,本机模型填 http://127.0.0.1:11434/v1 这类本地端点。

安装

pip install wechatbot-new==2.2.7

需要一键启动器的用户请下载源码包(.tar.gz)解压后运行 Run.exe;wheel 里没有启动器(pip 装出来的目录缺少 requirements.txt 与源码,启动器第一步就会失败)。

本版未覆盖的验证

  • 网页界面的渲染与端到端发送、真实撤回/朋友圈操作仍未在本机验证(构建环境没有 flask/openai,且真机发送涉及风控节奏)。
  • 上述识别层的数字来自本地微信库 5307 行只读扫描与桩测试;请在真实聊天里观察一天,有问题开 Issue。

依赖下限仍是 wechatauto-replica[guia]>=1.2.4.1。


免安装离线包(自带 Python)

不想在那台机器上装 Python、也不想联网拉依赖:下面这个 zip 是自包含目录——官方嵌入式 Python 3.12.9 + 本项目全部依赖 + 项目源码平铺在根目录,解压即用,不需要管理员权限,也不打成 exe(打成 exe 会被杀软按行为特征误报)。

  • 文件:wechatbot-new-offline-2.2.7.zip — 142.5 MB(解压后 406 MB / 4696 个文件)
  • md5:cf1b5c02b7c200b6da614e373b7ed475
  • 直链:https://livefile.xesimg.com/programme/python_assets/cf1b5c02b7c200b6da614e373b7ed475.zip
  • 解压后:双击 start.bat 打开配置网页(登录微信 → 填 API → Start Bot);wx.bat 你的脚本.py 用包内解释器跑任意脚本;diagnose.bat / check_env.py 自检能不能解密本地数据库;README-offline.md 是完整说明。
  • 前提:64 位 Windows 10/11,微信 4.1.12 及以上且已登录;不要「以管理员身份运行」——微信跑在普通权限时,提权进程读它的内存会被系统拒绝,表现为取不到密钥。
  • 出厂 config.py 是占位内容(微信名1 / 角色1,HISTORY_STYLE_USERS 为空),包内不含任何人的昵称、聊天记录或密钥缓存;运行时状态写在 %USERPROFILE%\.wechatauto\ 与 %LOCALAPPDATA%\wechatauto_keys\,不跟着包走。
  • 出包带一道 56 项验收闸门(版本号、源码能否编译、30 个运行时依赖能否 import、关键文件与目录是否齐、配置是否占位、DPI awareness 是否 PER_MONITOR_AWARE_V2)。本轮是把 zip 解压出来再跑闸门:56 项 0 失败,回拉的 149,384,190 字节与本地逐字节一致。

Release 2.2.6.1: 一键启动器 Run.exe 进 PyPI 源码包

Choose a tag to compare

@fanyuantaier fanyuantaier released this 25 Sep 15:58

v2.2.6.1(2026-09-25)

打包修正:一键启动器进 PyPI

  • Run.exe 现在随源码包发布。它此前只在 GitHub 仓库里,PyPI 的两份制品都没有它;现在 MANIFEST.in 把它和仓库根目录的 __init__.py 一起纳入 sdist(tar.gz),下载解压就是完整项目目录,双击 Run.exe 即可装依赖并打开 Web 配置页。
  • __init__.py 里的 os.system('Run.exe') 改为按自身所在目录用绝对路径调用:原来的写法要求调用者的当前工作目录正好是项目目录,从别处 import 会静默失败。非 Windows 或文件不存在时安静跳过,不影响正常导入。
  • wheel(pip 安装)里不放启动器:pip 装出来的目录没有 requirements.txt 和项目源码,启动器第一步 pip install -r requirements.txt 就会失败退出。需要用启动器的用户请下载源码包(tar.gz);pip 用户仍可用 wechatbot / wechatbot-webui 两个命令。

安装

# 需要一键启动器(推荐给不想折腾 Python 环境的用户)
下载 wechatbot_new-2.2.6.1.tar.gz 解压 → 双击 Run.exe

# 只是升级代码
pip install -U wechatbot-new

功能改动见 v2.2.6(依赖下限 wechatauto-replica>=1.2.4.1、防撤回与朋友圈新增功能、识图支持 DeepSeek)。

项目地址:https://github.com/fanyuantaier/wechatbot-new | PyPI:https://pypi.org/project/wechatbot-new/

Release 2.2.6: 适配 wechatauto 1.2.4.1,防撤回/朋友圈新增功能,识图支持 DeepSeek

Choose a tag to compare

@fanyuantaier fanyuantaier released this 25 Sep 15:52

v2.2.6(2026-09-25)

⚠️ 请先升级依赖

wechatauto-replica[guia] 最低版本提到 >=1.2.4.1(原先只要求 >=1.2.0,requirements.txt 里更是停在 >=1.0.4)。

低于 1.2.4 的版本在微信 4.1.15 上会直接失败——表现为收得到消息但发不出去。升级到 1.2.4.1 后,微信 4.1.15.13 的收起式搜索入口、朋友圈滚动与点赞评论都已修好。

新增功能:防撤回

  • /撤回(/rc):查看当前会话最近 5 条被撤回的消息,带原文
  • /撤回 10:临时指定条数(最多 50)
  • /撤回统计(/rcs):本会话共被撤回多少次、谁最常撤回、最近一次时间
  • 撤回提醒(配置项 ENABLE_RECALL_NOTICE,默认关):发现新的撤回时主动往那个会话发一条带原文的提醒
  • 可调项:RECALL_BACKFILL(启动回填历史条数)、RECALL_SCAN_INTERVAL(扫描间隔)、RECALL_SCAN_LIMIT(每轮重读条数)

新增功能:朋友圈

  • /朋友圈(/pyq):发指令者最近的朋友圈动态(时间 + 摘要 + 图/视频/赞/评论数量)
  • /朋友圈 老王:看指定昵称或备注的人;/朋友圈 10:临时指定条数
  • /朋友圈互动(/pyqi,配置项 ENABLE_MOMENTS_INTERACTIONS,默认关):谁赞了、谁评论了你的朋友圈
  • 朋友圈监听(ENABLE_MOMENTS_WATCH + MOMENTS_WATCH_INTERVAL,默认关):监听对象发了新动态时,机器人下次跟对方聊天会知道

以上都是只读本地数据库(sns.db / 镜像库),不打开朋友圈界面、不点按钮。

接入 wechatauto 1.2.x 的能力

  • 群消息发送者身份:群里的图片 / 文件 / 语音不再只显示一个数字,msg.sender_wxid 给出真 wxid,msg.sender 是备注或昵称
  • 语音取不到音频时给出原因:区分「微信没把音频落盘(要在微信里播放过一次)」和「库/索引读不到」,不再只给模型一句空的 [语音消息]:
  • 新增群成员查询(静态读库)、朋友列表会话上限 50 → 500

识图新增 DeepSeek

「图片/表情包识别配置」的服务商下拉新增 DeepSeek官方(https://api.deepseek.com + deepseek-flash)。请求格式与原有 Moonshot/WeAPIs 完全一致,API Key 填识图区块自己的字段。
另外:图片按扩展名给 MIME;接口非 200 时把服务端返回体写进日志,换服务商踩坑时能直接看到原因。

其他

  • 默认节流档位改为 fast(WECHATAUTO_RHYTHM):wechatauto 1.2.3 起的 natural 档会拖住本项目的分段回复
  • Web 配置页的「防撤回」「朋友圈查询」拆成两个独立面板,以开关和输入框为主;帮助文档同步更新
  • 版权面板与帮助页署名改为本仓库维护者,并指向本仓库与 PyPI

安装

pip install -U wechatbot-new

项目地址:https://github.com/fanyuantaier/wechatbot-new | PyPI:https://pypi.org/project/wechatbot-new/

Release v2.2.5

Choose a tag to compare

@fanyuantaier fanyuantaier released this 31 Aug 07:16

v2.2.5 Release Notes (2026-08-31)

修复:WAL 合并后数据库缓存损坏导致死循环

问题根因

WAL 合并把过期/错位页写进解密缓存后,_check_merged 只用 SELECT count(*) FROM sqlite_master 校验——这只查 schema 树,数据页已损坏却依然通过。缓存 stamp 又标记为"已是最新",于是后续每秒轮询都复用这份坏缓存,反复抛 database disk image is malformed,清缓存重建后同样复现(因为合并结果照样逃过校验),形成死循环。

修复内容

  1. _check_merged:改用 PRAGMA quick_check 全库校验(含数据页/索引页),合并结果一损坏立即触发全量重建重试(db.py:974)
  2. 新增 _invalidate_cache():清空 workdir 中全部解密 .db/.stamp 缓存(保留 keys.json),日志输出「已清 N 个缓存文件等待重建」(db.py:1131)
  3. 查询统一入口 _run_msg_query:get_messages/get_new_messages/get_message_row/_find_media_rows 查询命中 malformed 时清缓存→重建→自动重试一次,彻底恢复则抛给 Listener 跳过本轮,不再卡死(db.py:1180)
  4. _msg_conn 修复:命中连接之外的分片库连接立即关闭,避免 Windows 下删除缓存文件被占用(db.py:1151)

验证

  • 损坏数据页时旧校验通过但 SELECT 抛 malformed、新校验返回 False
  • 模拟「首次损坏→清缓存重建→重试成功」与「持续损坏→重抛被 Listener 兜住」两条路径均通过

安装

pip install wechatbot-new==2.2.5