@alemonjs/discord 2.1.5 → 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 -156
- 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,82 +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
61
|
}
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
mds.forEach(item => {
|
|
69
|
-
if (item.type === 'Markdown') {
|
|
70
|
-
const md = item.value;
|
|
71
|
-
md.forEach(line => {
|
|
72
|
-
if (mapToMarkdown[line.type]) {
|
|
73
|
-
contentMd += mapToMarkdown[line.type](line);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
});
|
|
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;
|
|
78
66
|
}
|
|
79
|
-
return
|
|
67
|
+
return '';
|
|
80
68
|
};
|
|
81
69
|
const sendchannel = async (client, param, val) => {
|
|
82
70
|
try {
|
|
@@ -84,53 +72,43 @@ const sendchannel = async (client, param, val) => {
|
|
|
84
72
|
return [];
|
|
85
73
|
}
|
|
86
74
|
const channelId = param?.channel_id ?? '';
|
|
87
|
-
const images = val.filter(item => item.type === 'Image' || item.type === 'ImageURL' || item.type === 'ImageFile');
|
|
88
|
-
const buttons = val.filter(item => item.type === 'BT.group');
|
|
89
|
-
const mds = val.filter(item => item.type === 'Markdown');
|
|
90
|
-
const nativeTypes = new Set(['Image', 'ImageURL', 'ImageFile', 'BT.group', 'Markdown', 'Mention', 'Text', 'Link']);
|
|
91
|
-
const unsupportedItems = val.filter(item => !nativeTypes.has(item.type));
|
|
92
75
|
const hide = getDiscordConfig().hideUnsupported;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
else if (item.options?.style === 'strikethrough') {
|
|
126
|
-
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
|
+
}
|
|
127
108
|
}
|
|
128
|
-
return item.value;
|
|
129
109
|
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const contentMd = buildDiscordMdContent(mds);
|
|
133
|
-
const finalContent = [content, contentMd, fallbackText]
|
|
110
|
+
}
|
|
111
|
+
const finalContent = [textParts.join(''), mdParts.join(''), fallbackParts.join('\n')]
|
|
134
112
|
.filter(Boolean)
|
|
135
113
|
.join('\n')
|
|
136
114
|
.replace(/^[^\S\n\r]+|[^\S\n\r]+$/g, '');
|
|
@@ -140,65 +118,28 @@ const sendchannel = async (client, param, val) => {
|
|
|
140
118
|
}
|
|
141
119
|
if (images.length > 0) {
|
|
142
120
|
let bufferData = null;
|
|
143
|
-
for (
|
|
121
|
+
for (const img of images) {
|
|
122
|
+
bufferData = await resolveImageBuffer(img);
|
|
144
123
|
if (bufferData) {
|
|
145
124
|
break;
|
|
146
125
|
}
|
|
147
|
-
const item = images[i];
|
|
148
|
-
if (item.type === 'Image') {
|
|
149
|
-
if (Buffer.isBuffer(item.value)) {
|
|
150
|
-
bufferData = item.value;
|
|
151
|
-
}
|
|
152
|
-
else if (typeof item.value === 'string') {
|
|
153
|
-
if (item.value.startsWith('http://') || item.value.startsWith('https://')) {
|
|
154
|
-
bufferData = await ImageURLToBuffer(item.value);
|
|
155
|
-
}
|
|
156
|
-
else if (item.value.startsWith('base64://')) {
|
|
157
|
-
bufferData = Buffer.from(item.value.slice(9), 'base64');
|
|
158
|
-
}
|
|
159
|
-
else if (item.value.startsWith('file://')) {
|
|
160
|
-
bufferData = readFileSync(item.value.slice(7));
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
bufferData = Buffer.from(item.value, 'base64');
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
else if (item.type === 'ImageURL') {
|
|
168
|
-
const res = await ImageURLToBuffer(item.value);
|
|
169
|
-
bufferData = res;
|
|
170
|
-
}
|
|
171
|
-
else if (item.type === 'ImageFile') {
|
|
172
|
-
bufferData = readFileSync(item.value);
|
|
173
|
-
}
|
|
174
126
|
}
|
|
175
|
-
const res = await client.channelsMessagesForm(channelId, {
|
|
176
|
-
content: finalContent
|
|
177
|
-
}, bufferData);
|
|
127
|
+
const res = await client.channelsMessagesForm(channelId, { content: finalContent }, bufferData);
|
|
178
128
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
179
129
|
}
|
|
180
|
-
if (buttons
|
|
130
|
+
if (buttons.length > 0) {
|
|
181
131
|
let components = null;
|
|
182
|
-
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const rows = item.value;
|
|
187
|
-
if (typeof rows === 'string') {
|
|
188
|
-
return;
|
|
132
|
+
for (const item of buttons) {
|
|
133
|
+
if (typeof item.value !== 'string') {
|
|
134
|
+
components = createButtonsData(item.value);
|
|
135
|
+
break;
|
|
189
136
|
}
|
|
190
|
-
|
|
191
|
-
});
|
|
192
|
-
const res = await client.channelsMessages(channelId, {
|
|
193
|
-
content: finalContent,
|
|
194
|
-
components: components
|
|
195
|
-
});
|
|
137
|
+
}
|
|
138
|
+
const res = await client.channelsMessages(channelId, { content: finalContent, components });
|
|
196
139
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
197
140
|
}
|
|
198
141
|
if (finalContent) {
|
|
199
|
-
const res = await client.channelsMessagesForm(channelId, {
|
|
200
|
-
content: finalContent
|
|
201
|
-
});
|
|
142
|
+
const res = await client.channelsMessagesForm(channelId, { content: finalContent });
|
|
202
143
|
return [createResult(ResultCode.Ok, '完成', res)];
|
|
203
144
|
}
|
|
204
145
|
return [];
|