From 990d6317caf00ce0c958175e39e2563192591d6b Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 29 Nov 2024 09:45:47 +0800 Subject: [PATCH] support metion list --- CHANGELOG.md | 3 ++ package.json | 2 +- src/common/index.js | 13 +++++- src/handlers/on-callback-message.js | 58 +++++++++++++++++++++-- src/handlers/on-message.js | 6 ++- src/proxy/aibotk.js | 1 + src/proxy/mqtt.js | 72 ++++++++++++++++++++--------- 7 files changed, 124 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbcbcca..f0a4f47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## 更新日志 +### V1.6.68(2024-11-29) +1、支持群消息带@ + ### V1.6.66(2024-10-25) 1、修复发送消息问题 diff --git a/package.json b/package.json index 76507ba..a3bcab0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wechaty-web-panel", - "version": "1.6.67", + "version": "1.6.68", "description": "智能微秘书插件", "exports": { ".": { diff --git a/src/common/index.js b/src/common/index.js index c0b4c2d..432e471 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -242,7 +242,11 @@ async function roomSay(room, contact, msg) { if (msg.type === 1 && msg.content) { const content = await formatContent(msg.content) // 文字 - contact ? await room.say(content, contact) : await room.say(content) + if(Array.isArray(contact)) { + await room.say(content, ...contact) + } else { + contact ? await room.say(content, contact) : await room.say(content) + } void addReplyHistory(this, { content, contact: null, room: room } ) } else if (msg.type === 2 && msg.url) { // url文件 @@ -257,10 +261,15 @@ async function roomSay(room, contact, msg) { } else if (msg.type === 3 && msg.url) { // bse64文件 let obj = FileBox.fromDataURL(msg.url, 'room-avatar.jpg') - contact ? await room.say('', contact) : '' + if(Array.isArray(contact)) { + await room.say('', ...contact) + } else { + contact ? await room.say('', contact) : '' + } await delay(500) await room.say(obj) } else if (msg.type === 4 && msg.url && msg.title && msg.description) { + // @ts-ignore const description = await formatContent(msg.description) const title = await formatContent(msg.title) let url = new this.UrlLink({ diff --git a/src/handlers/on-callback-message.js b/src/handlers/on-callback-message.js index 5c858dd..c62bcf6 100644 --- a/src/handlers/on-callback-message.js +++ b/src/handlers/on-callback-message.js @@ -23,8 +23,8 @@ async function onRecordMessage(msg) { const timestamp = msg.timestamp || dayjs().unix(); const robotInfo = this.currentUser const isOfficial = contact.type() === this.Contact.Type.Official - let content = '' if (msgSelf || isOfficial) return + console.log('msg', msg) const baseMsg = { conversionId: room ? room.id : contact.id, conversionName: room ? roomName : contactName, @@ -35,6 +35,39 @@ async function onRecordMessage(msg) { time: timestamp.length > 10 ? parseInt(timestamp / 1000) : timestamp } switch (type) { + case this.Message.Type.Channel: + baseMsg.type = '视频号' + const channelInfo = await msg.toChannel(); + baseMsg.mediaInfo = { + nickname: channelInfo.nickname(), + coverUrl: channelInfo.coverUrl(), + avatar: channelInfo.avatar(), + desc: channelInfo.desc(), + url: channelInfo.url(), + objectId: channelInfo.objectId(), + objectNonceId: channelInfo.objectNonceId() + } + break; + case this.Message.Type.Contact: + baseMsg.type = '名片' + const contactInfo = await msg.toContact(); + baseMsg.mediaInfo = { + name: contactInfo.name(), + avatar: contactInfo.payload.avatar || '', + wxid: contactInfo.id, + } + break; + case this.Message.Type.RedEnvelope: + baseMsg.type = '红包' + baseMsg.content = "收到红包" + break; + case this.Message.Type.Emoticon: + baseMsg.type = '自定义表情' + const emoticonFileBox = await msg.toFileBox(); + const emoticonBuffer = await emoticonFileBox.toBuffer() + const emoticonUrl = await uploadOssFile(`${conversationRecord?.ossConfig?.custom_path || ''}${emoticonFileBox.name}`, emoticonBuffer) + baseMsg.url = emoticonUrl + break; case this.Message.Type.Text: baseMsg.type = '文字' baseMsg.content = msg.text().trim() @@ -74,17 +107,24 @@ async function onRecordMessage(msg) { const url = await uploadOssFile(`${conversationRecord?.ossConfig?.custom_path || ''}${attachFileBox.name}`, buffer) baseMsg.url = url break + case this.Message.Type.Audio: + baseMsg.type = '语音' + const audioFileBox = await msg.toFileBox() + const audioBuffer = await audioFileBox.toBuffer() + const audioUrl = await uploadOssFile(`${conversationRecord?.ossConfig?.custom_path || ''}${audioFileBox.name}`, audioBuffer) + baseMsg.url = audioUrl + break default: break } console.log('baseMsg', baseMsg) - sendMessage(baseMsg, conversationRecord) + sendMessage(baseMsg, conversationRecord, robotInfo) } catch (e) { console.log('记录消息失败', e) } } -function sendMessage(msgInfo, recordConfig) { +function sendMessage(msgInfo, recordConfig, robotInfo) { const blackKey = ['conversationId', 'conversionName', 'isRoom', 'isRobot', 'chatName', 'chatId', 'chatAlias', 'time', 'type', 'url', 'mediaInfo', 'content'] const baseData = { ...msgInfo @@ -112,9 +152,17 @@ function sendMessage(msgInfo, recordConfig) { method: 'POST', timeout: timeout * 1000, headers: header, - data: baseData + data: { + robotInfo: { + wxid: robotInfo.id, + name: robotInfo.name(), + }, + message: baseData + } + } + if(recordConfig?.debug) { + console.log('消息回调请求参数', config) } - console.log('config', config) axios.request(config).then((res) => { console.log('消息发送成功', res) }).catch((err) => { diff --git a/src/handlers/on-message.js b/src/handlers/on-message.js index 3d705d4..0627303 100644 --- a/src/handlers/on-message.js +++ b/src/handlers/on-message.js @@ -245,8 +245,12 @@ async function dispatchRoomFilterByMsgType(that, room, msg) { } else { content = msg.text() } + let mentionSelf = await msg.mentionSelf() || content.includes(`@${userSelfName}`) + const isMentionAll = await msg.isMentionAll() + if(config?.ignoreRoomMentionAll && isMentionAll && mentionSelf) { + mentionSelf = false + } - const mentionSelf = await msg.mentionSelf() || content.includes(`@${userSelfName}`) const receiverName = receiver?.name() content = content.replace('@' + receiverName, '').replace('@' + userSelfName, '').replace(/@[^,,::\s@]+/g, '').trim() console.log(`群名: ${roomName} 发消息人: ${contactName} 内容: ${content} | 机器人被@:${mentionSelf ? '是' : '否'}`) diff --git a/src/proxy/aibotk.js b/src/proxy/aibotk.js index 21de667..bc13efd 100644 --- a/src/proxy/aibotk.js +++ b/src/proxy/aibotk.js @@ -249,6 +249,7 @@ async function getConfig() { openRecord: false, openWhisper: false, whisperConfig: {}, + ignoreRoomMentionAll: true, ...config, cloudRoom }) diff --git a/src/proxy/mqtt.js b/src/proxy/mqtt.js index e59bdf3..29f0c93 100644 --- a/src/proxy/mqtt.js +++ b/src/proxy/mqtt.js @@ -1,33 +1,42 @@ import * as mqtt from 'mqtt' -import { allConfig } from '../db/configDb.js' -import { contactSay, roomSay, sendRoomNotice } from '../common/index.js' -import {getConfig, getMqttConfig, getGptConfig, getRssConfig, getVerifyCode, getTasks } from "./aibotk.js"; -import { dispatchEventContent } from '../service/event-dispatch-service.js' -import { sendTaskMessage, initMultiTask, sendMultiTaskMessage } from "../task/index.js"; -import { delay, randomRange } from "../lib/index.js"; -import { reset } from './bot/chatgpt.js' -import { reset as difyReset } from './bot/dify.js' -import { reset as cozeReset } from './bot/coze.js' -import { reset as qanyReset } from './bot/qany.js' -import { reset as cozeV3Reset } from './bot/cozev3.js' -import { initRssTask, sendRssTaskMessage } from "../task/rss.js"; +import {allConfig} from '../db/configDb.js' +import {contactSay, roomSay, sendRoomNotice} from '../common/index.js' +import {getConfig, getGptConfig, getMqttConfig, getRssConfig, getTasks, getVerifyCode} from "./aibotk.js"; +import {dispatchEventContent} from '../service/event-dispatch-service.js' +import {initMultiTask, sendMultiTaskMessage, sendTaskMessage} from "../task/index.js"; +import {delay, randomRange} from "../lib/index.js"; +import {reset} from './bot/chatgpt.js' +import {reset as difyReset} from './bot/dify.js' +import {reset as cozeReset} from './bot/coze.js' +import {reset as qanyReset} from './bot/qany.js' +import {reset as cozeV3Reset} from './bot/cozev3.js' +import {initRssTask, sendRssTaskMessage} from "../task/rss.js"; import globalConfig from "../db/global.js"; -import { resetScanTime } from '../handlers/on-scan.js' -import { clearHistory } from "../db/chatHistory.js"; +import {resetScanTime} from '../handlers/on-scan.js' +import {clearHistory} from "../db/chatHistory.js"; let mqttclient = null +async function getContact(that, contact) { + const contactInfo = (contact.wxid && await that.Contact.find({id: contact.wxid || ''})) || (contact.id && await that.Contact.find({id: contact.id || ''})) || (contact.name && await that.Contact.find({name: contact.name || ''})) || (contact.alias && await that.Contact.find({alias: contact.alias || ''})) || (contact.weixin && await that.Contact.find({weixin: contact.weixin || ''})) + return contactInfo +} +async function getRoom(that, room) { + const roomInfo = (room.wxid && await that.Room.find({id: room.wxid || ''})) || (room.id && await that.Room.find({id: room.id || ''})) || (room.name && await that.Room.find({topic: room.name || ''})) || (room.roomName && await that.Room.find({topic: room.roomName || ''})) + return roomInfo +} -async function sendRoomSay(that, room, messages) { +async function sendRoomSay(that, room, messages, atList) { console.log(`收到群:${room.name}批量发送消息请求, 消息数量【${messages.length}】`) - const finalRoom = await that.Room.find({ id: room.id, topic: room.name }); + const finalRoom = await getRoom(room) if (!finalRoom) { console.log(`查找不到群:${room.name},请检查群名是否正确`) return } else { for (let message of messages) { - await roomSay.call(that,finalRoom, '', message) + const atContacts = await getAtContacts(that, atList) + await roomSay.call(that,finalRoom, atContacts, message) await delay(500) } } @@ -35,7 +44,7 @@ async function sendRoomSay(that, room, messages) { async function sendContactSay(that, contact, messages) { console.log(`收到好友:${contact.name}批量发送消息请求, 消息数量【${messages.length}】`) - const finalContact = await that.Contact.find({ id: contact.id || '', name: contact.name, alias: contact.alias || '', weixin: contact.weixin || '' }) + const finalContact = await getContact(that, contact) if (!finalContact) { console.log(`查找不到好友:${contact.name},请检查好友名称是否正确`) @@ -48,9 +57,27 @@ async function sendContactSay(that, contact, messages) { } } +async function getAtContacts(that, atList) { + if (!atList || atList.length === 0) return '' + console.log('atList', atList) + let contacts = [] + for (let contact of atList) { + if (contact.id === '@all' || contact.name === '@all') { + contacts.push('@all') + return contacts + } + let atContact = await getContact(that, contact) + if (atContact) { + contacts.push(atContact) + } + } + console.log('search contact', contacts) + return contacts +} + async function sendRoomsNotice(that, room, messages) { console.log(`收到群:${room.name}批量发送群公告请求, 公告数量【${messages.length}】`) - const finalRoom = await that.Room.find({ id: room.id, topic: room.name }) + const finalRoom = await getRoom(that, room) if (!finalRoom) { console.log(`查找不到群:${room.name},请检查群名是否正确`) @@ -108,11 +135,12 @@ async function initMqtt(that) { console.log(`查找不到群:${content.roomName},请检查群名是否正确`) return } else { - await roomSay.call(that,room, '', content.message) + const atContacts = content?.atList && content?.atList.length ? await getAtContacts(that, content?.atList) : '' + await roomSay.call(that, room, atContacts, content.message) } } else if (content.target === 'Contact' || content.target === 'contact') { console.log(`收到联系人:${content.alias || content.name}发送消息请求: ${content.message.content || content.message.url}`) - let contact = (content.wxid && await that.Contact.load(content.wxid)) || (await that.Contact.find({ name: content.name })) || (await that.Contact.find({ alias: content.alias })) || (await that.Contact.find({ weixin: content.weixin })) // 获取你要发送的联系人 + let contact = await getContact(that, content) // 获取你要发送的联系人 if (!contact) { console.log(`查找不到联系人:${content.name || content.alias},请检查联系人名称是否正确`) return @@ -124,7 +152,7 @@ async function initMqtt(that) { console.log('触发批量发送消息请求', content.target); if (content.target === 'Room' || content.target === 'room') { for(let room of content.groups) { - await sendRoomSay(that, room, content.messages) + await sendRoomSay(that, room, content.messages, content?.atList) await delay(600) } } else if (content.target === 'Contact' || content.target === 'contact') {