借正在忧企业微疑不博属智能谈天小帮忙?学您快速布置小龙虾 Openclaw,轻快完毕企业微疑取智能帮忙的无缝连接,一样平常办公征询、消息复兴齐弄定,齐程步调明了,老手也能随着干!前期准备
一台云效劳器(某云仄台便可),体系挑选 Linux,保证效劳器可一般联网并能截至端心战里板设置;
企业微疑办理员权力,可加入使用办理截至新删使用、设置效劳器等操纵;
MiniMax 账号(用于获得智能交心稀钥),民网备案便可,新用户自戴 15 元体会额度,充足前期尝试使用。
中心布置步调:先弄定 Openclaw 小龙虾根底情况
步调 1:云效劳器根底设置,盛开必备端心
购置 Linux 云效劳器后,起首加入效劳器防水墙树立,盛开 18789 端心(小龙虾 Openclaw 的中心效劳端心)战3000 端心(后绝企业微疑消息转收交心端心),二个端心缺一不成,需保证为进站划定规矩盛开,制止后绝跟尾失利。步调 2:装置 1panel 里板,布置 Openclaw中心 法式
正在云效劳器上装置 1panel 办理里板(装置号令可参照 1panel 民间文档,Linux零碎 一键装置便可),装置完毕后颠末效劳器 IP + 里板端心加入办理背景;
翻开 1panel 的使用市肆,搜刮Openclaw,挑选最新版原(目前为 2026.2.9)截至一键装置,里板会主动完毕容器化布置,无需脚动设置根底情况。
步调 3:设置 MiniMax 稀钥,启用 Openclaw 容器
登录 MiniMax 民网,正在小我私家中间找到交心稀钥,复造备用;
前去 1panel,加入 Openclaw 的容器办理页里,找到容器挂载的目次,正在情况变质设置项中粘揭复造的 MiniMax 交心稀钥;
保留设置后启用 Openclaw 容器,等候启用完毕后,正在浏览器输出http://[您的效劳器IP]:18789,便可加入 Openclaw 的谈天战办理界里,根底的小龙虾智能帮忙就能够用啦!
步调 4:考证 Openclaw 布置,完毕中心跟尾
加入 Openclaw 容器目次,找到openclaw.json文献,翻开后查找并复造里面的token值;
回到http://[您的效劳器IP]:18789的办理界里,面打Overview选项,正在 token输出 框中粘揭复造的实质,面打跟尾;
若界里Status显现为Connected,分析 Openclaw 小龙虾布置胜利,此时可间接正在该界里取小龙虾截至智能谈天尝试。
枢纽连接步调:买通企业微疑,完毕消息互通
布置佳根底的 Openclaw 后,交下来咱们将其取企业微疑连接,让企业微疑里的共事皆能颠末博属小帮忙战小龙虾谈天,中心是设置消息直达效劳,完毕企业微疑取 Openclaw 的消息单背转收。步调 5:企业微疑创立博属小龙虾小帮忙,设置效劳器回调
登录企业微疑办理背景,加入使用办理,面打创立使用,使用称呼挖写 “小龙虾小帮忙”,上传图标后完毕创立;
加入刚刚创立的小龙虾小帮忙使用概略页,找到Api接纳 消息效劳器设置;
设置项中挖写效劳器地点:http://[您的效劳器IP]:3000/wework/callback,其余项临时默认,面打保留;
保留后会随机天生Token战EncodingAESKey,必得记载下来;共时正在企业微疑背景找到企业的corpId、该使用的agentId战secret,局部备用,后绝设置会频仍用到。
设置IP 利剑名单:将云效劳器的公网 IP 增加到使用的 IP 利剑名单中,不然企业微疑没法背效劳器拉收消息。
步调 6:创立消息转收文献,设置连接参数
前去云效劳器,加入 Openclaw 容器的openclaw/data/workspace/目次;
新修文献wework-openclaw.js,该文献是企业微疑取 Openclaw 的消息直达中心,需正在文献中挖写如下设置参数,将以前记载的疑息对于应交流:
openclaw: { wsUrl: 'ws://127.0.0.1:18789/', token: '[您的openclaw Token]', sessionKey: 'agent:main:wechat' },wechat: { corpId: '[corpId]', agentId: '[agentId]', secret: '[secret]', token: '[token]', aesKey: '[aesKey]' }, const express = require('express');const WebSocket = require('ws');const crypto = require('crypto');const axios = require('axios');const app = express();let ws = null, wsHandshakeDone = false, accessToken = '', tokenExpireTime = 0;let runHandlers = {};function wechatDecrypt(text) { try { const aesKey = Buffer.from(CONFIG.wechat.aesKey + '=', 'base64'); const encrypted = Buffer.from(text, 'base64'); const decipher = crypto.createDecipheriv('aes-256-cbc', aesKey, encrypted.slice(0, 16)); decipher.setAutoPadding(false); let decrypted = decipher.update(encrypted.slice(16)) + decipher.final('binary'); const pad = decrypted.charCodeAt(decrypted.length - 1); if (pad < 1 || pad > 32) pad = 0; decrypted = decrypted.slice(0, decrypted.length - pad); const len = decrypted.charCodeAt(0) | (decrypted.charCodeAt(1) << 8) | (decrypted.charCodeAt(2) << 16) | (decrypted.charCodeAt(3) << 24); return decrypted.slice(4, 4 + len).toString(); } catch (e) { return null; }}function parseWeChatXML(xml) { const msgType = xml.match(/<MsgType[^>]*><!\[CDATA\[([^\]]+)\]\]><\/MsgType>/); const fromUser = xml.match(/<FromUserName[^>]*><!\[CDATA\[([^\]]+)\]\]><\/FromUserName>/); const content = xml.match(/<Content[^>]*><!\[CDATA\[([^\]]+)\]\]><\/Content>/); return { msgType: msgType?.[1]?.trim()||'', fromUser: fromUser?.[1]?.trim()||'', content: content?.[1]?.trim()||'' };}function connectOpenClaw() { console.log('🔌 跟尾 OpenClaw...'); ws = new WebSocket(CONFIG.openclaw.wsUrl); ws.on('open', () => { console.log('✅ 已经跟尾'); }); ws.on('message', (data) => { try { const raw = data.toString(); if (raw.includes('res') || raw.includes('event')) { console.log('📥 WS消息:', raw.slice(0, 150)); } const msg = JSON.parse(raw); // 认证 if (msg.event === 'connect.challenge') { ws.send(JSON.stringify({ type: 'req', method: 'connect', id: '1', params: { minProtocol: 1, maxProtocol: 3, client: { id: 'cli', displayName: 'WeChat', version: '1.0.0', platform: 'node', mode: 'cli' }, auth: { token: CONFIG.openclaw.token }, scopes: ['operator.admin'] } }) + '\n'); } else if (msg.type === 'res' && msg.id === '1' && msg.ok) { console.log('✅ 认证胜利'); wsHandshakeDone = true; } // 流式消息 - 挨印统统 agent 工作 else if (msg.type === 'event' && msg.event === 'agent') { console.log('📥 Agent工作:', JSON.stringify(msg.payload).slice(0, 200)); if (runHandlers[msg.payload?.runId]) { // 撑持多种格局的文原提炼 const text = msg.payload?.data?.text || msg.payload?.data?.delta || ''; if (text) { runHandlers[msg.payload.runId].reply += text; console.log('📝 积累文原:', text.slice(0, 50)); } if (msg.payload?.stream === 'stop' || msg.payload?.data?.phase === 'end') { const h = runHandlers[msg.payload.runId]; console.log('📬 完毕,复兴:', h?.reply?.slice(0, 100)); if (h) { h.resolve(h.reply); delete runHandlers[msg.payload.runId]; } } } } //照应 -保管 runId,没有简略 id版原的 handler else if (msg.type === 'res' && msg.id) { console.log('📥 支到照应, msg.id:', msg.id, ', 可否有handler:', !!runHandlers[msg.id], ', payload:', JSON.stringify(msg.payload).slice(0, 100)); if (runHandlers[msg.id]) { clearTimeout(runHandlers[msg.id].timeout); const runId = msg.payload?.runId; if (runId) { runHandlers[runId] = runHandlers[msg.id]; // 用 runId 联系关系 handler console.log('✅ 已经联系关系 runId:', runId); } // 没有要简略 id 版原的 handler,因为后绝可以借会用到 } } } catch (e) {} }); ws.on('error', (err) => console.error('WS 毛病:', err.message)); ws.on('close', () => { console.log('🔌 断启,3秒后沉连'); wsHandshakeDone = false; setTimeout(connectOpenClaw, 3000); });}function sendToOpenClaw(question) { return new Promise((resolve) => { if (!wsHandshakeDone) return resolve('OpenClaw 已跟尾'); const id = crypto.randomUUID(); let reply = ''; const timeout = setTimeout(() => { delete runHandlers[id]; resolve(reply || '请稍后再试'); }, 15000); runHandlers[id] = { resolve, reply, timeout }; // 用 id 动作 idempotencyKey,如许照应会用 id 动作复兴 id ws.send(JSON.stringify({ type: 'req', method: 'chat.send', id, params: { sessionKey: CONFIG.openclaw.sessionKey, message: question, idempotencyKey: id } }) + '\n'); console.log('📤 已经收收, request id:', id); });}async function getAccessToken() { if (Date.now() < tokenExpireTime) return accessToken; const res = await axios.get(`https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${CONFIG.wechat.corpId}&corpsecret=${CONFIG.wechat.secret}`); if (res.data.errcode !== 0) throw new Error(res.data.errmsg); accessToken = res.data.access_token; tokenExpireTime = Date.now() + (res.data.expires_in - 60) * 1000; return accessToken;}async function sendToWeChat(userId, content) { const token = await getAccessToken(); const res = await axios.post(`https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${token}`, { touser: userId, msgtype: 'text', agentid: CONFIG.wechat.agentId, text: { content }, safe: 0 }, { timeout: 5000 }); if (res.data.errcode !== 0) throw new Error(res.data.errmsg); console.log('✅ 已经复兴\n');}app.use(express.raw({ type: 'text/xml' }));app.use(express.raw({ type: 'application/xml' }));app.get('/wework/callback', (req, res) => res.send('success'));app.post('/wework/callback', async (req, res) => { console.log('📨 支到回调, body:', req.body?.toString?.()?.slice(0, 200)); try { const bodyStr = req.body?.toString?.() || ''; if (!bodyStr.includes('<Encrypt>')) return res.send('success'); const match = bodyStr.match(/<Encrypt[^>]*><!\[CDATA\[([^\]]+)\]\]><\/Encrypt>/); if (!match) return res.send('success'); const xml = wechatDecrypt(match[1]); if (!xml) return res.send('success'); const msg = parseWeChatXML(xml); if (!msg || msg.msgType !== 'text' || !msg.content) return res.send('success'); console.log(`📩 ${msg.fromUser}: ${msg.content}`); const reply = await sendToOpenClaw(msg.content); console.log(`💬 OpenClaw复兴: ${reply}`); await sendToWeChat(msg.fromUser, reply); res.send('success'); } catch (err) { console.error('毛病:', err.message); res.send('success'); }});console.log('🚀 企业微疑 → OpenClaw直达 效劳\n');connectOpenClaw();app.listen(CONFIG.server.port, () => console.log(`✅ 运行: http://localhost:${CONFIG.server.port}`));
保留文献,保证参数无拼写毛病,不然会招致消息转收失利。共时需要正在容器里装置相干的依靠。
步调 7:装置 Node.js,启用直达效劳并尝试
加入 Openclaw 容器内部,装置Node.js v20 及以上版原(可颠末民网下载装置包或者保证理器一键装置),装置完毕后颠末node -v考证版原;
正在openclaw/data/workspace/目次下,施行号令node wework-openclaw.js启用消息直达效劳;
启用后,翻开企业微疑,背 “小龙虾小帮忙” 收收尽情消息,若能支到 Openclaw 的智能复兴,分析直达效劳尝试胜利;若已支到,查抄参数设置战端心可否盛开。
步调 8:树立直达效劳自启用,完毕容器联动
为了不效劳器或者容正视开后直达效劳生效,咱们需要将直达效劳树立为随 Openclaw 容器共同启用的体系效劳,日积月累。
正在openclaw/data/workspace/目次下,新修文献wework-service.sh,编辑效劳启用剧本,中心实质为启用 wework-openclaw.js(剧本需保证可施行权力,可颠末chmod +x wework-service.sh树立);
#!/bin/bash# wework-service.sh - 企业微疑直达效劳 watchdog# 主动启用并保活SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"NODE_SCRIPT="$SCRIPT_DIR/wework-openclaw.js"LOG_FILE="$SCRIPT_DIR/wework-service.log"log(){ echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"}log "🚀 启用企业微疑直达效劳 watchdog"
while true; do if[!-f "$NODE_SCRIPT"]; then log "❌ 剧本没有存留: $NODE_SCRIPT" sleep 10 continue fi log "▶ 启用效劳..." node "$NODE_SCRIPT" >> "$LOG_FILE" 2 >& 1 log "⚠️ 历程参加,5秒后沉开..." sleep 5done
前去 1panel 的 Openclaw 容器编排页里,改正容器设置:
增加直达效劳启用号令:
sh -c "node dist/index.js gateway --bind lan --port 18789 & sleep 5 && /home/node/.openclaw/workspace/wework-service.sh"
增加直达效劳端心的窗心映照:
- ${HOST_IP}:${PANEL_APP_PORT_3000:-3000}:3000
保留容器设置后沉开 Openclaw 容器,沉开完毕后再次正在企业微疑尝试消息收收,确认复兴一般。
终极考证
统统步调完毕后,干二个简朴考证:
间接会见http://[效劳器IP]:18789,小龙虾谈天界里一般使用;
企业微疑背 “小龙虾小帮忙” 收收消息,秒级支到智能复兴,效劳器背景无报错。假设有成就能够检察日记文献去排查。
至此,小龙虾 Openclaw 便胜利布置并取企业微疑完毕连接啦!后绝可按照理论需要,正在 MiniMax 背景充值额度、调解 Openclaw 的智能复兴设置,也能够正在企业微疑中改正小帮忙的权力,树立可使用的部分战职员。全部布置历程中心正在于端心盛开、参数精确设置战效劳联动,只要随着步调一步步去,老手也能轻快弄定,赶快给自己的企业微疑摆设上博属智能小帮忙吧! |