wechaty-web-panel 1.6.112 → 1.6.113
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bot/chatgpt/index.js +235 -0
- package/dist/bot/coze/sdk/index.js +110 -0
- package/dist/bot/dify/sdk/index.js +461 -0
- package/dist/bot/dify/sdk/office.js +319 -0
- package/dist/bot/fastgpt/index.js +98 -0
- package/dist/bot/qanything/index.js +136 -0
- package/dist/botInstance/coze.js +167 -0
- package/dist/botInstance/cozev3.js +157 -0
- package/dist/botInstance/dify.js +160 -0
- package/dist/botInstance/fastgpt.js +130 -0
- package/dist/botInstance/gpt4v.js +95 -0
- package/dist/botInstance/officialOpenAi.js +186 -0
- package/dist/botInstance/qany.js +144 -0
- package/dist/botInstance/sdk/chatGPT4V.js +89 -0
- package/dist/botInstance/sdk/coze.js +200 -0
- package/dist/botInstance/sdk/difyClient.js +354 -0
- package/dist/botInstance/sdk/pTimeout.js +97 -0
- package/dist/botInstance/sdk/qanything.js +137 -0
- package/dist/botInstance/sdk/quick-lru.js +237 -0
- package/dist/common/hook.js +66 -0
- package/dist/common/index.js +513 -0
- package/dist/common/multiReply.js +158 -0
- package/dist/common/reply.js +23 -0
- package/dist/const/puppet-type.js +71 -0
- package/dist/db/aiDb.js +27 -0
- package/dist/db/aichatDb.js +84 -0
- package/dist/db/chatHistory.js +137 -0
- package/dist/db/configDb.js +97 -0
- package/dist/db/global.js +62 -0
- package/dist/db/gptConfig.js +85 -0
- package/dist/db/nedb.js +88 -0
- package/dist/db/puppetDb.js +58 -0
- package/dist/db/roomDb.js +83 -0
- package/dist/db/rssConfig.js +82 -0
- package/dist/db/rssHistory.js +88 -0
- package/dist/db/userDb.js +27 -0
- package/dist/handlers/on-callback-message.js +183 -0
- package/dist/handlers/on-error.js +5 -0
- package/dist/handlers/on-friend.js +62 -0
- package/dist/handlers/on-heartbeat.js +20 -0
- package/dist/handlers/on-login.js +58 -0
- package/dist/handlers/on-logout.js +17 -0
- package/dist/handlers/on-message.js +644 -0
- package/dist/handlers/on-ready.js +36 -0
- package/dist/handlers/on-record-message.js +56 -0
- package/dist/handlers/on-roomjoin.js +42 -0
- package/dist/handlers/on-roomleave.js +12 -0
- package/dist/handlers/on-roomtopic.js +16 -0
- package/dist/handlers/on-scan.js +64 -0
- package/dist/handlers/on-verifycode.js +42 -0
- package/dist/index.js +81 -69306
- package/dist/lib/contentCensor.js +23 -0
- package/dist/lib/index.js +562 -0
- package/dist/lib/oss.js +43 -0
- package/dist/lib/s3oss.js +33 -0
- package/dist/mcp/mcp-server.js +26 -0
- package/dist/mcp/src/config/database.js +51 -0
- package/dist/mcp/src/index.js +238 -0
- package/dist/mcp/src/mcp/schemas.js +178 -0
- package/dist/mcp/src/mcp/server.js +421 -0
- package/dist/mcp/src/mcp/streamable-server.js +690 -0
- package/dist/mcp/src/models/ChatMessage.js +151 -0
- package/dist/mcp/src/models/Friend.js +64 -0
- package/dist/mcp/src/models/Group.js +55 -0
- package/dist/mcp/src/models/GroupMember.js +67 -0
- package/dist/mcp/src/models/index.js +27 -0
- package/dist/mcp/src/scripts/migrate.js +21 -0
- package/dist/mcp/src/services/ChatDataService.js +284 -0
- package/dist/mcp/src/services/McpService.js +521 -0
- package/dist/mcp/src/services/McpTools.js +504 -0
- package/dist/mcp/streamable-examples.js +283 -0
- package/dist/mcp/streamable-server.js +79 -0
- package/dist/mcp/test-mcp.js +64 -0
- package/dist/mcp/test-streamable-server.js +86 -0
- package/dist/package-json.js +89 -0
- package/dist/proxy/aibotk.js +829 -0
- package/dist/proxy/api.js +431 -0
- package/dist/proxy/apib.js +587 -0
- package/dist/proxy/bot/chatgpt.js +38 -0
- package/dist/proxy/bot/coze.js +38 -0
- package/dist/proxy/bot/cozev3.js +38 -0
- package/dist/proxy/bot/dify.js +38 -0
- package/dist/proxy/bot/dispatch.js +81 -0
- package/dist/proxy/bot/fastgpt.js +27 -0
- package/dist/proxy/bot/qany.js +27 -0
- package/dist/proxy/config.js +14 -0
- package/dist/proxy/cozeAi.js +60 -0
- package/dist/proxy/cozeV3Ai.js +60 -0
- package/dist/proxy/difyAi.js +58 -0
- package/dist/proxy/fastgpt.js +55 -0
- package/dist/proxy/mqtt.js +275 -0
- package/dist/proxy/multimodal.js +122 -0
- package/dist/proxy/openAi.js +63 -0
- package/dist/proxy/outapi.js +62 -0
- package/dist/proxy/qAnyAi.js +57 -0
- package/dist/proxy/superagent.js +200 -0
- package/dist/proxy/tencent-open.js +255 -0
- package/dist/service/event-dispatch-service.js +309 -0
- package/dist/service/gpt4vService.js +45 -0
- package/dist/service/msg-filter-service.js +121 -0
- package/dist/service/msg-filters.js +645 -0
- package/dist/service/room-async-service.js +455 -0
- package/dist/task/index.js +535 -0
- package/dist/task/rss.js +174 -0
- package/package.json +2 -2
- package/src/package-json.js +2 -2
- package/tsconfig.json +3 -12
- package/dist/index.d.ts +0 -9
- package/tsconfig.cjs.json +0 -12
|
@@ -0,0 +1,644 @@
|
|
|
1
|
+
import { contactSay, roomSay } from '../common/index.js';
|
|
2
|
+
import { getContactTextReply, getFileReply, getRoomTextReply } from '../common/reply.js';
|
|
3
|
+
import { delay } from '../lib/index.js';
|
|
4
|
+
import { dispatchAsync } from '../service/room-async-service.js';
|
|
5
|
+
import { allConfig } from '../db/configDb.js';
|
|
6
|
+
import { getAibotConfig } from '../db/aiDb.js';
|
|
7
|
+
import { addRoomRecord } from '../db/roomDb.js';
|
|
8
|
+
import { privateForward } from '../common/hook.js';
|
|
9
|
+
import { getPuppetEol } from '../const/puppet-type.js';
|
|
10
|
+
import { getGpt4vChat } from '../service/gpt4vService.js';
|
|
11
|
+
import { getVoiceText } from '../proxy/multimodal.js';
|
|
12
|
+
import { getCustomConfig } from '../service/msg-filters.js';
|
|
13
|
+
import { getPuppetInfo } from '../db/puppetDb.js';
|
|
14
|
+
import { uploadGlobalOssFile } from '../lib/oss.js';
|
|
15
|
+
import path from "path";
|
|
16
|
+
import dayjs from "dayjs";
|
|
17
|
+
const ignoreRecord = [
|
|
18
|
+
{ type: 'include', word: '加入了群聊' },
|
|
19
|
+
{ type: 'include', word: '与群里其他人都不是朋友关系' },
|
|
20
|
+
{ type: 'include', word: '收到一条暂不支持的消息类型' },
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* 检测是否属于忽略的消息
|
|
24
|
+
* @param msg 用户信息
|
|
25
|
+
* @param list 需要忽略的列表
|
|
26
|
+
*/
|
|
27
|
+
function checkIgnore(msg, list) {
|
|
28
|
+
if (!list.length)
|
|
29
|
+
return false;
|
|
30
|
+
for (let item of list) {
|
|
31
|
+
const word = item.word;
|
|
32
|
+
const type = item.type;
|
|
33
|
+
if ((type === 'start' && msg.startsWith(word)) || (type === 'end' && msg.endsWith(word)) || (type === 'equal' && msg === word) || (type === 'include' && msg.includes(word))) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 根据消息类型过滤私聊消息事件
|
|
41
|
+
* @param {*} that bot实例
|
|
42
|
+
* @param {*} msg 消息主体
|
|
43
|
+
*/
|
|
44
|
+
async function dispatchFriendFilterByMsgType(that, msg) {
|
|
45
|
+
try {
|
|
46
|
+
const eol = await getPuppetEol();
|
|
47
|
+
const puppetInfo = await getPuppetInfo();
|
|
48
|
+
const aibotConfig = await getAibotConfig();
|
|
49
|
+
const config = await allConfig();
|
|
50
|
+
const type = msg.type();
|
|
51
|
+
const contact = msg.talker(); // 发消息人
|
|
52
|
+
const name = contact && await contact.name();
|
|
53
|
+
const userAlias = contact && (await contact.alias()) || '';
|
|
54
|
+
let isOfficial = null;
|
|
55
|
+
try {
|
|
56
|
+
isOfficial = contact && contact.type() === this.Contact.Type.Official;
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
console.log('check isOfficial error, don`t worry, no effect', e);
|
|
60
|
+
isOfficial = false;
|
|
61
|
+
}
|
|
62
|
+
let content = '';
|
|
63
|
+
let replys = [];
|
|
64
|
+
const res = await privateForward({ that, msg, name, config });
|
|
65
|
+
if (res) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
switch (type) {
|
|
69
|
+
case that.Message.Type.System:
|
|
70
|
+
case that.Message.Type.Text:
|
|
71
|
+
case that.Message.Type.Url:
|
|
72
|
+
if (type === that.Message.Type.Url) {
|
|
73
|
+
console.log(`发消息人${await contact.name()}:发了一个h5链接`);
|
|
74
|
+
const urlLink = await msg.toUrlLink();
|
|
75
|
+
if (config.parseMini && urlLink.payload) {
|
|
76
|
+
const urlParse = `【链接解析】${eol}${eol}标题:${urlLink.title()}${eol}描述:${urlLink.description()}${eol}链接:${urlLink.url()}${eol}缩略图:${urlLink.thumbnailUrl()}`;
|
|
77
|
+
contact.say(urlParse);
|
|
78
|
+
}
|
|
79
|
+
console.log('urlLink', urlLink);
|
|
80
|
+
content = `[链接]:${urlLink.url()}`;
|
|
81
|
+
}
|
|
82
|
+
else if (type === that.Message.Type.System) {
|
|
83
|
+
const stext = msg.text();
|
|
84
|
+
if (((stext.includes('你已添加') || stext.includes('You have added')) && puppetInfo.puppetType === 'PuppetMatrix') || ((stext.includes('开启了朋友验证') || stext.includes('has enabled Friend Confirmation')) && puppetInfo.puppetType === 'PuppetMatrix')) {
|
|
85
|
+
content = msg.text();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
console.log('其他系统消息', msg);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
content = msg.text();
|
|
94
|
+
}
|
|
95
|
+
if (!isOfficial) {
|
|
96
|
+
console.log(`发消息人${name}:${content}`);
|
|
97
|
+
const isIgnore = checkIgnore(content.trim(), aibotConfig.ignoreMessages);
|
|
98
|
+
if (content.trim() && !isIgnore) {
|
|
99
|
+
const gpt4vReplys = await getGpt4vChat({
|
|
100
|
+
that,
|
|
101
|
+
room: false,
|
|
102
|
+
roomId: '',
|
|
103
|
+
uniqueId: contact.id,
|
|
104
|
+
id: contact.id,
|
|
105
|
+
roomName: '',
|
|
106
|
+
isMention: false,
|
|
107
|
+
userAlias,
|
|
108
|
+
name,
|
|
109
|
+
msgContent: { type: 1, content },
|
|
110
|
+
});
|
|
111
|
+
if (gpt4vReplys.length) {
|
|
112
|
+
for (let reply of gpt4vReplys) {
|
|
113
|
+
await contactSay.call(that, contact, reply);
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
replys = await getContactTextReply(that, contact, content.trim());
|
|
118
|
+
for (let reply of replys) {
|
|
119
|
+
await contactSay.call(that, contact, reply);
|
|
120
|
+
config?.chatDelay ? await delay(config?.chatDelay * 1000) : await delay(200);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
console.log('公众号消息');
|
|
126
|
+
}
|
|
127
|
+
break;
|
|
128
|
+
case that.Message.Type.Audio:
|
|
129
|
+
let finalConfig = await getCustomConfig({ name, id: contact.id, roomName: '', roomId: '', room: false, type: 'openWhisper' });
|
|
130
|
+
if (!finalConfig && config?.customBot?.openWhisper) {
|
|
131
|
+
finalConfig = {
|
|
132
|
+
botConfig: {
|
|
133
|
+
whisperConfig: config?.customBot?.whisperConfig,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (finalConfig) {
|
|
138
|
+
const audioFileBox = await msg.toFileBox();
|
|
139
|
+
const text = puppetInfo.puppetType.includes('PuppetService') && !msg.text().startsWith('@') ? msg.text().trim() : await getVoiceText(audioFileBox, finalConfig.botConfig.whisperConfig);
|
|
140
|
+
console.log('语音解析结果:', text);
|
|
141
|
+
const keyword = finalConfig.botConfig.whisperConfig?.keywords?.length ? finalConfig.botConfig?.whisperConfig.keywords?.find((item) => text.includes(item)) : true;
|
|
142
|
+
const isIgnore = checkIgnore(content.trim(), aibotConfig.ignoreMessages);
|
|
143
|
+
if (text.trim() && !isIgnore && keyword) {
|
|
144
|
+
const gpt4vReplys = await getGpt4vChat({
|
|
145
|
+
that,
|
|
146
|
+
room: false,
|
|
147
|
+
roomId: '',
|
|
148
|
+
uniqueId: contact.id,
|
|
149
|
+
id: contact.id,
|
|
150
|
+
roomName: '',
|
|
151
|
+
isMention: false,
|
|
152
|
+
name,
|
|
153
|
+
msgContent: { type: 1, content: text },
|
|
154
|
+
});
|
|
155
|
+
if (gpt4vReplys.length) {
|
|
156
|
+
for (let reply of gpt4vReplys) {
|
|
157
|
+
await contactSay.call(that, contact, reply);
|
|
158
|
+
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
replys = await getContactTextReply(that, contact, text.trim());
|
|
162
|
+
for (let reply of replys) {
|
|
163
|
+
await contactSay.call(that, contact, reply);
|
|
164
|
+
config?.chatDelay ? await delay(config?.chatDelay * 1000) : await delay(200);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
console.log('语音解析结果没有匹配到需要回复的关键词');
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (config?.uploadFileConfig?.open) {
|
|
173
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
174
|
+
const attachFileBox = await msg.toFileBox();
|
|
175
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
176
|
+
const fileType = '文件';
|
|
177
|
+
const buffer = await attachFileBox.toBuffer();
|
|
178
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
179
|
+
const fileUrl = url;
|
|
180
|
+
const fileReplys = await getFileReply({
|
|
181
|
+
that,
|
|
182
|
+
room: false,
|
|
183
|
+
roomId: '',
|
|
184
|
+
uniqueId: contact.id,
|
|
185
|
+
id: contact.id,
|
|
186
|
+
roomName: '',
|
|
187
|
+
isMention: false,
|
|
188
|
+
userAlias,
|
|
189
|
+
name,
|
|
190
|
+
content: uploadFileConfig?.audioPrompt || '请识别这个语音的内容,并回复',
|
|
191
|
+
contact,
|
|
192
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
193
|
+
});
|
|
194
|
+
if (fileReplys.length) {
|
|
195
|
+
for (let reply of fileReplys) {
|
|
196
|
+
await contactSay.call(that, contact, reply);
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
case that.Message.Type.Emoticon:
|
|
203
|
+
console.log(`发消息人${await contact.name()}:发了一个表情`);
|
|
204
|
+
break;
|
|
205
|
+
case that.Message.Type.Image:
|
|
206
|
+
console.log(`发消息人${await contact.name()}:发了一张图片`);
|
|
207
|
+
if (config?.uploadFileConfig?.open) {
|
|
208
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
209
|
+
const attachFileBox = await msg.toFileBox();
|
|
210
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
211
|
+
const fileType = '图片';
|
|
212
|
+
const buffer = await attachFileBox.toBuffer();
|
|
213
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
214
|
+
const fileUrl = url;
|
|
215
|
+
const fileReplys = await getFileReply({
|
|
216
|
+
that,
|
|
217
|
+
room: false,
|
|
218
|
+
roomId: '',
|
|
219
|
+
uniqueId: contact.id,
|
|
220
|
+
id: contact.id,
|
|
221
|
+
roomName: '',
|
|
222
|
+
isMention: false,
|
|
223
|
+
userAlias,
|
|
224
|
+
name,
|
|
225
|
+
content: uploadFileConfig?.imagePrompt || '请描述这个图片上的内容',
|
|
226
|
+
contact,
|
|
227
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
228
|
+
});
|
|
229
|
+
if (fileReplys.length) {
|
|
230
|
+
for (let reply of fileReplys) {
|
|
231
|
+
await contactSay.call(that, contact, reply);
|
|
232
|
+
}
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const imgGpt4vReplys = await getGpt4vChat({
|
|
237
|
+
that,
|
|
238
|
+
room: false,
|
|
239
|
+
roomId: '',
|
|
240
|
+
id: contact.id,
|
|
241
|
+
uniqueId: contact.id,
|
|
242
|
+
roomName: '',
|
|
243
|
+
userAlias,
|
|
244
|
+
isMention: false,
|
|
245
|
+
name,
|
|
246
|
+
msgContent: { type: 3, id: msg.id },
|
|
247
|
+
});
|
|
248
|
+
if (imgGpt4vReplys.length) {
|
|
249
|
+
for (let reply of imgGpt4vReplys) {
|
|
250
|
+
await contactSay.call(that, contact, reply);
|
|
251
|
+
}
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case that.Message.Type.Video:
|
|
256
|
+
case that.Message.Type.Attachment:
|
|
257
|
+
if (config?.uploadFileConfig?.open) {
|
|
258
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
259
|
+
const attachFileBox = await msg.toFileBox();
|
|
260
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
261
|
+
const fileType = '文件';
|
|
262
|
+
const buffer = await attachFileBox.toBuffer();
|
|
263
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
264
|
+
const fileUrl = url;
|
|
265
|
+
const fileReplys = await getFileReply({
|
|
266
|
+
that,
|
|
267
|
+
room: false,
|
|
268
|
+
roomId: '',
|
|
269
|
+
uniqueId: contact.id,
|
|
270
|
+
id: contact.id,
|
|
271
|
+
roomName: '',
|
|
272
|
+
isMention: false,
|
|
273
|
+
userAlias,
|
|
274
|
+
name,
|
|
275
|
+
content: uploadFileConfig?.filePrompt || '请总结这个文件的内容',
|
|
276
|
+
contact,
|
|
277
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
278
|
+
});
|
|
279
|
+
if (fileReplys.length) {
|
|
280
|
+
for (let reply of fileReplys) {
|
|
281
|
+
await contactSay.call(that, contact, reply);
|
|
282
|
+
}
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
case that.Message.Type.MiniProgram:
|
|
288
|
+
console.log(`发消息人${await contact.name()}:发了一个小程序`);
|
|
289
|
+
const miniProgram = await msg.toMiniProgram();
|
|
290
|
+
if (config.parseMini && miniProgram.payload) {
|
|
291
|
+
const miniParse = `【小程序解析】${eol}${eol}appid:${miniProgram.appid()}${eol}username:${miniProgram.username().replace('@app', '')}${eol}标题:${miniProgram.title()}${eol}描述:${miniProgram.description()}${eol}路径:${decodeURIComponent(miniProgram.pagePath())}`;
|
|
292
|
+
contact.say(miniParse);
|
|
293
|
+
}
|
|
294
|
+
console.log('mini', miniProgram);
|
|
295
|
+
break;
|
|
296
|
+
case that.Message.Type.Transfer:
|
|
297
|
+
console.log(`发消息人${await contact.name()}: 发起一个转账,请在手机接收`);
|
|
298
|
+
console.log('内容', msg.payload);
|
|
299
|
+
break;
|
|
300
|
+
default:
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
console.log('监听消息错误', error);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* 根据消息类型过滤群消息事件
|
|
310
|
+
* @param {*} that bot实例
|
|
311
|
+
* @param {*} room room对象
|
|
312
|
+
* @param {*} msg 消息主体
|
|
313
|
+
*/
|
|
314
|
+
async function dispatchRoomFilterByMsgType(that, room, msg) {
|
|
315
|
+
const aibotConfig = await getAibotConfig();
|
|
316
|
+
const config = await allConfig();
|
|
317
|
+
const { role } = (config && config.userInfo) || { role: 'default' };
|
|
318
|
+
try {
|
|
319
|
+
const eol = await getPuppetEol();
|
|
320
|
+
const contact = msg.talker(); // 发消息人
|
|
321
|
+
const contactName = contact.name();
|
|
322
|
+
const roomName = await room.topic();
|
|
323
|
+
const isFriend = contact.friend();
|
|
324
|
+
const type = msg.type();
|
|
325
|
+
const receiver = msg.to();
|
|
326
|
+
let content = '';
|
|
327
|
+
let replys = '';
|
|
328
|
+
let contactId = contact.id;
|
|
329
|
+
let contactAvatar = await contact.avatar();
|
|
330
|
+
const userSelfName = that.currentUser?.name() || that.userSelf()?.name();
|
|
331
|
+
const userAlias = (await room?.alias(contact)) || (await contact.alias()) || '';
|
|
332
|
+
const userWeixin = contact.weixin() || '';
|
|
333
|
+
switch (type) {
|
|
334
|
+
case that.Message.Type.Text:
|
|
335
|
+
case that.Message.Type.Url:
|
|
336
|
+
if (type === that.Message.Type.Url) {
|
|
337
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发了一个h5链接`);
|
|
338
|
+
const urlLink = await msg.toUrlLink();
|
|
339
|
+
if (config.parseMiniRooms.includes(roomName) && urlLink.payload) {
|
|
340
|
+
const urlParse = `【链接解析】${eol}${eol}标题:${urlLink.title()}${eol}描述:${urlLink.description()}${eol}链接:${urlLink.url()}${eol}缩略图:${urlLink.thumbnailUrl()}`;
|
|
341
|
+
room.say(urlParse);
|
|
342
|
+
}
|
|
343
|
+
console.log('urlLink', urlLink);
|
|
344
|
+
content = `[链接]:${urlLink.url()}`;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
content = msg.text();
|
|
348
|
+
}
|
|
349
|
+
let mentionSelf = (await msg.mentionSelf()) || content.includes(`@${userSelfName}`);
|
|
350
|
+
const isMentionAll = await msg.isMentionAll();
|
|
351
|
+
if (config?.ignoreRoomMentionAll && isMentionAll && mentionSelf) {
|
|
352
|
+
mentionSelf = false;
|
|
353
|
+
}
|
|
354
|
+
const receiverName = receiver?.name();
|
|
355
|
+
content = content
|
|
356
|
+
.replace('@' + receiverName, '')
|
|
357
|
+
.replace('@' + userSelfName, '')
|
|
358
|
+
.replace(/@[^,,::\s@]+/g, '')
|
|
359
|
+
.trim();
|
|
360
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 内容: ${content} | 机器人被@:${mentionSelf ? '是' : '否'}`);
|
|
361
|
+
// 检测是否需要这条消息
|
|
362
|
+
const isIgnore = checkIgnore(content, aibotConfig.ignoreMessages);
|
|
363
|
+
if (isIgnore)
|
|
364
|
+
return;
|
|
365
|
+
const gpt4vReplys = await getGpt4vChat({
|
|
366
|
+
that,
|
|
367
|
+
room,
|
|
368
|
+
roomId: room.id,
|
|
369
|
+
id: contactId,
|
|
370
|
+
uniqueId: `${room.id}-${contactId}`,
|
|
371
|
+
roomName,
|
|
372
|
+
isMention: mentionSelf,
|
|
373
|
+
name: contactName,
|
|
374
|
+
userAlias,
|
|
375
|
+
userWeixin,
|
|
376
|
+
msgContent: { type: 1, content },
|
|
377
|
+
});
|
|
378
|
+
if (gpt4vReplys.length) {
|
|
379
|
+
for (let reply of gpt4vReplys) {
|
|
380
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
381
|
+
config?.chatDelay ? await delay(config?.chatDelay * 1000) : await delay(200);
|
|
382
|
+
}
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
replys = await getRoomTextReply({
|
|
386
|
+
that,
|
|
387
|
+
content,
|
|
388
|
+
isFriend,
|
|
389
|
+
name: contactName,
|
|
390
|
+
userAlias,
|
|
391
|
+
userWeixin,
|
|
392
|
+
id: contactId,
|
|
393
|
+
roomId: room.id,
|
|
394
|
+
avatar: contactAvatar,
|
|
395
|
+
room,
|
|
396
|
+
roomName,
|
|
397
|
+
isMention: mentionSelf,
|
|
398
|
+
});
|
|
399
|
+
for (let reply of replys) {
|
|
400
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
401
|
+
config?.chatDelay ? await delay(config?.chatDelay * 1000) : await delay(200);
|
|
402
|
+
}
|
|
403
|
+
const cloudRoom = config.cloudRoom;
|
|
404
|
+
if (role === 'vip' && cloudRoom.includes(roomName) && !checkIgnore(content, ignoreRecord)) {
|
|
405
|
+
const regex = /(<([^>]+)>)/gi;
|
|
406
|
+
content = content.replace(regex, '');
|
|
407
|
+
void addRoomRecord({
|
|
408
|
+
roomName,
|
|
409
|
+
roomId: room.id,
|
|
410
|
+
content,
|
|
411
|
+
contact: contactName,
|
|
412
|
+
wxid: contactId,
|
|
413
|
+
time: new Date().getTime(),
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
break;
|
|
417
|
+
case that.Message.Type.Emoticon:
|
|
418
|
+
content = msg.text();
|
|
419
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发了一个表情 ${content}`);
|
|
420
|
+
break;
|
|
421
|
+
case that.Message.Type.Image:
|
|
422
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发了一张图片`);
|
|
423
|
+
if (config?.uploadFileConfig?.open) {
|
|
424
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
425
|
+
const attachFileBox = await msg.toFileBox();
|
|
426
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
427
|
+
const fileType = '图片';
|
|
428
|
+
const buffer = await attachFileBox.toBuffer();
|
|
429
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
430
|
+
const fileUrl = url;
|
|
431
|
+
const fileReplys = await getFileReply({
|
|
432
|
+
that,
|
|
433
|
+
content: uploadFileConfig?.imagePrompt || '请描述这个图片上的内容',
|
|
434
|
+
isFriend,
|
|
435
|
+
name: contactName,
|
|
436
|
+
userAlias,
|
|
437
|
+
userWeixin,
|
|
438
|
+
id: contactId,
|
|
439
|
+
roomId: room.id,
|
|
440
|
+
avatar: contactAvatar,
|
|
441
|
+
room,
|
|
442
|
+
roomName,
|
|
443
|
+
isMention: true,
|
|
444
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
445
|
+
});
|
|
446
|
+
if (fileReplys.length) {
|
|
447
|
+
for (let reply of fileReplys) {
|
|
448
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
const imgGpt4vReplys = await getGpt4vChat({
|
|
454
|
+
that,
|
|
455
|
+
room,
|
|
456
|
+
roomId: room.id,
|
|
457
|
+
id: contactId,
|
|
458
|
+
uniqueId: `${room.id}-${contactId}`,
|
|
459
|
+
roomName,
|
|
460
|
+
isMention: false,
|
|
461
|
+
name: contactName,
|
|
462
|
+
msgContent: { type: 3, id: msg.id },
|
|
463
|
+
});
|
|
464
|
+
if (imgGpt4vReplys.length) {
|
|
465
|
+
for (let reply of imgGpt4vReplys) {
|
|
466
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
467
|
+
}
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
break;
|
|
471
|
+
case that.Message.Type.Attachment:
|
|
472
|
+
case that.Message.Type.Video:
|
|
473
|
+
if (config?.uploadFileConfig?.open) {
|
|
474
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
475
|
+
const attachFileBox = await msg.toFileBox();
|
|
476
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
477
|
+
const fileType = '文件';
|
|
478
|
+
const buffer = await attachFileBox.toBuffer();
|
|
479
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
480
|
+
const fileUrl = url;
|
|
481
|
+
const fileReplys = await getFileReply({
|
|
482
|
+
that,
|
|
483
|
+
content: uploadFileConfig?.filePrompt || '请总结这个文件的内容',
|
|
484
|
+
isFriend,
|
|
485
|
+
name: contactName,
|
|
486
|
+
userAlias,
|
|
487
|
+
userWeixin,
|
|
488
|
+
id: contactId,
|
|
489
|
+
roomId: room.id,
|
|
490
|
+
avatar: contactAvatar,
|
|
491
|
+
room,
|
|
492
|
+
roomName,
|
|
493
|
+
isMention: true,
|
|
494
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
495
|
+
});
|
|
496
|
+
if (fileReplys.length) {
|
|
497
|
+
for (let reply of fileReplys) {
|
|
498
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
499
|
+
}
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
break;
|
|
504
|
+
case that.Message.Type.Audio:
|
|
505
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发了一个语音`);
|
|
506
|
+
const puppetInfo = await getPuppetInfo();
|
|
507
|
+
let finalConfig = await getCustomConfig({ name: contactName, id: contactId, roomName, roomId: room.id, room, type: 'openWhisper' });
|
|
508
|
+
if (!finalConfig && config?.customBot?.openWhisper) {
|
|
509
|
+
finalConfig = {
|
|
510
|
+
botConfig: {
|
|
511
|
+
whisperConfig: config?.customBot?.whisperConfig,
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
if (finalConfig) {
|
|
516
|
+
const audioFileBox = await msg.toFileBox();
|
|
517
|
+
const text = puppetInfo.puppetType.includes('PuppetService') && !msg.text().startsWith('@') ? msg.text().trim() : await getVoiceText(audioFileBox, finalConfig.botConfig.whisperConfig);
|
|
518
|
+
console.log('语音解析结果', text);
|
|
519
|
+
const keyword = finalConfig.botConfig.whisperConfig?.keywords?.length ? finalConfig.botConfig?.whisperConfig?.keywords?.find((item) => text.includes(item)) : true;
|
|
520
|
+
const isIgnore = checkIgnore(content.trim(), aibotConfig.ignoreMessages);
|
|
521
|
+
if (text.trim() && !isIgnore && keyword) {
|
|
522
|
+
const gpt4vReplys = await getGpt4vChat({
|
|
523
|
+
that,
|
|
524
|
+
room,
|
|
525
|
+
roomId: room.id,
|
|
526
|
+
id: contactId,
|
|
527
|
+
uniqueId: `${room.id}-${contactId}`,
|
|
528
|
+
roomName,
|
|
529
|
+
isMention: true,
|
|
530
|
+
name: contactName,
|
|
531
|
+
msgContent: { type: 1, content: text },
|
|
532
|
+
});
|
|
533
|
+
if (gpt4vReplys.length) {
|
|
534
|
+
for (let reply of gpt4vReplys) {
|
|
535
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
536
|
+
}
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
replys = await getRoomTextReply({
|
|
540
|
+
that,
|
|
541
|
+
content: text,
|
|
542
|
+
isFriend,
|
|
543
|
+
name: contactName,
|
|
544
|
+
id: contactId,
|
|
545
|
+
roomId: room.id,
|
|
546
|
+
avatar: contactAvatar,
|
|
547
|
+
room,
|
|
548
|
+
userAlias,
|
|
549
|
+
userWeixin,
|
|
550
|
+
roomName,
|
|
551
|
+
isMention: true,
|
|
552
|
+
});
|
|
553
|
+
for (let reply of replys) {
|
|
554
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
555
|
+
config?.chatDelay ? await delay(config?.chatDelay * 1000) : await delay(200);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
console.log('语音解析结果没有匹配到需要回复的关键词');
|
|
560
|
+
}
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
if (config?.uploadFileConfig?.open) {
|
|
564
|
+
const uploadFileConfig = config?.uploadFileConfig || {};
|
|
565
|
+
const attachFileBox = await msg.toFileBox();
|
|
566
|
+
const fileExtname = path.extname(attachFileBox.name);
|
|
567
|
+
const fileType = '文件';
|
|
568
|
+
const buffer = await attachFileBox.toBuffer();
|
|
569
|
+
const url = await uploadGlobalOssFile(`${uploadFileConfig?.ossConfig?.custom_path || ''}${dayjs().valueOf()}_${attachFileBox.name}`, buffer);
|
|
570
|
+
const fileUrl = url;
|
|
571
|
+
const fileReplys = await getFileReply({
|
|
572
|
+
that,
|
|
573
|
+
content: uploadFileConfig?.audioPrompt || '请识别这个语音的内容,并回复',
|
|
574
|
+
isFriend,
|
|
575
|
+
name: contactName,
|
|
576
|
+
userAlias,
|
|
577
|
+
userWeixin,
|
|
578
|
+
id: contactId,
|
|
579
|
+
roomId: room.id,
|
|
580
|
+
avatar: contactAvatar,
|
|
581
|
+
room,
|
|
582
|
+
roomName,
|
|
583
|
+
isMention: true,
|
|
584
|
+
file: { fileType, fileUrl, fileExtname, fileName: attachFileBox.name },
|
|
585
|
+
});
|
|
586
|
+
if (fileReplys.length) {
|
|
587
|
+
for (let reply of fileReplys) {
|
|
588
|
+
await roomSay.call(that, room, contact, reply, config?.noNeedAt);
|
|
589
|
+
}
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
break;
|
|
594
|
+
case that.Message.Type.MiniProgram:
|
|
595
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发了一个小程序`);
|
|
596
|
+
const miniProgram = await msg.toMiniProgram();
|
|
597
|
+
if (config.parseMiniRooms.includes(roomName) && miniProgram.payload) {
|
|
598
|
+
const miniParse = `【小程序解析】${eol}${eol}appid:${miniProgram.appid()}${eol}username:${miniProgram.username().replace('@app', '')}${eol}标题:${miniProgram.title()}${eol}描述:${miniProgram.description()}${eol}路径:${decodeURIComponent(miniProgram.pagePath())}${eol}`;
|
|
599
|
+
room.say(miniParse);
|
|
600
|
+
}
|
|
601
|
+
console.log('mini', miniProgram);
|
|
602
|
+
break;
|
|
603
|
+
case that.Message.Type.Transfer:
|
|
604
|
+
console.log(`群名: ${roomName} 发消息人: ${contactName} 发起了转账,请在手机查看`);
|
|
605
|
+
console.log('内容', msg.payload);
|
|
606
|
+
break;
|
|
607
|
+
default:
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
catch (e) {
|
|
612
|
+
console.log('error', e);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
async function onMessage(msg) {
|
|
616
|
+
try {
|
|
617
|
+
const config = await allConfig();
|
|
618
|
+
const { role } = (config && config.userInfo) || { role: 'default' };
|
|
619
|
+
const room = msg.room(); // 是否为群消息
|
|
620
|
+
const msgSelf = msg.self(); // 是否自己发给自己的消息
|
|
621
|
+
if (msgSelf)
|
|
622
|
+
return;
|
|
623
|
+
if (room) {
|
|
624
|
+
const roomName = await room.topic();
|
|
625
|
+
const contact = msg.talker(); // 发消息人
|
|
626
|
+
const contactName = contact.name();
|
|
627
|
+
await dispatchRoomFilterByMsgType(this, room, msg);
|
|
628
|
+
if (role === 'vip' && roomName !== contactName) {
|
|
629
|
+
const roomAsyncList = config.roomAsyncList || [];
|
|
630
|
+
if (roomAsyncList.length) {
|
|
631
|
+
await dispatchAsync(this, msg, roomAsyncList);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
await dispatchFriendFilterByMsgType(this, msg);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
catch (e) {
|
|
640
|
+
console.log('监听消息失败', e);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
export default onMessage;
|
|
644
|
+
//# sourceMappingURL=on-message.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import common from '../common/index.js';
|
|
2
|
+
import { delay } from '../lib/index.js';
|
|
3
|
+
import { getConfig, sendHeartBeat } from "../proxy/aibotk.js";
|
|
4
|
+
import { getUser } from '../db/userDb.js';
|
|
5
|
+
import { initAllSchedule, initMultiTask } from "../task/index.js";
|
|
6
|
+
import { updatePuppetConfig } from "../db/puppetDb.js";
|
|
7
|
+
import { initRssTask } from "../task/rss.js";
|
|
8
|
+
import { allConfig } from "../db/configDb.js";
|
|
9
|
+
/**
|
|
10
|
+
* 准备好的事件
|
|
11
|
+
*/
|
|
12
|
+
async function onReady() {
|
|
13
|
+
try {
|
|
14
|
+
await updatePuppetConfig({ puppetType: this.puppet.constructor.name });
|
|
15
|
+
await getConfig(); // 获取配置文件
|
|
16
|
+
initAllSchedule(this); // 初始化任务
|
|
17
|
+
initMultiTask(this); // 初始化批量定时任务
|
|
18
|
+
const config = await allConfig();
|
|
19
|
+
const { role } = config.userInfo;
|
|
20
|
+
if (role === 'vip') {
|
|
21
|
+
initRssTask(this); // 初始化rss 任务
|
|
22
|
+
}
|
|
23
|
+
await getUser();
|
|
24
|
+
console.log(`所有数据准备完毕`);
|
|
25
|
+
sendHeartBeat('live');
|
|
26
|
+
await delay(3000);
|
|
27
|
+
common.updateContactInfo(this);
|
|
28
|
+
await delay(3000);
|
|
29
|
+
common.updateRoomInfo(this);
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
console.log('on ready error:', e);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export default onReady;
|
|
36
|
+
//# sourceMappingURL=on-ready.js.map
|