@kevlid/discordmenus 0.0.2
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/LICENSE +15 -0
- package/README.md +60 -0
- package/index.d.ts +255 -0
- package/package.json +27 -0
- package/src/builder.js +50 -0
- package/src/handle/component.js +379 -0
- package/src/handle/modal.js +231 -0
- package/src/index.js +19 -0
- package/src/menuBuilder.js +157 -0
- package/src/menuInstance.js +334 -0
- package/src/menuManager.js +83 -0
- package/src/options/boolean.js +38 -0
- package/src/options/category.js +27 -0
- package/src/options/list.js +105 -0
- package/src/options/number.js +50 -0
- package/src/options/object.js +74 -0
- package/src/options/selectMenu.js +132 -0
- package/src/options/string.js +50 -0
- package/src/render/list.js +347 -0
- package/src/render/modal.js +76 -0
- package/src/render/object.js +417 -0
- package/src/render/page.js +142 -0
- package/src/render/selectMenu.js +1 -0
- package/src/render/types.js +1 -0
- package/src/render/utils.js +60 -0
- package/src/utils/adapters.js +98 -0
- package/src/utils/componentsValidate.js +23 -0
- package/src/utils/constants.js +11 -0
- package/src/utils/customIds.js +67 -0
- package/src/utils/formatKey.js +1 -0
- package/src/utils/helpers.js +100 -0
- package/src/utils/parseModal.js +1 -0
- package/src/utils/storage.js +131 -0
- package/src/utils/types.js +34 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
function getPermissions(interaction) {
|
|
2
|
+
const raw = interaction?.member?.permissions ?? interaction?.member?.permission ?? interaction?.memberPermissions ?? null;
|
|
3
|
+
if (raw == null) {
|
|
4
|
+
return "0";
|
|
5
|
+
}
|
|
6
|
+
if (typeof raw === "object" && raw.allow != null) {
|
|
7
|
+
return String(raw.allow);
|
|
8
|
+
}
|
|
9
|
+
if (typeof raw.valueOf === "function") {
|
|
10
|
+
return String(raw.valueOf());
|
|
11
|
+
}
|
|
12
|
+
return String(raw);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function normalizeInteraction(interaction) {
|
|
16
|
+
const source = typeof interaction?.toJSON === "function" ? interaction.toJSON() : interaction ?? {};
|
|
17
|
+
|
|
18
|
+
const userId =
|
|
19
|
+
source.member?.user?.id
|
|
20
|
+
?? source.user?.id
|
|
21
|
+
?? interaction?.member?.user?.id
|
|
22
|
+
?? interaction?.user?.id
|
|
23
|
+
?? null;
|
|
24
|
+
|
|
25
|
+
let customId =
|
|
26
|
+
source.data?.custom_id
|
|
27
|
+
?? source.data?.customID
|
|
28
|
+
?? source.custom_id
|
|
29
|
+
?? source.customId
|
|
30
|
+
?? interaction?.data?.custom_id
|
|
31
|
+
?? interaction?.data?.customID
|
|
32
|
+
?? interaction?.custom_id
|
|
33
|
+
?? interaction?.customId
|
|
34
|
+
?? null;
|
|
35
|
+
|
|
36
|
+
if (customId == null && typeof source.id === "string" && source.id.length > 0) {
|
|
37
|
+
customId = source.id;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let values = source.data?.values ?? source.values ?? interaction?.data?.values ?? interaction?.values ?? [];
|
|
41
|
+
if (!Array.isArray(values)) {
|
|
42
|
+
values = [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
let components =
|
|
46
|
+
source.data?.components
|
|
47
|
+
?? source.components
|
|
48
|
+
?? source.fields?.components
|
|
49
|
+
?? interaction?.data?.components
|
|
50
|
+
?? interaction?.components
|
|
51
|
+
?? interaction?.fields?.components
|
|
52
|
+
?? [];
|
|
53
|
+
if (!Array.isArray(components)) {
|
|
54
|
+
components = [];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const normalized = {
|
|
58
|
+
type: source.type ?? interaction?.type ?? null,
|
|
59
|
+
guildId:
|
|
60
|
+
source.guildId
|
|
61
|
+
?? source.guild_id
|
|
62
|
+
?? source.guildID
|
|
63
|
+
?? interaction?.guildId
|
|
64
|
+
?? interaction?.guild_id
|
|
65
|
+
?? interaction?.guildID
|
|
66
|
+
?? null,
|
|
67
|
+
member: null,
|
|
68
|
+
user: null,
|
|
69
|
+
data: {
|
|
70
|
+
custom_id: customId,
|
|
71
|
+
values,
|
|
72
|
+
components,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
if (userId != null) {
|
|
77
|
+
normalized.user = { id: userId };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (source.member != null || interaction?.member != null) {
|
|
81
|
+
normalized.member = {
|
|
82
|
+
user: { id: userId },
|
|
83
|
+
permissions: getPermissions(interaction),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return normalized;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function fromEris(interaction) {
|
|
91
|
+
return normalizeInteraction(interaction);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function fromDiscordJS(interaction) {
|
|
95
|
+
return normalizeInteraction(interaction);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = { normalizeInteraction, fromEris, fromDiscordJS };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const { MaxComponents } = require("./constants");
|
|
2
|
+
|
|
3
|
+
function validateComponents(components, max = MaxComponents) {
|
|
4
|
+
if (!Array.isArray(components)) {
|
|
5
|
+
throw new Error("components must be an array");
|
|
6
|
+
}
|
|
7
|
+
if (components.length > max) {
|
|
8
|
+
throw new Error(`Too many components: ${components.length} > ${max}`);
|
|
9
|
+
}
|
|
10
|
+
for (const comp of components) {
|
|
11
|
+
if (typeof comp !== "object" || comp == null) {
|
|
12
|
+
throw new Error("Component is not an object");
|
|
13
|
+
}
|
|
14
|
+
if (!("type" in comp)) {
|
|
15
|
+
throw new Error("Component missing type field");
|
|
16
|
+
}
|
|
17
|
+
if (comp.components) {
|
|
18
|
+
validateComponents(comp.components, max);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { validateComponents };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
CustomIdPrefix: "dm",
|
|
3
|
+
ComponentsV2MessageFlags: 32768,
|
|
4
|
+
EphemeralMessageFlag: 64,
|
|
5
|
+
MaxComponents: 40,
|
|
6
|
+
PageRenderOverhead: 9,
|
|
7
|
+
OptionRenderCost: 4,
|
|
8
|
+
ObjectPageOverhead: 8,
|
|
9
|
+
ObjectListPageOverhead: 8,
|
|
10
|
+
ObjectListItemCost: 5,
|
|
11
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const { encodeCustomId, decodeCustomId, encodeToken, decodeToken } = require("@kevlid/customids");
|
|
2
|
+
const { CustomIdPrefix } = require("./constants");
|
|
3
|
+
|
|
4
|
+
const Presets = {
|
|
5
|
+
userId: "uid",
|
|
6
|
+
previousPage: "pp",
|
|
7
|
+
nextPage: "np",
|
|
8
|
+
previousCategory: "pc",
|
|
9
|
+
nextCategory: "nc",
|
|
10
|
+
nav: "nav",
|
|
11
|
+
view: "view",
|
|
12
|
+
done: "done",
|
|
13
|
+
add: "add",
|
|
14
|
+
edit: "edit",
|
|
15
|
+
delete: "delete",
|
|
16
|
+
modal: "modal",
|
|
17
|
+
subModal: "sub_modal",
|
|
18
|
+
subBoolean: "sub_boolean",
|
|
19
|
+
subList: "sub_list",
|
|
20
|
+
subListModal: "sub_list_modal",
|
|
21
|
+
listItemView: "iv",
|
|
22
|
+
listItemDone: "id",
|
|
23
|
+
listItemField: "if",
|
|
24
|
+
listItemModal: "im",
|
|
25
|
+
listItemBoolToggle: "it",
|
|
26
|
+
navSpacer: "ns",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function encodeId(menuKey, values = [], options = {}) {
|
|
30
|
+
let optionString = "";
|
|
31
|
+
if (Object.keys(options).length > 0) {
|
|
32
|
+
optionString += "|";
|
|
33
|
+
}
|
|
34
|
+
for (const [key, value] of Object.entries(options)) {
|
|
35
|
+
if (key.length > 9) throw new Error("Option keys must be at most 9 characters long");
|
|
36
|
+
optionString += `${key.length}${key}${encodeToken(value)};`;
|
|
37
|
+
}
|
|
38
|
+
let customId = CustomIdPrefix + encodeCustomId([menuKey, ...values]) + optionString;
|
|
39
|
+
if (customId.length > 100) {
|
|
40
|
+
throw new Error(`Encoded custom ID is too long (${customId.length} characters). Consider using shorter option keys or fewer values.`);
|
|
41
|
+
}
|
|
42
|
+
return customId;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function decodeId(id) {
|
|
46
|
+
const raw = id.slice(CustomIdPrefix.length);
|
|
47
|
+
const options = new Map();
|
|
48
|
+
const [parts, optionString] = raw.split("|");
|
|
49
|
+
const { values: decoded } = decodeCustomId(parts);
|
|
50
|
+
const [menu_key, ...values] = decoded;
|
|
51
|
+
if (optionString) {
|
|
52
|
+
const optionParts = optionString.split(";").filter(Boolean);
|
|
53
|
+
for (const part of optionParts) {
|
|
54
|
+
const keyLength = parseInt(part[0]);
|
|
55
|
+
const key = part.slice(1, 1 + keyLength);
|
|
56
|
+
const value = decodeToken(part.slice(1 + keyLength));
|
|
57
|
+
options.set(key, value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { menu_key, values, options };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
encodeId,
|
|
65
|
+
decodeId,
|
|
66
|
+
Presets,
|
|
67
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const { OptionTypes } = require("./types");
|
|
2
|
+
|
|
3
|
+
function arrayClone(v) {
|
|
4
|
+
return Array.isArray(v) ? [...v] : [];
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function asObject(v) {
|
|
8
|
+
return v != null && typeof v === "object" ? v : {};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function objectDefaultsFromKeys(options) {
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const opt of options || []) {
|
|
14
|
+
out[opt.key] = null;
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function objectListPropertyKey(option, token) {
|
|
20
|
+
if (!option || option.itemType !== OptionTypes.Object) {
|
|
21
|
+
return token;
|
|
22
|
+
}
|
|
23
|
+
const idx = parseInt(token, 10);
|
|
24
|
+
const props = option.itemConfig?.properties;
|
|
25
|
+
if (!Number.isNaN(idx) && Array.isArray(props) && props[idx]) {
|
|
26
|
+
return props[idx].key;
|
|
27
|
+
}
|
|
28
|
+
return token;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function objectListItemFailsRequired(option, currentItem) {
|
|
32
|
+
const props = option?.itemConfig?.properties;
|
|
33
|
+
if (!Array.isArray(props)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
for (const property of props) {
|
|
37
|
+
if (!property.required) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
let fieldValue;
|
|
41
|
+
if (currentItem != null && typeof currentItem === "object") {
|
|
42
|
+
fieldValue = currentItem[property.key];
|
|
43
|
+
} else {
|
|
44
|
+
fieldValue = null;
|
|
45
|
+
}
|
|
46
|
+
if (property.type === OptionTypes.String) {
|
|
47
|
+
if (fieldValue == null || String(fieldValue).trim() === "") {
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
} else if (property.type === OptionTypes.Number) {
|
|
51
|
+
if (fieldValue == null || Number.isNaN(Number(fieldValue))) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
} else if (property.type === OptionTypes.Boolean) {
|
|
55
|
+
if (fieldValue == null) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
} else if (fieldValue == null) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function listJumpSize(length) {
|
|
66
|
+
return Math.min(10, Math.max(1, Math.ceil(length * 0.1)));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function shapeObjectListItem(properties, raw) {
|
|
70
|
+
const s = raw != null && typeof raw === "object" ? raw : {};
|
|
71
|
+
const o = {};
|
|
72
|
+
for (const p of properties || []) {
|
|
73
|
+
o[p.key] = Object.prototype.hasOwnProperty.call(s, p.key) ? s[p.key] : null;
|
|
74
|
+
}
|
|
75
|
+
return o;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeObjectListItems(properties, items) {
|
|
79
|
+
if (!Array.isArray(items)) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
return items.map(item => shapeObjectListItem(properties, item));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function objectListItemsNeedReshape(properties, items) {
|
|
86
|
+
const norm = normalizeObjectListItems(properties, items);
|
|
87
|
+
return JSON.stringify(items) !== JSON.stringify(norm);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = {
|
|
91
|
+
arrayClone,
|
|
92
|
+
asObject,
|
|
93
|
+
objectDefaultsFromKeys,
|
|
94
|
+
objectListPropertyKey,
|
|
95
|
+
objectListItemFailsRequired,
|
|
96
|
+
listJumpSize,
|
|
97
|
+
shapeObjectListItem,
|
|
98
|
+
normalizeObjectListItems,
|
|
99
|
+
objectListItemsNeedReshape,
|
|
100
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const { ComponentTypes } = require("../render/types");
|
|
2
|
const results = [];
|
|
1
3
|
if (!Array.isArray(components)) {
|
|
2
4
|
return results;
|
|
3
5
|
}
|
|
4
6
|
for (const row of components) {
|
|
5
7
|
let inputs = [];
|
|
6
8
|
if (row.type === ComponentTypes.ActionRow) {
|
|
7
9
|
if (Array.isArray(row.components)) {
|
|
8
10
|
inputs = row.components;
|
|
9
11
|
}
|
|
10
12
|
} else if (row.type === ComponentTypes.Label) {
|
|
11
13
|
if (row.component != null) {
|
|
12
14
|
inputs = [row.component];
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
for (const input of inputs) {
|
|
16
18
|
if (input == null) {
|
|
17
19
|
continue;
|
|
18
20
|
}
|
|
19
21
|
const customId = input.custom_id ?? input.customId;
|
|
20
22
|
if (customId == null) {
|
|
21
23
|
continue;
|
|
22
24
|
}
|
|
23
25
|
results.push({
|
|
24
26
|
customId: String(customId),
|
|
25
27
|
type: input.type,
|
|
26
28
|
value: input.value ?? null,
|
|
27
29
|
});
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
return results;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
class MenuStorage {
|
|
2
|
+
constructor({ cache = false, cacheTTL = 60000, cacheMaxSize = 500 } = {}) {
|
|
3
|
+
this.cacheEnabled = cache;
|
|
4
|
+
this.cacheTTL = cacheTTL;
|
|
5
|
+
this.cacheMaxSize = cacheMaxSize;
|
|
6
|
+
this.cache = new Map();
|
|
7
|
+
|
|
8
|
+
if (cache) {
|
|
9
|
+
setInterval(() => {
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
for (const [k, entry] of this.cache.entries()) {
|
|
12
|
+
if (now - entry.ts > this.cacheTTL) {
|
|
13
|
+
this.cache.delete(k);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}, cacheTTL);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
cacheKey(key, guildId) {
|
|
21
|
+
if (guildId) {
|
|
22
|
+
return `${guildId}:${key}`;
|
|
23
|
+
}
|
|
24
|
+
return key;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
cacheGet(key, guildId) {
|
|
28
|
+
if (!this.cacheEnabled) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const ck = this.cacheKey(key, guildId);
|
|
32
|
+
const entry = this.cache.get(ck);
|
|
33
|
+
if (!entry) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
if (Date.now() - entry.ts > this.cacheTTL) {
|
|
37
|
+
this.cache.delete(ck);
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return entry.value;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
cacheSet(key, value, guildId) {
|
|
44
|
+
if (!this.cacheEnabled) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (this.cache.size >= this.cacheMaxSize) {
|
|
48
|
+
this.cache.delete(this.cache.keys().next().value);
|
|
49
|
+
}
|
|
50
|
+
this.cache.set(this.cacheKey(key, guildId), { value, ts: Date.now() });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
cacheDelete(key, guildId) {
|
|
54
|
+
if (!this.cacheEnabled) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.cache.delete(this.cacheKey(key, guildId));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
cacheClear(guildId) {
|
|
61
|
+
if (!this.cacheEnabled) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (guildId) {
|
|
65
|
+
const prefix = `${guildId}:`;
|
|
66
|
+
for (const k of this.cache.keys()) {
|
|
67
|
+
if (k.startsWith(prefix)) {
|
|
68
|
+
this.cache.delete(k);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
this.cache.clear();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async get(key, ctx = {}) {
|
|
77
|
+
throw new Error("MenuStorage: get() must be implemented");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async save(key, value, ctx = {}) {
|
|
81
|
+
throw new Error("MenuStorage: save() must be implemented");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handler() {
|
|
85
|
+
return {
|
|
86
|
+
get: async (key, ctx) => {
|
|
87
|
+
const guildId = ctx?.guildId ?? null;
|
|
88
|
+
const cached = this.cacheGet(key, guildId);
|
|
89
|
+
if (cached !== undefined) {
|
|
90
|
+
return cached;
|
|
91
|
+
}
|
|
92
|
+
const result = await this.get(key, ctx);
|
|
93
|
+
this.cacheSet(key, result, guildId);
|
|
94
|
+
return result;
|
|
95
|
+
},
|
|
96
|
+
save: async (key, value, ctx) => {
|
|
97
|
+
const guildId = ctx?.guildId ?? null;
|
|
98
|
+
this.cacheDelete(key, guildId);
|
|
99
|
+
return this.save(key, value, ctx);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
class MemoryMenuStorage extends MenuStorage {
|
|
106
|
+
constructor(opts = {}) {
|
|
107
|
+
super(opts);
|
|
108
|
+
this.data = new Map();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
storeKey(key, guildId) {
|
|
112
|
+
if (guildId) {
|
|
113
|
+
return `${guildId}:${key}`;
|
|
114
|
+
}
|
|
115
|
+
return key;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async get(key, { guildId } = {}) {
|
|
119
|
+
const stored = this.data.get(this.storeKey(key, guildId));
|
|
120
|
+
if (stored === undefined) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
return stored;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async save(key, value, { guildId } = {}) {
|
|
127
|
+
this.data.set(this.storeKey(key, guildId), value);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = { MenuStorage, MemoryMenuStorage };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const OptionTypes = {
|
|
2
|
+
Menu: "menu",
|
|
3
|
+
Category: "category",
|
|
4
|
+
String: "string",
|
|
5
|
+
Number: "number",
|
|
6
|
+
Boolean: "boolean",
|
|
7
|
+
List: "list",
|
|
8
|
+
Object: "object",
|
|
9
|
+
StringSelect: "string_select",
|
|
10
|
+
UserSelect: "user_select",
|
|
11
|
+
RoleSelect: "role_select",
|
|
12
|
+
MentionableSelect: "mentionable_select",
|
|
13
|
+
ChannelSelect: "channel_select",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const InteractionTypes = {
|
|
17
|
+
ApplicationCommand: 2,
|
|
18
|
+
MessageComponent: 3,
|
|
19
|
+
ModalSubmit: 5,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const ResponseTypes = {
|
|
23
|
+
ChannelMessageWithSource: 4,
|
|
24
|
+
DeferredChannelMessageWithSource: 5,
|
|
25
|
+
DeferredUpdateMessage: 6,
|
|
26
|
+
UpdateMessage: 7,
|
|
27
|
+
Modal: 9,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
OptionTypes,
|
|
32
|
+
InteractionTypes,
|
|
33
|
+
ResponseTypes,
|
|
34
|
+
};
|