@alemonjs/discord 2.1.0-alpha.5 → 2.1.0-alpha.8

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 (37) hide show
  1. package/README.md +6 -2
  2. package/lib/config.d.ts +3 -0
  3. package/lib/config.js +22 -0
  4. package/lib/index.d.ts +4 -2
  5. package/lib/index.js +25 -40
  6. package/lib/sdk/api.d.ts +879 -965
  7. package/lib/sdk/api.js +61 -35
  8. package/lib/sdk/typings.d.ts +221 -0
  9. package/lib/sdk/wss.js +9 -37
  10. package/lib/send.js +87 -82
  11. package/package.json +1 -1
  12. package/dist/assets/index.css +0 -1248
  13. package/dist/assets/index.js +0 -11015
  14. package/dist/index.html +0 -15
  15. package/lib/sdk/config.js +0 -10
  16. package/lib/sdk/core/config.js +0 -46
  17. package/lib/sdk/core/from.js +0 -42
  18. package/lib/sdk/message/CHANNEL_TOPIC_UPDATE.d.ts +0 -11
  19. package/lib/sdk/message/CHANNEL_UPDATE.d.ts +0 -48
  20. package/lib/sdk/message/GUILD_MEMBER_ADD.d.ts +0 -28
  21. package/lib/sdk/message/GUILD_MEMBER_REMOVE.d.ts +0 -18
  22. package/lib/sdk/message/GUILD_MEMBER_UPDATE.d.ts +0 -33
  23. package/lib/sdk/message/INTERACTION_CREATE.d.ts +0 -126
  24. package/lib/sdk/message/MESSAGE_CREATE.d.ts +0 -59
  25. package/lib/sdk/message/MESSAGE_DELETE.d.ts +0 -11
  26. package/lib/sdk/message/MESSAGE_REACTION_ADD.d.ts +0 -42
  27. package/lib/sdk/message/MESSAGE_UPDATE.d.ts +0 -56
  28. package/lib/sdk/message/PRESENCE_UPDATE.d.ts +0 -69
  29. package/lib/sdk/message/READY.d.ts +0 -9
  30. package/lib/sdk/message/TYPING_START.d.ts +0 -35
  31. package/lib/sdk/message/VOICE_CHANNEL_STATUS_UPDATE.d.ts +0 -10
  32. package/lib/sdk/message/VOICE_STATE_UPDATE.d.ts +0 -41
  33. package/lib/sdk/message.d.ts +0 -101
  34. package/lib/sdk/types.d.ts +0 -5
  35. package/lib/sdk/types.js +0 -25
  36. package/lib/sdk/wss.d.ts +0 -27
  37. package/lib/sdk/wss.types.d.ts +0 -30
package/lib/sdk/api.js CHANGED
@@ -1,23 +1,62 @@
1
1
  import FormData from 'form-data';
2
2
  import axios from 'axios';
3
- import { config } from './config.js';
4
- import { createPicFrom } from './core/from.js';
3
+ import { existsSync, createReadStream } from 'fs';
4
+ import { Readable, isReadable } from 'stream';
5
+ import { basename } from 'path';
6
+ import { fileTypeFromBuffer, fileTypeFromStream } from 'file-type';
7
+ import { getDiscordConfigValue } from '../config.js';
5
8
 
9
+ /**
10
+ * 创建form
11
+ * @param image
12
+ * @param name
13
+ * @returns
14
+ */
15
+ async function createPicFrom(image, name = 'image.jpg') {
16
+ let picData;
17
+ // 是 string
18
+ if (typeof image === 'string') {
19
+ if (!existsSync(image))
20
+ return false;
21
+ if (!name)
22
+ name = basename(image);
23
+ picData = createReadStream(image);
24
+ // 是 buffer
25
+ }
26
+ else if (Buffer.isBuffer(image)) {
27
+ if (!name)
28
+ name = 'file.' + (await fileTypeFromBuffer(image)).ext;
29
+ picData = new Readable();
30
+ picData.push(image);
31
+ picData.push(null);
32
+ // 是 文件流
33
+ }
34
+ else if (isReadable(image)) {
35
+ if (!name)
36
+ name = 'file.' + (await fileTypeFromStream(image)).ext;
37
+ picData = image;
38
+ }
39
+ else {
40
+ return false;
41
+ }
42
+ return { picData, image, name };
43
+ }
44
+ const API_URL = 'https://discord.com/api/v10';
45
+ const CDB_URL = 'https://cdn.discordapp.com';
6
46
  /**
7
47
  * api接口
8
48
  */
9
49
  class DCAPI {
10
- API_URL = 'https://discord.com/api/v10';
11
- CDB_URL = 'https://cdn.discordapp.com';
12
50
  /**
13
51
  * 基础请求
14
52
  * @param opstion
15
53
  * @returns
16
54
  */
17
55
  request(options) {
18
- const token = config.get('token');
56
+ const value = getDiscordConfigValue();
57
+ const token = value.token;
19
58
  const service = axios.create({
20
- baseURL: this.API_URL,
59
+ baseURL: API_URL,
21
60
  timeout: 6000,
22
61
  headers: {
23
62
  'Content-Type': 'application/json',
@@ -32,9 +71,10 @@ class DCAPI {
32
71
  * @returns
33
72
  */
34
73
  requestCDN(options) {
35
- const token = config.get('token');
74
+ const value = getDiscordConfigValue();
75
+ const token = value.token;
36
76
  const service = axios.create({
37
- baseURL: this.CDB_URL,
77
+ baseURL: CDB_URL,
38
78
  timeout: 6000,
39
79
  headers: {
40
80
  'Content-Type': 'application/json',
@@ -50,7 +90,7 @@ class DCAPI {
50
90
  * @returns
51
91
  */
52
92
  userAvatar(user_id, avatar_hash) {
53
- return `${this.CDB_URL}/avatars/${user_id}/${avatar_hash}.png`;
93
+ return `${CDB_URL}/avatars/${user_id}/${avatar_hash}.png`;
54
94
  }
55
95
  /**
56
96
  *
@@ -72,34 +112,20 @@ class DCAPI {
72
112
  * @param headers
73
113
  * @returns
74
114
  */
75
- async channelsMessages(channel_id, data, headers) {
76
- return this.request({
77
- url: `channels/${channel_id}/messages`,
78
- method: 'post',
79
- headers: headers,
80
- data
81
- }).then(res => res?.data);
82
- }
83
- /**
84
- *
85
- * @param channel_id
86
- * @param img
87
- * @returns
88
- */
89
- async channelsMessagesImage(channel_id, img, param) {
90
- const from = await createPicFrom(img);
91
- if (!from)
92
- return;
93
- const { picData, name } = from;
115
+ async channelsMessagesForm(channel_id, param = {}, img) {
94
116
  const formData = new FormData();
95
- if (param) {
96
- for (const key in param) {
97
- if (param[key]) {
98
- formData.append(key, param[key]);
99
- }
117
+ for (const key in param) {
118
+ if (param[key]) {
119
+ formData.append(key, param[key]);
120
+ }
121
+ }
122
+ if (img) {
123
+ const from = await createPicFrom(img);
124
+ if (from) {
125
+ const { picData, name } = from;
126
+ formData.append('file', picData, name);
100
127
  }
101
128
  }
102
- formData.append('file', picData, name);
103
129
  return this.request({
104
130
  method: 'post',
105
131
  url: `channels/${channel_id}/messages`,
@@ -1571,4 +1597,4 @@ class DCAPI {
1571
1597
  }
1572
1598
  }
1573
1599
 
1574
- export { DCAPI };
1600
+ export { API_URL, CDB_URL, DCAPI };
@@ -0,0 +1,221 @@
1
+ /**
2
+ * buttons start
3
+ */
4
+ type ComponentButton = {
5
+ type: number;
6
+ style: 2;
7
+ label?: string;
8
+ emoji?: any;
9
+ custom_id?: string;
10
+ sku_id?: any;
11
+ url?: string;
12
+ disabled?: boolean;
13
+ };
14
+ type ComponentButtons = {
15
+ type: 1;
16
+ components: ComponentButton[];
17
+ };
18
+ /**
19
+ * buttons end
20
+ */
21
+ /**
22
+ * select start
23
+ */
24
+ type ComponentSelectsOption = {
25
+ label: string;
26
+ value: string;
27
+ description?: string;
28
+ emoji?: {
29
+ name?: string;
30
+ id?: string;
31
+ };
32
+ };
33
+ type ComponentChannelSelect = {
34
+ type: 8;
35
+ custom_id: string;
36
+ placeholder?: string;
37
+ channel_types?: number[];
38
+ };
39
+ type ComponentMentionSelect = {
40
+ type: 7;
41
+ custom_id: string;
42
+ placeholder?: string;
43
+ };
44
+ type ComponentRuleSelect = {
45
+ type: 6;
46
+ custom_id: string;
47
+ placeholder?: string;
48
+ max_values?: number;
49
+ min_values?: number;
50
+ };
51
+ type ComponentUserSelect = {
52
+ type: 5;
53
+ custom_id: string;
54
+ placeholder?: string;
55
+ };
56
+ type ComponentSelect = {
57
+ type: 3;
58
+ custom_id: string;
59
+ max_values?: number;
60
+ min_values?: number;
61
+ options: ComponentSelectsOption[];
62
+ };
63
+ type ComponentSelects = {
64
+ type: 1;
65
+ components: (ComponentSelect | ComponentUserSelect | ComponentRuleSelect | ComponentMentionSelect | ComponentChannelSelect)[];
66
+ };
67
+ /**
68
+ * select end
69
+ */
70
+ /**
71
+ * input start
72
+ */
73
+ type ComponentInput = {
74
+ id?: number;
75
+ type: 4;
76
+ custom_id: string;
77
+ label: string;
78
+ style: number;
79
+ min_length?: number;
80
+ max_length?: number;
81
+ placeholder?: string;
82
+ required?: boolean;
83
+ };
84
+ type ComponentModal = {
85
+ title: string;
86
+ custom_id: string;
87
+ components: {
88
+ type: 1;
89
+ components: ComponentInput[];
90
+ }[];
91
+ };
92
+ /**
93
+ * input end
94
+ */
95
+ /**
96
+ * section start
97
+ */
98
+ type ComponentText = {
99
+ type: 10;
100
+ content: string;
101
+ };
102
+ type ComponentSection = {
103
+ type: 9;
104
+ components: ComponentText[];
105
+ accessory?: {
106
+ type: 11;
107
+ media: {
108
+ url: string;
109
+ };
110
+ };
111
+ };
112
+ /**
113
+ * section end
114
+ */
115
+ type ComponentMedia = {
116
+ type: 12;
117
+ items: {
118
+ media: {
119
+ url: string;
120
+ };
121
+ description?: string;
122
+ }[];
123
+ };
124
+ type ComponentFile = {
125
+ type: 13;
126
+ file: {
127
+ url: string;
128
+ };
129
+ };
130
+ type ComponentSeparator = {
131
+ type: 14;
132
+ divider: boolean;
133
+ spacing: number;
134
+ };
135
+ type ComponentContainer = {
136
+ type: 17;
137
+ accent_color: number;
138
+ components: (ComponentButtons | ComponentSelects | ComponentMedia | ComponentFile | ComponentText | ComponentSection | ComponentSeparator)[];
139
+ };
140
+ type MessageData = {
141
+ content?: string;
142
+ tts?: boolean;
143
+ /**
144
+ * 嵌入
145
+ */
146
+ embeds?: {
147
+ title?: string;
148
+ type?: string;
149
+ description?: string;
150
+ url?: string;
151
+ timestamp?: string;
152
+ color?: number;
153
+ footer?: {
154
+ text: string;
155
+ icon_url?: string;
156
+ proxy_icon_url?: string;
157
+ };
158
+ image?: {
159
+ url: string;
160
+ proxy_url?: string;
161
+ height?: number;
162
+ width?: number;
163
+ };
164
+ thumbnail?: {
165
+ url: string;
166
+ proxy_url?: string;
167
+ height?: number;
168
+ width?: number;
169
+ };
170
+ video?: {
171
+ url: string;
172
+ proxy_url?: string;
173
+ height?: number;
174
+ width?: number;
175
+ };
176
+ provider?: {
177
+ name: string;
178
+ url: string;
179
+ };
180
+ author?: {
181
+ name: string;
182
+ url?: string;
183
+ icon_url?: string;
184
+ proxy_icon_url?: string;
185
+ };
186
+ fields?: {
187
+ name: string;
188
+ value: string;
189
+ inline?: boolean;
190
+ }[];
191
+ }[];
192
+ allowed_mentions?: any;
193
+ message_reference?: any;
194
+ /**
195
+ * 组件
196
+ */
197
+ components?: (ComponentButtons | ComponentSelects | ComponentModal | ComponentMedia | ComponentFile | ComponentText | ComponentSection | ComponentSeparator | ComponentContainer)[];
198
+ sticker_ids?: any;
199
+ files?: any[];
200
+ payload_json?: string;
201
+ attachments?: {
202
+ id: string;
203
+ filename: string;
204
+ description?: string;
205
+ content_type?: string;
206
+ size: number;
207
+ url: string;
208
+ proxy_url?: string;
209
+ height?: number;
210
+ width?: number;
211
+ ephemeral?: boolean;
212
+ duration_secs?: number;
213
+ waveform?: string;
214
+ flags?: number;
215
+ }[];
216
+ flags?: number;
217
+ enforce_nonce?: boolean;
218
+ poll?: any;
219
+ };
220
+
221
+ export type { MessageData };
package/lib/sdk/wss.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import WebSocket from 'ws';
2
2
  import { DCAPI } from './api.js';
3
- import { config } from './config.js';
4
3
  import { getIntents } from './intents.js';
4
+ import { getDiscordConfigValue } from '../config.js';
5
5
 
6
6
  class DCClient extends DCAPI {
7
7
  #heartbeat_interval = 0;
@@ -10,16 +10,8 @@ class DCClient extends DCAPI {
10
10
  #timeout_id = null;
11
11
  #seq = null;
12
12
  #ws;
13
- /**
14
- * 设置配置
15
- * @param opstion
16
- */
17
- constructor(opstion) {
13
+ constructor() {
18
14
  super();
19
- config.set('intent', opstion.intent);
20
- config.set('shard', opstion.shard);
21
- config.set('token', opstion.token);
22
- config.set('gatewayURL', opstion.gatewayURL);
23
15
  return this;
24
16
  }
25
17
  /**
@@ -27,9 +19,10 @@ class DCClient extends DCAPI {
27
19
  * @returns
28
20
  */
29
21
  #aut() {
30
- const token = config.get('token');
31
- const intent = config.get('intent');
32
- const shard = config.get('shard');
22
+ const value = getDiscordConfigValue();
23
+ const token = value.token;
24
+ const intent = value.intent || [];
25
+ const shard = value.shard || [0, 1];
33
26
  return {
34
27
  op: 2,
35
28
  d: {
@@ -45,24 +38,6 @@ class DCClient extends DCAPI {
45
38
  }
46
39
  };
47
40
  }
48
- /**
49
- * 重新确认
50
- */
51
- // #reAut() {
52
- // const token = config.get('token')
53
- // const c = {
54
- // op: 6,
55
- // d: {
56
- // // 会话token
57
- // token: token,
58
- // session_id: this.#session_id,
59
- // // 收到的最后一个序列号
60
- // seq: this.#seq
61
- // }
62
- // }
63
- // console.log('[ws] c', c)
64
- // return c
65
- // }
66
41
  #events = {};
67
42
  /**
68
43
  * 注册事件处理程序
@@ -79,7 +54,9 @@ class DCClient extends DCAPI {
79
54
  * @param shard
80
55
  * @returns
81
56
  */
82
- async connect(gatewayURL) {
57
+ async connect() {
58
+ const value = getDiscordConfigValue();
59
+ const gatewayURL = value.gatewayURL;
83
60
  // 清除序列号
84
61
  this.#seq = null;
85
62
  // 清除心跳
@@ -131,11 +108,6 @@ class DCClient extends DCAPI {
131
108
  console.log('[ws] session_id', this.#session_id);
132
109
  }
133
110
  }
134
- // const events = ['PRESENCE_UPDATE','TYPING_START']
135
- // if (!events.includes(t)) {
136
- // console.log("t", t)
137
- // console.log("d", d)
138
- // }
139
111
  // 事件处理
140
112
  if (this.#events[t]) {
141
113
  try {
package/lib/send.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createResult, ResultCode } from 'alemonjs';
1
2
  import { readFileSync } from 'fs';
2
3
 
3
4
  const ImageURLToBuffer = async (url) => {
@@ -29,97 +30,101 @@ const createButtonsData = (rows) => {
29
30
  });
30
31
  };
31
32
  const sendchannel = async (client, param, val) => {
32
- if (val.length < 0)
33
- return [];
34
- const channel_id = param?.channel_id ?? '';
35
- // images
36
- const images = val.filter(item => item.type == 'Image' || item.type == 'ImageURL' || item.type == 'ImageFile');
37
- // buttons
38
- const buttons = val.filter(item => item.type == 'BT.group');
39
- // text
40
- const content = val
41
- .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
42
- .map(item => {
43
- if (item.type == 'Link') {
44
- return `[${item.value}](${item?.options?.link ?? item.value})`;
45
- }
46
- else if (item.type == 'Mention') {
47
- if (item.value == 'everyone' ||
48
- item.value == 'all' ||
49
- item.value == '' ||
50
- typeof item.value != 'string') {
51
- return `<@everyone>`;
52
- }
53
- if (item.options?.belong == 'user') {
54
- return `<@${item.value}>`;
55
- }
56
- else if (item.options?.belong == 'channel') {
57
- return `<#${item.value}>`;
58
- }
59
- return '';
60
- }
61
- else if (item.type == 'Text') {
62
- if (item.options?.style == 'block') {
63
- return `\`${item.value}\``;
33
+ try {
34
+ if (val.length < 0)
35
+ return [];
36
+ const channel_id = param?.channel_id ?? '';
37
+ // images
38
+ const images = val.filter(item => item.type == 'Image' || item.type == 'ImageURL' || item.type == 'ImageFile');
39
+ // buttons
40
+ const buttons = val.filter(item => item.type == 'BT.group');
41
+ // text
42
+ const content = val
43
+ .filter(item => item.type == 'Mention' || item.type == 'Text' || item.type == 'Link')
44
+ .map(item => {
45
+ if (item.type == 'Link') {
46
+ return `[${item.value}](${item?.options?.link ?? item.value})`;
64
47
  }
65
- else if (item.options?.style == 'italic') {
66
- return `*${item.value}*`;
48
+ else if (item.type == 'Mention') {
49
+ if (item.value == 'everyone' ||
50
+ item.value == 'all' ||
51
+ item.value == '' ||
52
+ typeof item.value != 'string') {
53
+ return `<@everyone>`;
54
+ }
55
+ if (item.options?.belong == 'user') {
56
+ return `<@${item.value}>`;
57
+ }
58
+ else if (item.options?.belong == 'channel') {
59
+ return `<#${item.value}>`;
60
+ }
61
+ return '';
67
62
  }
68
- else if (item.options?.style == 'bold') {
69
- return `**${item.value}**`;
63
+ else if (item.type == 'Text') {
64
+ if (item.options?.style == 'block') {
65
+ return `\`${item.value}\``;
66
+ }
67
+ else if (item.options?.style == 'italic') {
68
+ return `*${item.value}*`;
69
+ }
70
+ else if (item.options?.style == 'bold') {
71
+ return `**${item.value}**`;
72
+ }
73
+ else if (item.options?.style == 'strikethrough') {
74
+ return `~~${item.value}~~`;
75
+ }
76
+ return item.value;
70
77
  }
71
- else if (item.options?.style == 'strikethrough') {
72
- return `~~${item.value}~~`;
78
+ })
79
+ .join('');
80
+ if (images.length > 0) {
81
+ let bufferData = null;
82
+ for (let i = 0; i < images.length; i++) {
83
+ if (bufferData)
84
+ break;
85
+ const item = images[i];
86
+ if (item.type == 'Image') {
87
+ bufferData = Buffer.from(item.value, 'base64');
88
+ }
89
+ else if (item.type == 'ImageURL') {
90
+ const res = await ImageURLToBuffer(item.value);
91
+ bufferData = res;
92
+ }
93
+ else if (item.type == 'ImageFile') {
94
+ bufferData = readFileSync(item.value);
95
+ }
73
96
  }
74
- return item.value;
97
+ const res = await client.channelsMessagesForm(channel_id, {
98
+ content: content
99
+ }, bufferData);
100
+ return [createResult(ResultCode.Ok, '完成', {})];
75
101
  }
76
- })
77
- .join('');
78
- if (images.length > 0) {
79
- let isText = false;
80
- return Promise.all(images.map(async (item) => {
81
- // content
82
- let text = null;
83
- if (!isText) {
84
- text = content;
85
- }
86
- isText = true;
87
- if (item.type == 'Image') {
88
- return client.channelsMessagesImage(channel_id, Buffer.from(item.value, 'base64'), {
89
- content: text
90
- });
91
- }
92
- else if (item.type == 'ImageURL') {
93
- return client.channelsMessagesImage(channel_id, await ImageURLToBuffer(item.value), {
94
- content: text
95
- });
96
- }
97
- else if (item.type == 'ImageFile') {
98
- const data = readFileSync(item.value);
99
- return client.channelsMessagesImage(channel_id, data, { content: text });
100
- }
101
- }));
102
- }
103
- if (buttons && buttons.length > 0) {
104
- return Promise.all(buttons.map(async (item) => {
105
- const rows = item.value;
106
- // 构造成按钮
107
- const data = createButtonsData(rows);
108
- const res = await client.channelsMessages(channel_id, {
102
+ if (buttons && buttons.length > 0) {
103
+ let components = null;
104
+ buttons.forEach(item => {
105
+ if (components)
106
+ return;
107
+ const rows = item.value;
108
+ // 构造成按钮
109
+ components = createButtonsData(rows);
110
+ });
111
+ const res = await client.channelsMessagesForm(channel_id, {
109
112
  content: content,
110
- components: data
113
+ components: components
114
+ });
115
+ return [createResult(ResultCode.Ok, '完成', {})];
116
+ }
117
+ if (content) {
118
+ const res = await client.channelsMessagesForm(channel_id, {
119
+ content: content
111
120
  });
112
- return {
113
- id: res.id
114
- };
115
- }));
121
+ return [createResult(ResultCode.Ok, '完成', {})];
122
+ }
123
+ return [];
116
124
  }
117
- if (content) {
118
- return Promise.all([content].map(item => client.channelsMessages(channel_id, {
119
- content: item
120
- })));
125
+ catch (err) {
126
+ return [createResult(ResultCode.Fail, err?.response?.data ?? err?.message ?? err, null)];
121
127
  }
122
- return Promise.all([]);
123
128
  };
124
129
  const senduser = async (client, param, val) => {
125
130
  if (val.length < 0)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alemonjs/discord",
3
- "version": "2.1.0-alpha.5",
3
+ "version": "2.1.0-alpha.8",
4
4
  "description": "阿柠檬discord平台连接",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",