wechaty-web-panel 1.0.0 → 1.0.3-beta.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/.idea/workspace.xml +16 -14
- package/CHANGELOG.md +8 -0
- package/README.md +1 -1
- package/package.json +5 -13
- package/src/common/index.js +8 -3
- package/src/handlers/on-login.js +3 -3
- package/src/lib/index.js +3 -227
- package/src/puppeteer-paint/drawHelp.js +237 -0
- package/src/puppeteer-paint/index.js +37 -0
- package/src/puppeteer-paint/lanuch.js +38 -0
- package/src/puppeteer-paint/mainConfig.js +8 -0
- package/src/service/event-dispatch-service.js +6 -5
- package/src/service/msg-filters.js +2 -1
- package/src/service/room-async-service.js +6 -24
package/.idea/workspace.xml
CHANGED
|
@@ -2,18 +2,8 @@
|
|
|
2
2
|
<project version="4">
|
|
3
3
|
<component name="ChangeListManager">
|
|
4
4
|
<list default="true" id="2e980355-75b9-47a9-b344-f25eda9493b2" name="Default Changelist" comment="feat(模块): 添加了个很棒的功能 fix(模块): 修复了一些 bug docs(模块): 更新了一下文档 UI(模块): 修改了一下样式 chore(模块): 对脚手架做了些更改 locale(模块): 为国际化做了微小的贡献">
|
|
5
|
-
<change afterPath="$PROJECT_DIR$/.npmrc" afterDir="false" />
|
|
6
|
-
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
|
7
5
|
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
|
8
|
-
<change beforePath="$PROJECT_DIR$/src/common/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/common/index.js" afterDir="false" />
|
|
9
|
-
<change beforePath="$PROJECT_DIR$/src/handlers/on-login.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/handlers/on-login.js" afterDir="false" />
|
|
10
|
-
<change beforePath="$PROJECT_DIR$/src/handlers/on-message.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/handlers/on-message.js" afterDir="false" />
|
|
11
|
-
<change beforePath="$PROJECT_DIR$/src/lib/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib/index.js" afterDir="false" />
|
|
12
|
-
<change beforePath="$PROJECT_DIR$/src/proxy/api.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/proxy/api.js" afterDir="false" />
|
|
13
|
-
<change beforePath="$PROJECT_DIR$/src/proxy/mqtt.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/proxy/mqtt.js" afterDir="false" />
|
|
14
|
-
<change beforePath="$PROJECT_DIR$/src/service/event-dispatch-service.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/service/event-dispatch-service.js" afterDir="false" />
|
|
15
6
|
<change beforePath="$PROJECT_DIR$/src/service/room-async-service.js" beforeDir="false" afterPath="$PROJECT_DIR$/src/service/room-async-service.js" afterDir="false" />
|
|
16
|
-
<change beforePath="$PROJECT_DIR$/test/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/test/index.js" afterDir="false" />
|
|
17
7
|
</list>
|
|
18
8
|
<option name="SHOW_DIALOG" value="false" />
|
|
19
9
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
@@ -46,7 +36,7 @@
|
|
|
46
36
|
</component>
|
|
47
37
|
<component name="PropertiesComponent">
|
|
48
38
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
|
49
|
-
<property name="last_opened_file_path" value="$PROJECT_DIR
|
|
39
|
+
<property name="last_opened_file_path" value="$PROJECT_DIR$/test" />
|
|
50
40
|
<property name="node.js.detected.package.eslint" value="true" />
|
|
51
41
|
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
|
52
42
|
<property name="nodejs_package_manager_path" value="npm" />
|
|
@@ -57,11 +47,11 @@
|
|
|
57
47
|
</component>
|
|
58
48
|
<component name="RecentsManager">
|
|
59
49
|
<key name="CopyFile.RECENT_KEYS">
|
|
60
|
-
<recent name="$PROJECT_DIR$" />
|
|
61
50
|
<recent name="$PROJECT_DIR$/test" />
|
|
51
|
+
<recent name="$PROJECT_DIR$/src/puppeteer-paint" />
|
|
52
|
+
<recent name="$PROJECT_DIR$" />
|
|
62
53
|
<recent name="$PROJECT_DIR$/koa/bash" />
|
|
63
54
|
<recent name="$PROJECT_DIR$/koa/pubilc/static" />
|
|
64
|
-
<recent name="$PROJECT_DIR$/koa/pubilc/static/img" />
|
|
65
55
|
</key>
|
|
66
56
|
</component>
|
|
67
57
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
|
|
@@ -107,7 +97,15 @@
|
|
|
107
97
|
<workItem from="1642212984216" duration="11645000" />
|
|
108
98
|
<workItem from="1642384832300" duration="994000" />
|
|
109
99
|
<workItem from="1642386021423" duration="4268000" />
|
|
110
|
-
<workItem from="1642647009185" duration="
|
|
100
|
+
<workItem from="1642647009185" duration="3937000" />
|
|
101
|
+
<workItem from="1642657426395" duration="780000" />
|
|
102
|
+
<workItem from="1642678719784" duration="603000" />
|
|
103
|
+
<workItem from="1643094529038" duration="490000" />
|
|
104
|
+
<workItem from="1644319873832" duration="1868000" />
|
|
105
|
+
<workItem from="1645362804718" duration="427000" />
|
|
106
|
+
<workItem from="1645411323461" duration="15523000" />
|
|
107
|
+
<workItem from="1645440841278" duration="516000" />
|
|
108
|
+
<workItem from="1645757384419" duration="1249000" />
|
|
111
109
|
</task>
|
|
112
110
|
<servers />
|
|
113
111
|
</component>
|
|
@@ -126,4 +124,8 @@
|
|
|
126
124
|
</option>
|
|
127
125
|
<option name="oldMeFiltersMigrated" value="true" />
|
|
128
126
|
</component>
|
|
127
|
+
<component name="XSLT-Support.FileAssociations.UIState">
|
|
128
|
+
<expand />
|
|
129
|
+
<select />
|
|
130
|
+
</component>
|
|
129
131
|
</project>
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -118,7 +118,7 @@ $ npm install wechaty-web-panel@latest wechaty@latest --save
|
|
|
118
118
|
如果安装长时间没有反应,可以尝试
|
|
119
119
|
|
|
120
120
|
```
|
|
121
|
-
npm install wechaty-web-panel@latest wechaty@latest --save
|
|
121
|
+
npm install wechaty-web-panel@latest wechaty@latest --save
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
### Step 2: 创建机器人并配置插件的`apiKey`和`apiSecret`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wechaty-web-panel",
|
|
3
|
-
"version": "1.0.0",
|
|
3
|
+
"version": "1.0.3-beta.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -36,32 +36,24 @@
|
|
|
36
36
|
"eslint-config-prettier": "^6.11.0",
|
|
37
37
|
"eslint-plugin-prettier": "^3.1.4",
|
|
38
38
|
"prettier": "^2.0.5",
|
|
39
|
-
"wechaty": "^1.
|
|
39
|
+
"wechaty": "^1.13.12",
|
|
40
40
|
"wechaty-puppet-wechat": "^1.11.12"
|
|
41
41
|
},
|
|
42
42
|
"readme": "README.md",
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"ix": "^4.5.2",
|
|
45
|
-
"mcanvas": "^2.0.8",
|
|
46
45
|
"mqtt": "^4.2.6",
|
|
47
46
|
"mustache": "^4.2.0",
|
|
48
47
|
"nedb": "^1.8.0",
|
|
49
48
|
"node-schedule": "^1.3.2",
|
|
49
|
+
"puppeteer": "^13.3.2",
|
|
50
50
|
"qrcode-terminal": "^0.12.0",
|
|
51
51
|
"superagent": "^5.2.2",
|
|
52
52
|
"tencentcloud-sdk-nodejs": "^4.0.30"
|
|
53
53
|
},
|
|
54
|
-
"peerDependencies": {
|
|
55
|
-
"wechaty": "^1.11.42",
|
|
56
|
-
"wechaty-puppet-wechat": "^1.11.12"
|
|
57
|
-
},
|
|
58
54
|
"publishConfig": {
|
|
59
55
|
"registry": " https://registry.npmjs.org/"
|
|
60
56
|
},
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
"npm": ">=8.1"
|
|
64
|
-
},
|
|
65
|
-
"_id": "wechaty-web-panel@1.0.0",
|
|
66
|
-
"_commitid": "754bf1b"
|
|
57
|
+
"_id": "wechaty-web-panel@1.0.3-beta.0",
|
|
58
|
+
"_commitid": "6714817"
|
|
67
59
|
}
|
package/src/common/index.js
CHANGED
|
@@ -42,9 +42,14 @@ async function updateContactInfo(that) {
|
|
|
42
42
|
const contactList = await that.Contact.findAll()
|
|
43
43
|
let res = []
|
|
44
44
|
const notids = ['filehelper', 'fmessage']
|
|
45
|
-
let realContact = hasWeixin
|
|
45
|
+
let realContact = hasWeixin
|
|
46
|
+
? contactList.filter((item) => {
|
|
47
|
+
const payload = item.payload || item._payload
|
|
48
|
+
return payload.type === 1 && payload.friend && !notids.includes(payload.id)
|
|
49
|
+
})
|
|
50
|
+
: contactList
|
|
46
51
|
for (let i of realContact) {
|
|
47
|
-
let contact = i._payload
|
|
52
|
+
let contact = i.payload || i._payload
|
|
48
53
|
let obj = {
|
|
49
54
|
robotId: hasWeixin ? contactSelf.weixin : MD5(contactSelf.name),
|
|
50
55
|
contactId: hasWeixin ? contact.id : MD5(contactSelf.name + contact.name + contact.alias + contact.province + contact.city + contact.gender),
|
|
@@ -92,7 +97,7 @@ async function updateRoomInfo(that) {
|
|
|
92
97
|
const roomList = await that.Room.findAll()
|
|
93
98
|
let res = []
|
|
94
99
|
for (let i of roomList) {
|
|
95
|
-
let room = i._payload
|
|
100
|
+
let room = i.payload || i._payload
|
|
96
101
|
let obj = {
|
|
97
102
|
robotId: hasWeixin ? contactSelf.weixin : MD5(contactSelf.name),
|
|
98
103
|
roomId: MD5(room.topic),
|
package/src/handlers/on-login.js
CHANGED
|
@@ -2,7 +2,6 @@ const { delay, MD5 } = require('../lib')
|
|
|
2
2
|
const { getConfig, sendRobotInfo, sendError, putqn, setQrCode, updatePanelVersion } = require('../proxy/aibotk')
|
|
3
3
|
const { addUser } = require('../common/userDb')
|
|
4
4
|
const { initAllSchedule } = require('../task')
|
|
5
|
-
var pjson = require('../../package.json')
|
|
6
5
|
const { initMqtt } = require('../proxy/mqtt')
|
|
7
6
|
const { allConfig } = require('../common/configDb')
|
|
8
7
|
|
|
@@ -19,9 +18,10 @@ async function onLogin(user) {
|
|
|
19
18
|
await getConfig() // 获取配置文件
|
|
20
19
|
const config = await allConfig()
|
|
21
20
|
const { userId } = config.userInfo
|
|
21
|
+
const payload = user.payload || user._payload
|
|
22
22
|
const userInfo = {
|
|
23
|
-
...
|
|
24
|
-
robotId:
|
|
23
|
+
...payload,
|
|
24
|
+
robotId: payload.weixin || MD5(user.name()),
|
|
25
25
|
}
|
|
26
26
|
await addUser(userInfo) // 全局存储登录用户信息
|
|
27
27
|
const file = await user.avatar()
|
package/src/lib/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const Crypto = require('crypto')
|
|
2
2
|
const schedule = require('node-schedule')
|
|
3
3
|
const fs = require('fs')
|
|
4
|
-
const { MCanvas, MImage } = require('mcanvas')
|
|
5
4
|
const { addRoom, getRoom } = require('../common/roomAvatarDb')
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -416,7 +415,7 @@ function filterContacts(contacts, query) {
|
|
|
416
415
|
let { name, alias, friend, type, gender, province, city, address } = query
|
|
417
416
|
return contacts.filter((item) => {
|
|
418
417
|
let arr = []
|
|
419
|
-
let
|
|
418
|
+
let payload = item.payload || item._payload
|
|
420
419
|
if (friend) {
|
|
421
420
|
let bool = Number(friend) === 1 ? true : false
|
|
422
421
|
arr.push(bool === payload.friend)
|
|
@@ -440,7 +439,7 @@ function formatContacts(data) {
|
|
|
440
439
|
let arr = data.map(function (item) {
|
|
441
440
|
// const file = await item.avatar()
|
|
442
441
|
// let avatar = await file.toBase64(file.name, true);
|
|
443
|
-
let payload = item._payload
|
|
442
|
+
let payload = item.payload || item._payload
|
|
444
443
|
return {
|
|
445
444
|
id: payload.id,
|
|
446
445
|
name: payload.name,
|
|
@@ -517,11 +516,10 @@ async function getRoomAvatarList(room, name) {
|
|
|
517
516
|
let res = []
|
|
518
517
|
console.log('正在努力获取群成员信息...')
|
|
519
518
|
for (let i of members) {
|
|
520
|
-
let member = i._payload
|
|
519
|
+
let member = i.payload || i._payload
|
|
521
520
|
try {
|
|
522
521
|
const avatar = await i.avatar()
|
|
523
522
|
if (avatar._mediaType && avatar._name) {
|
|
524
|
-
console.log(avatar)
|
|
525
523
|
const base64 = member.weixin ? member.avatar : await avatar.toDataURL()
|
|
526
524
|
let obj = {
|
|
527
525
|
img: base64,
|
|
@@ -584,226 +582,6 @@ async function getRoomAvatar(roomObj, roomName, name) {
|
|
|
584
582
|
console.log('getRoomAvatar error', e)
|
|
585
583
|
}
|
|
586
584
|
}
|
|
587
|
-
|
|
588
|
-
/**
|
|
589
|
-
* 头像处理
|
|
590
|
-
* @param {*}} list
|
|
591
|
-
* @param {*} size
|
|
592
|
-
*/
|
|
593
|
-
async function cropImg(list, size = 74) {
|
|
594
|
-
try {
|
|
595
|
-
const arr = []
|
|
596
|
-
if (list.length >= 100) {
|
|
597
|
-
console.log('群成员数量超过100,生成群合影速度可能比较慢,请耐心等待')
|
|
598
|
-
}
|
|
599
|
-
for (const i of list) {
|
|
600
|
-
try {
|
|
601
|
-
if (i.img) {
|
|
602
|
-
const im = new MImage(i.img)
|
|
603
|
-
im.compress({
|
|
604
|
-
quality: 1,
|
|
605
|
-
width: size,
|
|
606
|
-
height: size,
|
|
607
|
-
}).crop({
|
|
608
|
-
radius: size,
|
|
609
|
-
})
|
|
610
|
-
const bas64 = await im.draw({ type: 'png' })
|
|
611
|
-
arr.push({ img: bas64 })
|
|
612
|
-
}
|
|
613
|
-
} catch (error) {
|
|
614
|
-
console.log('处理头像失败', error)
|
|
615
|
-
continue
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return arr
|
|
619
|
-
} catch (error) {
|
|
620
|
-
console.log('cropImg error', error)
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
/**
|
|
625
|
-
*
|
|
626
|
-
* @param {*} t 头像数组
|
|
627
|
-
* @param {*} param1
|
|
628
|
-
*/
|
|
629
|
-
function __beforePatternCircle(t, { size = 120, space = 24, circleSpace = 24, centerSizeMargin = 0 }) {
|
|
630
|
-
let i, r, n, s, o, c, l, p, u, g, m, d, h, f, v, b, w, y, C, _, k, I, x, S, j, q, D, z, P
|
|
631
|
-
for (u in ((i = size), (r = space), (n = circleSpace), (s = centerSizeMargin), (o = 1), (c = 0), (l = []), (p = r), t)) {
|
|
632
|
-
if (u > 0 && ((g = i / 2), (m = (i + n) * o), (m += s), (d = (2 * Math.PI * m) / (2 * g + r)), (d = Math.floor(d)), u > 0 && c === d - 1 ? (o++, (c = 0), l.push(d)) : c++, (h = t.length - 1 + ''), u === h && ((f = c), (v = c * i), c < d))) {
|
|
633
|
-
for (C in ((b = 0), (w = 0), (y = []), l)) {
|
|
634
|
-
C < l.length &&
|
|
635
|
-
((_ = l[C] * r),
|
|
636
|
-
_ >= i + r &&
|
|
637
|
-
((b += _),
|
|
638
|
-
(w += l[C]),
|
|
639
|
-
y.push({
|
|
640
|
-
level: C,
|
|
641
|
-
spaceUnit: _,
|
|
642
|
-
})))
|
|
643
|
-
}
|
|
644
|
-
v <= b && ((k = w + f === 0 ? 0 : (b - v) / (w + f)), (p = k))
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
for (j in ((I = 1), (x = 0), (S = 0), t)) j > 0 && ((q = i / 2), (D = (i + n) * I), (D += s), (z = (2 * Math.PI * D) / (2 * q + p)), (z = Math.floor(z)), t.length - j < z && ((P = t.length - 1 + ''), j === P && (S = 360 / (x + 1))), j > 0 && x === z - 1 ? (I++, (x = 0)) : x++)
|
|
648
|
-
return {
|
|
649
|
-
newSpace: p,
|
|
650
|
-
newRate: S,
|
|
651
|
-
lastCircleNumber: I,
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
function patternCircle(mc, t, info, i) {
|
|
656
|
-
let r, n, s, g, d, h, f, v, b, w, y, C, _, k, I, x, S, j, q
|
|
657
|
-
r = i.x
|
|
658
|
-
n = i.y
|
|
659
|
-
const o = i.centerSize || i.size
|
|
660
|
-
s = i.space
|
|
661
|
-
const c = o > i.size ? (o - i.size) / 2 : 0
|
|
662
|
-
const l = i.backWid
|
|
663
|
-
const p = i.backHei
|
|
664
|
-
const u = l / 2 // x中间坐标
|
|
665
|
-
g = p / 2 // y中间坐标
|
|
666
|
-
g = i.marginBottom ? p - i.marginBottom : g
|
|
667
|
-
r = u - i.size / 2
|
|
668
|
-
n = g - i.size / 2
|
|
669
|
-
const m = s
|
|
670
|
-
for (w in ((d = info), (s = d.newSpace), (h = d.newRate), (f = d.lastCircleNumber), (v = 1), (b = 0), t)) {
|
|
671
|
-
w > 0 &&
|
|
672
|
-
((y = i.size / 2),
|
|
673
|
-
(C = (i.size + m) * v),
|
|
674
|
-
(C += c),
|
|
675
|
-
(_ = (2 * Math.PI * C) / (2 * y + s)),
|
|
676
|
-
(_ = Math.floor(_)),
|
|
677
|
-
(k = 360 / _),
|
|
678
|
-
f === v && (k = h),
|
|
679
|
-
(I = ((2 * Math.PI) / 360) * k * b),
|
|
680
|
-
(x = u + Math.sin(I + (2 * Math.PI * 270) / 360) * C),
|
|
681
|
-
(S = g - Math.cos(I + (2 * Math.PI * 270) / 360) * C),
|
|
682
|
-
(r = x - y),
|
|
683
|
-
(n = S - y),
|
|
684
|
-
w > 0 && b === _ - 1 ? (v++, (b = 0)) : b++),
|
|
685
|
-
(j = i.size),
|
|
686
|
-
parseInt(w) === 0 && ((j = o), (r = u - o / 2), (n = g - o / 2)),
|
|
687
|
-
(q = t[w].img)
|
|
688
|
-
mc.add(q, {
|
|
689
|
-
width: j,
|
|
690
|
-
pos: {
|
|
691
|
-
x: r,
|
|
692
|
-
y: n,
|
|
693
|
-
scale: 1,
|
|
694
|
-
},
|
|
695
|
-
})
|
|
696
|
-
}
|
|
697
|
-
return mc
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* 绘制标题
|
|
702
|
-
* @param {*} mc
|
|
703
|
-
* @param {*} title
|
|
704
|
-
* @param {*} titleInfo
|
|
705
|
-
*/
|
|
706
|
-
|
|
707
|
-
function drawTitle(mc, title, titleInfo) {
|
|
708
|
-
mc.text(title, {
|
|
709
|
-
align: 'center',
|
|
710
|
-
width: '100%',
|
|
711
|
-
normalStyle: {
|
|
712
|
-
color: titleInfo.color,
|
|
713
|
-
lineHeight: titleInfo.fontSize,
|
|
714
|
-
font: `${titleInfo.fontSize}px Microsoft YaHei,sans-serif`,
|
|
715
|
-
},
|
|
716
|
-
pos: {
|
|
717
|
-
x: 0,
|
|
718
|
-
y: titleInfo.top,
|
|
719
|
-
},
|
|
720
|
-
})
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
async function generateRoomImg(list, options) {
|
|
724
|
-
try {
|
|
725
|
-
const { sizeInfo, titleInfo, background, roomName } = options
|
|
726
|
-
console.log('群合影生成中...')
|
|
727
|
-
list = await cropImg(list, sizeInfo.size)
|
|
728
|
-
const initOptions = {
|
|
729
|
-
title: titleInfo.title || roomName,
|
|
730
|
-
centerSize: sizeInfo.centerSize,
|
|
731
|
-
space: sizeInfo.space,
|
|
732
|
-
circleSpace: sizeInfo.space,
|
|
733
|
-
size: sizeInfo.size,
|
|
734
|
-
x: 0,
|
|
735
|
-
y: 0,
|
|
736
|
-
backWid: sizeInfo.width,
|
|
737
|
-
backHei: sizeInfo.height,
|
|
738
|
-
marginBottom: sizeInfo.bottom, // 距离底部高度
|
|
739
|
-
}
|
|
740
|
-
const mc = new MCanvas({
|
|
741
|
-
width: initOptions.backWid,
|
|
742
|
-
height: initOptions.backHei,
|
|
743
|
-
backgroundColor: '#ffffff',
|
|
744
|
-
})
|
|
745
|
-
mc.background(background, {
|
|
746
|
-
type: 'contain',
|
|
747
|
-
})
|
|
748
|
-
const info = __beforePatternCircle(list, initOptions)
|
|
749
|
-
patternCircle(mc, list, info, initOptions)
|
|
750
|
-
drawTitle(mc, initOptions.title, titleInfo)
|
|
751
|
-
const base64 = await mc.draw({ type: 'jpg', quality: 1 })
|
|
752
|
-
console.log('群合影生成成功!')
|
|
753
|
-
// var base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
|
|
754
|
-
// var dataBuffer = Buffer.from(base64Data, 'base64')
|
|
755
|
-
// fs.writeFile('image.jpg', dataBuffer, function (err) {
|
|
756
|
-
// if (err) {
|
|
757
|
-
// console.log(err)
|
|
758
|
-
// } else {
|
|
759
|
-
// console.log('保存成功!')
|
|
760
|
-
// }
|
|
761
|
-
// })
|
|
762
|
-
return base64
|
|
763
|
-
} catch (e) {
|
|
764
|
-
console.log('群合影生成失败', e)
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
async function generateAvatar(avatar, coverImg = 'http://image.xkboke.com/hat.png') {
|
|
769
|
-
try {
|
|
770
|
-
let mc = new MCanvas({
|
|
771
|
-
width: 880,
|
|
772
|
-
height: 880,
|
|
773
|
-
backgroundColor: '#ffffff',
|
|
774
|
-
})
|
|
775
|
-
mc.add(avatar, {
|
|
776
|
-
width: 860,
|
|
777
|
-
pos: {
|
|
778
|
-
x: 10,
|
|
779
|
-
y: 10,
|
|
780
|
-
scale: 1,
|
|
781
|
-
},
|
|
782
|
-
})
|
|
783
|
-
mc.add(coverImg, {
|
|
784
|
-
width: 880,
|
|
785
|
-
pos: {
|
|
786
|
-
x: 0,
|
|
787
|
-
y: 0,
|
|
788
|
-
scale: 1,
|
|
789
|
-
},
|
|
790
|
-
})
|
|
791
|
-
const base64 = await mc.draw({ type: 'jpg', quality: 1 })
|
|
792
|
-
// var base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
|
|
793
|
-
// var dataBuffer = Buffer.from(base64Data, 'base64')
|
|
794
|
-
// fs.writeFile('avatar.jpg', dataBuffer, function (err) {
|
|
795
|
-
// if (err) {
|
|
796
|
-
// console.log(err)
|
|
797
|
-
// } else {
|
|
798
|
-
// console.log('保存成功!')
|
|
799
|
-
// }
|
|
800
|
-
// })
|
|
801
|
-
return base64
|
|
802
|
-
} catch (e) {
|
|
803
|
-
console.log('头像生成失败', e)
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
|
|
807
585
|
module.exports = {
|
|
808
586
|
Base64Encode,
|
|
809
587
|
Base64Decode,
|
|
@@ -829,7 +607,5 @@ module.exports = {
|
|
|
829
607
|
getAllSchedule,
|
|
830
608
|
groupArray,
|
|
831
609
|
getRoomAvatarList,
|
|
832
|
-
generateRoomImg,
|
|
833
610
|
getRoomAvatar,
|
|
834
|
-
generateAvatar,
|
|
835
611
|
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成群合影
|
|
3
|
+
* @param list
|
|
4
|
+
* @param options
|
|
5
|
+
* @returns {Promise<unknown>}
|
|
6
|
+
*/
|
|
7
|
+
async function generateRoomImg({ list, options }) {
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {*} t 头像数组
|
|
11
|
+
* @param {*} param1
|
|
12
|
+
*/
|
|
13
|
+
const __beforePatternCircle = function (t, { size = 120, space = 24, circleSpace = 24, centerSizeMargin = 0 }) {
|
|
14
|
+
let i, r, n, s, o, c, l, p, u, g, m, d, h, f, v, b, w, y, C, _, k, I, x, S, j, q, D, z, P
|
|
15
|
+
for (u in ((i = size), (r = space), (n = circleSpace), (s = centerSizeMargin), (o = 1), (c = 0), (l = []), (p = r), t)) {
|
|
16
|
+
if (u > 0 && ((g = i / 2), (m = (i + n) * o), (m += s), (d = (2 * Math.PI * m) / (2 * g + r)), (d = Math.floor(d)), u > 0 && c === d - 1 ? (o++, (c = 0), l.push(d)) : c++, (h = t.length - 1 + ''), u === h && ((f = c), (v = c * i), c < d))) {
|
|
17
|
+
for (C in ((b = 0), (w = 0), (y = []), l)) {
|
|
18
|
+
C < l.length &&
|
|
19
|
+
((_ = l[C] * r),
|
|
20
|
+
_ >= i + r &&
|
|
21
|
+
((b += _),
|
|
22
|
+
(w += l[C]),
|
|
23
|
+
y.push({
|
|
24
|
+
level: C,
|
|
25
|
+
spaceUnit: _,
|
|
26
|
+
})))
|
|
27
|
+
}
|
|
28
|
+
v <= b && ((k = w + f === 0 ? 0 : (b - v) / (w + f)), (p = k))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (j in ((I = 1), (x = 0), (S = 0), t)) j > 0 && ((q = i / 2), (D = (i + n) * I), (D += s), (z = (2 * Math.PI * D) / (2 * q + p)), (z = Math.floor(z)), t.length - j < z && ((P = t.length - 1 + ''), j === P && (S = 360 / (x + 1))), j > 0 && x === z - 1 ? (I++, (x = 0)) : x++)
|
|
32
|
+
return {
|
|
33
|
+
newSpace: p,
|
|
34
|
+
newRate: S,
|
|
35
|
+
lastCircleNumber: I,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const patternCircle = function (mc, t, info, i) {
|
|
40
|
+
let r, n, s, g, d, h, f, v, b, w, y, C, _, k, I, x, S, j, q
|
|
41
|
+
r = i.x
|
|
42
|
+
n = i.y
|
|
43
|
+
const o = i.centerSize || i.size
|
|
44
|
+
s = i.space
|
|
45
|
+
const c = o > i.size ? (o - i.size) / 2 : 0
|
|
46
|
+
const l = i.backWid
|
|
47
|
+
const p = i.backHei
|
|
48
|
+
const u = l / 2 // x中间坐标
|
|
49
|
+
g = p / 2 // y中间坐标
|
|
50
|
+
g = i.marginBottom ? p - i.marginBottom : g
|
|
51
|
+
r = u - i.size / 2
|
|
52
|
+
n = g - i.size / 2
|
|
53
|
+
const m = s
|
|
54
|
+
for (w in ((d = info), (s = d.newSpace), (h = d.newRate), (f = d.lastCircleNumber), (v = 1), (b = 0), t)) {
|
|
55
|
+
w > 0 &&
|
|
56
|
+
((y = i.size / 2),
|
|
57
|
+
(C = (i.size + m) * v),
|
|
58
|
+
(C += c),
|
|
59
|
+
(_ = (2 * Math.PI * C) / (2 * y + s)),
|
|
60
|
+
(_ = Math.floor(_)),
|
|
61
|
+
(k = 360 / _),
|
|
62
|
+
f === v && (k = h),
|
|
63
|
+
(I = ((2 * Math.PI) / 360) * k * b),
|
|
64
|
+
(x = u + Math.sin(I + (2 * Math.PI * 270) / 360) * C),
|
|
65
|
+
(S = g - Math.cos(I + (2 * Math.PI * 270) / 360) * C),
|
|
66
|
+
(r = x - y),
|
|
67
|
+
(n = S - y),
|
|
68
|
+
w > 0 && b === _ - 1 ? (v++, (b = 0)) : b++),
|
|
69
|
+
(j = i.size),
|
|
70
|
+
parseInt(w) === 0 && ((j = o), (r = u - o / 2), (n = g - o / 2)),
|
|
71
|
+
(q = t[w].img)
|
|
72
|
+
mc.add(q, {
|
|
73
|
+
width: j,
|
|
74
|
+
pos: {
|
|
75
|
+
x: r,
|
|
76
|
+
y: n,
|
|
77
|
+
scale: 1,
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
return mc
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 绘制标题
|
|
86
|
+
* @param {*} mc
|
|
87
|
+
* @param {*} title
|
|
88
|
+
* @param {*} titleInfo
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
const drawTitle = function (mc, title, titleInfo) {
|
|
92
|
+
mc.text(title, {
|
|
93
|
+
align: 'center',
|
|
94
|
+
width: '100%',
|
|
95
|
+
normalStyle: {
|
|
96
|
+
color: titleInfo.color,
|
|
97
|
+
lineHeight: titleInfo.fontSize,
|
|
98
|
+
font: `${titleInfo.fontSize}px Microsoft YaHei,sans-serif`,
|
|
99
|
+
},
|
|
100
|
+
pos: {
|
|
101
|
+
x: 0,
|
|
102
|
+
y: titleInfo.top,
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 头像处理
|
|
108
|
+
* @param {*}} list
|
|
109
|
+
* @param {*} size
|
|
110
|
+
*/
|
|
111
|
+
const cropImg = async function (list, size = 74, MImage) {
|
|
112
|
+
try {
|
|
113
|
+
const arr = []
|
|
114
|
+
if (list.length >= 100) {
|
|
115
|
+
console.log('群成员数量超过100,生成群合影速度可能比较慢,请耐心等待')
|
|
116
|
+
}
|
|
117
|
+
for (const i of list) {
|
|
118
|
+
try {
|
|
119
|
+
if (i.img) {
|
|
120
|
+
const im = new MImage(i.img)
|
|
121
|
+
im.compress({
|
|
122
|
+
quality: 1,
|
|
123
|
+
width: size,
|
|
124
|
+
height: size,
|
|
125
|
+
}).crop({
|
|
126
|
+
radius: size,
|
|
127
|
+
})
|
|
128
|
+
const bas64 = await im.draw({ type: 'png' })
|
|
129
|
+
arr.push({ img: bas64 })
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.log('处理头像失败', error)
|
|
133
|
+
continue
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return arr
|
|
137
|
+
} catch (error) {
|
|
138
|
+
console.log('cropImg error', error)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return new Promise(async (resolve, reject) => {
|
|
143
|
+
let MCanvas = window.MCanvas.MCanvas
|
|
144
|
+
let MImage = window.MCanvas.MImage
|
|
145
|
+
try {
|
|
146
|
+
const { sizeInfo, titleInfo, background, roomName } = options
|
|
147
|
+
list = await cropImg(list, sizeInfo.size, MImage)
|
|
148
|
+
const initOptions = {
|
|
149
|
+
title: titleInfo.title || roomName,
|
|
150
|
+
centerSize: sizeInfo.centerSize,
|
|
151
|
+
space: sizeInfo.space,
|
|
152
|
+
circleSpace: sizeInfo.space,
|
|
153
|
+
size: sizeInfo.size,
|
|
154
|
+
x: 0,
|
|
155
|
+
y: 0,
|
|
156
|
+
backWid: sizeInfo.width,
|
|
157
|
+
backHei: sizeInfo.height,
|
|
158
|
+
marginBottom: sizeInfo.bottom, // 距离底部高度
|
|
159
|
+
}
|
|
160
|
+
const mc = new MCanvas({
|
|
161
|
+
width: initOptions.backWid,
|
|
162
|
+
height: initOptions.backHei,
|
|
163
|
+
backgroundColor: '#ffffff',
|
|
164
|
+
})
|
|
165
|
+
mc.background(background, {
|
|
166
|
+
type: 'contain',
|
|
167
|
+
})
|
|
168
|
+
const info = __beforePatternCircle(list, initOptions)
|
|
169
|
+
patternCircle(mc, list, info, initOptions)
|
|
170
|
+
drawTitle(mc, initOptions.title, titleInfo)
|
|
171
|
+
const base64 = await mc.draw({ type: 'jpg', quality: 1 })
|
|
172
|
+
console.log('群合影生成成功!')
|
|
173
|
+
// var base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
|
|
174
|
+
// var dataBuffer = Buffer.from(base64Data, 'base64')
|
|
175
|
+
// fs.writeFile('image.jpg', dataBuffer, function (err) {
|
|
176
|
+
// if (err) {
|
|
177
|
+
// console.log(err)
|
|
178
|
+
// } else {
|
|
179
|
+
// console.log('保存成功!')
|
|
180
|
+
// }
|
|
181
|
+
// })
|
|
182
|
+
resolve(base64)
|
|
183
|
+
} catch (e) {
|
|
184
|
+
console.log('群合影生成失败', e)
|
|
185
|
+
reject(`群合影生成失败:${e}`)
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function generateAvatar({ avatar, coverImg }) {
|
|
191
|
+
coverImg = coverImg || 'http://image.xkboke.com/hat.png'
|
|
192
|
+
return new Promise(async (resolve, reject) => {
|
|
193
|
+
try {
|
|
194
|
+
let MCanvas = window.MCanvas.MCanvas
|
|
195
|
+
let mc = new MCanvas({
|
|
196
|
+
width: 880,
|
|
197
|
+
height: 880,
|
|
198
|
+
backgroundColor: '#ffffff',
|
|
199
|
+
})
|
|
200
|
+
mc.add(avatar, {
|
|
201
|
+
width: 860,
|
|
202
|
+
pos: {
|
|
203
|
+
x: 10,
|
|
204
|
+
y: 10,
|
|
205
|
+
scale: 1,
|
|
206
|
+
},
|
|
207
|
+
})
|
|
208
|
+
mc.add(coverImg, {
|
|
209
|
+
width: 880,
|
|
210
|
+
pos: {
|
|
211
|
+
x: 0,
|
|
212
|
+
y: 0,
|
|
213
|
+
scale: 1,
|
|
214
|
+
},
|
|
215
|
+
})
|
|
216
|
+
const base64 = await mc.draw({ type: 'jpg', quality: 1 })
|
|
217
|
+
// var base64Data = base64.replace(/^data:image\/\w+;base64,/, '')
|
|
218
|
+
// var dataBuffer = Buffer.from(base64Data, 'base64')
|
|
219
|
+
// fs.writeFile('avatar.jpg', dataBuffer, function (err) {
|
|
220
|
+
// if (err) {
|
|
221
|
+
// console.log(err)
|
|
222
|
+
// } else {
|
|
223
|
+
// console.log('保存成功!')
|
|
224
|
+
// }
|
|
225
|
+
// })
|
|
226
|
+
resolve(base64)
|
|
227
|
+
} catch (e) {
|
|
228
|
+
console.log('头像生成失败', e)
|
|
229
|
+
reject(`头像生成失败:${e}`)
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
module.exports = {
|
|
235
|
+
generateAvatar,
|
|
236
|
+
generateRoomImg,
|
|
237
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const puppeteer = require('puppeteer')
|
|
2
|
+
const mainConfig = require('./mainConfig')
|
|
3
|
+
class BrowserManage {
|
|
4
|
+
browserDestructionTimeout //清理浏览器实例
|
|
5
|
+
browserInstance //浏览器实例
|
|
6
|
+
browserState = 'closed' //浏览器状态
|
|
7
|
+
/**
|
|
8
|
+
* 用于长时间未进行操作时关闭浏览器实例
|
|
9
|
+
*/
|
|
10
|
+
scheduleBrowserForDestruction() {
|
|
11
|
+
clearTimeout(this.browserDestructionTimeout)
|
|
12
|
+
this.browserDestructionTimeout = setTimeout(async () => {
|
|
13
|
+
if (this.browserInstance) {
|
|
14
|
+
this.browserState = 'closed'
|
|
15
|
+
await this.browserInstance.close() //关闭浏览器实例
|
|
16
|
+
}
|
|
17
|
+
}, 5000)
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 用于长时间未进行操作时关闭浏览器实例
|
|
21
|
+
*/
|
|
22
|
+
async getBrowser() {
|
|
23
|
+
return new Promise(async (resolve, reject) => {
|
|
24
|
+
if (this.browserState === 'closed') {
|
|
25
|
+
this.browserInstance = await puppeteer.launch(mainConfig.config.puppeteer) //开启浏览器实例
|
|
26
|
+
this.browserState = 'open'
|
|
27
|
+
resolve(this.browserInstance)
|
|
28
|
+
}
|
|
29
|
+
if (this.browserState === 'open') {
|
|
30
|
+
if (this.browserInstance) {
|
|
31
|
+
resolve(this.browserInstance)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
module.exports = new BrowserManage()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const browserManage = require('./index')
|
|
2
|
+
const drawHelpers = require('./drawHelp')
|
|
3
|
+
|
|
4
|
+
const generateRoomImg = async function (passedOptions) {
|
|
5
|
+
const browser = await browserManage.getBrowser()
|
|
6
|
+
const page = (await browser.pages())[0]
|
|
7
|
+
// 添加 mcanvas cdn地址
|
|
8
|
+
let filePath = 'http://image.xkboke.com/pubilc/cdn/mcanvas.js'
|
|
9
|
+
await page.addScriptTag({
|
|
10
|
+
url: filePath,
|
|
11
|
+
})
|
|
12
|
+
page.on('console', (msg) => console.log(msg.type(), msg.text())) //监听页面console事件
|
|
13
|
+
const base64 = await page.evaluate(drawHelpers.generateRoomImg, passedOptions)
|
|
14
|
+
browserManage.scheduleBrowserForDestruction()
|
|
15
|
+
// await FileBox.fromBase64(base64).toFile('./test.png')
|
|
16
|
+
// const buffer = Buffer.from(base64, 'base64')
|
|
17
|
+
return base64 //返回Base64 编码的图片
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const generateAvatar = async function (passedOptions) {
|
|
21
|
+
const browser = await browserManage.getBrowser()
|
|
22
|
+
const page = (await browser.pages())[0]
|
|
23
|
+
// 添加 mcanvas cdn地址
|
|
24
|
+
let filePath = 'http://image.xkboke.com/pubilc/cdn/mcanvas.js'
|
|
25
|
+
await page.addScriptTag({
|
|
26
|
+
url: filePath,
|
|
27
|
+
})
|
|
28
|
+
page.on('console', (msg) => console.log(msg.type(), msg.text())) //监听页面console事件
|
|
29
|
+
const base64 = await page.evaluate(drawHelpers.generateAvatar, passedOptions)
|
|
30
|
+
browserManage.scheduleBrowserForDestruction()
|
|
31
|
+
// await FileBox.fromBase64(base64).toFile('./test.png')
|
|
32
|
+
return base64 //返回Base64 编码的图片
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
generateAvatar,
|
|
37
|
+
generateRoomImg,
|
|
38
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const api = require('../proxy/api')
|
|
2
|
-
const { getConfig,
|
|
3
|
-
const { getConstellation, msgArr, getAllSchedule,
|
|
2
|
+
const { getConfig, getRoomPhotoConfig, getMeiNv } = require('../proxy/aibotk')
|
|
3
|
+
const { getConstellation, msgArr, getAllSchedule, getRoomAvatar } = require('../lib')
|
|
4
|
+
const { generateAvatar, generateRoomImg } = require('../puppeteer-paint/lanuch')
|
|
4
5
|
const { initTaskLocalSchedule } = require('../task/index')
|
|
5
6
|
const { updateContactAndRoom, updateContactOnly, updateRoomOnly } = require('../common/index')
|
|
6
7
|
const { chatTencent } = require('../proxy/tencent')
|
|
@@ -51,7 +52,7 @@ async function dispatchEventContent(that, eName, msg, name, id, avatar, room) {
|
|
|
51
52
|
if (avatar.mimeType) {
|
|
52
53
|
// 如果图片类型正确再进行头像处理
|
|
53
54
|
let base64Text = await avatar.toDataURL()
|
|
54
|
-
url = await generateAvatar(base64Text)
|
|
55
|
+
url = await generateAvatar({ avatar: base64Text })
|
|
55
56
|
type = 3
|
|
56
57
|
} else {
|
|
57
58
|
content = '你的头像属于高维世界产物,小助手能力不足,无法解析,待我修炼后为你提供服务'
|
|
@@ -80,7 +81,7 @@ async function dispatchEventContent(that, eName, msg, name, id, avatar, room) {
|
|
|
80
81
|
} else if (config.authList.length) {
|
|
81
82
|
if (config.authList.includes(name)) {
|
|
82
83
|
memberList = await getRoomAvatar(room, roomName, name)
|
|
83
|
-
const baseImg = await generateRoomImg(memberList, config)
|
|
84
|
+
const baseImg = await generateRoomImg({ list: memberList, options: config })
|
|
84
85
|
type = 3
|
|
85
86
|
url = baseImg
|
|
86
87
|
} else {
|
|
@@ -88,7 +89,7 @@ async function dispatchEventContent(that, eName, msg, name, id, avatar, room) {
|
|
|
88
89
|
}
|
|
89
90
|
} else {
|
|
90
91
|
memberList = await getRoomAvatar(room, roomName, name)
|
|
91
|
-
const baseImg = await generateRoomImg(memberList, config)
|
|
92
|
+
const baseImg = await generateRoomImg({ list: memberList, options: config })
|
|
92
93
|
type = 3
|
|
93
94
|
url = baseImg
|
|
94
95
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const dispatch = require('./event-dispatch-service')
|
|
2
2
|
const { setSchedule, updateSchedule } = require('../proxy/aibotk')
|
|
3
|
-
const { contentDistinguish, setLocalSchedule, isRealDate
|
|
3
|
+
const { contentDistinguish, setLocalSchedule, isRealDate } = require('../lib')
|
|
4
|
+
const { generateAvatar } = require('../puppeteer-paint/lanuch')
|
|
4
5
|
const { addRoom } = require('../common/index')
|
|
5
6
|
|
|
6
7
|
function emptyMsg() {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
const { log } = require('wechaty')
|
|
2
|
-
const { Message } = require('wechaty').types
|
|
3
1
|
const Mustache = require('mustache')
|
|
4
2
|
|
|
5
3
|
function roomTalker(options) {
|
|
6
|
-
log.verbose('WechatyPluginContrib', 'roomTalker(%s)', JSON.stringify(options))
|
|
7
4
|
if (!options) {
|
|
8
5
|
return () => undefined
|
|
9
6
|
}
|
|
@@ -12,7 +9,6 @@ function roomTalker(options) {
|
|
|
12
9
|
}
|
|
13
10
|
const optionList = options
|
|
14
11
|
return async function talkRoom(room, contact, mustacheView) {
|
|
15
|
-
log.verbose('WechatyPluginContrib', 'roomTalker() talkRoom(%s, %s, %s)', room, contact || '', mustacheView ? JSON.stringify(mustacheView) : '')
|
|
16
12
|
for (const option of optionList) {
|
|
17
13
|
let msg
|
|
18
14
|
if (option instanceof Function) {
|
|
@@ -47,18 +43,13 @@ function roomTalker(options) {
|
|
|
47
43
|
}
|
|
48
44
|
|
|
49
45
|
function messageMapper(mapperOptions, one) {
|
|
50
|
-
log.verbose('WechatyPluginContrib', 'messageMapper(%s)', typeof mapperOptions === 'function' ? 'function' : JSON.stringify(mapperOptions))
|
|
51
|
-
|
|
52
46
|
return async function mapMessage(message) {
|
|
53
|
-
log.verbose('WechatyPluginContrib', 'mapMessage(%s)', message)
|
|
54
|
-
|
|
55
47
|
return normalizeMappedMessageList(mapperOptions, message, one)
|
|
56
48
|
}
|
|
57
49
|
}
|
|
58
50
|
|
|
59
51
|
async function normalizeMappedMessageList(options, message, one) {
|
|
60
52
|
try {
|
|
61
|
-
log.verbose('WechatyPluginContrib', 'normalizeMappedMessageList(%s, %s)', JSON.stringify(options), message)
|
|
62
53
|
const msgList = []
|
|
63
54
|
let optionList
|
|
64
55
|
if (Array.isArray(options)) {
|
|
@@ -88,8 +79,6 @@ async function normalizeMappedMessageList(options, message, one) {
|
|
|
88
79
|
}
|
|
89
80
|
|
|
90
81
|
function messageMatcher(matcherOptions) {
|
|
91
|
-
log.verbose('WechatyPluginContrib', 'messageMatcher(%s)', JSON.stringify(matcherOptions))
|
|
92
|
-
|
|
93
82
|
if (!matcherOptions) {
|
|
94
83
|
return () => Promise.resolve(false)
|
|
95
84
|
}
|
|
@@ -102,7 +91,6 @@ function messageMatcher(matcherOptions) {
|
|
|
102
91
|
|
|
103
92
|
return async function matchMessage(message) {
|
|
104
93
|
try {
|
|
105
|
-
log.verbose('WechatyPluginContrib', 'messageMatcher() matchMessage(%s)', message)
|
|
106
94
|
const room = message.room()
|
|
107
95
|
const roomTopic = await room.topic()
|
|
108
96
|
const talker = message.talker()
|
|
@@ -185,7 +173,7 @@ const bidirectionalMapper = async (message) => {
|
|
|
185
173
|
try {
|
|
186
174
|
const abbrRoomTopicForDevelopersHome = abbrRoomTopicByRegex(/\s*([^\s]*\s*[^\s]+)$/)
|
|
187
175
|
// Drop all messages if not Text
|
|
188
|
-
if (message.type() !==
|
|
176
|
+
if (message.type() !== 7) {
|
|
189
177
|
return
|
|
190
178
|
}
|
|
191
179
|
|
|
@@ -219,7 +207,7 @@ const unidirectionalMapper = async (message, one) => {
|
|
|
219
207
|
const room = message.room()
|
|
220
208
|
const topic = await room.topic()
|
|
221
209
|
switch (message.type()) {
|
|
222
|
-
case
|
|
210
|
+
case 7:
|
|
223
211
|
messageList.push(`${prefix}: ${message.text()}`)
|
|
224
212
|
break
|
|
225
213
|
|
|
@@ -245,14 +233,11 @@ const unidirectionalMapper = async (message, one) => {
|
|
|
245
233
|
}
|
|
246
234
|
|
|
247
235
|
const isMatchConfig = (config) => {
|
|
248
|
-
log.verbose('WechatyPluginContrib', 'ManyToManyRoomConnector() isMatchConfig(%s)', JSON.stringify(config))
|
|
249
|
-
|
|
250
236
|
const matchWhitelist = messageMatcher(config.whitelist)
|
|
251
237
|
const matchBlacklist = messageMatcher(config.blacklist)
|
|
252
238
|
|
|
253
239
|
return async function isMatch(message) {
|
|
254
240
|
try {
|
|
255
|
-
log.verbose('WechatyPluginContrib', 'ManyToManyRoomConnector() isMatchConfig() isMatch(%s)', message.toString())
|
|
256
241
|
if (message.self()) {
|
|
257
242
|
return
|
|
258
243
|
}
|
|
@@ -292,7 +277,6 @@ const isMatchConfig = (config) => {
|
|
|
292
277
|
*/
|
|
293
278
|
async function manyToMany(that, config, msg) {
|
|
294
279
|
try {
|
|
295
|
-
log.verbose('WechatyPluginContrib', 'ManyToManyRoomConnector(%s)', JSON.stringify(config))
|
|
296
280
|
const isMatch = isMatchConfig(config)
|
|
297
281
|
const mapMessage = messageMapper(config.map)
|
|
298
282
|
const matchAndForward = async (message, roomList) => {
|
|
@@ -339,7 +323,6 @@ async function manyToMany(that, config, msg) {
|
|
|
339
323
|
|
|
340
324
|
async function manyToOne(that, config, msg) {
|
|
341
325
|
try {
|
|
342
|
-
log.verbose('WechatyPluginContrib', 'ManyToOneRoomConnector(%s)', JSON.stringify(config))
|
|
343
326
|
const isMatch = isMatchConfig(config)
|
|
344
327
|
const mapMessage = messageMapper(config.map)
|
|
345
328
|
const matchAndForward = async (message, room) => {
|
|
@@ -352,7 +335,7 @@ async function manyToOne(that, config, msg) {
|
|
|
352
335
|
const talkRoom = roomTalker(msgList)
|
|
353
336
|
await talkRoom(room)
|
|
354
337
|
} catch (e) {
|
|
355
|
-
log
|
|
338
|
+
console.log('WechatyPluginContrib, ManyToOneRoomConnector() filterThenToManyRoom(%s, %s) rejection: %s')
|
|
356
339
|
}
|
|
357
340
|
}
|
|
358
341
|
let oneRoom = ''
|
|
@@ -374,7 +357,6 @@ async function manyToOne(that, config, msg) {
|
|
|
374
357
|
*/
|
|
375
358
|
async function oneToMany(that, config, msg) {
|
|
376
359
|
try {
|
|
377
|
-
log.verbose('WechatyPluginContrib', 'OneToManyRoomConnector(%s)', JSON.stringify(config))
|
|
378
360
|
const isMatch = isMatchConfig(config)
|
|
379
361
|
const mapMessage = messageMapper(config.map, config.one)
|
|
380
362
|
const matchAndForward = async (message, roomList) => {
|
|
@@ -393,7 +375,7 @@ async function oneToMany(that, config, msg) {
|
|
|
393
375
|
}
|
|
394
376
|
}
|
|
395
377
|
} catch (e) {
|
|
396
|
-
log
|
|
378
|
+
console.log('WechatyPluginContrib', 'OneToManyRoomConnector() filterThenToManyRoom(%s, %s) rejection: %s')
|
|
397
379
|
}
|
|
398
380
|
}
|
|
399
381
|
let manyRoomList = []
|
|
@@ -422,7 +404,7 @@ async function dispatchAsync(that, msg, list) {
|
|
|
422
404
|
const type = msg.type()
|
|
423
405
|
const content = msg.text()
|
|
424
406
|
const mentionSelf = content.includes(`@${userSelfName}`)
|
|
425
|
-
if (
|
|
407
|
+
if (7 === type && mentionSelf) {
|
|
426
408
|
// 如果内容中有提及机器人的内容,不进行转发
|
|
427
409
|
return
|
|
428
410
|
}
|
|
@@ -431,7 +413,7 @@ async function dispatchAsync(that, msg, list) {
|
|
|
431
413
|
config.blacklist = [async () => true]
|
|
432
414
|
if (config.forward === 1) {
|
|
433
415
|
config.map = bidirectionalMapper
|
|
434
|
-
config.whitelist = [async (message) => message.type() ===
|
|
416
|
+
config.whitelist = [async (message) => message.type() === 7]
|
|
435
417
|
} else if (config.forward === 2) {
|
|
436
418
|
config.blacklist = []
|
|
437
419
|
config.map = unidirectionalMapper
|