@alemonjs/qq-bot 2.1.0-alpha.3 → 2.1.0-alpha.31

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.
Files changed (110) hide show
  1. package/README.md +7 -30
  2. package/dist/assets/index.js +1 -1
  3. package/lib/config.d.ts +8 -0
  4. package/lib/config.js +20 -0
  5. package/lib/desktop.d.ts +1 -3
  6. package/lib/desktop.js +3 -12
  7. package/lib/hook.d.ts +220 -9
  8. package/lib/hook.js +20 -18
  9. package/lib/index.d.ts +5 -6
  10. package/lib/index.js +12 -20
  11. package/lib/index.webhook.d.ts +1 -0
  12. package/lib/index.webhook.js +5 -4
  13. package/lib/index.websoket.d.ts +1 -0
  14. package/lib/index.websoket.js +45 -23
  15. package/lib/message/AT_MESSAGE_CREATE.d.ts +35 -0
  16. package/lib/message/AT_MESSAGE_CREATE.js +1 -0
  17. package/lib/message/CHANNEL_CREATE.d.ts +15 -0
  18. package/lib/message/CHANNEL_CREATE.js +1 -0
  19. package/lib/message/CHANNEL_DELETE.d.ts +15 -0
  20. package/lib/message/CHANNEL_DELETE.js +1 -0
  21. package/lib/message/CHANNEL_UPDATE.d.ts +15 -0
  22. package/lib/message/CHANNEL_UPDATE.js +1 -0
  23. package/lib/message/DIRECT_MESSAGE_CREATE.d.ts +29 -0
  24. package/lib/message/DIRECT_MESSAGE_CREATE.js +1 -0
  25. package/lib/message/DIRECT_MESSAGE_DELETE.d.ts +17 -0
  26. package/lib/message/DIRECT_MESSAGE_DELETE.js +1 -0
  27. package/lib/message/ERROR.d.ts +1 -0
  28. package/lib/message/ERROR.js +1 -0
  29. package/lib/message/GUILD_CREATE.d.ts +15 -0
  30. package/lib/message/GUILD_CREATE.js +1 -0
  31. package/lib/message/GUILD_DELETE.d.ts +15 -0
  32. package/lib/message/GUILD_DELETE.js +1 -0
  33. package/lib/message/GUILD_MEMBER_ADD.d.ts +14 -0
  34. package/lib/message/GUILD_MEMBER_ADD.js +1 -0
  35. package/lib/message/GUILD_MEMBER_REMOVE.d.ts +14 -0
  36. package/lib/message/GUILD_MEMBER_REMOVE.js +1 -0
  37. package/lib/message/GUILD_MEMBER_UPDATE.d.ts +14 -0
  38. package/lib/message/GUILD_MEMBER_UPDATE.js +1 -0
  39. package/lib/message/GUILD_UPDATE.d.ts +15 -0
  40. package/lib/message/GUILD_UPDATE.js +1 -0
  41. package/lib/message/INTERACTION_CREATE.d.ts +53 -0
  42. package/lib/message/INTERACTION_CREATE.js +1 -0
  43. package/lib/message/MESSAGE_CREATE.d.ts +1 -0
  44. package/lib/message/MESSAGE_CREATE.js +1 -0
  45. package/lib/message/MESSAGE_DELETE.d.ts +1 -0
  46. package/lib/message/MESSAGE_DELETE.js +1 -0
  47. package/lib/message/MESSAGE_REACTION_ADD.d.ts +13 -0
  48. package/lib/message/MESSAGE_REACTION_ADD.js +1 -0
  49. package/lib/message/MESSAGE_REACTION_REMOVE.d.ts +13 -0
  50. package/lib/message/MESSAGE_REACTION_REMOVE.js +1 -0
  51. package/lib/message/PUBLIC_MESSAGE_DELETE.d.ts +15 -0
  52. package/lib/message/PUBLIC_MESSAGE_DELETE.js +1 -0
  53. package/lib/message/READY.d.ts +6 -0
  54. package/lib/message/READY.js +1 -0
  55. package/lib/message/group/C2C_MESSAGE_CREATE.d.ts +9 -0
  56. package/lib/message/group/C2C_MESSAGE_CREATE.js +1 -0
  57. package/lib/message/group/C2C_MSG_RECEIVE.d.ts +4 -0
  58. package/lib/message/group/C2C_MSG_RECEIVE.js +1 -0
  59. package/lib/message/group/C2C_MSG_REJECT.d.ts +4 -0
  60. package/lib/message/group/C2C_MSG_REJECT.js +1 -0
  61. package/lib/message/group/FRIEND_ADD.d.ts +4 -0
  62. package/lib/message/group/FRIEND_ADD.js +1 -0
  63. package/lib/message/group/FRIEND_DEL.d.ts +4 -0
  64. package/lib/message/group/FRIEND_DEL.js +1 -0
  65. package/lib/message/group/GROUP_ADD_ROBOT.d.ts +5 -0
  66. package/lib/message/group/GROUP_ADD_ROBOT.js +1 -0
  67. package/lib/message/group/GROUP_AT_MESSAGE_CREATE.d.ts +11 -0
  68. package/lib/message/group/GROUP_AT_MESSAGE_CREATE.js +1 -0
  69. package/lib/message/group/GROUP_DEL_ROBOT.d.ts +5 -0
  70. package/lib/message/group/GROUP_DEL_ROBOT.js +1 -0
  71. package/lib/message/group/GROUP_MSG_RECEIVE.d.ts +5 -0
  72. package/lib/message/group/GROUP_MSG_RECEIVE.js +1 -0
  73. package/lib/message/group/GROUP_MSG_REJECT.d.ts +5 -0
  74. package/lib/message/group/GROUP_MSG_REJECT.js +1 -0
  75. package/lib/register.d.ts +2 -3
  76. package/lib/register.js +313 -189
  77. package/lib/sdk/api.d.ts +197 -0
  78. package/lib/sdk/api.js +294 -925
  79. package/lib/sdk/client.webhook.d.ts +9 -0
  80. package/lib/sdk/{client.js → client.webhook.js} +18 -55
  81. package/lib/sdk/client.websoket.d.ts +9 -0
  82. package/lib/sdk/client.websoket.js +52 -97
  83. package/lib/sdk/config.d.ts +1 -0
  84. package/lib/sdk/instance.d.ts +3 -0
  85. package/lib/sdk/instance.js +93 -0
  86. package/lib/sdk/intents.d.ts +3 -0
  87. package/lib/sdk/intents.js +25 -90
  88. package/lib/sdk/message.d.ts +4 -0
  89. package/lib/sdk/message.group.d.ts +24 -0
  90. package/lib/sdk/message.group.js +1 -0
  91. package/lib/sdk/message.guild.d.ts +38 -0
  92. package/lib/sdk/message.guild.js +1 -0
  93. package/lib/sdk/message.js +1 -0
  94. package/lib/sdk/message.public.d.ts +6 -0
  95. package/lib/sdk/message.public.js +1 -0
  96. package/lib/sdk/typing.d.ts +73 -0
  97. package/lib/sdk/typing.js +1 -0
  98. package/lib/sdk/webhook.secret.d.ts +14 -0
  99. package/lib/sdk/webhook.secret.js +6 -21
  100. package/lib/sends.d.ts +29 -0
  101. package/lib/sends.js +340 -596
  102. package/lib/utils.d.ts +1 -0
  103. package/lib/utils.js +8 -0
  104. package/package.json +9 -5
  105. package/lib/index.group.js +0 -19
  106. package/lib/index.guild.js +0 -36
  107. package/lib/sdk/client.websoket.group.js +0 -221
  108. package/lib/sdk/client.websoket.guild.js +0 -205
  109. package/lib/sdk/counter.js +0 -19
  110. package/lib/sdk/from.js +0 -44
package/lib/sends.js CHANGED
@@ -2,144 +2,80 @@ import { readFileSync } from 'fs';
2
2
  import { createResult, ResultCode } from 'alemonjs';
3
3
  import axios from 'axios';
4
4
 
5
- const createButtonsData = (rows) => {
6
- let id = 0;
7
- const data = {
8
- rows: rows.map(row => {
9
- const val = row.value;
10
- return {
11
- buttons: val.map(button => {
12
- const value = button.value;
13
- const options = button.options;
14
- id++;
15
- return {
16
- id: String(id),
17
- render_data: {
18
- label: typeof value == 'object' ? value.title : value,
19
- visited_label: typeof value == 'object' ? value.label : value,
20
- style: 0
21
- },
22
- action: {
23
- // 0 link 1 callback , 2 command
24
- type: typeof options.data === 'object' ? 1 : options?.isLink ? 0 : 2,
25
- permission: {
26
- // 所有人
27
- type: 2
28
- // "specify_role_ids": ["1", "2", "3"]
29
- },
30
- // "click_limit": 10,
31
- unsupport_tips: options?.toolTip ?? '',
32
- data: options?.data ?? '',
33
- // reply: true,
34
- at_bot_show_channel_list: options.showList ?? false,
35
- enter: options?.autoEnter ?? false
36
- }
37
- };
38
- })
39
- };
40
- })
41
- };
42
- return data;
43
- };
44
- const createArkCardData = (value) => {
45
- return {
46
- template_id: 24,
47
- kv: [
48
- {
49
- key: '#DESC#',
50
- value: value.decs
51
- },
52
- {
53
- key: '#PROMPT#',
54
- value: value.prompt
55
- },
56
- {
57
- key: '#TITLE#',
58
- value: value.title
59
- },
60
- {
61
- key: '#METADESC#',
62
- value: value.metadecs
63
- },
64
- {
65
- key: '#IMG#',
66
- value: value.cover
67
- },
68
- {
69
- key: '#LINK#',
70
- value: value.link
71
- },
72
- {
73
- key: '#SUBTITLE#',
74
- value: value.subtitle
75
- }
76
- ]
77
- };
78
- };
79
- const createArkBigCardData = (value) => {
5
+ const MAX_BUTTON_ROWS = 5;
6
+ const MAX_BUTTONS_PER_ROW = 5;
7
+ const createButtonsData = (rows, startId = 0) => {
8
+ let id = startId;
9
+ const clippedRows = rows.slice(0, MAX_BUTTON_ROWS);
80
10
  return {
81
- template_id: 37,
82
- kv: [
83
- {
84
- key: '#PROMPT#',
85
- value: value.prompt
86
- },
87
- {
88
- key: '#METATITLE#',
89
- value: value.title
90
- },
91
- {
92
- key: '#METASUBTITLE#',
93
- value: value.subtitle
94
- },
95
- {
96
- key: '#METACOVER#',
97
- value: value.cover
98
- },
99
- {
100
- key: '#METAURL#',
101
- value: value.link
102
- }
103
- ]
11
+ rows: clippedRows.map(row => ({
12
+ buttons: row.value.slice(0, MAX_BUTTONS_PER_ROW).map(button => {
13
+ const value = button.value;
14
+ const options = button.options;
15
+ id++;
16
+ const typing = options?.type ?? 'command';
17
+ const typeMap = { command: 2, link: 0, call: 1 };
18
+ return {
19
+ id: String(id),
20
+ render_data: {
21
+ label: value,
22
+ visited_label: value,
23
+ style: 0
24
+ },
25
+ action: {
26
+ type: typeMap[typing],
27
+ permission: { type: 2 },
28
+ unsupport_tips: options?.toolTip ?? '',
29
+ data: options?.data ?? '',
30
+ at_bot_show_channel_list: false,
31
+ enter: options?.autoEnter ?? false
32
+ }
33
+ };
34
+ })
35
+ })),
36
+ nextId: id
104
37
  };
105
38
  };
106
- const createArkList = (value) => {
39
+ const createArkCardData = (value) => ({
40
+ template_id: 24,
41
+ kv: [
42
+ { key: '#DESC#', value: value.decs },
43
+ { key: '#PROMPT#', value: value.prompt },
44
+ { key: '#TITLE#', value: value.title },
45
+ { key: '#METADESC#', value: value.metadecs },
46
+ { key: '#IMG#', value: value.cover },
47
+ { key: '#LINK#', value: value.link },
48
+ { key: '#SUBTITLE#', value: value.subtitle }
49
+ ]
50
+ });
51
+ const createArkBigCardData = (value) => ({
52
+ template_id: 37,
53
+ kv: [
54
+ { key: '#PROMPT#', value: value.prompt },
55
+ { key: '#METATITLE#', value: value.title },
56
+ { key: '#METASUBTITLE#', value: value.subtitle },
57
+ { key: '#METACOVER#', value: value.cover },
58
+ { key: '#METAURL#', value: value.link }
59
+ ]
60
+ });
61
+ const createArkListData = (value) => {
107
62
  const [tip, data] = value;
108
63
  return {
109
64
  template_id: 23,
110
65
  kv: [
111
- {
112
- key: '#DESC#',
113
- value: tip.value.desc
114
- },
115
- {
116
- key: '#PROMPT#',
117
- value: tip.value.prompt
118
- },
66
+ { key: '#DESC#', value: tip.value.desc },
67
+ { key: '#PROMPT#', value: tip.value.prompt },
119
68
  {
120
69
  key: '#LIST#',
121
70
  obj: data.value.map(item => {
122
- const value = item.value;
123
- if (typeof value === 'string') {
124
- return {
125
- obj_kv: [
126
- {
127
- key: 'desc',
128
- value: value
129
- }
130
- ]
131
- };
71
+ const v = item.value;
72
+ if (typeof v === 'string') {
73
+ return { obj_kv: [{ key: 'desc', value: v }] };
132
74
  }
133
75
  return {
134
76
  obj_kv: [
135
- {
136
- key: 'desc',
137
- value: value.title
138
- },
139
- {
140
- key: 'link',
141
- value: value.link
142
- }
77
+ { key: 'desc', value: v.title },
78
+ { key: 'link', value: v.link }
143
79
  ]
144
80
  };
145
81
  })
@@ -147,525 +83,333 @@ const createArkList = (value) => {
147
83
  ]
148
84
  };
149
85
  };
150
- /**
151
- * 群组消息
152
- * @param client
153
- * @param event
154
- * @param val
155
- * @returns
156
- */
157
- const GROUP_AT_MESSAGE_CREATE = async (client, event, val) => {
158
- const content = val
159
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
160
- .map(item => {
161
- if (item.type == 'Link') {
162
- return `[${item.value}](${item?.options?.link})`;
163
- }
164
- else if (item.type == 'Mention') {
165
- if (item.value == 'everyone' ||
166
- item.value == 'all' ||
167
- item.value == '' ||
168
- typeof item.value != 'string') {
169
- return ``;
170
- }
171
- if (item.options?.belong == 'user') {
172
- return `<@${item.value}>`;
173
- }
86
+ const mdFormatters = {
87
+ 'MD.title': value => `# ${value}`,
88
+ 'MD.subtitle': value => `## ${value}`,
89
+ 'MD.text': value => `${value} `,
90
+ 'MD.bold': value => `**${value}** `,
91
+ 'MD.divider': () => '\n————————\n',
92
+ 'MD.italic': value => `_${value}_ `,
93
+ 'MD.italicStar': value => `*${value}* `,
94
+ 'MD.strikethrough': value => `~~${value}~~ `,
95
+ 'MD.blockquote': value => `\n> ${value}`,
96
+ 'MD.newline': () => '\n',
97
+ 'MD.link': value => `[🔗${value.text}](${value.url}) `,
98
+ 'MD.image': (value, options) => `\n![text #${options?.width || 208}px #${options?.height || 320}px](${value})\n`,
99
+ 'MD.mention': (value, options) => {
100
+ const { belong } = options || {};
101
+ if (belong === 'channel') {
174
102
  return '';
175
103
  }
176
- else if (item.type == 'Text') {
177
- return item.value;
104
+ if (belong === 'user') {
105
+ return `<qqbot-at-user id="${value}" />`;
178
106
  }
107
+ if (value === 'everyone') {
108
+ return '<qqbot-at-everyone />';
109
+ }
110
+ return `<qqbot-at-user id="${value}" />`;
111
+ },
112
+ 'MD.content': value => `${value}`,
113
+ 'MD.button': (title, options) => {
114
+ const { data } = options || {};
115
+ return `<qqbot-cmd-input text="${data}" show="${title}" />`;
116
+ }
117
+ };
118
+ const createMarkdownText = (data) => {
119
+ return data
120
+ .map(mdItem => {
121
+ if (mdFormatters[mdItem.type]) {
122
+ return mdFormatters[mdItem.type](mdItem?.value, mdItem?.options);
123
+ }
124
+ if (mdItem.type === 'MD.list' && typeof mdItem.value !== 'string') {
125
+ const listStr = mdItem.value.map(listItem => {
126
+ return typeof listItem.value === 'object' ? `\n${listItem.value.index}. ${listItem.value.text}` : `\n- ${listItem.value}`;
127
+ });
128
+ return `${listStr.join('')}\n`;
129
+ }
130
+ if (mdItem.type === 'MD.code') {
131
+ const language = mdItem?.options?.language || '';
132
+ return `\n\`\`\`${language}\n${mdItem.value}\n\`\`\`\n`;
133
+ }
134
+ return String(mdItem['value'] || '');
179
135
  })
180
136
  .join('');
181
- if (content) {
182
- const res = await Promise.all([content].map(async (item) => {
183
- const res = await client.groupOpenMessages(event.GuildId, {
184
- content: item,
185
- msg_id: event.MessageId,
186
- msg_type: 0,
187
- msg_seq: client.getMessageSeq(event.MessageId)
188
- });
189
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
190
- id: res.id
191
- });
192
- })).catch(err => [
193
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
194
- ]);
195
- return res;
137
+ };
138
+ const formatMention = (item, mode) => {
139
+ if (mode === 'guild-direct') {
140
+ return '';
196
141
  }
197
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageFile' || item.type == 'ImageURL');
198
- if (images && images.length > 0) {
199
- return Promise.all(images.map(async (item) => {
200
- if (item.type == 'ImageURL') {
201
- const res = await client.groupOpenMessages(event.GuildId, {
202
- content: '',
203
- media: {
204
- file_info: item.value
205
- },
206
- msg_id: event.MessageId,
207
- msg_type: 7,
208
- msg_seq: client.getMessageSeq(event.MessageId)
209
- });
210
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
211
- id: res.id
212
- });
213
- }
214
- try {
215
- const file_data = item.type == 'ImageFile' ? readFileSync(item.value, 'base64') : item.value;
216
- const file_info = await client
217
- .postRichMediaByGroup(event.GuildId, {
218
- file_type: 1,
219
- file_data: file_data
220
- })
221
- .then(res => res?.file_info);
222
- if (!file_info) {
223
- return createResult(ResultCode.Fail, 'client.postRichMediaByGroup', null);
224
- }
225
- const res = await client.groupOpenMessages(event.GuildId, {
226
- content: '',
227
- media: {
228
- file_info
229
- },
230
- msg_id: event.MessageId,
231
- msg_type: 7,
232
- msg_seq: client.getMessageSeq(event.MessageId)
233
- });
234
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
235
- id: res.id
236
- });
237
- }
238
- catch (error) {
239
- return createResult(ResultCode.Fail, error ? error?.message ?? error : 'client.groupOpenMessages', null);
240
- }
241
- })).catch(err => [
242
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
243
- ]);
142
+ const value = item.value;
143
+ const isEmptyMention = value === 'everyone' || value === 'all' || value === '' || typeof value !== 'string';
144
+ if (mode === 'guild-public') {
145
+ if (isEmptyMention) {
146
+ return '@everyone';
147
+ }
148
+ if (item.options?.belong === 'user') {
149
+ return `<@!${value}>`;
150
+ }
151
+ if (item.options?.belong === 'channel') {
152
+ return `<#${value}>`;
153
+ }
154
+ return '';
244
155
  }
245
- // buttons
246
- const buttons = val.filter(item => item.type == 'BT.group');
247
- if (buttons && buttons.length > 0) {
248
- return Promise.all(buttons.map(async (item) => {
249
- const template_id = item?.options?.template_id;
250
- if (template_id) {
251
- const res = await client.groupOpenMessages(event.GuildId, {
252
- content: '',
253
- msg_id: event.MessageId,
254
- keyboard: {
255
- id: template_id
256
- },
257
- msg_type: 2,
258
- msg_seq: client.getMessageSeq(event.MessageId)
259
- });
260
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
261
- id: res.id
262
- });
263
- }
264
- const rows = item.value;
265
- // 构造成按钮
266
- const data = createButtonsData(rows);
267
- const res = await client.groupOpenMessages(event.GuildId, {
268
- content: '',
269
- msg_id: event.MessageId,
270
- keyboard: {
271
- content: data
272
- },
273
- msg_type: 2,
274
- msg_seq: client.getMessageSeq(event.MessageId)
275
- });
276
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
277
- id: res.id
278
- });
279
- })).catch(err => [
280
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
281
- ]);
156
+ if (isEmptyMention) {
157
+ return '';
282
158
  }
283
- // ark
284
- const ark = val.filter(item => item.type == 'Ark.BigCard' || item.type == 'Ark.Card' || item.type == 'Ark.list');
285
- if (ark && ark.length > 0) {
286
- return Promise.all(ark.map(async (item) => {
287
- if (item.type === 'Ark.Card') {
288
- const arkData = createArkCardData(item.value);
289
- const res = await client.groupOpenMessages(event.GuildId, {
290
- msg_id: event.MessageId,
291
- ark: arkData,
292
- msg_type: 3,
293
- msg_seq: client.getMessageSeq(event.MessageId)
294
- });
295
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', {
296
- id: res.id
297
- });
298
- }
299
- if (item.type === 'Ark.BigCard') {
300
- const arkData = createArkBigCardData(item.value);
301
- const res = await client.groupOpenMessages(event.GuildId, {
302
- msg_id: event.MessageId,
303
- ark: arkData,
304
- msg_type: 3,
305
- msg_seq: client.getMessageSeq(event.MessageId)
306
- });
307
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', { id: res.id });
308
- }
309
- const arkData = createArkList(item.value);
310
- const res = await client.groupOpenMessages(event.GuildId, {
311
- msg_id: event.MessageId,
312
- ark: arkData,
313
- msg_type: 3,
314
- msg_seq: client.getMessageSeq(event.MessageId)
315
- });
316
- return createResult(ResultCode.Ok, 'client.groupOpenMessages', { id: res.id });
317
- })).catch(err => [
318
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
319
- ]);
159
+ if (item.options?.belong === 'user') {
160
+ return `<@${value}>`;
320
161
  }
321
- return Promise.all([]);
162
+ return '';
322
163
  };
323
- /**
324
- * 私聊消息
325
- * @param client
326
- * @param event
327
- * @param val
328
- * @returns
329
- */
330
- const C2C_MESSAGE_CREATE = (client, event, val) => {
331
- const content = val
332
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
164
+ const extractContent = (val, mode) => {
165
+ return val
166
+ .filter(item => item.type === 'Mention' || item.type === 'Text' || item.type === 'Link')
333
167
  .map(item => {
334
- if (item.type == 'Link') {
168
+ if (item.type === 'Link') {
335
169
  return `[${item.value}](${item?.options?.link})`;
336
170
  }
337
- else if (item.type == 'Text') {
171
+ if (item.type === 'Mention') {
172
+ return formatMention(item, mode);
173
+ }
174
+ if (item.type === 'Text') {
338
175
  return item.value;
339
176
  }
340
177
  return '';
341
178
  })
342
179
  .join('');
343
- if (content) {
344
- return Promise.all([content].map(async (item) => {
345
- const res = await client.usersOpenMessages(event.OpenId, {
346
- content: item,
347
- msg_id: event.MessageId,
348
- msg_type: 0,
349
- msg_seq: client.getMessageSeq(event.MessageId)
350
- });
351
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', {
352
- id: res.id
353
- });
354
- })).catch(err => [
355
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
356
- ]);
180
+ };
181
+ const buildBaseParams = (tag, messageId, interactionTag) => {
182
+ if (tag === interactionTag) {
183
+ return { event_id: messageId };
357
184
  }
358
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageFile' || item.type == 'ImageURL');
359
- if (images && images.length > 0) {
360
- return Promise.all(images.map(async (item) => {
361
- if (item.type == 'ImageURL') {
362
- const res = await client.usersOpenMessages(event.OpenId, {
363
- content: '',
364
- media: {
365
- file_info: item.value
366
- },
367
- msg_id: event.MessageId,
368
- msg_type: 7,
369
- msg_seq: client.getMessageSeq(event.MessageId)
370
- });
371
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', {
372
- id: res.id
373
- });
374
- }
375
- const file_data = item.type == 'ImageFile' ? readFileSync(item.value, 'base64') : item.value;
376
- const file_info = await client
377
- .postRichMediaByUsers(event.OpenId, {
378
- file_type: 1,
379
- file_data: file_data
380
- })
381
- .then(res => res?.file_info);
382
- if (!file_info)
383
- return Promise.resolve(null);
384
- return client.usersOpenMessages(event.OpenId, {
385
- content: '',
386
- media: {
387
- file_info
388
- },
389
- msg_id: event.MessageId,
390
- msg_type: 7,
391
- msg_seq: client.getMessageSeq(event.MessageId)
392
- });
393
- })).catch(err => [
394
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
395
- ]);
185
+ return { msg_id: messageId };
186
+ };
187
+ const buildMdAndButtonsParams = (val) => {
188
+ const items = val.filter(item => item.type === 'Markdown' || item.type === 'BT.group' || item.type === 'ButtonTemplate');
189
+ if (items.length === 0) {
190
+ return null;
396
191
  }
397
- // buttons
398
- const buttons = val.filter(item => item.type == 'BT.group');
399
- if (buttons && buttons.length > 0) {
400
- return Promise.all(buttons.map(async (item) => {
401
- const template_id = item?.options?.template_id;
402
- if (template_id) {
403
- const res = await client.usersOpenMessages(event.GuildId, {
404
- content: '',
405
- msg_id: event.MessageId,
406
- keyboard: {
407
- id: template_id
408
- },
409
- msg_type: 2,
410
- msg_seq: client.getMessageSeq(event.MessageId)
411
- });
412
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', {
413
- id: res.id
414
- });
192
+ const params = {};
193
+ for (const item of items) {
194
+ if (item.type === 'ButtonTemplate') {
195
+ if (item?.value) {
196
+ params['keyboard'] = { id: item.value };
415
197
  }
416
- const rows = item.value;
417
- // 构造成按钮
418
- const data = createButtonsData(rows);
419
- const res = await client.usersOpenMessages(event.GuildId, {
420
- content: '',
421
- msg_id: event.MessageId,
422
- keyboard: {
423
- content: data
424
- },
425
- msg_type: 2,
426
- msg_seq: client.getMessageSeq(event.MessageId)
427
- });
428
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', {
429
- id: res.id
430
- });
431
- })).catch(err => [
432
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
433
- ]);
434
- }
435
- // ark
436
- const ark = val.filter(item => item.type == 'Ark.BigCard' || item.type == 'Ark.Card' || item.type == 'Ark.list');
437
- if (ark && ark.length > 0) {
438
- return Promise.all(ark.map(async (item) => {
439
- if (item.type === 'Ark.Card') {
440
- const arkData = createArkCardData(item.value);
441
- const res = await client.usersOpenMessages(event.GuildId, {
442
- msg_id: event.MessageId,
443
- ark: arkData,
444
- msg_type: 3,
445
- msg_seq: client.getMessageSeq(event.MessageId)
446
- });
447
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', { id: res.id });
198
+ }
199
+ else if (item.type === 'BT.group' && typeof item?.value !== 'string') {
200
+ if (params['keyboard']?.content?.rows) {
201
+ const existingRows = params['keyboard'].content.rows;
202
+ const currentId = params['keyboard'].content.nextId ?? existingRows.length;
203
+ const remaining = MAX_BUTTON_ROWS - existingRows.length;
204
+ if (remaining > 0) {
205
+ const { rows: newRows, nextId } = createButtonsData(item.value.slice(0, remaining), currentId);
206
+ existingRows.push(...newRows);
207
+ params['keyboard'].content.nextId = nextId;
208
+ }
448
209
  }
449
- if (item.type === 'Ark.BigCard') {
450
- const arkData = createArkBigCardData(item.value);
451
- const res = await client.usersOpenMessages(event.GuildId, {
452
- msg_id: event.MessageId,
453
- ark: arkData,
454
- msg_type: 3,
455
- msg_seq: client.getMessageSeq(event.MessageId)
456
- });
457
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', { id: res.id });
210
+ else {
211
+ const result = createButtonsData(item.value);
212
+ params['keyboard'] = { content: result };
458
213
  }
459
- const arkData = createArkList(item.value);
460
- const res = await client.usersOpenMessages(event.GuildId, {
461
- msg_id: event.MessageId,
462
- ark: arkData,
463
- msg_type: 3,
464
- msg_seq: client.getMessageSeq(event.MessageId)
465
- });
466
- return createResult(ResultCode.Ok, 'client.usersOpenMessages', { id: res.id });
467
- })).catch(err => [
468
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
469
- ]);
214
+ }
215
+ else if (item.type === 'Markdown' && typeof item?.value !== 'string') {
216
+ const content = createMarkdownText(item.value);
217
+ if (content) {
218
+ if (params['markdown']?.content) {
219
+ params['markdown'].content += content;
220
+ }
221
+ else {
222
+ params['markdown'] = { content };
223
+ }
224
+ }
225
+ }
226
+ }
227
+ if (params['keyboard']?.content?.nextId !== undefined) {
228
+ delete params['keyboard'].content.nextId;
470
229
  }
471
- return Promise.all([]);
230
+ return params;
472
231
  };
473
- /**
474
- * 频道私聊
475
- * @param client
476
- * @param event
477
- * @param val
478
- * @returns
479
- */
480
- const DIRECT_MESSAGE_CREATE = (client, event, val) => {
481
- const content = val
482
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
483
- .map(item => {
484
- if (item.type == 'Link') {
485
- return `[${item.value}](${item?.options?.link})`;
232
+ const buildArkParams = (val) => {
233
+ const items = val.filter(item => item.type === 'Ark.BigCard' || item.type === 'Ark.Card' || item.type === 'Ark.list');
234
+ if (items.length === 0) {
235
+ return null;
236
+ }
237
+ const params = {};
238
+ for (const item of items) {
239
+ if (item.type === 'Ark.Card' && typeof item?.value !== 'string') {
240
+ params['ark'] = createArkCardData(item.value);
486
241
  }
487
- if (item.type == 'Text') {
488
- return item.value;
242
+ else if (item.type === 'Ark.BigCard' && typeof item?.value !== 'string') {
243
+ params['ark'] = createArkBigCardData(item.value);
244
+ }
245
+ else if (item.type === 'Ark.list' && typeof item?.value !== 'string') {
246
+ params['ark'] = createArkListData(item.value);
489
247
  }
490
- return '';
491
- })
492
- .join('');
493
- if (content) {
494
- return Promise.all([content].map(async (item) => {
495
- const res = await client.dmsMessage(event.OpenId, {
496
- content: item,
497
- msg_id: event.MessageId
498
- });
499
- return createResult(ResultCode.Ok, 'client.dmsMessage', { id: res?.id });
500
- })).catch(err => [
501
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
502
- ]);
503
- }
504
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageFile' || item.type == 'ImageURL');
505
- if (images && images.length > 0) {
506
- return Promise.all(images.map(async (item) => {
507
- if (item.value == 'ImageURL') {
508
- // 请求得到buffer
509
- const data = await axios
510
- .get(item.value, {
511
- responseType: 'arraybuffer'
512
- })
513
- .then(res => res?.data);
514
- const res = await client.postDirectImage(event.OpenId, {
515
- msg_id: event.MessageId,
516
- image: data
517
- });
518
- return createResult(ResultCode.Ok, 'client.postDirectImage', { id: res?.id });
519
- }
520
- const file_data = item.type == 'ImageFile' ? readFileSync(item.value) : item.value;
521
- const res = await client.postDirectImage(event.OpenId, {
522
- msg_id: event.MessageId,
523
- image: Buffer.isBuffer(file_data) ? file_data : Buffer.from(file_data)
524
- });
525
- return createResult(ResultCode.Ok, 'client.postDirectImage', { id: res?.id });
526
- })).catch(err => [
527
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
528
- ]);
529
248
  }
530
- return Promise.all([]);
249
+ return params;
531
250
  };
532
- const AT_MESSAGE_CREATE = (client, event, val) => {
533
- const content = val
534
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
535
- .map(item => {
536
- if (item.type == 'Link') {
537
- return `[${item.value}](${item?.options?.link})`;
251
+ const filterImages = (val) => {
252
+ return val.filter(item => item.type === 'Image' || item.type === 'ImageFile' || item.type === 'ImageURL');
253
+ };
254
+ const resolveRichMediaUrl = async (images, uploadMedia) => {
255
+ for (const item of images) {
256
+ let fileData;
257
+ let fileInfo;
258
+ if (item.type === 'ImageURL') {
259
+ fileData = await axios.get(item.value, { responseType: 'arraybuffer' }).then(res => Buffer.from(res.data, 'binary').toString('base64'));
538
260
  }
539
- if (item.type == 'Mention') {
540
- if (item.value == 'everyone' ||
541
- item.value == 'all' ||
542
- item.value == '' ||
543
- typeof item.value != 'string') {
544
- return `@everyone`;
261
+ else if (item.type === 'Image') {
262
+ if (typeof item.value === 'string' && (item.value.startsWith('https://') || item.value.startsWith('http://'))) {
263
+ fileData = await axios.get(item.value, { responseType: 'arraybuffer' }).then(res => Buffer.from(res.data, 'binary').toString('base64'));
545
264
  }
546
- if (item.options?.belong == 'user') {
547
- return `<@!${item.value}>`;
265
+ else if (typeof item.value === 'string' && item.value.startsWith('file://')) {
266
+ const localFilePath = item.value.replace('file://', '');
267
+ fileData = readFileSync(localFilePath, 'base64');
548
268
  }
549
- else if (item.options?.belong == 'channel') {
550
- return `<#${item.value}>`;
269
+ else if (typeof item.value === 'string' && item.value.startsWith('base64://')) {
270
+ fileData = item.value.replace('base64://', '');
271
+ }
272
+ else if (Buffer.isBuffer(item.value)) {
273
+ fileData = item.value.toString('base64');
274
+ }
275
+ else if (typeof item.value === 'string') {
276
+ fileData = item.value;
551
277
  }
552
- return '';
553
278
  }
554
- else if (item.type == 'Text') {
555
- return item.value;
279
+ else if (item.type === 'ImageFile') {
280
+ fileData = readFileSync(item.value, 'base64');
281
+ }
282
+ if (fileData) {
283
+ fileInfo = await uploadMedia({ file_type: 1, file_data: fileData }).then(res => res?.file_info);
284
+ }
285
+ if (fileInfo) {
286
+ return fileInfo;
556
287
  }
557
- })
558
- .join('');
559
- if (content) {
560
- return Promise.all([content].map(async (item) => {
561
- const res = await client.channelsMessagesPost(event.ChannelId, {
562
- content: item,
563
- msg_id: event.MessageId
564
- });
565
- return createResult(ResultCode.Ok, 'client.channelsMessagesPost', { id: res?.id });
566
- })).catch(err => [
567
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
568
- ]);
569
288
  }
570
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageFile' || item.type == 'ImageURL');
571
- if (images && images.length > 0) {
572
- return Promise.all(images.map(async (item) => {
573
- if (item.value == 'ImageURL') {
574
- // 请求得到buffer
575
- const data = await axios
576
- .get(item.value, {
577
- responseType: 'arraybuffer'
578
- })
579
- .then(res => res.data);
580
- const res = await client.postImage(event.ChannelId, {
581
- msg_id: event.MessageId,
582
- image: data
583
- });
584
- return createResult(ResultCode.Ok, 'client.postImage', { id: res?.id });
585
- }
586
- const file_data = item.type == 'ImageFile' ? readFileSync(item.value) : item.value;
587
- const res = await client.postImage(event.ChannelId, {
588
- msg_id: event.MessageId,
589
- image: Buffer.isBuffer(file_data) ? file_data : Buffer.from(file_data)
590
- });
591
- return createResult(ResultCode.Ok, 'client.postImage', { id: res?.id });
592
- })).catch(err => [
593
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
594
- ]);
289
+ return undefined;
290
+ };
291
+ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMessage, label) => {
292
+ const images = filterImages(val);
293
+ if (images.length > 0) {
294
+ const url = await resolveRichMediaUrl(images, uploadMedia);
295
+ if (!url) {
296
+ return [createResult(ResultCode.Fail, '图片上传失败', null)];
297
+ }
298
+ const res = await sendMessage({
299
+ content,
300
+ media: { file_info: url },
301
+ msg_type: 7,
302
+ ...baseParams
303
+ });
304
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
305
+ }
306
+ const mdParams = buildMdAndButtonsParams(val);
307
+ if (mdParams) {
308
+ const res = await sendMessage({ content, msg_type: 2, ...mdParams, ...baseParams });
309
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
310
+ }
311
+ const arkParams = buildArkParams(val);
312
+ if (arkParams) {
313
+ const res = await sendMessage({ content, msg_type: 3, ...arkParams, ...baseParams });
314
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
315
+ }
316
+ if (content) {
317
+ const res = await sendMessage({ content, msg_type: 0, ...baseParams });
318
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
595
319
  }
596
- return Promise.all([]);
320
+ return [];
597
321
  };
598
- /**
599
- *
600
- * @param event
601
- * @param val
602
- * @returns
603
- */
604
- const MESSAGE_CREATE = (client, event, val) => {
605
- const content = val
606
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
607
- .map(item => {
608
- if (item.type == 'Link') {
609
- return `[${item.value}](${item?.options?.link})`;
322
+ const resolveImageBuffer = async (images) => {
323
+ for (const item of images) {
324
+ if (item.type === 'ImageURL') {
325
+ return await axios.get(item.value, { responseType: 'arraybuffer' }).then(res => res?.data);
326
+ }
327
+ if (item.type === 'ImageFile') {
328
+ return readFileSync(item.value);
610
329
  }
611
- if (item.type == 'Mention') {
612
- if (item.value == 'everyone' ||
613
- item.value == 'all' ||
614
- item.value == '' ||
615
- typeof item.value != 'string') {
616
- return `@everyone`;
330
+ if (typeof item.value === 'string') {
331
+ if (item.value.startsWith('https://') || item.value.startsWith('http://')) {
332
+ return await axios.get(item.value, { responseType: 'arraybuffer' }).then(res => res?.data);
617
333
  }
618
- if (item.options?.belong == 'user') {
619
- return `<@!${item.value}>`;
334
+ if (item.value.startsWith('base64://')) {
335
+ return Buffer.from(item.value.replace('base64://', ''), 'base64');
620
336
  }
621
- else if (item.options?.belong == 'channel') {
622
- return `<#${item.value}>`;
337
+ if (item.value.startsWith('file://')) {
338
+ return readFileSync(item.value.replace('file://', ''));
623
339
  }
624
- return '';
340
+ return Buffer.from(item.value, 'base64');
625
341
  }
626
- else if (item.type == 'Text') {
342
+ if (Buffer.isBuffer(item.value)) {
627
343
  return item.value;
628
344
  }
629
- })
630
- .join('');
345
+ }
346
+ return null;
347
+ };
348
+ const sendGuildMessage = async (content, val, baseParams, sendMessage, label) => {
349
+ const images = filterImages(val);
350
+ if (images.length > 0) {
351
+ const imageBuffer = await resolveImageBuffer(images);
352
+ const res = await sendMessage({ content, ...baseParams }, imageBuffer);
353
+ return [createResult(ResultCode.Ok, label, { id: res?.id })];
354
+ }
355
+ const mdParams = buildMdAndButtonsParams(val);
356
+ if (mdParams) {
357
+ const res = await sendMessage({ content: '', ...mdParams, ...baseParams });
358
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
359
+ }
360
+ const arkParams = buildArkParams(val);
361
+ if (arkParams) {
362
+ const res = await sendMessage({ content, ...arkParams, ...baseParams });
363
+ return [createResult(ResultCode.Ok, label, { id: res.id })];
364
+ }
631
365
  if (content) {
632
- return Promise.all([content].map(async (item) => {
633
- const res = await client.channelsMessagesPost(event.ChannelId, {
634
- content: item,
635
- msg_id: event.MessageId
636
- });
637
- return createResult(ResultCode.Ok, 'client.channelsMessagesPost', { id: res?.id });
638
- })).catch(err => [
639
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
640
- ]);
366
+ const res = await sendMessage({ content, ...baseParams });
367
+ return [createResult(ResultCode.Ok, label, { id: res?.id })];
641
368
  }
642
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageFile' || item.type == 'ImageURL');
643
- if (images && images.length > 0) {
644
- return Promise.all(images.map(async (item) => {
645
- if (item.value == 'ImageURL') {
646
- // 请求得到buffer
647
- const data = await axios
648
- .get(item.value, {
649
- responseType: 'arraybuffer'
650
- })
651
- .then(res => res.data);
652
- const res = await client.postImage(event.ChannelId, {
653
- msg_id: event.MessageId,
654
- image: data
655
- });
656
- return createResult(ResultCode.Ok, 'client.postImage', { id: res?.id });
657
- }
658
- const file_data = item.type == 'ImageFile' ? readFileSync(item.value) : item.value;
659
- const res = await client.postImage(event.ChannelId, {
660
- msg_id: event.MessageId,
661
- image: Buffer.isBuffer(file_data) ? file_data : Buffer.from(file_data)
662
- });
663
- return createResult(ResultCode.Ok, 'client.postImage', { id: res?.id });
664
- })).catch(err => [
665
- createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)
666
- ]);
369
+ return [];
370
+ };
371
+ const GROUP_AT_MESSAGE_CREATE = async (client, event, val) => {
372
+ const baseParams = buildBaseParams(event.tag, event.MessageId, 'INTERACTION_CREATE_GROUP');
373
+ const content = extractContent(val, 'group');
374
+ try {
375
+ return await sendOpenApiMessage(content, val, baseParams, data => client.postRichMediaByGroup(event.ChannelId, data), data => client.groupOpenMessages(event.ChannelId, data), 'client.groupOpenMessages');
376
+ }
377
+ catch (err) {
378
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
379
+ }
380
+ };
381
+ const C2C_MESSAGE_CREATE = async (client, event, val) => {
382
+ const baseParams = buildBaseParams(event.tag, event.MessageId, 'INTERACTION_CREATE_C2C');
383
+ const content = extractContent(val, 'group');
384
+ try {
385
+ return await sendOpenApiMessage(content, val, baseParams, data => client.postRichMediaByUser(event.UserId, data), data => client.usersOpenMessages(event.UserId, data), 'client.usersOpenMessages');
667
386
  }
668
- return Promise.all([]);
387
+ catch (err) {
388
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
389
+ }
390
+ };
391
+ const DIRECT_MESSAGE_CREATE = async (client, event, val) => {
392
+ const baseParams = buildBaseParams(event.tag, event.MessageId, 'INTERACTION_CREATE_GUILD');
393
+ const content = extractContent(val, 'guild-direct');
394
+ try {
395
+ return await sendGuildMessage(content, val, baseParams, (data, buf) => client.dmsMessages(event.UserId, data, buf), 'client.dmsMessage');
396
+ }
397
+ catch (err) {
398
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
399
+ }
400
+ };
401
+ const MESSAGE_CREATE = async (client, event, val) => {
402
+ const baseParams = buildBaseParams(event.tag, event.MessageId, 'INTERACTION_CREATE_GUILD');
403
+ const content = extractContent(val, 'guild-public');
404
+ try {
405
+ return await sendGuildMessage(content, val, baseParams, (data, buf) => client.channelsMessages(event.ChannelId, data, buf), 'client.channelsMessagesPost');
406
+ }
407
+ catch (err) {
408
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
409
+ }
410
+ };
411
+ const AT_MESSAGE_CREATE = (client, event, val) => {
412
+ return MESSAGE_CREATE(client, event, val);
669
413
  };
670
414
 
671
415
  export { AT_MESSAGE_CREATE, C2C_MESSAGE_CREATE, DIRECT_MESSAGE_CREATE, GROUP_AT_MESSAGE_CREATE, MESSAGE_CREATE };