From df0e082df511b77e8f362f0a07b8e54e409169b8 Mon Sep 17 00:00:00 2001 From: Nicholas Sylke Date: Sun, 20 Jun 2021 18:10:02 -0500 Subject: [PATCH 1/3] feat: follow command --- src/rest/commands/general/follow.ts | 131 ++++++++++++++++++ .../en_US/commands/general/follow.json | 9 ++ 2 files changed, 140 insertions(+) create mode 100644 src/rest/commands/general/follow.ts create mode 100644 src/rest/languages/en_US/commands/general/follow.json diff --git a/src/rest/commands/general/follow.ts b/src/rest/commands/general/follow.ts new file mode 100644 index 0000000..2dce586 --- /dev/null +++ b/src/rest/commands/general/follow.ts @@ -0,0 +1,131 @@ +import Command, { + basicInteractionResponse, +} from "../../common/command/Command.ts"; +import { bot } from "../../cache.ts"; +import { enTranslate, translate } from "../../common/util/i18next.ts"; +import { + DiscordApplicationCommandOptionTypes, + followChannel, + getChannelWebhooks, + snowflakeToBigint, + validatePermissions, +} from "../../../../deps.ts"; + +const FollowCommand: Command = async (interaction) => { + const guildId: bigint = snowflakeToBigint(interaction.guildId!); + + if ( + !validatePermissions(snowflakeToBigint(interaction.member!.permissions), [ + "MANAGE_WEBHOOKS", + ]) + ) { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "permission:USER_MISSING_PERMISSION", { + permission: "Manage Webhooks", + }), + ); + } + + const raw = interaction.data?.options?.[0]; + + if (raw?.name === "announcements") { + const channelId: bigint = snowflakeToBigint(interaction.channelId!); + + const channelWebhooks = await getChannelWebhooks( + channelId, + ); + + if (channelWebhooks.size >= 10) { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:WEBHOOK_LIMIT"), + ); + } + + try { + // 268559149175013376 is the ID of our announcement channel. + await followChannel(snowflakeToBigint("268559149175013376"), channelId); + } catch { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "permission:SELF_MISSING_PERMISSION", { + permission: "Manage Webhooks", + }), + ); + } + + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:ANNOUNCEMENTS_FOLLOWED"), + ); + } else if (raw?.name === "status") { + const channelId: bigint = snowflakeToBigint(interaction.channelId!); + + const channelWebhooks = await getChannelWebhooks( + channelId, + ); + + if (channelWebhooks.size >= 10) { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:WEBHOOK_LIMIT"), + ); + } + + try { + // 621817852726607882 is the ID of our status channel. + await followChannel(snowflakeToBigint("621817852726607882"), channelId); + } catch { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "permission:SELF_MISSING_PERMISSION", { + permission: "Manage Webhooks", + }), + ); + } + + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:STATUS_FOLLOWED"), + ); + } else { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:INVALID_ARGUMENT"), + ); + } +}; + +FollowCommand.options = { + name: "follow", + description: enTranslate("commands/general/follow:COMMAND_DESCRIPTION"), + options: [ + { + required: false, + name: "announcements", + description: enTranslate( + "commands/general/follow:SUBCOMMAND_DESCRIPTION_ANNOUNCEMENTS", + ), + type: DiscordApplicationCommandOptionTypes.SubCommand, + }, + { + required: false, + name: "status", + description: enTranslate( + "commands/general/follow:SUBCOMMAND_DESCRIPTION_STATUS", + ), + type: DiscordApplicationCommandOptionTypes.SubCommand, + }, + ], +}; + +bot.commands.add(FollowCommand); diff --git a/src/rest/languages/en_US/commands/general/follow.json b/src/rest/languages/en_US/commands/general/follow.json new file mode 100644 index 0000000..416a105 --- /dev/null +++ b/src/rest/languages/en_US/commands/general/follow.json @@ -0,0 +1,9 @@ +{ + "COMMAND_DESCRIPTION": "Creates a webhook to follow TypicalBot announcements or status updates in this channel.", + "SUBCOMMAND_DESCRIPTION_ANNOUNCEMENTS": "Follow TypicalBot announcements in this channel.", + "SUBCOMMAND_DESCRIPTION_STATUS": "Follow TypicalBot status updates in this channel.", + "INVALID_ARGUMENT": "Please specify which TypicalBot channel you want to follow.", + "WEBHOOK_LIMIT": "The maximum webhooks that Discord allows in one channel is 10. Please remove a webhook and try again.", + "ANNOUNCEMENTS_FOLLOWED": "You have successfully followed TypicalBot announcements in this channel.", + "STATUS_FOLLOWED": "You have successfully followed TypicalBot status updates in this channel." +} From e66ae4c2f48527ecb68e59236659510f6e486eec Mon Sep 17 00:00:00 2001 From: Nicholas Sylke Date: Sun, 20 Jun 2021 19:44:51 -0500 Subject: [PATCH 2/3] refactor: use env for channel to follow; clean up code --- .env.example | 2 + src/rest/commands/general/follow.ts | 61 +++++-------------- .../en_US/commands/general/follow.json | 4 +- 3 files changed, 19 insertions(+), 48 deletions(-) diff --git a/.env.example b/.env.example index fc041d7..7260803 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,5 @@ EVENT_HANDLER_PORT=8080 EVENT_HANDLER_SECRET_KEY= EVENT_HANDLER_URL=http://localhost:8080 INTERNAL_API= +FOLLOW_ANNOUNCEMENTS=268559149175013376 +FOLLOW_STATUS=621817852726607882 \ No newline at end of file diff --git a/src/rest/commands/general/follow.ts b/src/rest/commands/general/follow.ts index 2dce586..76b56cf 100644 --- a/src/rest/commands/general/follow.ts +++ b/src/rest/commands/general/follow.ts @@ -30,42 +30,20 @@ const FollowCommand: Command = async (interaction) => { const raw = interaction.data?.options?.[0]; - if (raw?.name === "announcements") { - const channelId: bigint = snowflakeToBigint(interaction.channelId!); - - const channelWebhooks = await getChannelWebhooks( - channelId, - ); - - if (channelWebhooks.size >= 10) { - return basicInteractionResponse( - interaction.id, - interaction.token, - translate(guildId, "commands/general/follow:WEBHOOK_LIMIT"), - ); - } - - try { - // 268559149175013376 is the ID of our announcement channel. - await followChannel(snowflakeToBigint("268559149175013376"), channelId); - } catch { - return basicInteractionResponse( - interaction.id, - interaction.token, - translate(guildId, "permission:SELF_MISSING_PERMISSION", { - permission: "Manage Webhooks", - }), - ); - } - + if (!raw || !(raw.name === "announcements" || raw.name === "status")) { return basicInteractionResponse( interaction.id, interaction.token, - translate(guildId, "commands/general/follow:ANNOUNCEMENTS_FOLLOWED"), + translate(guildId, "commands/general/follow:INVALID_ARGUMENT"), ); - } else if (raw?.name === "status") { - const channelId: bigint = snowflakeToBigint(interaction.channelId!); + } + const channelId: bigint = snowflakeToBigint(interaction.channelId!); + const channelToFollow = Deno.env.get( + `FOLLOW_${raw.name.toUpperCase()}`, + ); + + try { const channelWebhooks = await getChannelWebhooks( channelId, ); @@ -78,29 +56,20 @@ const FollowCommand: Command = async (interaction) => { ); } - try { - // 621817852726607882 is the ID of our status channel. - await followChannel(snowflakeToBigint("621817852726607882"), channelId); - } catch { - return basicInteractionResponse( - interaction.id, - interaction.token, - translate(guildId, "permission:SELF_MISSING_PERMISSION", { - permission: "Manage Webhooks", - }), - ); - } + await followChannel(snowflakeToBigint(channelToFollow!), channelId); return basicInteractionResponse( interaction.id, interaction.token, - translate(guildId, "commands/general/follow:STATUS_FOLLOWED"), + translate(guildId, `commands/general/follow:${channelToFollow!}`), ); - } else { + } catch { return basicInteractionResponse( interaction.id, interaction.token, - translate(guildId, "commands/general/follow:INVALID_ARGUMENT"), + translate(guildId, "permission:SELF_MISSING_PERMISSION", { + permission: "Manage Webhooks", + }), ); } }; diff --git a/src/rest/languages/en_US/commands/general/follow.json b/src/rest/languages/en_US/commands/general/follow.json index 416a105..d632155 100644 --- a/src/rest/languages/en_US/commands/general/follow.json +++ b/src/rest/languages/en_US/commands/general/follow.json @@ -4,6 +4,6 @@ "SUBCOMMAND_DESCRIPTION_STATUS": "Follow TypicalBot status updates in this channel.", "INVALID_ARGUMENT": "Please specify which TypicalBot channel you want to follow.", "WEBHOOK_LIMIT": "The maximum webhooks that Discord allows in one channel is 10. Please remove a webhook and try again.", - "ANNOUNCEMENTS_FOLLOWED": "You have successfully followed TypicalBot announcements in this channel.", - "STATUS_FOLLOWED": "You have successfully followed TypicalBot status updates in this channel." + "FOLLOW_ANNOUNCEMENTS": "You have successfully followed TypicalBot announcements in this channel.", + "FOLLOW_STATUS": "You have successfully followed TypicalBot status updates in this channel." } From 672b3991a2364755793a3b75bcdf137267b9d771 Mon Sep 17 00:00:00 2001 From: Nicholas Sylke Date: Mon, 5 Jul 2021 12:09:25 -0500 Subject: [PATCH 3/3] feat: vote command --- .../src/commands/general/vote.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/typicalbot-rest/src/commands/general/vote.ts diff --git a/packages/typicalbot-rest/src/commands/general/vote.ts b/packages/typicalbot-rest/src/commands/general/vote.ts new file mode 100644 index 0000000..cccf109 --- /dev/null +++ b/packages/typicalbot-rest/src/commands/general/vote.ts @@ -0,0 +1,20 @@ +import Command, { + basicInteractionResponse, +} from "../../common/command/Command.ts"; +import { bot } from "../../cache.ts"; +import { enTranslate } from "../../common/util/i18next.ts"; + +const VoteCommand: Command = (interaction) => { + return basicInteractionResponse( + interaction.id, + interaction.token, + "You can vote for TypicalBot at https://typicalbot.com/vote.", + ); +}; + +VoteCommand.options = { + name: "vote", + description: enTranslate("commands/general/vote:COMMAND_DESCRIPTION"), +}; + +bot.commands.add(VoteCommand);