wechaty-web-panel 1.1.11 → 1.2.0

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/CHANGELOG.md CHANGED
@@ -1,4 +1,8 @@
1
1
  ## 更新日志
2
+ ### V1.1.21(2022-10-31)
3
+
4
+ 1、添加群中关键词触发是否需要@功能
5
+
2
6
  ### V1.0.6(2022-07-14)
3
7
 
4
8
  1、修复机器人无法对话功能
package/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
 
6
6
  Wechaty Web Panel 插件,让你的 wechaty 机器人快速接入 web 控制面板
7
7
 
8
+ 本项目为面板源码,如需可直接运行的项目,请直接拉取 [https://github.com/leochen-g/wechat-assistant-pro](https://github.com/leochen-g/wechat-assistant-pro) 即可
9
+
8
10
  ## 面板主要功能
9
11
 
10
12
  - [x] 微信每日说,定时给女朋友发送每日天气提醒,以及每日一句
@@ -8,7 +8,7 @@ export function getContactTextReply(that: any, contact: any, msg: any): Promise<
8
8
  * @param {*} name 发消息者昵称
9
9
  * @param {*} id 发消息者id
10
10
  */
11
- export function getRoomTextReply(that: any, content: any, name: any, id: any, avatar: any, room: any): Promise<number>;
11
+ export function getRoomTextReply({ that, content, name, id, avatar, room, isMention }: any): Promise<number>;
12
12
  declare namespace _default {
13
13
  export { getContactTextReply };
14
14
  export { getRoomTextReply };
@@ -19,8 +19,8 @@ exports.getContactTextReply = getContactTextReply;
19
19
  * @param {*} name 发消息者昵称
20
20
  * @param {*} id 发消息者id
21
21
  */
22
- async function getRoomTextReply(that, content, name, id, avatar, room) {
23
- let result = await msg_filter_service_js_1.default.filterRoomMsg(that, content, name, id, avatar, room);
22
+ async function getRoomTextReply({ that, content, name, id, avatar, room, isMention }) {
23
+ let result = await msg_filter_service_js_1.default.filterRoomMsg({ that, msg: content, name, id, avatar, room, isMention });
24
24
  return result;
25
25
  }
26
26
  exports.getRoomTextReply = getRoomTextReply;
@@ -26,10 +26,15 @@ async function onLogin(user) {
26
26
  };
27
27
  await (0, userDb_js_1.addUser)(userInfo); // 全局存储登录用户信息
28
28
  const file = await user.avatar();
29
- const base = await file.toBase64();
30
- const avatarUrl = await (0, aibotk_js_1.putqn)(base, userId);
31
- await (0, aibotk_js_1.sendRobotInfo)(avatarUrl, user.name(), userInfo.robotId); // 更新用户头像
32
- await (0, index_js_1.delay)(3000);
29
+ if (file) {
30
+ const base = await file.toBase64();
31
+ const avatarUrl = await (0, aibotk_js_1.putqn)(base, userId);
32
+ await (0, aibotk_js_1.sendRobotInfo)(avatarUrl, user.name(), userInfo.robotId); // 更新用户头像
33
+ await (0, index_js_1.delay)(1000);
34
+ }
35
+ else {
36
+ console.log('头像未获取到,不影响项目正常使用');
37
+ }
33
38
  await (0, index_js_2.initAllSchedule)(this); // 初始化任务
34
39
  await (0, mqtt_js_1.initMqtt)(this); // 初始化mqtt任务
35
40
  }
@@ -10,7 +10,7 @@ const roomDb_js_1 = require("../db/roomDb.js");
10
10
  const ignoreRecord = [
11
11
  { type: "include", word: "加入了群聊" },
12
12
  { type: "include", word: "与群里其他人都不是朋友关系" },
13
- { type: "include", word: "收到一条暂不支持的消息类型" },
13
+ { type: "include", word: "收到一条暂不支持的消息类型" }
14
14
  ];
15
15
  /**
16
16
  * 检测是否属于忽略的消息
@@ -23,7 +23,7 @@ function checkIgnore(msg, list) {
23
23
  for (let item of list) {
24
24
  const word = item.word;
25
25
  const type = item.type;
26
- if ((type === 'start' && msg.startsWith(word)) || (type === 'end' && msg.endsWith(word)) || (type === 'equal' && msg === word) || (type === 'include' && msg.includes(word))) {
26
+ if ((type === "start" && msg.startsWith(word)) || (type === "end" && msg.endsWith(word)) || (type === "equal" && msg === word) || (type === "include" && msg.includes(word))) {
27
27
  return true;
28
28
  }
29
29
  }
@@ -40,7 +40,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
40
40
  const type = msg.type();
41
41
  const contact = msg.talker(); // 发消息人
42
42
  const isOfficial = contact.type() === that.Contact.Type.Official;
43
- let content = '';
43
+ let content = "";
44
44
  let replys = [];
45
45
  switch (type) {
46
46
  case that.Message.Type.Text:
@@ -57,7 +57,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
57
57
  }
58
58
  }
59
59
  else {
60
- console.log('公众号消息');
60
+ console.log("公众号消息");
61
61
  }
62
62
  break;
63
63
  case that.Message.Type.Emoticon:
@@ -80,7 +80,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
80
80
  }
81
81
  }
82
82
  catch (error) {
83
- console.log('监听消息错误', error);
83
+ console.log("监听消息错误", error);
84
84
  }
85
85
  }
86
86
  /**
@@ -99,32 +99,45 @@ async function dispatchRoomFilterByMsgType(that, room, msg) {
99
99
  const roomName = await room.topic();
100
100
  const type = msg.type();
101
101
  const userSelfName = that.currentUser?.name() || that.userSelf()?.name();
102
- let content = '';
103
- let replys = '';
104
- let contactId = contact.id || '111';
102
+ let content = "";
103
+ let replys = "";
104
+ let contactId = contact.id || "111";
105
105
  let contactAvatar = await contact.avatar();
106
106
  switch (type) {
107
107
  case that.Message.Type.Text:
108
108
  content = msg.text();
109
109
  console.log(`群名: ${roomName} 发消息人: ${contactName} 内容: ${content}`);
110
110
  const mentionSelf = content.includes(`@${userSelfName}`);
111
- if (mentionSelf) {
112
- content = content.replace(/@[^,,::\s@]+/g, '').trim();
113
- // 检测是否需要这条消息
114
- const isIgnore = checkIgnore(content, aibotConfig.ignoreMessages);
115
- if (isIgnore)
116
- return;
117
- replys = await (0, reply_js_1.getRoomTextReply)(that, content, contactName, contactId, contactAvatar, room);
118
- for (let reply of replys) {
119
- await (0, index_js_2.delay)(1000);
120
- await index_js_1.roomSay.call(that, room, contact, reply);
121
- }
111
+ content = content.replace(/@[^,,::\s@]+/g, "").trim();
112
+ // 检测是否需要这条消息
113
+ const isIgnore = checkIgnore(content, aibotConfig.ignoreMessages);
114
+ if (isIgnore)
115
+ return;
116
+ replys = await (0, reply_js_1.getRoomTextReply)({
117
+ that,
118
+ content,
119
+ name: contactName,
120
+ id: contactId,
121
+ avatar: contactAvatar,
122
+ room,
123
+ isMention: mentionSelf
124
+ });
125
+ for (let reply of replys) {
126
+ await (0, index_js_2.delay)(1000);
127
+ await index_js_1.roomSay.call(that, room, contact, reply);
122
128
  }
123
129
  const cloudRoom = config.cloudRoom;
124
- if (role === 'vip' && cloudRoom.includes(roomName) && !checkIgnore(content, ignoreRecord)) {
130
+ if (role === "vip" && cloudRoom.includes(roomName) && !checkIgnore(content, ignoreRecord)) {
125
131
  const regex = /(<([^>]+)>)/ig;
126
132
  content = content.replace(regex, "");
127
- (0, roomDb_js_1.addRoomRecord)({ roomName, roomId: room.id, content, contact: contactName, wxid: contactId, time: new Date().getTime() });
133
+ (0, roomDb_js_1.addRoomRecord)({
134
+ roomName,
135
+ roomId: room.id,
136
+ content,
137
+ contact: contactName,
138
+ wxid: contactId,
139
+ time: new Date().getTime()
140
+ });
128
141
  }
129
142
  break;
130
143
  case that.Message.Type.Emoticon:
@@ -148,7 +161,7 @@ async function dispatchRoomFilterByMsgType(that, room, msg) {
148
161
  }
149
162
  }
150
163
  catch (e) {
151
- console.log('error', e);
164
+ console.log("error", e);
152
165
  }
153
166
  }
154
167
  async function onMessage(msg) {
@@ -164,7 +177,7 @@ async function onMessage(msg) {
164
177
  const contact = msg.talker(); // 发消息人
165
178
  const contactName = contact.name();
166
179
  await dispatchRoomFilterByMsgType(this, room, msg);
167
- if (role === 'vip' && roomName !== contactName) {
180
+ if (role === "vip" && roomName !== contactName) {
168
181
  const roomAsyncList = config.roomAsyncList || [];
169
182
  if (roomAsyncList.length) {
170
183
  await (0, room_async_service_js_1.dispatchAsync)(this, msg, roomAsyncList);
@@ -176,7 +189,7 @@ async function onMessage(msg) {
176
189
  }
177
190
  }
178
191
  catch (e) {
179
- console.log('监听消息失败', e);
192
+ console.log("监听消息失败", e);
180
193
  }
181
194
  }
182
195
  exports.default = onMessage;
@@ -12,7 +12,7 @@ const userDb_js_1 = require("../db/userDb.js");
12
12
  */
13
13
  async function onReady() {
14
14
  try {
15
- const userInfo = await (0, userDb_js_1.getUser)();
15
+ await (0, userDb_js_1.getUser)();
16
16
  console.log(`所有数据准备完毕`);
17
17
  await (0, aibotk_js_1.sendHeartBeat)('live');
18
18
  await index_js_1.default.updateContactInfo(this);
@@ -6,7 +6,7 @@ exports.packageJson = void 0;
6
6
  */
7
7
  exports.packageJson = {
8
8
  "name": "wechaty-web-panel",
9
- "version": "1.1.11",
9
+ "version": "1.2.0",
10
10
  "description": "",
11
11
  "exports": {
12
12
  ".": {
@@ -175,9 +175,7 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
175
175
  const replys = [];
176
176
  multiList.forEach((item) => {
177
177
  item = item.replace(/<\/?.+?\/?>/g, '');
178
- console.log('item', item);
179
178
  const reply = getFormatReply(item, resData.options || [], userInfo, config.puppetType);
180
- console.log('reply', reply);
181
179
  replys.push(...reply);
182
180
  });
183
181
  return replys;
@@ -190,13 +188,14 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
190
188
  else if (resData.answer_type === 'music') {
191
189
  // web 端协议以文字和图片的形式发送
192
190
  if (config.puppetType === 'wechaty-puppet-wechat') {
193
- const music = resData.msg[0];
194
- const musicContent = `【歌名】:《${music && music.song_name}》\n【歌手】:${music && music.singer_name}\n【听歌地址】:${music && music.music_url}`;
195
- const musicPic = music && music.pic_url;
191
+ const res = JSON.parse(resData.answer);
192
+ const music = res.news.articles[0];
193
+ const musicContent = `【歌名】:《${music && music.title}》\n【听歌地址】:${music && music.url}`;
194
+ const musicPic = music && music.picurl;
196
195
  return [
197
196
  {
198
197
  type: 1,
199
- content: resData.answer + '\n\n' + musicContent,
198
+ content: musicContent,
200
199
  },
201
200
  {
202
201
  type: 2,
@@ -208,11 +207,7 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
208
207
  // 其他协议可以发链接的用H5卡片发送
209
208
  const music = resData.msg[0];
210
209
  return [
211
- {
212
- type: 1,
213
- content: resData.answer,
214
- },
215
- { type: 4, url: music.music_url, title: music.song_name, thumbnailUrl: music.pic_url, description: music.singer_name },
210
+ { type: 4, url: music.url, title: music.title, thumbnailUrl: music.picurl, description: music.description },
216
211
  ];
217
212
  }
218
213
  }
@@ -24,5 +24,5 @@ export function filterFriendMsg(that: any, contact: Object, msg: string): number
24
24
  * 1 开启了好友验证 || 朋友推荐消息 || 发送的文字消息过长,大于40个字符
25
25
  * 2 初次添加好友
26
26
  */
27
- export function filterRoomMsg(that: any, msg: any, name: any, id: any, avatar: any, room: any): number;
27
+ export function filterRoomMsg({ that, msg, name, id, avatar, room, isMention }: any): number;
28
28
  //# sourceMappingURL=msg-filter-service.d.ts.map
@@ -10,13 +10,13 @@ const WEIXINOFFICIAL = ['朋友推荐消息', '微信支付', '微信运动', '
10
10
  const DELETEFRIEND = '开启了朋友验证'; // 被人删除后,防止重复回复
11
11
  const REMINDKEY = '提醒';
12
12
  const NEWADDFRIEND = '你已添加';
13
- async function getMsgReply(resArray, { that, msg, name, contact, config, avatar, id, room }) {
13
+ async function getMsgReply(resArray, { that, msg, name, contact, config, avatar, id, room, isMention }) {
14
14
  try {
15
15
  let msgArr = [];
16
16
  for (let i = 0; i < resArray.length; i++) {
17
17
  const item = resArray[i];
18
18
  if (item.bool) {
19
- msgArr = (await msg_filters_js_1.default[item.method]({ that, msg, name, contact, config, avatar, id, room })) || [];
19
+ msgArr = (await msg_filters_js_1.default[item.method]({ that, msg, name, contact, config, avatar, id, room, isMention })) || [];
20
20
  }
21
21
  if (msgArr.length > 0) {
22
22
  return msgArr;
@@ -40,7 +40,6 @@ async function getMsgReply(resArray, { that, msg, name, contact, config, avatar,
40
40
  async function filterFriendMsg(that, contact, msg) {
41
41
  try {
42
42
  const config = await (0, configDb_js_1.allConfig)(); // 获取配置信息
43
- console.log('callback', config.callBackEvents);
44
43
  const name = contact.name();
45
44
  const id = contact.id;
46
45
  const avatar = await contact.avatar();
@@ -76,7 +75,7 @@ exports.filterFriendMsg = filterFriendMsg;
76
75
  * 1 开启了好友验证 || 朋友推荐消息 || 发送的文字消息过长,大于40个字符
77
76
  * 2 初次添加好友
78
77
  */
79
- async function filterRoomMsg(that, msg, name, id, avatar, room) {
78
+ async function filterRoomMsg({ that, msg, name, id, avatar, room, isMention }) {
80
79
  try {
81
80
  const config = await (0, configDb_js_1.allConfig)(); // 获取配置信息
82
81
  const resArray = [
@@ -87,7 +86,7 @@ async function filterRoomMsg(that, msg, name, id, avatar, room) {
87
86
  { bool: true, method: 'keywordsMsg' },
88
87
  { bool: config.autoReply, method: 'robotMsg' },
89
88
  ];
90
- const msgArr = await getMsgReply(resArray, { that, msg, name, config, avatar, id, room });
89
+ const msgArr = await getMsgReply(resArray, { that, msg, name, config, avatar, id, room, isMention });
91
90
  return msgArr.length > 0 ? msgArr : [{ type: 1, content: '', url: '' }];
92
91
  }
93
92
  catch (e) {
@@ -21,13 +21,14 @@ export default _default;
21
21
  * @param room
22
22
  * @returns Promise
23
23
  */
24
- export function callbackEvent({ that, msg, name, id, config, room }: {
24
+ export function callbackEvent({ that, msg, name, id, config, room, isMention }: {
25
25
  that: any;
26
26
  msg: any;
27
27
  name: any;
28
28
  id: any;
29
29
  config: any;
30
30
  room: any;
31
+ isMention: any;
31
32
  }): Promise<never[] | import("axios").AxiosResponse<any, any>>;
32
33
  /**
33
34
  * 头像处理
@@ -72,7 +73,7 @@ export function scheduleJobMsg({ that, msg, name }: {
72
73
  msg: any;
73
74
  name: any;
74
75
  }): Promise<any>;
75
- export function eventMsg({ that, msg, name, id, avatar, config, room }: {
76
+ export function eventMsg({ that, msg, name, id, avatar, config, room, isMention }: {
76
77
  that: any;
77
78
  msg: any;
78
79
  name: any;
@@ -80,19 +81,24 @@ export function eventMsg({ that, msg, name, id, avatar, config, room }: {
80
81
  avatar: any;
81
82
  config: any;
82
83
  room: any;
84
+ isMention: any;
83
85
  }): Promise<string | never[]>;
84
86
  /**
85
87
  * 关键词回复
86
88
  * @returns {Promise<*>}
87
89
  */
88
- export function keywordsMsg({ msg, config }: {
90
+ export function keywordsMsg({ msg, config, room, isMention }: {
89
91
  msg: any;
90
92
  config: any;
93
+ room: any;
94
+ isMention: any;
91
95
  }): Promise<any>;
92
- export function robotMsg({ msg, name, id, config }: {
96
+ export function robotMsg({ msg, name, id, config, isMention, room }: {
93
97
  msg: any;
94
98
  name: any;
95
99
  id: any;
96
100
  config: any;
101
+ isMention: any;
102
+ room: any;
97
103
  }): Promise<any[]>;
98
104
  //# sourceMappingURL=msg-filters.d.ts.map
@@ -147,11 +147,15 @@ async function getEventReply(that, event, msg, name, id, avatar, room) {
147
147
  * @param room
148
148
  * @returns Promise
149
149
  */
150
- async function callbackEvent({ that, msg, name, id, config, room }) {
150
+ async function callbackEvent({ that, msg, name, id, config, room, isMention }) {
151
151
  try {
152
152
  for (let item of config.callBackEvents) {
153
153
  for (let key of item.keywords) {
154
154
  if ((item.reg === 1 && msg.includes(key)) || (item.reg === 2 && msg === key)) {
155
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
156
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
157
+ return [];
158
+ }
155
159
  msg = msg.trim();
156
160
  const data = {
157
161
  uid: id,
@@ -181,11 +185,15 @@ async function callbackEvent({ that, msg, name, id, config, room }) {
181
185
  }
182
186
  }
183
187
  exports.callbackEvent = callbackEvent;
184
- async function eventMsg({ that, msg, name, id, avatar, config, room }) {
188
+ async function eventMsg({ that, msg, name, id, avatar, config, room, isMention }) {
185
189
  try {
186
190
  for (let item of config.eventKeywords) {
187
191
  for (let key of item.keywords) {
188
192
  if ((item.reg === 1 && msg.includes(key)) || (item.reg === 2 && msg === key)) {
193
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
194
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
195
+ return [];
196
+ }
189
197
  msg = msg.replace(key, '');
190
198
  let res = await getEventReply(that, item.event, msg, name, id, avatar, room);
191
199
  return res;
@@ -204,17 +212,25 @@ exports.eventMsg = eventMsg;
204
212
  * 关键词回复
205
213
  * @returns {Promise<*>}
206
214
  */
207
- async function keywordsMsg({ msg, config }) {
215
+ async function keywordsMsg({ msg, config, room, isMention }) {
208
216
  try {
209
217
  if (config.replyKeywords && config.replyKeywords.length > 0) {
210
218
  for (let item of config.replyKeywords) {
211
219
  if (item.reg === 2 && item.keywords.includes(msg)) {
220
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
221
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
222
+ return [];
223
+ }
212
224
  console.log(`精确匹配到关键词${msg},正在回复用户`);
213
225
  return item.replys;
214
226
  }
215
227
  else if (item.reg === 1) {
216
228
  for (let key of item.keywords) {
217
229
  if (msg.includes(key)) {
230
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
231
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
232
+ return [];
233
+ }
218
234
  console.log(`模糊匹配到关键词${msg},正在回复用户`);
219
235
  return item.replys;
220
236
  }
@@ -232,22 +248,28 @@ async function keywordsMsg({ msg, config }) {
232
248
  }
233
249
  }
234
250
  exports.keywordsMsg = keywordsMsg;
235
- async function robotMsg({ msg, name, id, config }) {
236
- try {
237
- let msgArr = []; // 返回的消息列表
238
- if (config.autoReply) {
239
- console.log('开启了机器人自动回复功能');
240
- msgArr = await event_dispatch_service_js_1.default.dispatchAiBot(config.defaultBot, msg, name, id);
251
+ async function robotMsg({ msg, name, id, config, isMention, room }) {
252
+ // 如果群里没有提及不开启机器人聊天
253
+ if (room && !isMention) {
254
+ return [];
255
+ }
256
+ else {
257
+ try {
258
+ let msgArr = []; // 返回的消息列表
259
+ if (config.autoReply) {
260
+ console.log('开启了机器人自动回复功能');
261
+ msgArr = await event_dispatch_service_js_1.default.dispatchAiBot(config.defaultBot, msg, name, id);
262
+ }
263
+ else {
264
+ console.log('没有开启机器人自动回复功能');
265
+ msgArr = [{ type: 1, content: '', url: '' }];
266
+ }
267
+ return msgArr;
241
268
  }
242
- else {
243
- console.log('没有开启机器人自动回复功能');
244
- msgArr = [{ type: 1, content: '', url: '' }];
269
+ catch (e) {
270
+ console.log('robotMsg error:', e);
271
+ return [];
245
272
  }
246
- return msgArr;
247
- }
248
- catch (e) {
249
- console.log('robotMsg error:', e);
250
- return [];
251
273
  }
252
274
  }
253
275
  exports.robotMsg = robotMsg;
@@ -102,7 +102,7 @@ exports.sendRoomTaskMessage = sendRoomTaskMessage;
102
102
  async function setEveryDayTask(that, item, name) {
103
103
  try {
104
104
  let time = item.date;
105
- let contact = (await that.Contact.find({ alias: item.alias })) || (await that.Contact.find({ name: item.name })); // 获取你要发送的联系人
105
+ let contact = item.name && (await that.Contact.find({ name: item.name })) || item.alias && (await that.Contact.find({ alias: item.alias })); // 获取你要发送的联系人
106
106
  if (!contact) {
107
107
  console.log(`查找不到用户昵称为'${item.name}'或备注为'${item.alias}'的用户,请检查设置用户是否正确`);
108
108
  return;
@@ -129,7 +129,7 @@ async function setEveryDayTask(that, item, name) {
129
129
  async function sendContactTaskMessage(that, info) {
130
130
  try {
131
131
  const item = info.message;
132
- let contact = (await that.Contact.find({ alias: item.alias })) || (await that.Contact.find({ name: item.name })); // 获取你要发送的联系人
132
+ let contact = item.name && (await that.Contact.find({ name: item.name })) || item.alias && (await that.Contact.find({ alias: item.alias })); // 获取你要发送的联系人
133
133
  if (!contact) {
134
134
  console.log(`查找不到用户昵称为'${item.name}'或备注为'${item.alias}'的用户,请检查设置用户是否正确`);
135
135
  return;
@@ -8,7 +8,7 @@ export function getContactTextReply(that: any, contact: any, msg: any): Promise<
8
8
  * @param {*} name 发消息者昵称
9
9
  * @param {*} id 发消息者id
10
10
  */
11
- export function getRoomTextReply(that: any, content: any, name: any, id: any, avatar: any, room: any): Promise<number>;
11
+ export function getRoomTextReply({ that, content, name, id, avatar, room, isMention }: any): Promise<number>;
12
12
  declare namespace _default {
13
13
  export { getContactTextReply };
14
14
  export { getRoomTextReply };
@@ -12,8 +12,8 @@ export async function getContactTextReply(that, contact, msg) {
12
12
  * @param {*} name 发消息者昵称
13
13
  * @param {*} id 发消息者id
14
14
  */
15
- export async function getRoomTextReply(that, content, name, id, avatar, room) {
16
- let result = await service.filterRoomMsg(that, content, name, id, avatar, room);
15
+ export async function getRoomTextReply({ that, content, name, id, avatar, room, isMention }) {
16
+ let result = await service.filterRoomMsg({ that, msg: content, name, id, avatar, room, isMention });
17
17
  return result;
18
18
  }
19
19
  export default {
@@ -24,10 +24,15 @@ async function onLogin(user) {
24
24
  };
25
25
  await addUser(userInfo); // 全局存储登录用户信息
26
26
  const file = await user.avatar();
27
- const base = await file.toBase64();
28
- const avatarUrl = await putqn(base, userId);
29
- await sendRobotInfo(avatarUrl, user.name(), userInfo.robotId); // 更新用户头像
30
- await delay(3000);
27
+ if (file) {
28
+ const base = await file.toBase64();
29
+ const avatarUrl = await putqn(base, userId);
30
+ await sendRobotInfo(avatarUrl, user.name(), userInfo.robotId); // 更新用户头像
31
+ await delay(1000);
32
+ }
33
+ else {
34
+ console.log('头像未获取到,不影响项目正常使用');
35
+ }
31
36
  await initAllSchedule(this); // 初始化任务
32
37
  await initMqtt(this); // 初始化mqtt任务
33
38
  }
@@ -1,14 +1,14 @@
1
- import { contactSay, roomSay } from '../common/index.js';
2
- import { getContactTextReply, 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';
1
+ import { contactSay, roomSay } from "../common/index.js";
2
+ import { getContactTextReply, 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
8
  const ignoreRecord = [
9
9
  { type: "include", word: "加入了群聊" },
10
10
  { type: "include", word: "与群里其他人都不是朋友关系" },
11
- { type: "include", word: "收到一条暂不支持的消息类型" },
11
+ { type: "include", word: "收到一条暂不支持的消息类型" }
12
12
  ];
13
13
  /**
14
14
  * 检测是否属于忽略的消息
@@ -21,7 +21,7 @@ function checkIgnore(msg, list) {
21
21
  for (let item of list) {
22
22
  const word = item.word;
23
23
  const type = item.type;
24
- if ((type === 'start' && msg.startsWith(word)) || (type === 'end' && msg.endsWith(word)) || (type === 'equal' && msg === word) || (type === 'include' && msg.includes(word))) {
24
+ if ((type === "start" && msg.startsWith(word)) || (type === "end" && msg.endsWith(word)) || (type === "equal" && msg === word) || (type === "include" && msg.includes(word))) {
25
25
  return true;
26
26
  }
27
27
  }
@@ -38,7 +38,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
38
38
  const type = msg.type();
39
39
  const contact = msg.talker(); // 发消息人
40
40
  const isOfficial = contact.type() === that.Contact.Type.Official;
41
- let content = '';
41
+ let content = "";
42
42
  let replys = [];
43
43
  switch (type) {
44
44
  case that.Message.Type.Text:
@@ -55,7 +55,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
55
55
  }
56
56
  }
57
57
  else {
58
- console.log('公众号消息');
58
+ console.log("公众号消息");
59
59
  }
60
60
  break;
61
61
  case that.Message.Type.Emoticon:
@@ -78,7 +78,7 @@ async function dispatchFriendFilterByMsgType(that, msg) {
78
78
  }
79
79
  }
80
80
  catch (error) {
81
- console.log('监听消息错误', error);
81
+ console.log("监听消息错误", error);
82
82
  }
83
83
  }
84
84
  /**
@@ -97,32 +97,45 @@ async function dispatchRoomFilterByMsgType(that, room, msg) {
97
97
  const roomName = await room.topic();
98
98
  const type = msg.type();
99
99
  const userSelfName = that.currentUser?.name() || that.userSelf()?.name();
100
- let content = '';
101
- let replys = '';
102
- let contactId = contact.id || '111';
100
+ let content = "";
101
+ let replys = "";
102
+ let contactId = contact.id || "111";
103
103
  let contactAvatar = await contact.avatar();
104
104
  switch (type) {
105
105
  case that.Message.Type.Text:
106
106
  content = msg.text();
107
107
  console.log(`群名: ${roomName} 发消息人: ${contactName} 内容: ${content}`);
108
108
  const mentionSelf = content.includes(`@${userSelfName}`);
109
- if (mentionSelf) {
110
- content = content.replace(/@[^,,::\s@]+/g, '').trim();
111
- // 检测是否需要这条消息
112
- const isIgnore = checkIgnore(content, aibotConfig.ignoreMessages);
113
- if (isIgnore)
114
- return;
115
- replys = await getRoomTextReply(that, content, contactName, contactId, contactAvatar, room);
116
- for (let reply of replys) {
117
- await delay(1000);
118
- await roomSay.call(that, room, contact, reply);
119
- }
109
+ content = content.replace(/@[^,,::\s@]+/g, "").trim();
110
+ // 检测是否需要这条消息
111
+ const isIgnore = checkIgnore(content, aibotConfig.ignoreMessages);
112
+ if (isIgnore)
113
+ return;
114
+ replys = await getRoomTextReply({
115
+ that,
116
+ content,
117
+ name: contactName,
118
+ id: contactId,
119
+ avatar: contactAvatar,
120
+ room,
121
+ isMention: mentionSelf
122
+ });
123
+ for (let reply of replys) {
124
+ await delay(1000);
125
+ await roomSay.call(that, room, contact, reply);
120
126
  }
121
127
  const cloudRoom = config.cloudRoom;
122
- if (role === 'vip' && cloudRoom.includes(roomName) && !checkIgnore(content, ignoreRecord)) {
128
+ if (role === "vip" && cloudRoom.includes(roomName) && !checkIgnore(content, ignoreRecord)) {
123
129
  const regex = /(<([^>]+)>)/ig;
124
130
  content = content.replace(regex, "");
125
- addRoomRecord({ roomName, roomId: room.id, content, contact: contactName, wxid: contactId, time: new Date().getTime() });
131
+ addRoomRecord({
132
+ roomName,
133
+ roomId: room.id,
134
+ content,
135
+ contact: contactName,
136
+ wxid: contactId,
137
+ time: new Date().getTime()
138
+ });
126
139
  }
127
140
  break;
128
141
  case that.Message.Type.Emoticon:
@@ -146,7 +159,7 @@ async function dispatchRoomFilterByMsgType(that, room, msg) {
146
159
  }
147
160
  }
148
161
  catch (e) {
149
- console.log('error', e);
162
+ console.log("error", e);
150
163
  }
151
164
  }
152
165
  async function onMessage(msg) {
@@ -162,7 +175,7 @@ async function onMessage(msg) {
162
175
  const contact = msg.talker(); // 发消息人
163
176
  const contactName = contact.name();
164
177
  await dispatchRoomFilterByMsgType(this, room, msg);
165
- if (role === 'vip' && roomName !== contactName) {
178
+ if (role === "vip" && roomName !== contactName) {
166
179
  const roomAsyncList = config.roomAsyncList || [];
167
180
  if (roomAsyncList.length) {
168
181
  await dispatchAsync(this, msg, roomAsyncList);
@@ -174,7 +187,7 @@ async function onMessage(msg) {
174
187
  }
175
188
  }
176
189
  catch (e) {
177
- console.log('监听消息失败', e);
190
+ console.log("监听消息失败", e);
178
191
  }
179
192
  }
180
193
  export default onMessage;
@@ -7,7 +7,7 @@ import { getUser } from '../db/userDb.js';
7
7
  */
8
8
  async function onReady() {
9
9
  try {
10
- const userInfo = await getUser();
10
+ await getUser();
11
11
  console.log(`所有数据准备完毕`);
12
12
  await sendHeartBeat('live');
13
13
  await common.updateContactInfo(this);
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const packageJson = {
5
5
  "name": "wechaty-web-panel",
6
- "version": "1.1.11",
6
+ "version": "1.2.0",
7
7
  "description": "",
8
8
  "exports": {
9
9
  ".": {
@@ -169,9 +169,7 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
169
169
  const replys = [];
170
170
  multiList.forEach((item) => {
171
171
  item = item.replace(/<\/?.+?\/?>/g, '');
172
- console.log('item', item);
173
172
  const reply = getFormatReply(item, resData.options || [], userInfo, config.puppetType);
174
- console.log('reply', reply);
175
173
  replys.push(...reply);
176
174
  });
177
175
  return replys;
@@ -184,13 +182,14 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
184
182
  else if (resData.answer_type === 'music') {
185
183
  // web 端协议以文字和图片的形式发送
186
184
  if (config.puppetType === 'wechaty-puppet-wechat') {
187
- const music = resData.msg[0];
188
- const musicContent = `【歌名】:《${music && music.song_name}》\n【歌手】:${music && music.singer_name}\n【听歌地址】:${music && music.music_url}`;
189
- const musicPic = music && music.pic_url;
185
+ const res = JSON.parse(resData.answer);
186
+ const music = res.news.articles[0];
187
+ const musicContent = `【歌名】:《${music && music.title}》\n【听歌地址】:${music && music.url}`;
188
+ const musicPic = music && music.picurl;
190
189
  return [
191
190
  {
192
191
  type: 1,
193
- content: resData.answer + '\n\n' + musicContent,
192
+ content: musicContent,
194
193
  },
195
194
  {
196
195
  type: 2,
@@ -202,11 +201,7 @@ async function getTencentOpenReply({ msg, id, userInfo }) {
202
201
  // 其他协议可以发链接的用H5卡片发送
203
202
  const music = resData.msg[0];
204
203
  return [
205
- {
206
- type: 1,
207
- content: resData.answer,
208
- },
209
- { type: 4, url: music.music_url, title: music.song_name, thumbnailUrl: music.pic_url, description: music.singer_name },
204
+ { type: 4, url: music.url, title: music.title, thumbnailUrl: music.picurl, description: music.description },
210
205
  ];
211
206
  }
212
207
  }
@@ -24,5 +24,5 @@ export function filterFriendMsg(that: any, contact: Object, msg: string): number
24
24
  * 1 开启了好友验证 || 朋友推荐消息 || 发送的文字消息过长,大于40个字符
25
25
  * 2 初次添加好友
26
26
  */
27
- export function filterRoomMsg(that: any, msg: any, name: any, id: any, avatar: any, room: any): number;
27
+ export function filterRoomMsg({ that, msg, name, id, avatar, room, isMention }: any): number;
28
28
  //# sourceMappingURL=msg-filter-service.d.ts.map
@@ -4,13 +4,13 @@ const WEIXINOFFICIAL = ['朋友推荐消息', '微信支付', '微信运动', '
4
4
  const DELETEFRIEND = '开启了朋友验证'; // 被人删除后,防止重复回复
5
5
  const REMINDKEY = '提醒';
6
6
  const NEWADDFRIEND = '你已添加';
7
- async function getMsgReply(resArray, { that, msg, name, contact, config, avatar, id, room }) {
7
+ async function getMsgReply(resArray, { that, msg, name, contact, config, avatar, id, room, isMention }) {
8
8
  try {
9
9
  let msgArr = [];
10
10
  for (let i = 0; i < resArray.length; i++) {
11
11
  const item = resArray[i];
12
12
  if (item.bool) {
13
- msgArr = (await msgFilter[item.method]({ that, msg, name, contact, config, avatar, id, room })) || [];
13
+ msgArr = (await msgFilter[item.method]({ that, msg, name, contact, config, avatar, id, room, isMention })) || [];
14
14
  }
15
15
  if (msgArr.length > 0) {
16
16
  return msgArr;
@@ -34,7 +34,6 @@ async function getMsgReply(resArray, { that, msg, name, contact, config, avatar,
34
34
  async function filterFriendMsg(that, contact, msg) {
35
35
  try {
36
36
  const config = await allConfig(); // 获取配置信息
37
- console.log('callback', config.callBackEvents);
38
37
  const name = contact.name();
39
38
  const id = contact.id;
40
39
  const avatar = await contact.avatar();
@@ -69,7 +68,7 @@ async function filterFriendMsg(that, contact, msg) {
69
68
  * 1 开启了好友验证 || 朋友推荐消息 || 发送的文字消息过长,大于40个字符
70
69
  * 2 初次添加好友
71
70
  */
72
- async function filterRoomMsg(that, msg, name, id, avatar, room) {
71
+ async function filterRoomMsg({ that, msg, name, id, avatar, room, isMention }) {
73
72
  try {
74
73
  const config = await allConfig(); // 获取配置信息
75
74
  const resArray = [
@@ -80,7 +79,7 @@ async function filterRoomMsg(that, msg, name, id, avatar, room) {
80
79
  { bool: true, method: 'keywordsMsg' },
81
80
  { bool: config.autoReply, method: 'robotMsg' },
82
81
  ];
83
- const msgArr = await getMsgReply(resArray, { that, msg, name, config, avatar, id, room });
82
+ const msgArr = await getMsgReply(resArray, { that, msg, name, config, avatar, id, room, isMention });
84
83
  return msgArr.length > 0 ? msgArr : [{ type: 1, content: '', url: '' }];
85
84
  }
86
85
  catch (e) {
@@ -21,13 +21,14 @@ export default _default;
21
21
  * @param room
22
22
  * @returns Promise
23
23
  */
24
- export function callbackEvent({ that, msg, name, id, config, room }: {
24
+ export function callbackEvent({ that, msg, name, id, config, room, isMention }: {
25
25
  that: any;
26
26
  msg: any;
27
27
  name: any;
28
28
  id: any;
29
29
  config: any;
30
30
  room: any;
31
+ isMention: any;
31
32
  }): Promise<never[] | import("axios").AxiosResponse<any, any>>;
32
33
  /**
33
34
  * 头像处理
@@ -72,7 +73,7 @@ export function scheduleJobMsg({ that, msg, name }: {
72
73
  msg: any;
73
74
  name: any;
74
75
  }): Promise<any>;
75
- export function eventMsg({ that, msg, name, id, avatar, config, room }: {
76
+ export function eventMsg({ that, msg, name, id, avatar, config, room, isMention }: {
76
77
  that: any;
77
78
  msg: any;
78
79
  name: any;
@@ -80,19 +81,24 @@ export function eventMsg({ that, msg, name, id, avatar, config, room }: {
80
81
  avatar: any;
81
82
  config: any;
82
83
  room: any;
84
+ isMention: any;
83
85
  }): Promise<string | never[]>;
84
86
  /**
85
87
  * 关键词回复
86
88
  * @returns {Promise<*>}
87
89
  */
88
- export function keywordsMsg({ msg, config }: {
90
+ export function keywordsMsg({ msg, config, room, isMention }: {
89
91
  msg: any;
90
92
  config: any;
93
+ room: any;
94
+ isMention: any;
91
95
  }): Promise<any>;
92
- export function robotMsg({ msg, name, id, config }: {
96
+ export function robotMsg({ msg, name, id, config, isMention, room }: {
93
97
  msg: any;
94
98
  name: any;
95
99
  id: any;
96
100
  config: any;
101
+ isMention: any;
102
+ room: any;
97
103
  }): Promise<any[]>;
98
104
  //# sourceMappingURL=msg-filters.d.ts.map
@@ -136,11 +136,15 @@ async function getEventReply(that, event, msg, name, id, avatar, room) {
136
136
  * @param room
137
137
  * @returns Promise
138
138
  */
139
- async function callbackEvent({ that, msg, name, id, config, room }) {
139
+ async function callbackEvent({ that, msg, name, id, config, room, isMention }) {
140
140
  try {
141
141
  for (let item of config.callBackEvents) {
142
142
  for (let key of item.keywords) {
143
143
  if ((item.reg === 1 && msg.includes(key)) || (item.reg === 2 && msg === key)) {
144
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
145
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
146
+ return [];
147
+ }
144
148
  msg = msg.trim();
145
149
  const data = {
146
150
  uid: id,
@@ -169,11 +173,15 @@ async function callbackEvent({ that, msg, name, id, config, room }) {
169
173
  return [];
170
174
  }
171
175
  }
172
- async function eventMsg({ that, msg, name, id, avatar, config, room }) {
176
+ async function eventMsg({ that, msg, name, id, avatar, config, room, isMention }) {
173
177
  try {
174
178
  for (let item of config.eventKeywords) {
175
179
  for (let key of item.keywords) {
176
180
  if ((item.reg === 1 && msg.includes(key)) || (item.reg === 2 && msg === key)) {
181
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
182
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
183
+ return [];
184
+ }
177
185
  msg = msg.replace(key, '');
178
186
  let res = await getEventReply(that, item.event, msg, name, id, avatar, room);
179
187
  return res;
@@ -191,17 +199,25 @@ async function eventMsg({ that, msg, name, id, avatar, config, room }) {
191
199
  * 关键词回复
192
200
  * @returns {Promise<*>}
193
201
  */
194
- async function keywordsMsg({ msg, config }) {
202
+ async function keywordsMsg({ msg, config, room, isMention }) {
195
203
  try {
196
204
  if (config.replyKeywords && config.replyKeywords.length > 0) {
197
205
  for (let item of config.replyKeywords) {
198
206
  if (item.reg === 2 && item.keywords.includes(msg)) {
207
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
208
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
209
+ return [];
210
+ }
199
211
  console.log(`精确匹配到关键词${msg},正在回复用户`);
200
212
  return item.replys;
201
213
  }
202
214
  else if (item.reg === 1) {
203
215
  for (let key of item.keywords) {
204
216
  if (msg.includes(key)) {
217
+ // 如果匹配到关键词 群消息要求是必须@,但是没@ 就不需要回复
218
+ if (room && item.needAt === 1 && !isMention || room && item.needAt === undefined && !isMention) {
219
+ return [];
220
+ }
205
221
  console.log(`模糊匹配到关键词${msg},正在回复用户`);
206
222
  return item.replys;
207
223
  }
@@ -218,22 +234,28 @@ async function keywordsMsg({ msg, config }) {
218
234
  return [];
219
235
  }
220
236
  }
221
- async function robotMsg({ msg, name, id, config }) {
222
- try {
223
- let msgArr = []; // 返回的消息列表
224
- if (config.autoReply) {
225
- console.log('开启了机器人自动回复功能');
226
- msgArr = await dispatch.dispatchAiBot(config.defaultBot, msg, name, id);
237
+ async function robotMsg({ msg, name, id, config, isMention, room }) {
238
+ // 如果群里没有提及不开启机器人聊天
239
+ if (room && !isMention) {
240
+ return [];
241
+ }
242
+ else {
243
+ try {
244
+ let msgArr = []; // 返回的消息列表
245
+ if (config.autoReply) {
246
+ console.log('开启了机器人自动回复功能');
247
+ msgArr = await dispatch.dispatchAiBot(config.defaultBot, msg, name, id);
248
+ }
249
+ else {
250
+ console.log('没有开启机器人自动回复功能');
251
+ msgArr = [{ type: 1, content: '', url: '' }];
252
+ }
253
+ return msgArr;
227
254
  }
228
- else {
229
- console.log('没有开启机器人自动回复功能');
230
- msgArr = [{ type: 1, content: '', url: '' }];
255
+ catch (e) {
256
+ console.log('robotMsg error:', e);
257
+ return [];
231
258
  }
232
- return msgArr;
233
- }
234
- catch (e) {
235
- console.log('robotMsg error:', e);
236
- return [];
237
259
  }
238
260
  }
239
261
  /**
@@ -98,7 +98,7 @@ async function sendRoomTaskMessage(that, info) {
98
98
  async function setEveryDayTask(that, item, name) {
99
99
  try {
100
100
  let time = item.date;
101
- let contact = (await that.Contact.find({ alias: item.alias })) || (await that.Contact.find({ name: item.name })); // 获取你要发送的联系人
101
+ let contact = item.name && (await that.Contact.find({ name: item.name })) || item.alias && (await that.Contact.find({ alias: item.alias })); // 获取你要发送的联系人
102
102
  if (!contact) {
103
103
  console.log(`查找不到用户昵称为'${item.name}'或备注为'${item.alias}'的用户,请检查设置用户是否正确`);
104
104
  return;
@@ -125,7 +125,7 @@ async function setEveryDayTask(that, item, name) {
125
125
  async function sendContactTaskMessage(that, info) {
126
126
  try {
127
127
  const item = info.message;
128
- let contact = (await that.Contact.find({ alias: item.alias })) || (await that.Contact.find({ name: item.name })); // 获取你要发送的联系人
128
+ let contact = item.name && (await that.Contact.find({ name: item.name })) || item.alias && (await that.Contact.find({ alias: item.alias })); // 获取你要发送的联系人
129
129
  if (!contact) {
130
130
  console.log(`查找不到用户昵称为'${item.name}'或备注为'${item.alias}'的用户,请检查设置用户是否正确`);
131
131
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wechaty-web-panel",
3
- "version": "1.1.11",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "exports": {
6
6
  ".": {
@@ -72,7 +72,7 @@
72
72
  },
73
73
  "publishConfig": {
74
74
  "registry": " https://registry.npmjs.org/",
75
- "tag": "next",
75
+ "tag": "latest",
76
76
  "access": "public"
77
77
  },
78
78
  "_id": "wechaty-web-panel@1.0.6",