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,513 @@
|
|
|
1
|
+
import { getNews, getTXweather, getSweetWord } from '../proxy/api.js';
|
|
2
|
+
import { AIBOTK_OUTAPI } from '../proxy/config.js';
|
|
3
|
+
import { sendFriend, sendRoom, asyncData, getOne, getMaterial, getCustomNews } from '../proxy/aibotk.js';
|
|
4
|
+
import { getUser } from '../db/userDb.js';
|
|
5
|
+
import { formatDate, getDay, groupArray, delay } from '../lib/index.js';
|
|
6
|
+
import { FileBox } from 'file-box';
|
|
7
|
+
import { allConfig } from '../db/configDb.js';
|
|
8
|
+
import { getPuppetEol, isWindowsPlatform } from "../const/puppet-type.js";
|
|
9
|
+
import dayjs from "dayjs";
|
|
10
|
+
import { addHistory } from "../db/chatHistory.js";
|
|
11
|
+
import { getPuppetInfo } from "../db/puppetDb.js";
|
|
12
|
+
async function formatContent(text) {
|
|
13
|
+
text = text.replaceAll('\\n', '\n');
|
|
14
|
+
const isWin = await isWindowsPlatform();
|
|
15
|
+
if (isWin) {
|
|
16
|
+
return text.replaceAll(/\n/g, "\r").replaceAll(/\n/g, "\r");
|
|
17
|
+
}
|
|
18
|
+
return text;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 获取每日新闻内容
|
|
22
|
+
* @param {*} sortId 新闻资讯分类Id
|
|
23
|
+
* @param {*} endWord 结尾备注
|
|
24
|
+
*/
|
|
25
|
+
async function getNewsContent(sortId, endWord = '', num = 10) {
|
|
26
|
+
const eol = await getPuppetEol();
|
|
27
|
+
let today = formatDate(new Date()); //获取今天的日期
|
|
28
|
+
let news = await getNews(sortId, num);
|
|
29
|
+
let content = `${today}${eol}${news}${eol}${endWord ? '————————' : ''}${endWord}`;
|
|
30
|
+
return content;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 获取自定义定制内容
|
|
34
|
+
* @param {*} sortId 定制Id
|
|
35
|
+
* @param taskId
|
|
36
|
+
*/
|
|
37
|
+
export async function getCustomContent(sortId, taskId) {
|
|
38
|
+
let news = await getCustomNews(sortId, taskId);
|
|
39
|
+
return news;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 获取每日说内容
|
|
43
|
+
* @param {*} date 与朋友的纪念日
|
|
44
|
+
* @param {*} city 朋友所在城市
|
|
45
|
+
* @param {*} endWord 结尾备注
|
|
46
|
+
*/
|
|
47
|
+
async function getEveryDayContent(date, city, endWord) {
|
|
48
|
+
const eol = await getPuppetEol();
|
|
49
|
+
let one = await getOne(); //获取每日一句
|
|
50
|
+
let weather = await getTXweather(city); //获取天气信息
|
|
51
|
+
let today = formatDate(new Date()); //获取今天的日期
|
|
52
|
+
let memorialDay = getDay(date); //获取纪念日天数
|
|
53
|
+
let sweetWord = await getSweetWord(); // 土味情话
|
|
54
|
+
let str = `${today}${eol}我们在一起的第${memorialDay}天${eol}${eol}元气满满的一天开始啦,要开心噢^_^${eol}${eol}今日天气${eol}${weather.weatherTips}${eol}${weather.todayWeather}${eol}每日一句:${eol}${one}${eol}${eol}情话对你说:${eol}${sweetWord}${eol}${eol}————————${endWord}`;
|
|
55
|
+
return str;
|
|
56
|
+
}
|
|
57
|
+
async function getRoomEveryDayContent(date, city, endWord) {
|
|
58
|
+
const eol = await getPuppetEol();
|
|
59
|
+
let one = await getOne(); //获取每日一句
|
|
60
|
+
let weather = await getTXweather(city); //获取天气信息
|
|
61
|
+
let today = formatDate(new Date()); //获取今天的日期
|
|
62
|
+
let memorialDay = getDay(date); //获取纪念日天数
|
|
63
|
+
let str = `${today}${eol}家人们相聚在一起的第${memorialDay}天${eol}${eol}元气满满的一天开始啦,家人们要努力保持活跃啊^_^${eol}${eol}今日天气${eol}${weather.weatherTips}${eol}${weather.todayWeather}${eol}每日一句:${eol}${one}${eol}${eol}————————${endWord}`;
|
|
64
|
+
return str;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 获取倒计时内容
|
|
68
|
+
* @param date
|
|
69
|
+
* @param prefix
|
|
70
|
+
* @param suffix
|
|
71
|
+
* @param endWord
|
|
72
|
+
* @return {string}
|
|
73
|
+
*/
|
|
74
|
+
async function getCountDownContent(date, prefix, suffix, endWord) {
|
|
75
|
+
const eol = await getPuppetEol();
|
|
76
|
+
let countDownDay = getDay(date); //获取倒计时天数
|
|
77
|
+
let today = formatDate(new Date()); //获取今天的日期
|
|
78
|
+
let str = `${today}距离${prefix}还有${eol}${eol}${countDownDay}天${eol}${eol}${suffix}${endWord ? `${eol}${eol}————————${endWord}` : ''}`;
|
|
79
|
+
return str;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 更新用户信息
|
|
83
|
+
*/
|
|
84
|
+
async function updateContactInfo(that, noCache = false) {
|
|
85
|
+
try {
|
|
86
|
+
if (noCache && that.puppet.syncContact) {
|
|
87
|
+
await that.puppet.syncContact(true);
|
|
88
|
+
await delay(3000);
|
|
89
|
+
}
|
|
90
|
+
const contactSelf = await getUser();
|
|
91
|
+
const contactList = await that.Contact.findAll() || [];
|
|
92
|
+
let res = [];
|
|
93
|
+
const notids = ['filehelper', 'fmessage'];
|
|
94
|
+
let realContact = contactList.filter((item) => {
|
|
95
|
+
const payload = item.payload || item._payload;
|
|
96
|
+
return payload.friend && !notids.includes(payload.id) && !payload.id.includes('gh_');
|
|
97
|
+
});
|
|
98
|
+
for (let i of realContact) {
|
|
99
|
+
await i.sync();
|
|
100
|
+
let contact = i.payload || i._payload;
|
|
101
|
+
let obj = {
|
|
102
|
+
robotId: contactSelf.robotId,
|
|
103
|
+
contactId: contact.id,
|
|
104
|
+
wxid: contact.id,
|
|
105
|
+
name: contact.name || '',
|
|
106
|
+
alias: contact.alias || '',
|
|
107
|
+
gender: contact.gender,
|
|
108
|
+
avatar: contact.avatar || '',
|
|
109
|
+
friend: contact.friend,
|
|
110
|
+
type: contact.type || '',
|
|
111
|
+
weixin: contact.weixin || '',
|
|
112
|
+
};
|
|
113
|
+
res.push(obj);
|
|
114
|
+
}
|
|
115
|
+
await updateFriendInfo(res, 80);
|
|
116
|
+
console.log(`更新好友列表完毕,共获取到${realContact.length}个好友信息`);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
console.log('e', e);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 分批次更新好友信息
|
|
124
|
+
* @param {*} list 好友列表
|
|
125
|
+
* @param {*} num 每次发送数据
|
|
126
|
+
*/
|
|
127
|
+
async function updateFriendInfo(list, num) {
|
|
128
|
+
const arr = groupArray(list, num);
|
|
129
|
+
for (let i = 0; i < arr.length; i++) {
|
|
130
|
+
const item = arr[i];
|
|
131
|
+
await sendFriend(item);
|
|
132
|
+
await delay(500);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* 更新群列表
|
|
137
|
+
*/
|
|
138
|
+
async function updateRoomInfo(that, noCache = false) {
|
|
139
|
+
try {
|
|
140
|
+
if (noCache && that.puppet.syncContact) {
|
|
141
|
+
await that.puppet.syncContact(true);
|
|
142
|
+
await delay(5000);
|
|
143
|
+
}
|
|
144
|
+
const contactSelf = await getUser();
|
|
145
|
+
const roomList = await that.Room.findAll() || [];
|
|
146
|
+
let res = [];
|
|
147
|
+
for (let i of roomList) {
|
|
148
|
+
await i.sync();
|
|
149
|
+
let room = i.payload || i._payload;
|
|
150
|
+
let obj = {
|
|
151
|
+
robotId: contactSelf.robotId,
|
|
152
|
+
wxid: room.id,
|
|
153
|
+
roomId: room.id,
|
|
154
|
+
topic: room.topic,
|
|
155
|
+
avatar: room.avatar || '',
|
|
156
|
+
ownerId: room.ownerId || '',
|
|
157
|
+
adminIds: room.adminIdList.toString(),
|
|
158
|
+
memberCount: room.memberIdList.length,
|
|
159
|
+
};
|
|
160
|
+
res.push(obj);
|
|
161
|
+
}
|
|
162
|
+
await updateRoomsInfo(res, 80);
|
|
163
|
+
console.log(`更新群列表完毕,共获取到${roomList.length}个群聊`);
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
console.log('e', e);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 更新群信息
|
|
171
|
+
* @param {*} list 好友列表
|
|
172
|
+
* @param {*} num 每次发送数据
|
|
173
|
+
*/
|
|
174
|
+
async function updateRoomsInfo(list, num) {
|
|
175
|
+
const arr = groupArray(list, num);
|
|
176
|
+
for (let i = 0; i < arr.length; i++) {
|
|
177
|
+
const item = arr[i];
|
|
178
|
+
await sendRoom(item);
|
|
179
|
+
await delay(500);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* 统一触发加群欢迎词
|
|
184
|
+
* @param room 群
|
|
185
|
+
* @param roomName 群名
|
|
186
|
+
* @param contactName 进群人
|
|
187
|
+
* @param msg 消息
|
|
188
|
+
*/
|
|
189
|
+
async function addRoomWelcomeSay(room, roomName, contactName, msg) {
|
|
190
|
+
if (msg.type === 1 && msg.content !== '') {
|
|
191
|
+
// 文字
|
|
192
|
+
console.log('回复内容', msg.content);
|
|
193
|
+
await room.say(`${roomName}:欢迎新朋友 @${contactName},\n${msg.content}`);
|
|
194
|
+
}
|
|
195
|
+
else if (msg.type === 2 && msg.url !== '') {
|
|
196
|
+
// url文件
|
|
197
|
+
let obj = FileBox.fromUrl(msg.url);
|
|
198
|
+
console.log('回复内容', obj);
|
|
199
|
+
await room.say(obj);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function addReplyHistory(that, { content, contact, room }) {
|
|
203
|
+
const config = await allConfig();
|
|
204
|
+
const { role } = config.userInfo;
|
|
205
|
+
if (role !== 'vip')
|
|
206
|
+
return;
|
|
207
|
+
const robotInfo = that ? that?.currentUser : {};
|
|
208
|
+
const userSelfName = robotInfo ? robotInfo?.name() : ''; // 机器人名称
|
|
209
|
+
const userSelfId = robotInfo ? robotInfo?.id : ''; // 机器人名称
|
|
210
|
+
const contactName = contact && contact?.name ? contact?.name() : ''; // 接收消息人昵称
|
|
211
|
+
const contactId = contact ? contact?.id : ''; // 接收消息人id
|
|
212
|
+
const roomName = room ? await room.topic() : '';
|
|
213
|
+
const historyItem = {
|
|
214
|
+
conversionId: room ? room.id : contactId,
|
|
215
|
+
conversionName: room ? roomName : contactName,
|
|
216
|
+
isRoom: !!room,
|
|
217
|
+
isRobot: true,
|
|
218
|
+
content: content,
|
|
219
|
+
chatName: userSelfName,
|
|
220
|
+
chatId: userSelfId,
|
|
221
|
+
time: dayjs().unix()
|
|
222
|
+
};
|
|
223
|
+
void addHistory(historyItem);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* 群关键词回复
|
|
227
|
+
* @param room
|
|
228
|
+
* @param {*} contact
|
|
229
|
+
* @param {*} msg
|
|
230
|
+
* @param noNeedAt
|
|
231
|
+
*/
|
|
232
|
+
async function roomSay(room, contact, msg, noNeedAt = false) {
|
|
233
|
+
const config = await allConfig();
|
|
234
|
+
const { role } = config.userInfo;
|
|
235
|
+
if (msg.id && role === 'vip') {
|
|
236
|
+
const res = await getMaterial(msg.id);
|
|
237
|
+
if (res.id) {
|
|
238
|
+
msg = res;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
console.log('回复内容:', JSON.stringify(msg));
|
|
242
|
+
try {
|
|
243
|
+
if (msg.type === 1 && msg.content) {
|
|
244
|
+
const content = await formatContent(msg.content);
|
|
245
|
+
if (noNeedAt || !contact) {
|
|
246
|
+
await room.say(content);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
// 文字
|
|
250
|
+
if (Array.isArray(contact)) {
|
|
251
|
+
await room.say(content, ...contact);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
await room.say(content, contact);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
void addReplyHistory(this, { content, contact: null, room: room });
|
|
258
|
+
}
|
|
259
|
+
else if (msg.type === 2 && msg.url) {
|
|
260
|
+
// url文件
|
|
261
|
+
let obj = FileBox.fromUrl(msg.url);
|
|
262
|
+
if (obj.mediaType === 'image/webp') {
|
|
263
|
+
obj = FileBox.fromUrl(`${AIBOTK_OUTAPI}/convert?url=${msg.url}`);
|
|
264
|
+
}
|
|
265
|
+
// contact ? await room.say('', contact) : ''
|
|
266
|
+
await delay(500);
|
|
267
|
+
await room.say(obj);
|
|
268
|
+
void addReplyHistory(this, { content: `[文件或图片](${msg.url})`, contact: null, room: room });
|
|
269
|
+
}
|
|
270
|
+
else if (msg.type === 3 && msg.url) {
|
|
271
|
+
// bse64文件
|
|
272
|
+
let obj = FileBox.fromDataURL(msg.url, 'room-avatar.jpg');
|
|
273
|
+
if (Array.isArray(contact)) {
|
|
274
|
+
await room.say('', ...contact);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
contact ? await room.say('', contact) : '';
|
|
278
|
+
}
|
|
279
|
+
await delay(500);
|
|
280
|
+
await room.say(obj);
|
|
281
|
+
}
|
|
282
|
+
else if (msg.type === 4 && msg.url && msg.title && msg.description) {
|
|
283
|
+
// @ts-ignore
|
|
284
|
+
const description = await formatContent(msg.description);
|
|
285
|
+
const title = await formatContent(msg.title);
|
|
286
|
+
let url = new this.UrlLink({
|
|
287
|
+
description: description,
|
|
288
|
+
thumbnailUrl: msg.thumbUrl,
|
|
289
|
+
title: title,
|
|
290
|
+
url: msg.url,
|
|
291
|
+
});
|
|
292
|
+
await room.say(url);
|
|
293
|
+
void addReplyHistory(this, { content: `[链接](${msg.url})`, contact: null, room: room });
|
|
294
|
+
}
|
|
295
|
+
else if (msg.type === 5 && msg.appid && msg.title && msg.pagePath && msg.description && msg.thumbUrl) {
|
|
296
|
+
let miniProgram = new this.MiniProgram({
|
|
297
|
+
appid: msg.appid,
|
|
298
|
+
title: msg.title,
|
|
299
|
+
pagePath: msg.pagePath,
|
|
300
|
+
description: msg.description,
|
|
301
|
+
thumbUrl: msg.thumbUrl,
|
|
302
|
+
thumbKey: msg.thumbKey,
|
|
303
|
+
username: msg.username || ''
|
|
304
|
+
});
|
|
305
|
+
await room.say(miniProgram);
|
|
306
|
+
}
|
|
307
|
+
else if (msg.type === 8 && msg.url && msg.voiceLength) {
|
|
308
|
+
const fileBox = FileBox.fromUrl(msg.url);
|
|
309
|
+
fileBox.mimeType = "audio/silk";
|
|
310
|
+
const puppetInfo = await getPuppetInfo();
|
|
311
|
+
if (puppetInfo.puppetType === 'PuppetService') {
|
|
312
|
+
fileBox.metadata = {
|
|
313
|
+
duration: msg.voiceLength / 1000,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
fileBox.metadata = {
|
|
318
|
+
voiceLength: msg.voiceLength,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
await room.say(fileBox);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch (e) {
|
|
325
|
+
console.log('群回复错误', e);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* 私聊发送消息
|
|
330
|
+
* @param contact
|
|
331
|
+
* @param msg
|
|
332
|
+
* @param isRoom
|
|
333
|
+
* type 1 文字 2 图片url 3 图片base64 4 url链接 5 小程序 6 名片 7 富文本 8 语音
|
|
334
|
+
*/
|
|
335
|
+
async function contactSay(contact, msg, isRoom = false) {
|
|
336
|
+
const config = await allConfig();
|
|
337
|
+
const { role } = config.userInfo;
|
|
338
|
+
if (msg.id && role === 'vip') {
|
|
339
|
+
const res = await getMaterial(msg.id);
|
|
340
|
+
if (res.id) {
|
|
341
|
+
msg = res;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
console.log('回复内容:', JSON.stringify(msg));
|
|
345
|
+
try {
|
|
346
|
+
if (msg.type === 1 && msg.content) {
|
|
347
|
+
const content = await formatContent(msg.content);
|
|
348
|
+
// 文字
|
|
349
|
+
await contact.say(content);
|
|
350
|
+
void addReplyHistory(this, { content, contact, room: null });
|
|
351
|
+
}
|
|
352
|
+
else if (msg.type === 2 && msg.url) {
|
|
353
|
+
// url文件
|
|
354
|
+
let obj = FileBox.fromUrl(msg.url);
|
|
355
|
+
await obj.ready();
|
|
356
|
+
if (obj.mediaType === 'image/webp') {
|
|
357
|
+
obj = FileBox.fromUrl(`${AIBOTK_OUTAPI}/convert?url=${msg.url}`);
|
|
358
|
+
}
|
|
359
|
+
await contact.say(obj);
|
|
360
|
+
void addReplyHistory(this, { content: `[文件或图片](${msg.url})`, contact, room: null });
|
|
361
|
+
}
|
|
362
|
+
else if (msg.type === 3 && msg.url) {
|
|
363
|
+
// bse64文件
|
|
364
|
+
let obj = FileBox.fromDataURL(msg.url, 'user-avatar.jpg');
|
|
365
|
+
await contact.say(obj);
|
|
366
|
+
}
|
|
367
|
+
else if (msg.type === 4 && msg.url && msg.title && msg.description) {
|
|
368
|
+
const description = await formatContent(msg.description);
|
|
369
|
+
const title = await formatContent(msg.title);
|
|
370
|
+
let url = new this.UrlLink({
|
|
371
|
+
description: description,
|
|
372
|
+
thumbnailUrl: msg.thumbUrl,
|
|
373
|
+
title: title,
|
|
374
|
+
url: msg.url,
|
|
375
|
+
});
|
|
376
|
+
await contact.say(url);
|
|
377
|
+
void addReplyHistory(this, { content: `[链接](${msg.url})`, contact, room: null });
|
|
378
|
+
}
|
|
379
|
+
else if (msg.type === 5 && msg.appid && msg.title && msg.pagePath && msg.description && msg.thumbUrl) {
|
|
380
|
+
let miniProgram = new this.MiniProgram({
|
|
381
|
+
appid: msg.appid,
|
|
382
|
+
title: msg.title,
|
|
383
|
+
pagePath: msg.pagePath,
|
|
384
|
+
description: msg.description,
|
|
385
|
+
thumbUrl: msg.thumbUrl,
|
|
386
|
+
thumbKey: msg.thumbKey,
|
|
387
|
+
username: msg.username || ''
|
|
388
|
+
});
|
|
389
|
+
await contact.say(miniProgram);
|
|
390
|
+
}
|
|
391
|
+
else if (msg.type === 8 && msg.url && msg.voiceLength) {
|
|
392
|
+
const fileBox = FileBox.fromUrl(msg.url);
|
|
393
|
+
fileBox.mimeType = "audio/silk";
|
|
394
|
+
const puppetInfo = await getPuppetInfo();
|
|
395
|
+
if (puppetInfo.puppetType === 'PuppetService') {
|
|
396
|
+
fileBox.metadata = {
|
|
397
|
+
duration: msg.voiceLength / 1000,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
fileBox.metadata = {
|
|
402
|
+
voiceLength: msg.voiceLength,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
await contact.say(fileBox);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
console.log('私聊发送消息失败', e);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* 统一邀请加群
|
|
414
|
+
* @param that
|
|
415
|
+
* @param contact
|
|
416
|
+
*/
|
|
417
|
+
async function addRoom(that, contact, roomName, replys) {
|
|
418
|
+
let room = await that.Room.find({ topic: roomName });
|
|
419
|
+
if (room) {
|
|
420
|
+
try {
|
|
421
|
+
for (const item of replys) {
|
|
422
|
+
await delay(2000);
|
|
423
|
+
await contactSay.call(that, contact, item);
|
|
424
|
+
}
|
|
425
|
+
await room.add(contact);
|
|
426
|
+
}
|
|
427
|
+
catch (e) {
|
|
428
|
+
console.error('加群报错', e);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
console.log(`不存在此群:${roomName}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* 发送群公告
|
|
437
|
+
* @param roomIds
|
|
438
|
+
* @param content
|
|
439
|
+
* @return {Promise<void>}
|
|
440
|
+
*/
|
|
441
|
+
async function sendRoomNotice(room, content) {
|
|
442
|
+
const config = await allConfig();
|
|
443
|
+
const { role } = config.userInfo;
|
|
444
|
+
if (role === 'vip' && room && content) {
|
|
445
|
+
await room.announce(content);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* 重新同步好友和群组
|
|
450
|
+
* @param that
|
|
451
|
+
* @returns {Promise<void>}
|
|
452
|
+
*/
|
|
453
|
+
async function updateContactAndRoom(that) {
|
|
454
|
+
const contactSelf = await getUser();
|
|
455
|
+
await asyncData(contactSelf.robotId, 1);
|
|
456
|
+
await delay(2000);
|
|
457
|
+
await asyncData(contactSelf.robotId, 2);
|
|
458
|
+
await delay(2000);
|
|
459
|
+
await updateRoomInfo(that, true);
|
|
460
|
+
await delay(2000);
|
|
461
|
+
await updateContactInfo(that);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* 重新同步好友
|
|
465
|
+
* @param that
|
|
466
|
+
* @returns {Promise<void>}
|
|
467
|
+
*/
|
|
468
|
+
async function updateContactOnly(that) {
|
|
469
|
+
const contactSelf = await getUser();
|
|
470
|
+
await asyncData(contactSelf.robotId, 1);
|
|
471
|
+
await delay(2000);
|
|
472
|
+
await updateContactInfo(that, true);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* 重新同步群
|
|
476
|
+
* @param that
|
|
477
|
+
* @returns {Promise<void>}
|
|
478
|
+
*/
|
|
479
|
+
async function updateRoomOnly(that) {
|
|
480
|
+
const contactSelf = await getUser();
|
|
481
|
+
await asyncData(contactSelf.robotId, 2);
|
|
482
|
+
await delay(2000);
|
|
483
|
+
await updateRoomInfo(that, true);
|
|
484
|
+
}
|
|
485
|
+
export { updateRoomOnly };
|
|
486
|
+
export { updateContactOnly };
|
|
487
|
+
export { getEveryDayContent };
|
|
488
|
+
export { getNewsContent };
|
|
489
|
+
export { updateContactInfo };
|
|
490
|
+
export { updateRoomInfo };
|
|
491
|
+
export { addRoom };
|
|
492
|
+
export { contactSay };
|
|
493
|
+
export { roomSay };
|
|
494
|
+
export { addRoomWelcomeSay };
|
|
495
|
+
export { updateContactAndRoom };
|
|
496
|
+
export { getRoomEveryDayContent };
|
|
497
|
+
export { getCountDownContent };
|
|
498
|
+
export { sendRoomNotice };
|
|
499
|
+
export default {
|
|
500
|
+
updateRoomOnly,
|
|
501
|
+
updateContactOnly,
|
|
502
|
+
getEveryDayContent,
|
|
503
|
+
getNewsContent,
|
|
504
|
+
updateContactInfo,
|
|
505
|
+
updateRoomInfo,
|
|
506
|
+
addRoom,
|
|
507
|
+
contactSay,
|
|
508
|
+
roomSay,
|
|
509
|
+
addRoomWelcomeSay,
|
|
510
|
+
updateContactAndRoom,
|
|
511
|
+
getCountDownContent
|
|
512
|
+
};
|
|
513
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { get4vReply, getDify4vReply } from "../botInstance/gpt4v.js";
|
|
2
|
+
import { getImageVision } from '../proxy/multimodal.js';
|
|
3
|
+
class MultiReply {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.step = 0; // 当前step
|
|
6
|
+
this.stepRecord = []; // 经历过的step
|
|
7
|
+
this.imageIds = []; // 用户发送的图片消息id
|
|
8
|
+
}
|
|
9
|
+
paramsInit() {
|
|
10
|
+
this.step = 0; // 当前step
|
|
11
|
+
this.stepRecord = []; // 经历过的step
|
|
12
|
+
this.imageIds = []; // 用户发送的图片消息id
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
class BotManage {
|
|
16
|
+
constructor(maxuser = 50, that) {
|
|
17
|
+
this.Bot = that;
|
|
18
|
+
this.userBotDict = {}; // 存放所有对话的用户
|
|
19
|
+
this.userTimeDict = {};
|
|
20
|
+
this.maxuser = maxuser; // 最大同时处理的用户数
|
|
21
|
+
}
|
|
22
|
+
async creatBot(username, content) {
|
|
23
|
+
console.log("bot process create");
|
|
24
|
+
this.userBotDict[username] = new MultiReply();
|
|
25
|
+
this.userBotDict[username].userName = username;
|
|
26
|
+
this.userBotDict[username].imageIds = [content.id];
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
console.log('清理图像识别对话缓存');
|
|
29
|
+
this.removeBot(username);
|
|
30
|
+
}, 10 * 60 * 1000);
|
|
31
|
+
return await this.updateBot(username, content);
|
|
32
|
+
}
|
|
33
|
+
// 更新对话
|
|
34
|
+
async updateBot(username, content, config) {
|
|
35
|
+
console.log(`更新{${username}}对话`);
|
|
36
|
+
this.userTimeDict[username] = new Date().getTime();
|
|
37
|
+
return await this.talk(username, content, config);
|
|
38
|
+
}
|
|
39
|
+
async talk(username, content, config) {
|
|
40
|
+
if (this.userBotDict[username].step == 0) {
|
|
41
|
+
this.userBotDict[username].stepRecord.push(0);
|
|
42
|
+
if (content.type === 3) {
|
|
43
|
+
this.userBotDict[username].step += 1;
|
|
44
|
+
// 请描述你对图片的问题,最多支持5张图片,已收到${this.userBotDict[username].imageIds.length}张图片
|
|
45
|
+
return [
|
|
46
|
+
{ type: 1, content: '' }
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (this.userBotDict[username].step == 1) {
|
|
51
|
+
console.log("第二轮对话,用户输入了需要提问的内容");
|
|
52
|
+
this.userBotDict[username].stepRecord.push(1);
|
|
53
|
+
if (content.type === 1) {
|
|
54
|
+
// 用户选择了漫画模式
|
|
55
|
+
const res = await this.generateImage(username, content.content, config);
|
|
56
|
+
this.removeBot(username);
|
|
57
|
+
return res;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
removeBot(uid) {
|
|
62
|
+
delete this.userTimeDict[uid];
|
|
63
|
+
delete this.userBotDict[uid];
|
|
64
|
+
}
|
|
65
|
+
getBotList() {
|
|
66
|
+
return this.userBotDict;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 识别图片内容
|
|
70
|
+
* @param {*} username 用户名
|
|
71
|
+
* @returns
|
|
72
|
+
*/
|
|
73
|
+
async generateImage(username, question, config) {
|
|
74
|
+
const images = [];
|
|
75
|
+
if (config.robotType === 8) {
|
|
76
|
+
// 如果是 dify 平台
|
|
77
|
+
for (let id of this.userBotDict[username].imageIds) {
|
|
78
|
+
const msg = await this.Bot.Message.find({ id });
|
|
79
|
+
const file = await msg.toFileBox();
|
|
80
|
+
images.push(file);
|
|
81
|
+
}
|
|
82
|
+
const replys = await getDify4vReply(images, question, config, username);
|
|
83
|
+
return replys;
|
|
84
|
+
}
|
|
85
|
+
else if (config.robotType === 6) {
|
|
86
|
+
for (let id of this.userBotDict[username].imageIds) {
|
|
87
|
+
const msg = await this.Bot.Message.find({ id });
|
|
88
|
+
const file = await msg.toFileBox();
|
|
89
|
+
const base = await file.toDataURL();
|
|
90
|
+
images.push(base);
|
|
91
|
+
}
|
|
92
|
+
const replys = await get4vReply(images, question, config);
|
|
93
|
+
return replys;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
for (let id of this.userBotDict[username].imageIds) {
|
|
97
|
+
const msg = await this.Bot.Message.find({ id });
|
|
98
|
+
const file = await msg.toFileBox();
|
|
99
|
+
const base = await file.toDataURL();
|
|
100
|
+
images.push(base);
|
|
101
|
+
}
|
|
102
|
+
const replys = await getImageVision(images, question, config);
|
|
103
|
+
return replys;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
getImage(username, content, step) {
|
|
107
|
+
if (this.userBotDict[username].imageIds.length === 5) {
|
|
108
|
+
this.removeBot(username);
|
|
109
|
+
// 本次对话已经重置,请重新发送图片
|
|
110
|
+
let replys = {
|
|
111
|
+
type: 1,
|
|
112
|
+
content: ""
|
|
113
|
+
};
|
|
114
|
+
return [replys];
|
|
115
|
+
}
|
|
116
|
+
this.userBotDict[username].step = step;
|
|
117
|
+
this.userBotDict[username].imageIds.push(content.id);
|
|
118
|
+
if (this.userBotDict[username].imageIds.length === 5) {
|
|
119
|
+
// 已收到5张图片,请描述你的问题,再次发送图片将会重置本次对话
|
|
120
|
+
let replys = {
|
|
121
|
+
type: 1,
|
|
122
|
+
content: ""
|
|
123
|
+
};
|
|
124
|
+
return [replys];
|
|
125
|
+
}
|
|
126
|
+
// `请描述你的问题,最多支持5张图片,已收到${this.userBotDict[username].imageIds.length}张图片`
|
|
127
|
+
let replys = {
|
|
128
|
+
type: 1,
|
|
129
|
+
content: ''
|
|
130
|
+
};
|
|
131
|
+
return [replys];
|
|
132
|
+
}
|
|
133
|
+
// 对话入口
|
|
134
|
+
async run(userId, content, config) {
|
|
135
|
+
if (content.type === 1) {
|
|
136
|
+
if (Object.keys(this.userTimeDict).includes(userId)) {
|
|
137
|
+
return this.updateBot(userId, content, config);
|
|
138
|
+
}
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
else if (content.type === 3) {
|
|
142
|
+
if (Object.keys(this.userTimeDict).includes(userId)) {
|
|
143
|
+
return this.getImage(userId, content, 1);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
if (this.userBotDict.length > this.maxuser) {
|
|
147
|
+
const minNum = Math.min(...Object.values(this.userTimeDict));
|
|
148
|
+
const earlyIndex = Object.values(this.userTimeDict).indexOf(minNum);
|
|
149
|
+
const earlyKey = Object.keys(this.userTimeDict)[earlyIndex];
|
|
150
|
+
this.removeBot(earlyKey);
|
|
151
|
+
}
|
|
152
|
+
return await this.creatBot(userId, content);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export { BotManage };
|
|
158
|
+
//# sourceMappingURL=multiReply.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import service from '../service/msg-filter-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* 获取私聊返回内容
|
|
4
|
+
*/
|
|
5
|
+
export async function getContactTextReply(that, contact, msg) {
|
|
6
|
+
let result = await service.filterFriendMsg(that, contact, msg);
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
export async function getFileReply({ that, contact, content, name, id, avatar, room, userWeixin, isMention, roomName, userAlias, roomId, isFriend, file }) {
|
|
10
|
+
let result = await service.filterFile({ that, userWeixin, msg: content, userAlias, name, id, avatar, room, isMention, roomName, roomId, isFriend, contact, file });
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 获取群消息回复
|
|
15
|
+
* @param {*} content 群消息内容
|
|
16
|
+
* @param {*} name 发消息者昵称
|
|
17
|
+
* @param {*} id 发消息者id
|
|
18
|
+
*/
|
|
19
|
+
export async function getRoomTextReply({ that, content, name, id, avatar, room, userWeixin, isMention, roomName, userAlias, roomId, isFriend }) {
|
|
20
|
+
let result = await service.filterRoomMsg({ that, userWeixin, msg: content, userAlias, name, id, avatar, room, isMention, roomName, roomId, isFriend });
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=reply.js.map
|