reminders command

This commit is contained in:
Julian 2022-08-27 13:22:42 -04:00
parent 5d66c55b5b
commit c0d8ad62cb
Signed by: NotNite
GPG Key ID: BD91A5402CCEB08A
7 changed files with 184 additions and 35 deletions

View File

@ -4,7 +4,6 @@ type Command = {
name: string;
description: string;
aliases?: string[];
draft: boolean;
options?: ApplicationCommandOptions[];
type?: 1;

View File

@ -2,10 +2,12 @@ import Command from "./command";
import ping from "./ping";
import remind from "./remind";
import reminders from "./reminders";
const commands: { [key: string]: Command } = {
ping,
remind
remind,
reminders
};
export default commands;

View File

@ -3,7 +3,6 @@ import Command from "./command";
const ping: Command = {
name: "ping",
description: "Ping the bot.",
draft: false,
command: async (interaction) => {
await interaction.createMessage("Pong!");
}

View File

@ -3,14 +3,19 @@ import Command from "./command";
import db from "../things/db";
import bot from "../things/bot";
import { Constants } from "eris";
import { Constants, InteractionDataOptionsString } from "eris";
import parse from "parse-duration";
import logger from "../things/logger";
import {
Optional,
unravelOption,
unravelOptionalOption
} from "../utils/options";
const remind: Command = {
name: "remind",
description: "Reminds you to do something.",
draft: false,
options: [
{
name: "when",
@ -25,18 +30,19 @@ const remind: Command = {
}
],
command: async (interaction) => {
const whenOption = interaction.data.options?.find((x) => x.name === "when");
const whatOption = interaction.data.options?.find((x) => x.name === "what");
let what = null;
if (whatOption?.type === Constants.ApplicationCommandOptionTypes.STRING)
what = whatOption.value;
// fucking ts
if (whenOption?.type != Constants.ApplicationCommandOptionTypes.STRING)
return;
// i love abusing types
const options = interaction.data.options!;
const whenOption = unravelOption<InteractionDataOptionsString>(
"when",
options
);
const whatOption = unravelOptionalOption<
Optional<InteractionDataOptionsString>
>("what", options);
const when = parse(whenOption.value);
const what = whatOption?.value;
if (when === null) {
await interaction.createMessage({
content:

125
src/commands/reminders.ts Normal file
View File

@ -0,0 +1,125 @@
import Command from "./command";
import db from "../things/db";
import {
CommandInteraction,
Constants,
InteractionDataOptionsNumber,
InteractionDataOptionsSubCommand
} from "eris";
import {
Optional,
unravelOption,
unravelOptionalOption
} from "../utils/options";
async function listReminders(interaction: CommandInteraction) {
const userReminders = await db.reminder.findMany({
where: {
user: (interaction.member || interaction.user)!.id
}
});
console.log(userReminders);
await interaction.createMessage({
embeds: [
{
title: "Your reminders",
description: userReminders
.map((x) => {
const timestamp = `<t:${Math.floor(x.sendAt.getTime() / 1000)}:R>`;
const id = `ID: \`${x.id}\``;
const message = x.message || "No message set";
return `${timestamp} - ${id} - ${message}`;
})
.join("\n")
}
]
});
}
async function deleteReminder(interaction: CommandInteraction, id: number) {
const reminder = await db.reminder.findUnique({
where: {
id
}
});
if (!reminder) {
await interaction.createMessage({
content: "That reminder doesn't exist.",
flags: Constants.MessageFlags.EPHEMERAL
});
return;
}
const user = (interaction.member || interaction.user)!.id;
if (reminder.user !== user) {
await interaction.createMessage({
content: "You can't delete someone else's reminder.",
flags: Constants.MessageFlags.EPHEMERAL
});
return;
}
await db.reminder.delete({
where: {
id
}
});
await interaction.createMessage({
content: "Reminder deleted.",
flags: Constants.MessageFlags.EPHEMERAL
});
}
const reminders: Command = {
name: "reminders",
description: "List your set reminders.",
options: [
{
name: "list",
description: "List all your reminders.",
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND
},
{
name: "delete",
description: "Delete a reminder.",
type: Constants.ApplicationCommandOptionTypes.SUB_COMMAND,
options: [
{
name: "id",
description: "The ID of the reminder to delete.",
required: true,
type: Constants.ApplicationCommandOptionTypes.NUMBER
}
]
}
],
command: async (interaction) => {
const options = interaction.data.options!;
const listOption = unravelOptionalOption<
Optional<InteractionDataOptionsSubCommand>
>("list", options);
const deleteOption = unravelOptionalOption<
Optional<InteractionDataOptionsSubCommand>
>("delete", options);
if (listOption !== undefined) await listReminders(interaction);
if (deleteOption !== undefined) {
const id = unravelOption<InteractionDataOptionsNumber>(
"id",
deleteOption.options!
);
await deleteReminder(interaction, id.value);
}
}
};
export default reminders;

View File

@ -6,29 +6,26 @@ import commands from "./commands/index";
import Eris, { Constants } from "eris";
bot.on("ready", () => {
for (const command of Object.values(commands)) {
if (command.draft) {
logger.info(`Loading draft command ${command.name}`);
const cmds = Object.values(commands).map((x) => {
return {
name: x.name,
description: x.description,
type: Constants.ApplicationCommandTypes.CHAT_INPUT,
options: x.options
};
});
if (process.env["NODE_ENV"] === "production") {
logger.info(`Loading ${cmds.length} commands in global mode...`);
bot.bulkEditCommands(cmds);
} else {
logger.info(`Loading ${cmds.length} commands in test mode...`);
for (const guild of config.testGuilds) {
logger.info(`Loading draft command ${command.name} for guild ${guild}`);
logger.info(`Loading commands in guild ${guild}...`);
bot.createGuildCommand(guild, {
name: command.name,
description: command.description,
type: Constants.ApplicationCommandTypes.CHAT_INPUT,
options: command.options
});
}
} else {
logger.info(`Loading command ${command.name}`);
bot.createCommand({
name: command.name,
description: command.description,
type: Constants.ApplicationCommandTypes.CHAT_INPUT,
options: command.options
});
bot.bulkEditGuildCommands(guild, cmds);
}
}
@ -49,6 +46,11 @@ bot.on("interactionCreate", async (interaction) => {
{ err },
`Error running command ${commandName} for interaction ${interaction.id}`
);
await interaction.createMessage({
content: ":warn: Something went wrong running this command.",
flags: Constants.MessageFlags.EPHEMERAL
});
}
} else {
logger.warn(`Unhandled command ${commandName}?`);

16
src/utils/options.ts Normal file
View File

@ -0,0 +1,16 @@
import { InteractionDataOptions, InteractionDataOptionsSubCommand } from "eris";
export type Optional<T> = T | undefined;
export function unravelOption<T extends InteractionDataOptions>(
name: string,
options: InteractionDataOptions[]
): T {
return options.find((x) => x.name === name) as T;
}
export function unravelOptionalOption<
T extends Optional<InteractionDataOptions>
>(name: string, options: InteractionDataOptions[]): T {
return options.find((x) => x.name === name) as T;
}