feat: 使用正确的 Gateway API - chat.send
关键修复:
- 之前错误:直接发送 message.inbound 事件
- 现在正确:使用 Gateway 的 chat.send 方法
Gateway API 调用:
{
"type": "req",
"method": "chat.send",
"params": {
"sessionKey": "wecom:group:chatId",
"message": "文本内容",
"attachments": [{"type": "image", "path": "..."}],
"deliver": true,
"idempotencyKey": "messageId"
}
}
会话管理:
- sessionKey 格式:wecom:chatType:chatId
- 例如:wecom:group:123456789 或 wecom:direct:zhangsan
- OpenClaw 会自动创建或复用会话
媒体文件处理:
- 下载企业微信图片/文件
- 保存到本地媒体目录
- 通过 attachments 参数传递给 chat.send
这样才符合 OpenClaw Gateway 协议规范!
This commit is contained in:
93
electron/main-chat-fix.js
Normal file
93
electron/main-chat-fix.js
Normal file
@@ -0,0 +1,93 @@
|
||||
// 修复:使用正确的 Gateway API 发送消息
|
||||
|
||||
// 转发消息到 OpenClaw - 使用 chat.send 方法
|
||||
async forwardMessageToOpenClaw(frame) {
|
||||
if (!openclawConnection || !openclawConnection.isConnected) {
|
||||
console.log('[WeCom] OpenClaw not connected, skipping forward');
|
||||
return;
|
||||
}
|
||||
|
||||
const body = frame.body;
|
||||
const chatId = body.chatid || body.from.userid;
|
||||
const chatType = body.chattype === 'group' ? 'group' : 'direct';
|
||||
const messageId = body.msgid;
|
||||
const reqId = frame.headers.req_id;
|
||||
|
||||
reqIdMap.set(chatId, reqId);
|
||||
|
||||
// 提取文本
|
||||
let text = '';
|
||||
if (body.text?.content) {
|
||||
text = body.text.content;
|
||||
} else if (body.mixed?.msg_item) {
|
||||
for (const item of body.mixed.msg_item) {
|
||||
if (item.msgtype === 'text' && item.text?.content) {
|
||||
text += item.text.content + '\n';
|
||||
}
|
||||
}
|
||||
} else if (body.voice?.content) {
|
||||
text = body.voice.content;
|
||||
}
|
||||
|
||||
if (body.chattype === 'group') {
|
||||
text = text.replace(/@\S+/g, '').trim();
|
||||
}
|
||||
|
||||
// 构建 sessionKey(格式:wecom:chatType:chatId)
|
||||
const sessionKey = `wecom:${chatType}:${chatId}`;
|
||||
|
||||
// 处理媒体文件
|
||||
const attachments = [];
|
||||
|
||||
// 下载图片
|
||||
if (body.image?.url) {
|
||||
try {
|
||||
console.log('[WeCom] Downloading image:', body.image.url);
|
||||
const { buffer, filename } = await downloadFile(body.image.url, body.image.aeskey);
|
||||
const saved = await saveMediaFile(buffer, filename, 'inbound');
|
||||
attachments.push({
|
||||
type: 'image',
|
||||
path: saved.path,
|
||||
contentType: saved.contentType
|
||||
});
|
||||
console.log('[WeCom] Image saved:', saved.path);
|
||||
} catch (error) {
|
||||
console.error('[WeCom] Failed to download image:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
if (body.file?.url) {
|
||||
try {
|
||||
console.log('[WeCom] Downloading file:', body.file.url);
|
||||
const { buffer, filename } = await downloadFile(body.file.url, body.file.aeskey);
|
||||
const saved = await saveMediaFile(buffer, filename, 'inbound');
|
||||
attachments.push({
|
||||
type: 'file',
|
||||
path: saved.path,
|
||||
contentType: saved.contentType
|
||||
});
|
||||
console.log('[WeCom] File saved:', saved.path);
|
||||
} catch (error) {
|
||||
console.error('[WeCom] Failed to download file:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用 chat.send 方法发送消息到 OpenClaw
|
||||
const chatSendMessage = {
|
||||
type: 'req',
|
||||
id: this.nextId(),
|
||||
method: 'chat.send',
|
||||
params: {
|
||||
sessionKey: sessionKey,
|
||||
message: text,
|
||||
attachments: attachments.length > 0 ? attachments : undefined,
|
||||
deliver: true, // 立即投递到 AI
|
||||
idempotencyKey: messageId // 使用消息 ID 作为幂等键
|
||||
}
|
||||
};
|
||||
|
||||
console.log('[OpenClaw] Sending via chat.send:', sessionKey);
|
||||
openclawConnection.send(JSON.stringify(chatSendMessage));
|
||||
console.log(`[Forward] WeCom -> OpenClaw: ${messageId}`);
|
||||
}
|
||||
Reference in New Issue
Block a user