@alemonjs/discord 2.1.6 → 2.1.7
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/lib/config.js +3 -3
- package/lib/format.js +11 -6
- package/lib/send.js +97 -161
- package/package.json +1 -1
package/lib/config.js
CHANGED
|
@@ -8,13 +8,13 @@ const getDiscordConfig = () => {
|
|
|
8
8
|
};
|
|
9
9
|
const getMaster = (UserId) => {
|
|
10
10
|
const config = getDiscordConfig();
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const masterKey = config.master_key || [];
|
|
12
|
+
const masterId = config.master_id || [];
|
|
13
13
|
const UserKey = useUserHashKey({
|
|
14
14
|
Platform: platform,
|
|
15
15
|
UserId: UserId
|
|
16
16
|
});
|
|
17
|
-
const is =
|
|
17
|
+
const is = masterKey.includes(UserKey) || masterId.includes(UserId);
|
|
18
18
|
return [is, UserKey];
|
|
19
19
|
};
|
|
20
20
|
|
package/lib/format.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const markdownToDiscordText = (items, hideUnsupported) => {
|
|
2
|
-
if (Number(hideUnsupported) >= 4)
|
|
2
|
+
if (Number(hideUnsupported) >= 4) {
|
|
3
3
|
return '';
|
|
4
|
+
}
|
|
4
5
|
return items
|
|
5
6
|
.map(item => {
|
|
6
7
|
switch (item.type) {
|
|
@@ -19,8 +20,9 @@ const markdownToDiscordText = (items, hideUnsupported) => {
|
|
|
19
20
|
return `~~${item.value}~~`;
|
|
20
21
|
case 'MD.link': {
|
|
21
22
|
const v = item.value;
|
|
22
|
-
if (Number(hideUnsupported) >= 3)
|
|
23
|
+
if (Number(hideUnsupported) >= 3) {
|
|
23
24
|
return '';
|
|
25
|
+
}
|
|
24
26
|
return Number(hideUnsupported) >= 2 ? v.url : `[${v.text}](${v.url})`;
|
|
25
27
|
}
|
|
26
28
|
case 'MD.image':
|
|
@@ -52,12 +54,13 @@ const markdownToDiscordText = (items, hideUnsupported) => {
|
|
|
52
54
|
case 'MD.content':
|
|
53
55
|
return item.value;
|
|
54
56
|
case 'MD.button':
|
|
55
|
-
if (Number(hideUnsupported) >= 3)
|
|
57
|
+
if (Number(hideUnsupported) >= 3) {
|
|
56
58
|
return '';
|
|
59
|
+
}
|
|
57
60
|
if (Number(hideUnsupported) >= 2) {
|
|
58
61
|
return item.options?.data || String(item.value);
|
|
59
62
|
}
|
|
60
|
-
return
|
|
63
|
+
return item.value;
|
|
61
64
|
default:
|
|
62
65
|
return String(item?.value ?? '');
|
|
63
66
|
}
|
|
@@ -65,15 +68,17 @@ const markdownToDiscordText = (items, hideUnsupported) => {
|
|
|
65
68
|
.join('');
|
|
66
69
|
};
|
|
67
70
|
const markdownRawToDiscordText = (raw, hideUnsupported) => {
|
|
68
|
-
if (Number(hideUnsupported) >= 4)
|
|
71
|
+
if (Number(hideUnsupported) >= 4) {
|
|
69
72
|
return '';
|
|
73
|
+
}
|
|
70
74
|
let text = raw;
|
|
71
75
|
text = text.replace(/!\[([^\]]*)\]\(([^)]*)\)/g, hideUnsupported ? '' : '[$1]($2)');
|
|
72
76
|
return text;
|
|
73
77
|
};
|
|
74
78
|
const dataEnumToDiscordText = (item, hideUnsupported) => {
|
|
75
|
-
if (Number(hideUnsupported) >= 4)
|
|
79
|
+
if (Number(hideUnsupported) >= 4) {
|
|
76
80
|
return '';
|
|
81
|
+
}
|
|
77
82
|
switch (item.type) {
|
|
78
83
|
case 'MarkdownOriginal':
|
|
79
84
|
return markdownRawToDiscordText(String(item.value), hideUnsupported);
|
package/lib/send.js
CHANGED
|
@@ -1,87 +1,70 @@
|
|
|
1
1
|
import { createResult, ResultCode } from 'alemonjs';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
|
-
import { dataEnumToDiscordText } from './format.js';
|
|
3
|
+
import { dataEnumToDiscordText, markdownRawToDiscordText, markdownToDiscordText } from './format.js';
|
|
4
4
|
import { getDiscordConfig } from './config.js';
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const fetchImageBuffer = async (url) => {
|
|
7
7
|
const arrayBuffer = await fetch(url).then(res => res.arrayBuffer());
|
|
8
8
|
return Buffer.from(arrayBuffer);
|
|
9
9
|
};
|
|
10
|
-
const createButtonsData = (rows) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
10
|
+
const createButtonsData = (rows) => rows.map(row => ({
|
|
11
|
+
type: 1,
|
|
12
|
+
components: row.value.map(button => ({
|
|
13
|
+
type: 2,
|
|
14
|
+
custom_id: button.options?.data ?? '',
|
|
15
|
+
style: 1,
|
|
16
|
+
label: button.value
|
|
17
|
+
}))
|
|
18
|
+
}));
|
|
19
|
+
const resolveImageBuffer = async (item) => {
|
|
20
|
+
if (item.type === 'Image') {
|
|
21
|
+
if (Buffer.isBuffer(item.value)) {
|
|
22
|
+
return item.value;
|
|
23
|
+
}
|
|
24
|
+
if (typeof item.value !== 'string') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (item.value.startsWith('http://') || item.value.startsWith('https://')) {
|
|
28
|
+
return await fetchImageBuffer(item.value);
|
|
29
|
+
}
|
|
30
|
+
if (item.value.startsWith('base64://')) {
|
|
31
|
+
return Buffer.from(item.value.slice(9), 'base64');
|
|
32
|
+
}
|
|
33
|
+
if (item.value.startsWith('file://')) {
|
|
34
|
+
return readFileSync(item.value.slice(7));
|
|
35
|
+
}
|
|
36
|
+
return Buffer.from(item.value, 'base64');
|
|
37
|
+
}
|
|
38
|
+
if (item.type === 'ImageURL') {
|
|
39
|
+
return await fetchImageBuffer(item.value);
|
|
40
|
+
}
|
|
41
|
+
if (item.type === 'ImageFile') {
|
|
42
|
+
return readFileSync(item.value);
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
27
45
|
};
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'MD.image': (item) => ``,
|
|
35
|
-
'MD.italicStar': (item) => `*${item.value}*`,
|
|
36
|
-
'MD.link': (item) => `[${item.value.text}](${item.value.url})`,
|
|
37
|
-
'MD.newline': () => '\n',
|
|
38
|
-
'MD.strikethrough': (item) => `~~${item.value}~~`,
|
|
39
|
-
'MD.subtitle': (item) => `## ${item.value}\n`,
|
|
40
|
-
'MD.title': (item) => `# ${item.value}\n`,
|
|
41
|
-
'MD.code': (item) => `\`\`\`${item.options?.language ?? ''}\n${item.value}\n\`\`\`\n`,
|
|
42
|
-
'MD.list': (item) => {
|
|
43
|
-
const listStr = item.value.map(listItem => {
|
|
44
|
-
if (typeof listItem.value === 'object') {
|
|
45
|
-
return `\n${listItem.value.index}. ${listItem.value.text}`;
|
|
46
|
-
}
|
|
47
|
-
return `\n- ${listItem.value}`;
|
|
48
|
-
});
|
|
49
|
-
return `${listStr.join('')}\n`;
|
|
50
|
-
},
|
|
51
|
-
'MD.mention': (item) => {
|
|
52
|
-
const { value, options } = item;
|
|
53
|
-
if (value === 'everyone' || value === 'all' || value === '' || typeof value !== 'string') {
|
|
46
|
+
const formatTextItem = (item) => {
|
|
47
|
+
if (item.type === 'Link') {
|
|
48
|
+
return `[${item.value}](${item?.options?.link ?? item.value})`;
|
|
49
|
+
}
|
|
50
|
+
if (item.type === 'Mention') {
|
|
51
|
+
if (item.options?.belong === 'everyone' || item.value === 'everyone' || item.value === 'all' || item.value === '' || typeof item.value !== 'string') {
|
|
54
52
|
return '<@everyone>';
|
|
55
53
|
}
|
|
56
|
-
if (options?.belong === 'user') {
|
|
57
|
-
return `<@${value}>`;
|
|
54
|
+
if (item.options?.belong === 'user') {
|
|
55
|
+
return `<@${item.value}>`;
|
|
58
56
|
}
|
|
59
|
-
|
|
60
|
-
return `<#${value}>`;
|
|
57
|
+
if (item.options?.belong === 'channel') {
|
|
58
|
+
return `<#${item.value}>`;
|
|
61
59
|
}
|
|
62
60
|
return '';
|
|
63
|
-
},
|
|
64
|
-
'MD.content': (item) => item.value,
|
|
65
|
-
'MD.button': (item) => {
|
|
66
|
-
const { value } = item || {};
|
|
67
|
-
return value;
|
|
68
61
|
}
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
mds.forEach(item => {
|
|
74
|
-
if (item.type === 'Markdown') {
|
|
75
|
-
const md = item.value;
|
|
76
|
-
md.forEach(line => {
|
|
77
|
-
if (mapToMarkdown[line.type]) {
|
|
78
|
-
contentMd += mapToMarkdown[line.type](line);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
});
|
|
62
|
+
if (item.type === 'Text') {
|
|
63
|
+
const wrapMap = { block: '`', italic: '*', bold: '**', boldItalic: '***', strikethrough: '~~' };
|
|
64
|
+
const wrap = wrapMap[item.options?.style];
|
|
65
|
+
return wrap ? `${wrap}${item.value}${wrap}` : item.value;
|
|
83
66
|
}
|
|
84
|
-
return
|
|
67
|
+
return '';
|
|
85
68
|
};
|
|
86
69
|
const sendchannel = async (client, param, val) => {
|
|
87
70
|
try {
|
|
@@ -89,53 +72,43 @@ const sendchannel = async (client, param, val) => {
|
|
|
89
72
|
return [];
|
|
90
73
|
}
|
|
91
74
|
const channelId = param?.channel_id ?? '';
|
|
92
|
-
const images = val.filter(item => item.type === 'Image' || item.type === 'ImageURL' || item.type === 'ImageFile');
|
|
93
|
-
const buttons = val.filter(item => item.type === 'BT.group');
|
|
94
|
-
const mds = val.filter(item => item.type === 'Markdown');
|
|
95
|
-
const nativeTypes = new Set(['Image', 'ImageURL', 'ImageFile', 'BT.group', 'Markdown', 'Mention', 'Text', 'Link']);
|
|
96
|
-
const unsupportedItems = val.filter(item => !nativeTypes.has(item.type));
|
|
97
75
|
const hide = getDiscordConfig().hideUnsupported;
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
else if (item.options?.style === 'strikethrough') {
|
|
131
|
-
return `~~${item.value}~~`;
|
|
76
|
+
const images = [];
|
|
77
|
+
const buttons = [];
|
|
78
|
+
const textParts = [];
|
|
79
|
+
const mdParts = [];
|
|
80
|
+
const fallbackParts = [];
|
|
81
|
+
for (const item of val) {
|
|
82
|
+
switch (item.type) {
|
|
83
|
+
case 'Image':
|
|
84
|
+
case 'ImageURL':
|
|
85
|
+
case 'ImageFile':
|
|
86
|
+
images.push(item);
|
|
87
|
+
break;
|
|
88
|
+
case 'BT.group':
|
|
89
|
+
case 'ButtonGroup':
|
|
90
|
+
buttons.push(item);
|
|
91
|
+
break;
|
|
92
|
+
case 'Markdown':
|
|
93
|
+
mdParts.push(markdownToDiscordText(item.value, hide));
|
|
94
|
+
break;
|
|
95
|
+
case 'MarkdownOriginal':
|
|
96
|
+
mdParts.push(markdownRawToDiscordText(String(item.value), hide));
|
|
97
|
+
break;
|
|
98
|
+
case 'Mention':
|
|
99
|
+
case 'Text':
|
|
100
|
+
case 'Link':
|
|
101
|
+
textParts.push(formatTextItem(item));
|
|
102
|
+
break;
|
|
103
|
+
default: {
|
|
104
|
+
const t = dataEnumToDiscordText(item, hide);
|
|
105
|
+
if (t) {
|
|
106
|
+
fallbackParts.push(t);
|
|
107
|
+
}
|
|
132
108
|
}
|
|
133
|
-
return item.value;
|
|
134
109
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const contentMd = buildDiscordMdContent(mds);
|
|
138
|
-
const finalContent = [content, contentMd, fallbackText]
|
|
110
|
+
}
|
|
111
|
+
const finalContent = [textParts.join(''), mdParts.join(''), fallbackParts.join('\n')]
|
|
139
112
|
.filter(Boolean)
|
|
140
113
|
.join('\n')
|
|
141
114
|
.replace(/^[^\S\n\r]+|[^\S\n\r]+$/g, '');
|
|
@@ -145,65 +118,28 @@ const sendchannel = async (client, param, val) => {
|
|
|
145
118
|
}
|
|
146
119
|
if (images.length > 0) {
|
|
147
120
|
let bufferData = null;
|
|
148
|
-
for (
|
|
121
|
+
for (const img of images) {
|
|
122
|
+
bufferData = await resolveImageBuffer(img);
|
|
149
123
|
if (bufferData) {
|
|
150
124
|
break;
|
|
151
125
|
}
|
|
152
|
-
const item = images[i];
|
|
153
|
-
if (item.type === 'Image') {
|
|
154
|
-
if (Buffer.isBuffer(item.value)) {
|
|
155
|
-
bufferData = item.value;
|
|
156
|
-
}
|
|
157
|
-
else if (typeof item.value === 'string') {
|
|
158
|
-
if (item.value.startsWith('http://') || item.value.startsWith('https://')) {
|
|
159
|
-
bufferData = await ImageURLToBuffer(item.value);
|
|
160
|
-
}
|
|
161
|
-
else if (item.value.startsWith('base64://')) {
|
|
162
|
-
bufferData = Buffer.from(item.value.slice(9), 'base64');
|
|
163
|
-
}
|
|
164
|
-
else if (item.value.startsWith('file://')) {
|
|
165
|
-
bufferData = readFileSync(item.value.slice(7));
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
bufferData = Buffer.from(item.value, 'base64');
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
else if (item.type === 'ImageURL') {
|
|
173
|
-
const res = await ImageURLToBuffer(item.value);
|
|
174
|
-
bufferData = res;
|
|
175
|
-
}
|
|
176
|
-
else if (item.type === 'ImageFile') {
|
|
177
|
-
bufferData = readFileSync(item.value);
|
|
178
|
-
}
|
|
179
126
|
}
|
|
180
|
-
const res = await client.channelsMessagesForm(channelId, {
|
|
181
|
-
content: finalContent
|
|
182
|
-
}, bufferData);
|
|
127
|
+
const res = await client.channelsMessagesForm(channelId, { content: finalContent }, bufferData);
|
|
183
128
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
184
129
|
}
|
|
185
|
-
if (buttons
|
|
130
|
+
if (buttons.length > 0) {
|
|
186
131
|
let components = null;
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const rows = item.value;
|
|
192
|
-
if (typeof rows === 'string') {
|
|
193
|
-
return;
|
|
132
|
+
for (const item of buttons) {
|
|
133
|
+
if (typeof item.value !== 'string') {
|
|
134
|
+
components = createButtonsData(item.value);
|
|
135
|
+
break;
|
|
194
136
|
}
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
const res = await client.channelsMessages(channelId, {
|
|
198
|
-
content: finalContent,
|
|
199
|
-
components: components
|
|
200
|
-
});
|
|
137
|
+
}
|
|
138
|
+
const res = await client.channelsMessages(channelId, { content: finalContent, components });
|
|
201
139
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
202
140
|
}
|
|
203
141
|
if (finalContent) {
|
|
204
|
-
const res = await client.channelsMessagesForm(channelId, {
|
|
205
|
-
content: finalContent
|
|
206
|
-
});
|
|
142
|
+
const res = await client.channelsMessagesForm(channelId, { content: finalContent });
|
|
207
143
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
208
144
|
}
|
|
209
145
|
return [];
|