blob: 4feee826949ea1e2a24dd7aafe3051cfd304e4cb [file] [log] [blame]
pineafan63fc5e22022-08-04 22:04:10 +01001import { callback as roleMenu } from "../actions/roleMenu.js";
pineafan73a7c4a2022-07-24 10:38:04 +01002import verify from "../reflex/verify.js";
3import create from "../actions/tickets/create.js";
4import close from "../actions/tickets/delete.js";
5import createTranscript from "../premium/createTranscript.js";
pineafan02ba0232022-07-24 22:16:15 +01006import Fuse from "fuse.js";
pineafan63fc5e22022-08-04 22:04:10 +01007import { autocomplete as tagAutocomplete } from "../commands/tag.js";
pineafan0f5cc782022-08-12 21:55:42 +01008import type { AutocompleteInteraction, Interaction, MessageComponentInteraction } from "discord.js";
PineaFan64486c42022-12-28 09:21:04 +00009import type { HaikuClient } from "../utils/haiku/index.js";
pineafanad54d752022-04-18 19:01:43 +010010
pineafan63fc5e22022-08-04 22:04:10 +010011export const event = "interactionCreate";
pineafanad54d752022-04-18 19:01:43 +010012
Skyler Greyf21323a2022-08-13 23:58:22 +010013function getAutocomplete(typed: string, options: string[]): { name: string; value: string }[] {
Skyler Grey75ea9172022-08-06 10:22:23 +010014 options = options.filter((option) => option.length <= 100); // thanks discord. 6000 character limit on slash command inputs but only 100 for autocomplete.
15 if (!typed)
16 return options
17 .slice(0, 25)
18 .sort()
19 .map((option) => ({ name: option, value: option }));
20 const fuse = new Fuse(options, {
21 useExtendedSearch: true,
22 findAllMatches: true,
23 minMatchCharLength: 0
24 }).search(typed);
Skyler Grey11236ba2022-08-08 21:13:33 +010025 return fuse.slice(0, 25).map((option) => ({ name: option.item, value: option.item }));
pineafan02ba0232022-07-24 22:16:15 +010026}
27
pineafan0f5cc782022-08-12 21:55:42 +010028function generateStatsChannelAutocomplete(typed: string) {
Skyler Grey11236ba2022-08-08 21:13:33 +010029 const validReplacements = ["serverName", "memberCount", "memberCount:bots", "memberCount:humans"];
pineafan63fc5e22022-08-04 22:04:10 +010030 const autocompletions = [];
31 const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
Skyler Grey75ea9172022-08-06 10:22:23 +010032 if (beforeLastOpenBracket !== null) {
33 for (const replacement of validReplacements) {
Skyler Grey11236ba2022-08-08 21:13:33 +010034 autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`);
Skyler Grey75ea9172022-08-06 10:22:23 +010035 }
36 } else {
37 for (const replacement of validReplacements) {
38 autocompletions.push(`${typed} {${replacement}}`);
39 }
40 }
pineafan63fc5e22022-08-04 22:04:10 +010041 return getAutocomplete(typed, autocompletions);
pineafan41d93562022-07-30 22:10:15 +010042}
pineafan0f5cc782022-08-12 21:55:42 +010043function generateWelcomeMessageAutocomplete(typed: string) {
Skyler Grey75ea9172022-08-06 10:22:23 +010044 const validReplacements = [
45 "serverName",
46 "memberCount",
47 "memberCount:bots",
48 "memberCount:humans",
49 "member:mention",
50 "member:name"
51 ];
pineafan63fc5e22022-08-04 22:04:10 +010052 const autocompletions = [];
53 const beforeLastOpenBracket = typed.match(/(.*){[^{}]{0,15}$/);
Skyler Grey75ea9172022-08-06 10:22:23 +010054 if (beforeLastOpenBracket !== null) {
55 for (const replacement of validReplacements) {
Skyler Grey11236ba2022-08-08 21:13:33 +010056 autocompletions.push(`${beforeLastOpenBracket[1]} {${replacement}}`);
Skyler Grey75ea9172022-08-06 10:22:23 +010057 }
58 } else {
59 for (const replacement of validReplacements) {
60 autocompletions.push(`${typed} {${replacement}}`);
61 }
62 }
pineafan63fc5e22022-08-04 22:04:10 +010063 return getAutocomplete(typed, autocompletions);
pineafan02ba0232022-07-24 22:16:15 +010064}
65
pineafan0f5cc782022-08-12 21:55:42 +010066async function interactionCreate(interaction: Interaction) {
Skyler Greyf21323a2022-08-13 23:58:22 +010067 if (
68 interaction.type === "MESSAGE_COMPONENT" &&
69 (interaction as MessageComponentInteraction).componentType === "BUTTON"
70 ) {
71 const int = interaction as MessageComponentInteraction;
pineafan0f5cc782022-08-12 21:55:42 +010072 switch (int.customId) {
Skyler Grey75ea9172022-08-06 10:22:23 +010073 case "rolemenu": {
74 return await roleMenu(interaction);
75 }
76 case "verifybutton": {
pineafan0f5cc782022-08-12 21:55:42 +010077 return verify(int);
Skyler Grey75ea9172022-08-06 10:22:23 +010078 }
79 case "createticket": {
80 return create(interaction);
81 }
82 case "closeticket": {
83 return close(interaction);
84 }
85 case "createtranscript": {
pineafan0f5cc782022-08-12 21:55:42 +010086 return createTranscript(int);
Skyler Grey75ea9172022-08-06 10:22:23 +010087 }
pineafan02ba0232022-07-24 22:16:15 +010088 }
pineafan02ba0232022-07-24 22:16:15 +010089 } else if (interaction.type === "APPLICATION_COMMAND_AUTOCOMPLETE") {
Skyler Greyf21323a2022-08-13 23:58:22 +010090 const int = interaction as AutocompleteInteraction;
91 switch (`${int.commandName} ${int.options.getSubcommandGroup(false)} ${int.options.getSubcommand(false)}`) {
Skyler Grey75ea9172022-08-06 10:22:23 +010092 case "tag null null": {
Skyler Greyf21323a2022-08-13 23:58:22 +010093 return int.respond(getAutocomplete(int.options.getString("tag") ?? "", await tagAutocomplete(int)));
Skyler Grey75ea9172022-08-06 10:22:23 +010094 }
95 case "settings null stats": {
pineafan0f5cc782022-08-12 21:55:42 +010096 return int.respond(generateStatsChannelAutocomplete(int.options.getString("name") ?? ""));
Skyler Grey75ea9172022-08-06 10:22:23 +010097 }
98 case "settings null welcome": {
Skyler Greyf21323a2022-08-13 23:58:22 +010099 return int.respond(generateWelcomeMessageAutocomplete(int.options.getString("message") ?? ""));
Skyler Grey75ea9172022-08-06 10:22:23 +0100100 }
pineafan02ba0232022-07-24 22:16:15 +0100101 }
pineafanad54d752022-04-18 19:01:43 +0100102 }
103}
104
pineafan0f5cc782022-08-12 21:55:42 +0100105export async function callback(_client: HaikuClient, interaction: Interaction) {
pineafan63fc5e22022-08-04 22:04:10 +0100106 await interactionCreate(interaction);
Skyler Grey75ea9172022-08-06 10:22:23 +0100107}