@alemonjs/discord 2.1.20 → 2.1.22

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/format.js CHANGED
@@ -26,7 +26,7 @@ const markdownToDiscordText = (items, hideUnsupported) => {
26
26
  return Number(hideUnsupported) >= 2 ? v.url : `[${v.text}](${v.url})`;
27
27
  }
28
28
  case 'MD.image':
29
- return `![image](${item.value})`;
29
+ return `[image](${item.value})`;
30
30
  case 'MD.list':
31
31
  return (item.value
32
32
  .map(li => {
package/lib/index.js CHANGED
@@ -5,6 +5,18 @@ import { getMaster, platform } from './config.js';
5
5
  export { DCAPI as API } from './sdk/api.js';
6
6
  export { useClient, useValue } from './hook.js';
7
7
 
8
+ const SELECT_DUP_PREFIX = '__alemon_dup__:';
9
+ const decodeDuplicateSelectValue = (value) => {
10
+ if (typeof value !== 'string' || !value.startsWith(SELECT_DUP_PREFIX)) {
11
+ return value;
12
+ }
13
+ const content = value.slice(SELECT_DUP_PREFIX.length);
14
+ const separatorIndex = content.indexOf(':');
15
+ if (separatorIndex < 0) {
16
+ return value;
17
+ }
18
+ return content.slice(separatorIndex + 1);
19
+ };
8
20
  const main = () => {
9
21
  const port = process.env?.port || 17117;
10
22
  const url = `ws://127.0.0.1:${port}`;
@@ -60,6 +72,10 @@ const main = () => {
60
72
  else ;
61
73
  });
62
74
  client.on('INTERACTION_CREATE', event => {
75
+ const selectedValues = Array.isArray(event?.data?.values) ? event.data.values.map(item => decodeDuplicateSelectValue(item)) : [];
76
+ if (selectedValues.length > 0) {
77
+ event.data.values = selectedValues.filter((item) => typeof item === 'string');
78
+ }
63
79
  const isPrivate = typeof event['user'] === 'object' ? true : false;
64
80
  const user = isPrivate ? event['user'] : event['member'].user;
65
81
  const UserId = user.id;
@@ -68,7 +84,8 @@ const main = () => {
68
84
  const [isMaster, UserKey] = getMaster(UserId);
69
85
  const isCustom = !!event.data?.custom_id;
70
86
  const isName = !!event.data?.name;
71
- const command = isCustom ? event.data.custom_id : (isName ? `/${event.data.name}` : '');
87
+ const selectedCommand = typeof selectedValues[0] === 'string' ? selectedValues[0] : '';
88
+ const command = selectedCommand || (isCustom ? event.data.custom_id : isName ? `/${event.data.name}` : '');
72
89
  const notAutoConfirmation = isCustom ? /^notAutoConfirmation:/.test(command) : false;
73
90
  const currentMessageText = notAutoConfirmation ? command.replace(/^notAutoConfirmation:/, '') : command;
74
91
  if (isPrivate) {
package/lib/sdk/api.js CHANGED
@@ -44,18 +44,14 @@ class DCAPI {
44
44
  }
45
45
  async channelsMessagesForm(channel_id, param = {}, img) {
46
46
  const formData = new FormData();
47
- for (const key in param) {
48
- if (param[key]) {
49
- formData.append(key, param[key]);
50
- }
51
- }
52
47
  if (img) {
53
48
  const from = await createPicFrom(img);
54
49
  if (from) {
55
50
  const { picData, name } = from;
56
- formData.append('file', picData, name);
51
+ formData.append('files[0]', picData, name);
57
52
  }
58
53
  }
54
+ formData.append('payload_json', JSON.stringify(param ?? {}));
59
55
  return this.request({
60
56
  method: 'post',
61
57
  url: `channels/${channel_id}/messages`,
@@ -82,6 +82,7 @@ interface Data {
82
82
  component_type?: number;
83
83
  type?: number;
84
84
  name?: string;
85
+ values?: string[];
85
86
  }
86
87
  type Public = {
87
88
  version: number;
package/lib/send.js CHANGED
@@ -3,19 +3,23 @@ import { readFileSync } from 'fs';
3
3
  import { dataEnumToDiscordText, markdownRawToDiscordText, markdownToDiscordText } from './format.js';
4
4
  import { getDiscordConfig } from './config.js';
5
5
 
6
+ const SELECT_DUP_PREFIX = '__alemon_dup__:';
7
+ const encodeDuplicateSelectValue = (value, index) => `${SELECT_DUP_PREFIX}${index}:${value}`;
6
8
  const fetchImageBuffer = async (url) => {
7
9
  const arrayBuffer = await fetch(url).then(res => res.arrayBuffer());
8
10
  return Buffer.from(arrayBuffer);
9
11
  };
10
- const createButtonsData = (rows) => rows.map(row => ({
11
- type: 1,
12
- components: row.value.map(button => ({
13
- type: 2,
14
- custom_id: button.options?.notAutoConfirmation ? `notAutoConfirmation:${button.options.data}` : button.options?.data ?? '',
15
- style: 1,
16
- label: button.value
17
- }))
18
- }));
12
+ const createButtonsData = (rows) => {
13
+ return rows.map(row => ({
14
+ type: 1,
15
+ components: row.value.map(button => ({
16
+ type: 2,
17
+ custom_id: button.options?.notAutoConfirmation ? `notAutoConfirmation:${button.options.data}` : (button.options?.data ?? ''),
18
+ style: 1,
19
+ label: button.value
20
+ }))
21
+ }));
22
+ };
19
23
  const createSelectData = (select) => {
20
24
  const meta = select.options ?? {};
21
25
  const kind = meta.kind ?? 'string';
@@ -29,13 +33,19 @@ const createSelectData = (select) => {
29
33
  disabled: meta.disabled
30
34
  };
31
35
  if (kind === 'string') {
32
- base.options = (select.value ?? []).map(opt => ({
33
- label: opt.label,
34
- value: opt.value,
35
- description: opt.description,
36
- default: opt.default,
37
- emoji: opt.emoji ? { name: opt.emoji } : undefined
38
- }));
36
+ const seenValues = new Map();
37
+ base.options = (select.value ?? []).map(opt => {
38
+ const rawValue = String(opt.value ?? '');
39
+ const nextIndex = seenValues.get(rawValue) ?? 0;
40
+ seenValues.set(rawValue, nextIndex + 1);
41
+ return {
42
+ label: opt.label,
43
+ value: nextIndex > 0 ? encodeDuplicateSelectValue(rawValue, nextIndex) : rawValue,
44
+ description: opt.description,
45
+ default: opt.default,
46
+ emoji: opt.emoji ? { name: opt.emoji } : undefined
47
+ };
48
+ });
39
49
  }
40
50
  return { type: 1, components: [base] };
41
51
  };
@@ -135,9 +145,6 @@ const sendchannel = async (client, param, val) => {
135
145
  case 'Embed':
136
146
  embeds.push(item);
137
147
  break;
138
- case 'Modal':
139
- logger.warn('[discord] Modal 必须通过 interaction callback 发送,channelsMessages 流程已跳过');
140
- break;
141
148
  case 'Markdown':
142
149
  mdParts.push(markdownToDiscordText(item.value, hide));
143
150
  break;
@@ -175,6 +182,18 @@ const sendchannel = async (client, param, val) => {
175
182
  components.push(createSelectData(sel));
176
183
  }
177
184
  const embedData = embeds.length > 0 ? embeds.map(createEmbedData) : undefined;
185
+ const hasComponents = components.length > 0;
186
+ const hasEmbeds = !!embedData;
187
+ const payload = {};
188
+ if (finalContent) {
189
+ payload.content = finalContent;
190
+ }
191
+ if (hasComponents) {
192
+ payload.components = components;
193
+ }
194
+ if (hasEmbeds) {
195
+ payload.embeds = embedData;
196
+ }
178
197
  if (images.length > 0) {
179
198
  let bufferData = null;
180
199
  for (const img of images) {
@@ -183,25 +202,20 @@ const sendchannel = async (client, param, val) => {
183
202
  break;
184
203
  }
185
204
  }
186
- const payload = { content: finalContent };
187
- if (components.length > 0) {
188
- payload.components = components;
189
- }
190
- if (embedData) {
191
- payload.embeds = embedData;
205
+ if (bufferData) {
206
+ payload.attachments = [{ id: 0, filename: 'image.png' }];
207
+ if (hasEmbeds) {
208
+ const firstEmbed = payload.embeds[0];
209
+ if (firstEmbed && !firstEmbed.image) {
210
+ firstEmbed.image = { url: 'attachment://image.png' };
211
+ }
212
+ }
192
213
  }
193
- const res = await client.channelsMessagesForm(channelId, payload, bufferData);
214
+ const res = await client.channelsMessagesForm(channelId, payload, bufferData ?? undefined);
194
215
  return [createResult(ResultCode.Ok, '完成', res)];
195
216
  }
196
- if (components.length > 0 || embedData || finalContent) {
197
- const payload = { content: finalContent };
198
- if (components.length > 0) {
199
- payload.components = components;
200
- }
201
- if (embedData) {
202
- payload.embeds = embedData;
203
- }
204
- const res = components.length > 0 || embedData ? await client.channelsMessages(channelId, payload) : await client.channelsMessagesForm(channelId, payload);
217
+ if (hasComponents || hasEmbeds || finalContent) {
218
+ const res = await client.channelsMessages(channelId, payload);
205
219
  return [createResult(ResultCode.Ok, '完成', res)];
206
220
  }
207
221
  return [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alemonjs/discord",
3
- "version": "2.1.20",
3
+ "version": "2.1.22",
4
4
  "description": "discord platform connection",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",