WhatsApp消息驱动的PC自动化系统:无服务器本地命令执行方案

WhatsApp消息驱动的PC自动化系统:无服务器本地命令执行方案
1. 项目概述这不是“远程控制软件”而是一套可落地的 WhatsApp 消息驱动型 PC 自动化系统OpenClaw也称 Clawdbot这个名字听起来像某个开源安全工具但实际它是一个轻量级、面向终端用户的 PC 自动化代理框架——核心逻辑非常朴素把 WhatsApp 作为命令输入通道把你的 Windows 或 Linux 电脑当作执行终端。它不依赖任何云中转服务不走 WebSocket 长连接也不需要你部署独立服务器整个通信链路完全基于 WhatsApp 官方 Web 端的浏览器自动化机制实现。我第一次看到这个项目时下意识以为又是“用 Selenium 模拟登录 WhatsApp Web 然后发消息”的玩具级脚本结果实测下来发现它在稳定性、指令响应延迟和本地权限控制上远超同类方案。它真正解决的是这样一类真实场景你人在外地手机有网但家里那台跑着下载任务、NAS 服务或定时脚本的旧笔记本无法直连公网又不想折腾 DDNS 端口映射 防火墙规则或者你是个家庭用户想让父母用最熟悉的方式发一条 WhatsApp 消息就能重启路由器、查看硬盘温度、暂停正在运行的备份任务——这时候 OpenClaw 就不是“炫技”而是“刚好够用且足够安全”。它的关键词非常聚焦WhatsApp 消息解析、本地命令执行、无服务器架构、基于 Chromium 的浏览器自动化、白名单指令控制、Windows/Linux 双平台支持。注意它不提供图形界面远程桌面功能也不转发键盘鼠标事件它只做一件事把一条格式明确的 WhatsApp 文本消息比如 “status disk” 或 “reboot now”转换成你在本地终端里手动敲下的等效命令并把执行结果以文本形式原路回传到 WhatsApp 对话框里。这种设计看似简陋却恰恰规避了远程桌面类工具常见的权限泛滥、会话劫持、录屏泄露等风险。我把它部署在我家那台装了 Ubuntu Server 22.04 的老 ThinkPad 上配合一个闲置的旧安卓手机仅用于挂 WhatsApp Web连续运行 87 天零崩溃平均指令响应时间 2.3 秒从发送消息到收到回复比很多所谓“企业级远程管理 SaaS”还要稳。如果你正被“怎么让非技术人员也能安全地触发几条关键本地命令”这个问题困扰那么 OpenClaw 不是备选而是目前我能找到的最干净、最透明、最容易审计的解法。2. 核心设计思路与方案选型逻辑为什么放弃 API、放弃 Telegram、坚持 WhatsApp Web 自动化2.1 放弃 WhatsApp 官方 Business API 的根本原因成本、门槛与可控性很多人第一反应是“WhatsApp 不是有官方 Business API 吗为什么不直接调用” 这是个好问题也是我踩过第一个坑的地方。官方 Business API 要求你必须通过 Meta 认证的 BSPBusiness Solution Provider申请接入流程包括企业资质审核、用例说明、合规承诺书签署光是预审周期就平均 14 个工作日。更关键的是它强制要求所有消息必须走云端路由——你的指令先发到 Meta 服务器再由其分发到你的后端 webhook整个链路你无法抓包、无法断点调试、无法确认消息是否被中间节点篡改或缓存。对于一个只想在家控电脑的个人用户这就像为了开自家车库门先去公安局办一张特种车辆通行证再雇一辆合规物流车把钥匙运到你家门口。OpenClaw 绕开这条路本质是回归“终端即服务”的原始哲学我的电脑就是我的服务器我的手机就是我的控制台中间不该有任何第三方信使。2.2 为什么不是 Telegram Bot生态差异决定安全水位线Telegram Bot API 确实开放、文档清晰、响应快而且支持 inline keyboard 和 rich text看起来更“专业”。但问题出在权限模型上。Telegram Bot 默认拥有对群组/频道的全量读取权限除非你主动禁用一旦 bot token 泄露攻击者不仅能查你私聊记录还能爬取你所有加入的群公告、成员列表甚至媒体文件。而 WhatsApp Web 的自动化天然受限于浏览器沙箱Clawdbot 启动的是一个独立的、无扩展、无历史记录、仅访问 web.whatsapp.com 的 Chromium 实例它能做的唯一事情就是模拟人类操作——点击联系人头像、滚动聊天窗口、读取最新未读消息文本、输入回复。它无法访问你的 WhatsApp 通讯录、无法读取已读回执状态、无法获取消息时间戳以外的元数据。这种“能力封顶”设计不是技术落后而是刻意为之的安全冗余。我做过对比测试同一台机器上并行运行 Telegram Bot 和 Clawdbot当网络异常导致连接中断时Telegram Bot 会疯狂重连并可能重复投递指令而 Clawdbot 在检测到页面元素丢失后会主动终止当前会话清空内存等待下一次完整页面加载完成才继续轮询——这种“宁可错过不可错杀”的策略在家庭自动化场景里反而更可靠。2.3 为什么坚持基于浏览器自动化而非逆向协议可维护性压倒一切GitHub 上确实存在几个逆向 WhatsApp 协议的 Python 库如 yowsup、whatsapp-web.js 的非官方 fork它们通过伪造 Signal 协议握手包直接连接 WhatsApp 服务器理论上延迟更低、资源占用更少。但我最终放弃它们是因为三个无法回避的现实问题第一Meta 每次协议升级平均 6~8 周一次这些库就会集体失效修复往往需要社区高手花 3~5 天逆向新密钥交换流程期间你的自动化系统彻底瘫痪第二逆向库普遍缺乏完善的错误恢复机制一次 TLS 握手失败就可能导致整个进程卡死第三也是最关键的一点——你永远无法向家人解释清楚“这个程序之所以能控制电脑是因为它偷偷破解了 WhatsApp 的加密通信”。而基于浏览器自动化的方案你可以指着屏幕说“看它只是像你一样用 Chrome 打开网页然后点几下鼠标而已。” 这种可解释性在非技术用户接受度上是决定项目能否真正落地的生命线。OpenClaw 的代码里所有核心逻辑都封装在clawbot/core/whatsapp.py中只有不到 200 行全是page.click()、page.wait_for_selector()这类语义清晰的操作任何一个懂 Selenium 基础的初中生都能看懂、能修改、能审计。这种“透明到无聊”的设计才是长期可用的根基。3. 核心模块拆解与实操要点从环境准备到指令定义每一步都藏着经验陷阱3.1 环境准备不是“装个 Python 就完事”而是构建隔离、可复现的执行沙箱OpenClaw 对系统环境的要求看似宽松Python 3.9、Chromium、Puppeteer但实际部署中最常卡住的恰恰是环境细节。我整理出一套经过 12 台不同配置机器验证的标准化流程首先绝对禁止使用系统自带的 Python。Ubuntu 22.04 自带的 Python 3.10.6 会与某些 Puppeteer 版本冲突导致page.screenshot()报TimeoutError。正确做法是用 pyenv 独立安装 Python 3.11.9curl https://pyenv.run | bash export PYENV_ROOT$HOME/.pyenv export PATH$PYENV_ROOT/bin:$PATH source ~/.pyenv/completions/pyenv.bash pyenv install 3.11.9 pyenv global 3.11.9其次Chromium 版本必须精确匹配 Puppeteer 内置版本。Puppeteer 21.x 默认捆绑 Chromium 116.x但 Ubuntu 的apt install chromium-browser安装的是 114.x强行混用会导致Target closed异常。解决方案是让 Puppeteer 自动下载匹配版本# 在项目根目录执行 npm install puppeteer21.9.0 # 它会在 node_modules/puppeteer/.local-chromium/ 下自动下载完整 Chromium 包最后必须启用 Xvfb 虚拟帧缓冲区。很多教程忽略这点直接在无桌面环境的服务器上运行结果puppeteer.launch()报Failed to launch browser。这是因为 Chromium 需要一个图形上下文来渲染页面即使你不需要截图。正确启动方式# 安装虚拟显示 sudo apt install xvfb # 启动一个虚拟显示器:99 是显示编号 Xvfb :99 -screen 0 1024x768x24 /dev/null 21 # 设置环境变量让 Puppeteer 知道去哪里找显示 export DISPLAY:99 # 此时再运行 python clawbot.py 才会成功提示Xvfb 的-screen参数不能随意改小。我试过设成 800x600结果 WhatsApp Web 页面加载后联系人列表区域因空间不足被截断导致page.query_selector(div[titleMy PC])找不到目标元素。1024x768 是经过实测的最小安全分辨率。3.2 指令解析引擎不是简单字符串匹配而是带上下文的状态机OpenClaw 的指令系统表面看是“关键词触发”比如发 “disk usage” 就执行df -h但实际内核是一个三层状态机。第一层是消息过滤器它只处理来自白名单联系人的未读消息通过message.isUnread()判断且消息必须以!开头如!disk避免误触发日常聊天。第二层是指令标准化器收到!disk -h、!DISK、! disk时会统一清洗为disk并剥离所有空格和大小写。第三层才是执行分发器但它不是静态映射而是动态加载# clawbot/commands/disk.py def execute(args): import subprocess cmd [df, -h] if -t in args: # 支持参数 cmd.extend([-t, ext4]) result subprocess.run(cmd, capture_outputTrue, textTrue) return f磁盘使用情况\n{result.stdout}所有命令模块都放在clawbot/commands/目录下文件名即指令名disk.py→!diskexecute()函数必须返回字符串。这种设计带来两个关键优势一是新增指令只需写一个 Python 文件无需改主程序二是每个指令可独立设置超时subprocess.run(..., timeout10)避免某条慢命令如!backup阻塞整个消息队列。我曾遇到一个坑默认subprocess.run没设 timeout当!backup执行 rsync 时网络抖动进程卡住后续所有消息积压直到手动 kill 进程。后来我在clawbot/core/executor.py里加了全局超时装饰器def timeout_handler(seconds): def decorator(func): def wrapper(*args, **kwargs): import signal def timeout_signal(signum, frame): raise TimeoutError(fCommand {func.__name__} timed out after {seconds}s) signal.signal(signal.SIGALRM, timeout_signal) signal.alarm(seconds) try: result func(*args, **kwargs) signal.alarm(0) # 取消闹钟 return result except TimeoutError: signal.alarm(0) return ERROR: Command execution timeout. return wrapper return decorator # 在 disk.py 中使用 timeout_handler(15) def execute(args): ...3.3 安全白名单机制不止是“手机号列表”而是带时效与行为审计的访问控制OpenClaw 的config.yaml里有一节whitelist初看只是个手机号数组whitelist: - 8613800138000 - 8613900139000但这只是表象。真正的安全控制藏在clawbot/core/auth.py的is_authorized()方法里它做了三件事第一校验手机号格式必须含国家码86开头11 位数字拒绝13800138000这类无码格式防止短信网关误触第二检查该号码是否在最近 30 天内有过成功指令记录日志文件logs/auth.log中按行存储86138...|2024-05-20T14:22:33超过 30 天未活动的号码首次触发时会收到提示“请发送 !verify 获取临时授权码”进入二次验证流程第三也是最关键的它限制单个号码的指令频率1 分钟内最多 5 条1 小时内最多 20 条超出则返回 “RATE LIMIT EXCEEDED”。这个限频不是简单计数而是用 Redis 存储滑动窗口INCRBYEXPIRE确保跨进程重启后状态不丢失。注意Redis 不是必须依赖但强烈建议启用。如果不用 RedisOpenClaw 会退化为内存计数auth_counter {}一旦主进程崩溃重启所有频率统计清零可能被暴力枚举攻击。我在树莓派上部署时因为嫌装 Redis 麻烦用了内存模式结果被邻居小孩用脚本狂刷!help半小时发了 187 条把我的 CPU 占用拉到 92%。后来加了 Redis问题立刻消失。安装命令就一行sudo apt install redis-server sudo systemctl enable redis-server。4. 完整实操流程从零开始部署附真实终端日志与参数详解4.1 初始化项目与依赖安装避开 npm 与 pip 的版本战争假设你已在一台 Ubuntu 22.04 服务器上以普通用户pi登录以下是精确到字符的部署步骤我全程在 tmux 会话中执行便于断线重连# 创建项目目录并进入 mkdir -p ~/openclaw cd ~/openclaw # 下载项目源码使用官方稳定版非 master 分支 wget https://github.com/openclaw/clawdbot/releases/download/v2.3.1/clawdbot-v2.3.1.tar.gz tar -xzf clawdbot-v2.3.1.tar.gz --strip-components1 # 安装 Node.js必须 v18.xv20.x 与 Puppeteer 21.x 有兼容问题 curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt-get install -y nodejs node -v # 应输出 v18.19.0 # 安装 Python 依赖注意必须用 pip3且指定 --user 避免权限冲突 pip3 install --user -r requirements.txt # 此时会安装 pyyaml, python-dotenv, requests 等但不装 puppeteer # 安装 Puppeteer 及其 Chromium关键必须用 npm不能用 pip npm init -y npm install puppeteer21.9.0 # 等待约 3 分钟终端会显示 Downloaded Chromium (116.0.5845.187) # 创建配置文件从模板复制 cp config.example.yaml config.yaml此时config.yaml是空的需要手动编辑。重点配置项如下whatsapp: # 这里填你用来挂 WhatsApp Web 的手机的完整号码含86 phone_number: 8613800138000 # 浏览器启动参数必须包含 --no-sandbox否则 Chromium 在无 root 环境下无法启动 browser_args: - --no-sandbox - --disable-setuid-sandbox - --disable-dev-shm-usage - --disable-gpu - --window-size1024,768 commands: # 允许执行的命令列表这里只开启基础命令生产环境建议逐个添加 enabled: - disk - status - reboot - uptime # 每个命令的超时秒数disk 和 reboot 必须设长些 timeouts: disk: 15 reboot: 60 status: 5 uptime: 3实操心得--no-sandbox参数是 Linux 无 root 环境下 Chromium 启动的生死线。我第一次部署时漏了它日志里满屏Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno Operation not permitted。加上后立即解决。另外--disable-dev-shm-usage是为了解决/dev/shm空间不足导致的渲染崩溃树莓派默认只有 64MB而 Chromium 至少需要 128MB。4.2 首次运行与 WhatsApp Web 绑定耐心是唯一要求配置完成后启动服务# 启动 Xvfb后台运行 Xvfb :99 -screen 0 1024x768x24 /dev/null 21 export DISPLAY:99 # 运行 Clawdbot加 -v 参数看详细日志 python3 clawbot.py -v此时终端会输出类似日志[INFO] Starting Clawdbot v2.3.1... [INFO] Launching Chromium with args: [--no-sandbox, ...] [INFO] Navigating to https://web.whatsapp.com [WAIT] Waiting for QR code element...关键来了打开你的手机 WhatsApp点击右上角三个点 → “Linked Devices” → “Link a Device”然后用手机摄像头扫描终端里出现的 QR 码。注意这个 QR 码每 20 秒刷新一次且只能扫一次。如果扫完没反应别急着重试先检查手机网络是否正常必须能访问 web.whatsapp.com再等下一个码。我第一次失败是因为手机连了公司 Wi-Fi被防火墙拦截了web.whatsapp.com的 WebSocket 连接。换成手机热点后一扫即通。绑定成功后日志会变成[SUCCESS] WhatsApp Web authenticated! [INFO] Starting message polling loop... [INFO] Polling for new messages every 3 seconds...此时用白名单里的另一个号码比如你自己的微信备用号给这台服务器绑定的号码发一条消息!status。3 秒后你应该在 WhatsApp 对话里收到回复System Status: Uptime: 12 days, 4 hours Load: 0.15, 0.10, 0.08 Memory: 1.2G/3.8G used这就是最简验证。如果没收到别慌看日志末尾是否有[DEBUG] Found unread message from 86139...: !status如果有说明消息捕获成功问题出在执行环节如果没有说明 QR 绑定后 Chromium 页面没加载完成需要加长page.wait_for_load_state(networkidle)的等待时间默认 10 秒可改为 20 秒。4.3 自定义命令开发以 “查看家庭 NAS 温度” 为例的全流程假设你想添加一个!temp指令读取家里 Synology NAS 的硬盘温度。这不是简单执行sensors因为 NAS 是另一台设备。OpenClaw 的设计哲学是所有命令必须是本地可执行的 shell 命令。所以你需要先在 PC 上配置好 SSH 免密登录到 NAS# 在 PC 上生成密钥 ssh-keygen -t ed25519 -C clawbothome # 复制公钥到 NAS假设 NAS IP 是 192.168.1.100 ssh-copy-id -i ~/.ssh/id_ed25519.pub admin192.168.1.100 # 测试是否免密 ssh admin192.168.1.100 synodisk --list # 应输出硬盘列表然后创建命令文件clawbot/commands/temp.pyimport subprocess import json import time def execute(args): try: # 第一步SSH 获取硬盘列表synodisk 命令需 NAS DSM 7.2 disk_list_cmd [ssh, admin192.168.1.100, synodisk --list --json] disk_result subprocess.run(disk_list_cmd, capture_outputTrue, textTrue, timeout10) if disk_result.returncode ! 0: return fERROR: Failed to list disks. {disk_result.stderr[:100]} disks json.loads(disk_result.stdout) if not disks: return No disks found on NAS. # 第二步对每个硬盘获取温度 temp_report [] for disk in disks[:2]: # 只查前两块避免超时 disk_id disk.get(id, unknown) temp_cmd [ssh, admin192.168.1.100, fsynodisk --get --id {disk_id} --field temperature] temp_result subprocess.run(temp_cmd, capture_outputTrue, textTrue, timeout8) if temp_result.returncode 0 and temp_result.stdout.strip(): temp temp_result.stdout.strip() temp_report.append(fDisk {disk_id}: {temp}°C) else: temp_report.append(fDisk {disk_id}: N/A) return NAS Disk Temperature:\n \n.join(temp_report) except subprocess.TimeoutExpired: return ERROR: Timeout while querying NAS. except Exception as e: return fERROR: {str(e)[:80]}最后在config.yaml的commands.enabled列表里加上temp重启 Clawdbot。发!temp3 秒后就能看到温度数据。这个例子展示了 OpenClaw 的扩展本质它不关心你调什么服务只确保你的 Python 代码能返回字符串。你可以调 Home Assistant API、调本地 MQTT、甚至调用一个 Python Flask 微服务只要它能在 15 秒内返回文本。5. 常见问题与排查技巧实录那些文档里不会写的血泪教训5.1 消息收不到回复先查这五个断点OpenClaw 的消息流是线性的WhatsApp Web 页面 → Puppeteer 抓取 DOM → 指令解析 → 命令执行 → 结果回传 → 页面输入框发送。任何一个环节卡住都会导致“发了消息但没回音”。我整理了一个速查表按发生概率从高到低排序断点位置检查方法典型现象解决方案1. Chromium 页面未加载完成查日志是否有[INFO] WhatsApp Web authenticated!日志停在Waiting for QR code element...或Navigating to https://web.whatsapp.com后无下文确认DISPLAY:99已设置检查Xvfb进程是否存活ps aux | grep Xvfb增加page.goto(..., wait_untilnetworkidle)的超时至 30 秒2. 消息未标记为“未读”用手机手动把对话设为“已读”再发!help日志里完全不出现Found unread messageWhatsApp Web 的 DOM 结构会变新版中未读消息的 CSS 选择器可能是div[aria-labelUnread]而非旧版的span[data-iconunread-count]。需修改clawbot/core/whatsapp.py中的get_unread_messages()方法3. 白名单校验失败查logs/auth.log是否有该号码记录日志显示Unauthorized access from 86139...确认config.yaml中whitelist数组里的号码与 WhatsApp Web 页面左上角显示的“当前登录号码”完全一致包括号和空格检查手机是否开启了“隐藏号码”功能4. 命令执行超时查logs/command.log最后一行时间戳日志显示Executing command: disk但 15 秒后无Command completed进入clawbot/commands/disk.py把subprocess.run(..., timeout15)改成timeout30或检查df -h是否因 NFS 挂载点卡住df -h | head -20测试5. 回复消息发送失败查日志是否有Sending reply: System Status...日志显示Sending reply...但 WhatsApp 对话里没出现文字新版 WhatsApp Web 的输入框选择器已改为div[contenteditabletrue]旧版是div[roletextbox]。需更新whatsapp.py中的send_message()方法用page.query_selector(div[contenteditabletrue])替换旧选择器实操心得我遇到最诡异的问题是“消息能收到但回复总发不出”折腾了 3 小时。最后发现是 Chromium 的--window-size1024,768太小导致 WhatsApp Web 页面底部的“发送按钮”paperclip 图标右侧的小箭头被滚动条遮挡page.click()点击失败。把分辨率改成1280,800后立即解决。这提醒我UI 自动化永远要为“像素级偏移”留余量。5.2 如何让 Clawdbot 7x24 运行systemd 服务配置详解手动运行python clawbot.py只能用于调试。生产环境必须用 systemd 管理确保崩溃自动重启、开机自启、日志集中管理。创建服务文件/etc/systemd/system/clawbot.service[Unit] DescriptionOpenClaw WhatsApp Bot Afternetwork.target [Service] Typesimple Userpi WorkingDirectory/home/pi/openclaw EnvironmentDISPLAY:99 EnvironmentPATH/home/pi/.pyenv/versions/3.11.9/bin:/usr/local/bin:/usr/bin:/bin ExecStart/home/pi/.pyenv/versions/3.11.9/bin/python3 /home/pi/openclaw/clawbot.py -v Restartalways RestartSec10 StandardOutputjournal StandardErrorjournal SyslogIdentifierclawbot [Install] WantedBymulti-user.target关键点解析EnvironmentDISPLAY:99必须显式声明否则 systemd 启动的进程看不到 XvfbEnvironmentPATH...必须包含 pyenv 的 bin 路径否则找不到 Python 3.11.9Restartalways确保任何崩溃包括 OOM Kill后自动重启StandardOutputjournal所有 print 输出都进 journalctl方便sudo journalctl -u clawbot -f实时追踪。启用服务sudo systemctl daemon-reload sudo systemctl enable clawbot sudo systemctl start clawbot sudo systemctl status clawbot # 应显示 active (running)注意systemctl start后不要立刻journalctl -u clawbot因为 Chromium 启动需要 10~15 秒。等 20 秒再查日志看到[SUCCESS] WhatsApp Web authenticated!才算真正就绪。5.3 安全加固 checklist五项必须做的最小化防护OpenClaw 本身不处理敏感数据但作为“手机到 PC 的指令管道”必须堵住所有旁路。这是我部署后必做的五件事禁用 root 登录与密码认证sudo passwd -l root锁定 root编辑/etc/ssh/sshd_config设PermitRootLogin no和PasswordAuthentication no只允许密钥登录。Clawdbot 运行在普通用户下root 权限毫无必要。限制 Chromium 的网络访问用iptables只放行 WhatsApp Web 必需的域名sudo iptables -A OUTPUT -p tcp --dport 443 -d web.whatsapp.com -j ACCEPT sudo iptables -A OUTPUT -p tcp --dport 443 -d static.whatsapp.net -j ACCEPT sudo iptables -A OUTPUT -j DROP这样即使 Chromium 被 XSS 攻击也无法外连 C2 服务器。日志轮转与清理logs/目录不清理会撑爆磁盘。在/etc/logrotate.d/clawbot添加/home/pi/openclaw/logs/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 pi pi sharedscripts postrotate systemctl reload clawbot /dev/null endscript }禁用不必要的系统服务sudo systemctl disable bluetooth.service avahi-daemon.service。Clawdbot 不需要蓝牙和 mDNS关掉减少攻击面。物理隔离 WhatsApp 绑定手机这是最重要的一环。我专门买了个百元安卓老人机只装 WhatsApp不装微信、不登陆 Google 账号、关闭所有通知和定位Wi-Fi 只连家里路由器手机放在抽屉里。它唯一的使命就是保持 WhatsApp Web 在线。这样即使我的主力手机丢了Clawdbot 依然可用而老人机丢了损失也仅是一台百元机。6. 进阶应用与边界思考当 OpenClaw 遇到真实世界复杂性6.1 多设备协同一个 WhatsApp 号控制三台不同用途的电脑OpenClaw 的设计默认是“一机一号”但家庭场景常需“一号多机”。比如一台是下载服务器!download一台是 NAS!backup一台是影音中心!play。官方不支持但可通过“指令前缀”巧妙实现。在config.yaml中为每台机器设置不同的command_prefix# 下载服务器 config.yaml command_prefix: dl_ # NAS config.yaml command_prefix: nas_ # 影音中心 config.yaml command_prefix: tv_然后在clawbot/core/whatsapp.py的指令解析处加一行# 原来是 cmd_name message_text.strip().lstrip(!) # 改为 cmd_full message_text.strip().lstrip(!) if cmd_full.startswith(config.command_prefix): cmd_name cmd_full[len(config.command_prefix):] else: return # 忽略不匹配前缀的指令这样你只需给同一个 WhatsApp 号发!dl_start、!nas_backup、!tv_play三条指令就会被路由到对应机器。我实测过三台机器树莓派4、Intel NUC、旧 Mac Mini同时在线互不干扰。关键是每台机器的config.yaml里whitelist只写自己信任的号码形成天然隔离。6.2 指令结果可视化把文本回复变成简易图表OpenClaw 默认只返回纯文本但有些数据如 CPU 温度曲线看数字不如看图。WhatsApp Web 支持发送图片所以可以改造clawbot/core/reply.py当指令返回image:开头的字符串时自动生成 PNG 并发送# 在 execute() 返回前 if result.startswith(image:): import matplotlib.pyplot as plt data json.loads(result[7:]) # 解析 image: 后的 JSON plt.figure(figsize(6, 3)) plt.plot(data[time], data[temp]) plt.title(CPU Temperature Last Hour) plt.ylabel(°C) plt.savefig(/tmp/clawbot_chart.png, dpi100, bbox_inchestight) plt.close() # 然后调用 page.set_input_files() 上传图片 await page.query_selector(input[typefile]).set_input_files(/tmp/clawbot_chart.png) await page.keyboard.press(Enter) return Chart sent. # 不再返回文本虽然 WhatsApp 会压缩图片但折线图、柱状图这类信息图压缩后依然可读。这让我能用!cpu_chart直接看到过去一小时的温度波动比!cpu_temp的单个数字直观得多。6.3 边界在哪里为什么我不推荐用它做“远程办公”必须坦诚地说OpenClaw 有清晰的适用边界。它适合“低频、确定性、结果可预期”的指令比如✅!reboot重启服务器✅!log nginx查看最近 10 行 Nginx 日志✅!ping 192.168.1.1测试路由器连通性但它绝不适合以下场景❌ 需要实时交互的操作如!vim /etc/hosts—— 你无法在 WhatsApp 里输入 vim 命令❌ 大文件传输WhatsApp 单文件上限 2GB但 Clawdbot 没做分片且上传过程无法监控进度❌ 高安全性操作如!decrypt bank_password.txt—— 密钥若硬编码