slash command system added

This commit is contained in:
Ean Milligan (Bastion) 2023-01-11 21:21:43 -05:00
parent 3e6168a396
commit e0497b8526
12 changed files with 155 additions and 34 deletions

View File

@ -12,6 +12,10 @@ export const config = {
'password': '', // Password for the account, user account may need to be authenticated with the "Standard" Authentication Type if this does not work out of the box 'password': '', // Password for the account, user account may need to be authenticated with the "Standard" Authentication Type if this does not work out of the box
'name': '', // Name of the database Schema to use for the bot 'name': '', // Name of the database Schema to use for the bot
}, },
'link': { // Links to various sites
'sourceCode': 'https://github.com/Burn-E99/GroupUp', // Link to the repository
'supportServer': '', // Invite link to the Discord support server
},
'logChannel': 'the_log_channel', // Discord channel ID where the bot should put startup messages and other error messages needed 'logChannel': 'the_log_channel', // Discord channel ID where the bot should put startup messages and other error messages needed
'reportChannel': 'the_report_channel', // Discord channel ID where reports will be sent when using the built-in report command 'reportChannel': 'the_report_channel', // Discord channel ID where reports will be sent when using the built-in report command
'devServer': 'the_dev_server', // Discord guild ID where testing of indev features/commands will be handled, used in conjuction with the DEVMODE bool in mod.ts 'devServer': 'the_dev_server', // Discord guild ID where testing of indev features/commands will be handled, used in conjuction with the DEVMODE bool in mod.ts

32
deps.ts
View File

@ -7,8 +7,36 @@ export const botId = getBotIdFromToken(LOCALMODE ? config.localToken : config.to
export { enableCachePlugin, enableCacheSweepers } from 'https://deno.land/x/discordeno@17.0.1/plugins/cache/mod.ts'; export { enableCachePlugin, enableCacheSweepers } from 'https://deno.land/x/discordeno@17.0.1/plugins/cache/mod.ts';
export type { BotWithCache } from 'https://deno.land/x/discordeno@17.0.1/plugins/cache/mod.ts'; export type { BotWithCache } from 'https://deno.land/x/discordeno@17.0.1/plugins/cache/mod.ts';
export { ActivityTypes, createBot, editBotMember, editBotStatus, getBotIdFromToken, Intents, sendInteractionResponse, sendMessage, startBot } from 'https://deno.land/x/discordeno@17.0.1/mod.ts'; export {
export type { ActionRow, Bot, ButtonComponent, CreateMessage, Embed, EventHandlers, Guild, Interaction, Message } from 'https://deno.land/x/discordeno@17.0.1/mod.ts'; ActivityTypes,
ApplicationCommandFlags,
ApplicationCommandTypes,
createBot,
editBotMember,
editBotStatus,
getBotIdFromToken,
Intents,
InteractionResponseTypes,
sendInteractionResponse,
sendMessage,
startBot,
} from 'https://deno.land/x/discordeno@17.0.1/mod.ts';
export type {
ActionRow,
ApplicationCommand,
ApplicationCommandOption,
Bot,
ButtonComponent,
CreateApplicationCommand,
CreateMessage,
Embed,
EventHandlers,
Guild,
Interaction,
MakeRequired,
Message,
PermissionStrings,
} from 'https://deno.land/x/discordeno@17.0.1/mod.ts';
export { Client } from 'https://deno.land/x/mysql@v2.11.0/mod.ts'; export { Client } from 'https://deno.land/x/mysql@v2.11.0/mod.ts';

5
mod.ts
View File

@ -2,6 +2,7 @@ import config from './config.ts';
import { DEBUG, LOCALMODE } from './flags.ts'; import { DEBUG, LOCALMODE } from './flags.ts';
import { createBot, enableCachePlugin, enableCacheSweepers, initLog, Intents, startBot } from './deps.ts'; import { createBot, enableCachePlugin, enableCacheSweepers, initLog, Intents, startBot } from './deps.ts';
import { events } from './src/events.ts'; import { events } from './src/events.ts';
import { createSlashCommands } from './src/commands/_index.ts';
// Initialize logging client with folder to use for logs, needs --allow-write set on Deno startup // Initialize logging client with folder to use for logs, needs --allow-write set on Deno startup
initLog('logs', DEBUG); initLog('logs', DEBUG);
@ -15,4 +16,6 @@ const bot = enableCachePlugin(createBot({
enableCacheSweepers(bot); enableCacheSweepers(bot);
// Start the bot // Start the bot
startBot(bot); await startBot(bot);
await createSlashCommands(bot);

View File

@ -1,4 +1,6 @@
import { ApplicationCommandFlags } from '../deps.ts';
import config from '../config.ts'; import config from '../config.ts';
import { lfgChannels } from './db.ts';
export const failColor = 0xe71212; export const failColor = 0xe71212;
export const warnColor = 0xe38f28; export const warnColor = 0xe38f28;
@ -7,24 +9,14 @@ export const infoColor1 = 0x313bf9;
export const infoColor2 = 0x6805e9; export const infoColor2 = 0x6805e9;
export const getRandomStatus = (guildCount: number): string => { export const getRandomStatus = (guildCount: number): string => {
let status = ''; const statuses = [
switch (Math.floor((Math.random() * 5) + 1)) { `Running V${config.version}`,
case 1: `${config.prefix}info to learn more`,
status = `${config.prefix}help for commands`; `Running LFGs in ${guildCount} servers`,
break; ];
case 2: return statuses[Math.floor((Math.random() * statuses.length) + 1)];
status = `Running V${config.version}`; };
break;
case 3: export const isLFGChannel = (channelId: bigint) => {
status = `${config.prefix}info to learn more`; return (lfgChannels.includes(channelId) || channelId === 0n) ? ApplicationCommandFlags.Ephemeral : undefined;
break;
case 4:
status = 'Mention me to check my prefix!';
break;
default:
status = `Running LFGs in ${guildCount} servers`;
break;
}
return status;
}; };

23
src/commands/_index.ts Normal file
View File

@ -0,0 +1,23 @@
import { Bot, CreateApplicationCommand, log, LT, MakeRequired } from '../../deps.ts';
import { Commands } from '../types/commandTypes.ts';
import utils from '../utils.ts';
import info from './info.ts';
export const commands: Array<Commands> = [info];
export const createSlashCommands = async (bot: Bot) => {
const globalCommands: MakeRequired<CreateApplicationCommand, 'name'>[] = [];
for (const command of commands) {
globalCommands.push({
name: command.details.name,
description: command.details.description,
type: command.details.type,
options: command.details.options ? command.details.options : undefined,
dmPermission: command.details.dmPermission ? command.details.dmPermission : false,
defaultMemberPermissions: command.details.defaultMemberPermissions ? command.details.defaultMemberPermissions : undefined,
});
}
await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch((errMsg) => log(LT.ERROR, `Failed to upsert application commands | ${utils.jsonStringifyBig(errMsg)}`));
};

41
src/commands/info.ts Normal file
View File

@ -0,0 +1,41 @@
import config from '../../config.ts';
import { ApplicationCommandTypes, Bot, Interaction, InteractionResponseTypes } from '../../deps.ts';
import { infoColor2, isLFGChannel } from '../commandUtils.ts';
import { CommandDetails } from '../types/commandTypes.ts';
import utils from '../utils.ts';
const details: CommandDetails = {
name: 'info',
description: `Information about ${config.name} and its developer`,
type: ApplicationCommandTypes.ChatInput,
};
const execute = (bot: Bot, interaction: Interaction) => {
bot.helpers.sendInteractionResponse(
interaction.id,
interaction.token,
{
type: InteractionResponseTypes.ChannelMessageWithSource,
data: {
flags: isLFGChannel(interaction.channelId || 0n),
embeds: [{
color: infoColor2,
title: `${config.name}, the LFG bot`,
description: `${config.name} is developed by Ean AKA Burn_E99.
Want to check out my source code? Check it out [here](${config.links.sourceCode}).
Need help with this bot? Join my support server [here](${config.links.supportServer}).
Ran into a bug? Report it to my developers using \`/report [issue description]\`.`,
footer: {
text: `Current Version: ${config.version}`,
},
}],
},
},
).catch((e: Error) => utils.commonLoggers.interactionSendError('info.ts', interaction, e));
};
export default {
details,
execute,
};

View File

@ -13,3 +13,5 @@ export const dbClient = await new Client().connect({
export const queries = { export const queries = {
callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`, callIncCnt: (cmdName: string) => `CALL INC_CNT("${cmdName}");`,
}; };
export const lfgChannels: Array<bigint> = [1055568692697649232n];

View File

@ -1,8 +1,5 @@
import { DEVMODE } from '../flags.ts'; import { DEVMODE } from '../flags.ts';
import { import { EventHandlers } from '../deps.ts';
// Discordeno deps
EventHandlers,
} from '../deps.ts';
import eventHandlers from './events/_index.ts'; import eventHandlers from './events/_index.ts';
export const events: Partial<EventHandlers> = {}; export const events: Partial<EventHandlers> = {};
@ -11,6 +8,7 @@ events.ready = eventHandlers.ready;
events.guildCreate = eventHandlers.guildCreate; events.guildCreate = eventHandlers.guildCreate;
events.guildDelete = eventHandlers.guildDelete; events.guildDelete = eventHandlers.guildDelete;
events.messageCreate = eventHandlers.messageCreate; events.messageCreate = eventHandlers.messageCreate;
events.interactionCreate = eventHandlers.interactionCreate;
if (DEVMODE) { if (DEVMODE) {
events.debug = eventHandlers.debug; events.debug = eventHandlers.debug;

View File

@ -3,6 +3,7 @@ import { guildCreate } from './guildCreate.ts';
import { guildDelete } from './guildDelete.ts'; import { guildDelete } from './guildDelete.ts';
import { debug } from './debug.ts'; import { debug } from './debug.ts';
import { messageCreate } from './messageCreate.ts'; import { messageCreate } from './messageCreate.ts';
import { interactionCreate } from './interactionCreate.ts';
export default { export default {
ready, ready,
@ -10,4 +11,5 @@ export default {
guildDelete, guildDelete,
debug, debug,
messageCreate, messageCreate,
interactionCreate,
}; };

View File

@ -0,0 +1,16 @@
import { Bot, BotWithCache, Interaction } from '../../deps.ts';
import { commands } from '../commands/_index.ts';
const commandNames: Array<string> = commands.map((command) => command.details.name);
export const interactionCreate = (rawBot: Bot, interaction: Interaction) => {
const bot = rawBot as BotWithCache;
if (interaction.data && interaction.id) {
if (interaction.data.name) {
if (commandNames.includes(interaction.data.name)) {
const cmdIdx = commandNames.indexOf(interaction.data.name);
commands[cmdIdx].execute(bot, interaction);
}
}
}
};

15
src/types/commandTypes.ts Normal file
View File

@ -0,0 +1,15 @@
import { ApplicationCommandOption, ApplicationCommandTypes, PermissionStrings } from '../../deps.ts';
export type CommandDetails = {
name: string;
description: string;
type: ApplicationCommandTypes;
options?: ApplicationCommandOption[];
dmPermission?: boolean;
defaultMemberPermissions?: PermissionStrings[];
};
export type Commands = {
details: CommandDetails;
execute: Function;
};

View File

@ -1,16 +1,12 @@
import { import { Interaction, log, LT, Message } from '../deps.ts';
// Log4Deno deps
log,
LT,
// Discordeno deps
Message,
} from '../deps.ts';
const jsonStringifyBig = (input: any) => { const jsonStringifyBig = (input: any) => {
return JSON.stringify(input, (_key, value) => typeof value === 'bigint' ? value.toString() + 'n' : value); return JSON.stringify(input, (_key, value) => typeof value === 'bigint' ? value.toString() + 'n' : value);
}; };
const genericLogger = (level: LT, message: string) => log(level, message); const genericLogger = (level: LT, message: string) => log(level, message);
const interactionSendError = (location: string, interaction: Interaction | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to respond to interaction: ${jsonStringifyBig(interaction)} | Error: ${err.name} - ${err.message}`);
const messageEditError = (location: string, message: Message | string, err: Error) => const messageEditError = (location: string, message: Message | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to edit message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`); genericLogger(LT.ERROR, `${location} | Failed to edit message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const messageGetError = (location: string, message: Message | string, err: Error) => const messageGetError = (location: string, message: Message | string, err: Error) =>
@ -28,6 +24,7 @@ const dbError = (location: string, type: string, err: Error) => genericLogger(LT
export default { export default {
commonLoggers: { commonLoggers: {
dbError, dbError,
interactionSendError,
messageGetError, messageGetError,
messageEditError, messageEditError,
messageSendError, messageSendError,