@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 CHANGED
@@ -8,13 +8,13 @@ const getDiscordConfig = () => {
8
8
  };
9
9
  const getMaster = (UserId) => {
10
10
  const config = getDiscordConfig();
11
- const master_key = config.master_key || [];
12
- const master_id = config.master_id || [];
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 = master_key.includes(UserKey) || master_id.includes(UserId);
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 `[${item.value}]`;
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 ImageURLToBuffer = async (url) => {
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
- return rows.map(row => {
12
- const val = row.value;
13
- return {
14
- type: 1,
15
- components: val.map(button => {
16
- const value = button.value;
17
- const text = button.options?.data ?? '';
18
- return {
19
- type: 2,
20
- custom_id: text,
21
- style: 1,
22
- label: value
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 mapToMarkdown = {
29
- 'MD.text': (item) => item.value,
30
- 'MD.blockquote': (item) => `> ${item.value}\n`,
31
- 'MD.bold': (item) => `**${item.value}**`,
32
- 'MD.italic': (item) => `*${item.value}*`,
33
- 'MD.divider': () => '---\n',
34
- 'MD.image': (item) => `![${item.value}](${item.value})`,
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
- else if (options?.belong === 'channel') {
60
- return `<#${value}>`;
57
+ if (item.options?.belong === 'channel') {
58
+ return `<#${item.value}>`;
61
59
  }
62
60
  return '';
63
61
  }
64
- };
65
- const buildDiscordMdContent = (mds) => {
66
- let contentMd = '';
67
- if (mds && mds.length > 0) {
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 contentMd;
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 fallbackText = unsupportedItems
94
- .map(item => dataEnumToDiscordText(item, hide))
95
- .filter(Boolean)
96
- .join('\n');
97
- const content = val
98
- .filter(item => item.type === 'Mention' || item.type === 'Text' || item.type === 'Link')
99
- .map(item => {
100
- if (item.type === 'Link') {
101
- return `[${item.value}](${item?.options?.link ?? item.value})`;
102
- }
103
- else if (item.type === 'Mention') {
104
- if (item.value === 'everyone' || item.value === 'all' || item.value === '' || typeof item.value !== 'string') {
105
- return '<@everyone>';
106
- }
107
- if (item.options?.belong === 'user') {
108
- return `<@${item.value}>`;
109
- }
110
- else if (item.options?.belong === 'channel') {
111
- return `<#${item.value}>`;
112
- }
113
- return '';
114
- }
115
- else if (item.type === 'Text') {
116
- if (item.options?.style === 'block') {
117
- return `\`${item.value}\``;
118
- }
119
- else if (item.options?.style === 'italic') {
120
- return `*${item.value}*`;
121
- }
122
- else if (item.options?.style === 'bold') {
123
- return `**${item.value}**`;
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
- .join('');
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 (let i = 0; i < images.length; i++) {
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 && buttons.length > 0) {
130
+ if (buttons.length > 0) {
181
131
  let components = null;
182
- buttons.forEach(item => {
183
- if (components) {
184
- return;
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
- components = createButtonsData(rows);
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 [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alemonjs/discord",
3
- "version": "2.1.5",
3
+ "version": "2.1.7",
4
4
  "description": "discord platform connection",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",