手机上的OpenClaw怎么玩?我花了3天接入飞书终于搞定了…(详细教程)
先说结论:真正把AI代理用起来,关键不在于模型多聪明,而在于你随时能唤醒它、指挥它。我过去在电脑上折腾OpenClaw,总觉得缺了点什么——直到我把飞书接进去,手机扫个码,在聊天窗口里给它下指令,它自己去做事,做完再把结果发回来。这种“揣在兜里的遥控器”感觉,和守着终端敲命令完全是两回事。
这篇教程把我从零到一接入飞书的完整过程写出来,包括架构怎么设计、飞书后台怎么配、消息桥接服务怎么写、手机上实际能怎么用,还有我踩过的各种坑。没有废话,所有代码和步骤都是最终跑通的版本,你可以直接照抄。
1. 整体设计:为什么用飞书给OpenClaw开了个前门
1.1 手机端操作AI代理的原理拆解
先把需求说透。OpenClaw这种AI代理,本质上是一个能接收自然语言指令、调用工具、完成复杂任务的程序。它适合跑在服务器或者一台长期开机的电脑上,但问题也出在这里:它没有一个天然的、随手可用的移动端入口。
我想实现的目标很简单,就是在地铁上用手机发一句话,服务器上的OpenClaw能收到并开始执行,执行完了把结果推回来。要达到这个效果,一般有两条路:第一条是给OpenClaw套一个带网页界面的壳,手机浏览器访问,但浏览器在锁屏后连接就会断,通知也不及时;第二条是接一个成熟的IM平台,把聊天窗口当控制台,消息推送由IM平台负责,用户这边完全不操心连接保活。
我选了第二条,而且选的是飞书。理由不复杂:飞书机器人接口成熟,支持事件订阅、消息推送、富文本回复,权限模型也足够细。最关键的,它天然就带着“手机端”和“PC端”两个入口,不需要我再为移动端单独做适配。
整个链路的逻辑是这样的:手机端发消息到飞书会话 → 飞书开放平台把这个事件推送到我的中转服务 → 中转服务解析消息内容并传给OpenClaw → OpenClaw执行任务 → 把结果返回到中转服务 → 中转服务再通过飞书API发回会话。看起来环节多,实际运行时每条链路都在秒级以内,唯一耗时的是OpenClaw执行任务那一步。
从这个架构能看出来,中转服务是整个系统的核心。它既要处理飞书的事件请求,又要负责和OpenClaw通信。所以这个服务得独立部署,不能挂在OpenClaw内部,免得OpenClaw重启时整个通道都断掉。
1.2 方案选型时我考虑的其它选项
在决定用飞书之前,我也评估过其它几个方案,这里把对比列一下,方便你判断哪种更适合自己的场景。
SSH加终端模拟器:最直接,但手机上跑终端体验很糟糕,而且OpenClaw的输出动辄好几屏,手机屏幕根本看不过来。这套路适合应急,不适合日常。
Telegram Bot:如果用户本身能正常访问Telegram,这确实是最省事的方案,生态成熟、文档齐全。但国内使用环境的现实限制让我放弃了这个选项。
自己写一个手机App:成本太高,为了一个控制入口专门做App维护,不值当。
飞书机器人:最终选择。它最大的优势是把“通信层”完全交给飞书,我只负责写一个中间层。飞书的消息加密、重试、会话管理都替你做了,省下大量工作。
选型时还有一个隐藏的折点:飞书开放平台的“事件订阅”机制非常稳定,它支持长连接和Webhook两种收消息的方式。很多人一上来就只研究Webhook,其实飞书还提供长连接模式,连公网入口都不用暴露,非常适合部署在内网的场景。我这次因为服务器本来就有对外域名,所以用的Webhook方式,如果你手头只有内网机器,建议直接走长连接模式。
2. 环境准备与部署OpenClaw
2.1 准备一台长期运行的机器
接入飞书之后,OpenClaw就要在后台持续待命了,所以运行环境不能是笔记本这种随时会休眠的设备。我自己用的是一台云服务器,配置不高,2核4G,跑OpenClaw加中转服务完全够用。
要注意的是,OpenClaw里如果接了浏览器自动化或者本地工具链,对内存的占用会明显上升。我实测下来,一个带浏览器操作能力的OpenClaw实例,空闲时大约占800MB内存,跑任务时峰值能到2GB。如果你要让它频繁操作浏览器,建议配置直接上4核8G,免得任务跑到一半内存被打满。
另外,机器最好能保持网络稳定。飞书的事件订阅有一个规则:如果回调地址连续多次响应超时,飞书会暂停推送并发送告警。这意味着服务器不是“能跑起来就行”,而是要持续稳定在线。
2.2 安装与基础配置细节
判断OpenClaw本身能不能正常跑通。这里不展开完整的安装命令,因为版本更新快,以官方仓库的README为准。我只把通用步骤和关键配置点写出来。
# 拉取代码 git clone https://github.com/your-path/openclaw cd openclaw # 安装依赖(Python示例) pip install -r requirements.txt # 启动服务,不同版本入口可能不同 python run.py安装完成后,第一件事就是改配置文件。OpenClaw通常有一个config.ym或.env,里面至少要配三样东西:模型API的密钥、允许执行的命令白名单、以及服务监听端口。模型API我建议选带function calling能力的那种,因为OpenClaw的核心卖点就是“把自然语言拆成可执行的工具调用”,模型的工具调用能力直接决定它的上限。
在正式接入飞书之前,先在本地终端里做一轮冒烟测试。给OpenClaw发一个最简单的指令,比如“把当前系统时间告诉我”,确认它能正常调用模型并返回结果。这一步很关键,因为后面所有问题排查都要基于“OpenClaw本身是好的”这个前提。如果OpenClaw在本地就回得出错,那接入飞书之后只会更乱。
OpenClaw跑起来以后,记下它默认的服务端口。之后中转服务会通过这个端口和它通信,通信协议一般是HTTP,少数版本会提供CLI调用模式,这两种后面都会讲。
3. 创建飞书应用与权限配置
3.1 在飞书开放平台创建自建应用
飞书接入的第一步是创建应用。打开飞书开放平台的后台,选择“企业自建应用”,填写应用名称和描述,创建完成后进入应用详情页。这里拿到的App ID、App Secret、Verification Token、Encrypt Key四个参数,是后面所有调用的凭证基础。
需要说明的是这四个字段的作用:App ID和App Secret用于换取调用API的tenant_access_token;Verification Token是飞书在推送事件时带上的签名,用于验证请求确实来自飞书;Encrypt Key是消息内容加密用的,如果你的回调请求开启了加密,就用它解密,不开启就用不到。
我的建议是首次调试阶段不要开启消息加密,先把链路跑通,再考虑加密。因为消息加密会让所有的事件消息变成一串密文,出了问题很难判断是解密导致的还是业务逻辑导致的。等整个系统稳定了,再回过头来把加密打开,这样排查起来会清爽很多。
创建完应用之后,还需要在“应用能力”里添加机器人,这一步等同于给应用赋予“在会话里说话”的身份。没有添加机器人能力的应用只能接收事件,不能主动发消息。
应用创建好之后,下一步就是配置权限。权限这步最容易被忽略,也最容易出错。飞书的权限模型是“先声明后授权”,如果你调用的API没有对应的权限声明,即使申请了临时凭证也一样会被拒绝。
我最终用到的权限只有这几个:
- im:message:发送消息
- im:message.group_at_msg:readonly:读取群聊中@机器人的消息
- im:message.p2p_msg:readonly:读取单聊消息
打开权限管理,把这几项都加上。申请之后,如果应用是自建应用且你是管理员,一般几分钟内就能通过,不需要走审批流。
3.2 配置事件订阅与回调地址
事件订阅是这次接入的核心环节。飞书会把用户在会话里的行为以事件的形式推给你配置的服务器地址。
在飞书后台的“事件与回调”页面,添加一个事件,我是用的“接收消息(receive_message)”。事件添加完成后,下面会有一栏“请求地址”,你要填一个公网可访问的HTTPS地址,这个地址必须能响应飞书的URL验证请求。
这里有一个特别容易踩坑的点:飞书的URL验证不是简单POST一个字符串就能通过,它发来的请求体里有“type”为“url_verification”的JSON,你必须原样返回“challenge”字段。
以我用Python Flask写的中转服务为例,验证接口长这样:
@app.route("/feishu/webhook", methods=["POST"]) def feishu_webhook(): body = request.get_json() if body.get("type") == "url_verification": return jsonify({"challenge": body["challenge"]}) # 其他事件处理 ...这里返回的challenge必须是请求体里带过来的那个值,一个字符都不能差。我第一遍测试的时候,手欠在返回前对challenge做了一次json.dumps,结果多套了一层引号,飞书显示“验证失败”,排查了半天。
验证通过之后,飞书后台会显示“事件订阅已启用”。但要注意,启用不代表所有事件都会推过来,你还要确认添加的事件是否处于“已发布”状态。飞书的配置有两种状态:草稿和已发布,我经常在后台改了配置忘记发布,结果事件死活不推过来。
4. 实现消息转发连接逻辑
4.1 写一个轻量级的消息中转服务
中转服务的定位就是桥接层:一边接收飞书的事件推送,另一边把指令交给OpenClaw,再将结果拿回来回复给飞书。
我选的技术栈是Python加Flask,主要是脚本逻辑简单,方便后续修改。整个服务只有两个文件:主程序app.py和适配器adapter.py。主程序负责处理飞书的HTTP请求和应答,适配器负责把消息格式化后交给OpenClaw。
先看主程序的核心路由:
@app.route("/feishu/webhook", methods=["POST"]) def feishu_webhook(): body = request.get_json(force=True) if body.get("type") == "url_verification": return jsonify({"challenge": body["challenge"]}) # 处理接收消息事件 event = body.get("event", {}) msg = event.get("message", {}) chat_id = msg.get("chat_id") content = json.loads(msg.get("content")) text = content.get("text", "") # 去重处理,避免同一事件被飞书重复推送引发多次执行 request_id = body.get("header", {}).get("event_id") if request_id in processed_ids: return jsonify({"code": 0}) processed_ids.add(request_id) # 丢给OpenClaw处理,结果通过飞书API回复 handle_task(chat_id, text) return jsonify({"code": 0})这里有一个重要的设计细节:飞书在事件推送时自带了一个event_id,我用它做幂等去重。因为飞书为了保证消息不丢,会做重试推送,如果你没做去重,搞不好同一个指令会被OpenClaw执行两次。这个坑我把是实战里踩过的,后面排查重试问题时才想起来。
4.2 调用OpenClaw并发送结果回飞书
OpenClaw的调用方式取决于你跑的是哪个版本。通常有两类:一类是HTTP API模式,另一类是CLI命令行模式。我这边因为改动最小,用的是CLI模式:
import subprocess def handle_task(chat_id, text): # 将文本指令传给OpenClaw并等待执行结果 result = subprocess.run( ["python", "openclaw_cli.py", "--task", text], capture_output=True, text=True, timeout=300 ) output = result.stdout.strip() # 调用飞书API发送结果 send_feishu_message(chat_id, output)如果是HTTP模式,核心逻辑就是requests.post(openclaw_url, json={"prompt": text}),没有本质区别。
真正需要提醒的是超时问题。OpenClaw执行一个任务可能要几十秒甚至几分钟,而飞书的Webhook请求等待响应的时间很短,如果一直等OpenClaw跑完才返回,飞书早就判定超时并触发重试了。我这里的处理方式是:先立刻返回一个“已收到,任务开始执行”的占位响应,再在后台线程里异步执行OpenClaw任务,完成后主动调用飞书API把结果推回去。
这个异步设计要感谢某位开发者在网上分享的类似经验,不然我都想不到这个点。很多教程里没写清楚这个细节,导致跟着做的人总遇到“明明收到指令了却不回复”的假故障。
发送消息的飞书API也不复杂,核心就是先拿到tenant_access_token,再调发送消息接口。具体接口路径是im/v1/messages,请求体大致如下:
{ "receive_id": "oc_xxxxxx", "msg_type": "text", "content": "{\"text\":\"任务完成:已生成报告\"}" }拿token的时候注意要带换行,换行错了会得到一个神秘的“invalid token”报错。
5. 手机端使用场景与技巧
5.1 手机发指令的日常玩法
接入完成后,手机就是OpenClaw的移动遥控器。我的使用习惯是给飞书里的OpenClaw机器人建一个单聊,把经常用的指令都存成快捷短语,比如“查看当前服务器负载”、“把日志打包”、“生成一篇摘要”之类。想用的时候打开飞书点一下快捷短语,就能发送。
举几个实际场景:早上出门前,手机给OpenClaw发一句“帮我整理一下今天要跟进的事项”,它会调日历和待办工具,几分钟后发回来一张排好序的清单;下午在路上,又发一句“把昨晚生成的报告发到群文件”,它也能自己完成。
具体代码层面,这些能力都需要你在OpenClaw侧把对应工具接好。飞书这条链路只是入口,OpenClaw能不能完成任务,取决于它有没有对应的工具接口。所以我的建议是,接飞书的同时,花点时间把OpenClaw的常用工具链都验证一遍,不然入口通了,里面是空壳,也没意义。
这里还有一个体验细节值得优化:给机器人做“指令前缀”设计。比如所有命令前面加一个#号,这样群聊里其它人发的消息不会误触发。我自己的单聊里就设置成,只有以#开头的内容才进入OpenClaw逻辑,其他内容默认忽略。这样既避免了频繁的“好的,正在处理”,也让聊天窗口更干净。
5.2 权限控制与隐私安全
手机接入后,安全边界会比之前扩大很多。原来只在电脑上受控访问的AI代理,现在变成了一个通过IM触达的公开入口。需要注意的几个点:
飞书事件回调的请求IP最好做白名单过滤,只接收飞书官方IP段的请求。我在中转服务里加了一段简单的IP校验,不属于飞书IP段的直接拒绝,避免有人扫描到你的回调地址伪造恶意请求。
另外,OpenClaw的能力边界要靠配置文件控制。我强烈建议不要让它以root权限运行,并且把可执行的命令限制在一个白名单里。比如我只允许它调用“读取文件、打包压缩、执行测试脚本、发送HTTP请求”这几类动作,其它操作一概拒绝。这样即使飞书账号被盗,攻击者能利用的范围也有限。
如果传输的是比较敏感的信息,飞书后台的“消息加密”一定要打开。打开之后,事件推送的content字段会变成密文,需要在回调里用Encrypt Key解密。我后来抽时间把这块也补上了,过程不复杂,官方文档有现成的AES解密代码模板。
6. 常见问题排查与踩坑记录
6.1 高频问题速查表
接入过程中十有八九会遇到下面这些问题,我按症状、原因和解决办法整理了一张表,方便你对照:
| 症状 | 常见原因 | 处理办法 |
|---|---|---|
| 后台配置回调URL一直验证失败 | 返回值没有原样返回challenge | 检查响应体是不是只有{"challenge": "xxx"} |
| 事件订阅配置成功但收不到消息 | 应用版本是草稿未发布 | 在飞书后台点击“发布版本” |
| 收到消息但OpenClaw没执行 | 消息没有以预期格式传给OpenClaw | 在中转服务里打印日志,检查text字段解析 |
| 机器人发不出消息 | 权限没有申请或token过期 | 检查权限列表和tenant_access_token有效期 |
| 同一个指令被重复执行 | 飞书重试机制触发 | 用event_id做幂等去重 |
| 任务执行很慢,像是在排队 | 中转服务没有做异步处理 | 改成后台线程并发执行任务 |
6.2 我花三天踩出来的几个经验
第一天,我基本消耗在飞书后台的配置上。最典型的一个问题是,我同时开启了“消息加密”和“事件订阅”调试,结果回调里收到的全是密文,又因为没有解密,走了各种弯路。后面关掉加密才发现,事件本身推得很正常,问题就出在解密逻辑上。
第二天,我开始写中转服务。初版代码写的是同步执行OpenClaw任务,结果一调用就是几百秒,飞书那边反复重试,最后直接把事件停了。第二天晚上我把异步逻辑改好,才彻底解决。
第三天基本是在打磨细节。包括指令前缀、去重、超时控制、日志记录,这些单个看起来都很小的事,但凑在一起才让整个系统有了可用性。
在这里说一个日常容易忽略的小技巧:中转服务的进程一定要配systemd守护,设置成自动重启。OpenClaw这种长期跑的AI代理,偶尔会有内存布局异常退出,如果没有守护进程,可能第二天早上你会发现自己“喊了它半天没人应”。配合套路,我建议再加一个简单的存活告警脚本,每隔几分钟检测一次中转服务和OpenClaw进程是否在线上,异常就发一条飞书消息给你,这样至少能第一时间知道“遥控器断线了”。
最后一个经验是日志。中转服务一定要把每个请求的event_id、chat_id、消息内容、执行结果都记录下来。没有日志的时候,问题全靠猜,有了日志之后,排查速度能快十倍。我甚至会在消息内容里附带一个request id,用OpenClaw执行任务前先打一条日志,这样就能定位到底卡在哪个环节。
接入完成之后,我其实不太会天天盯着终端看OpenClaw输出了,遇到什么事在飞书里说一句就行。这种“手机当遥控器、服务器当手脚”的用法,比单纯在电脑上和AI代理对话顺手很多。如果你手头也有OpenClaw,建议试一下这个接入方案,三天把这个链路跑通是值得的。