diff --git a/packages/typicalbot-rest/.env.example b/packages/typicalbot-rest/.env.example index df41e7c..15cfe8b 100644 --- a/packages/typicalbot-rest/.env.example +++ b/packages/typicalbot-rest/.env.example @@ -3,3 +3,5 @@ DISCORD_TOKEN= EVENT_HANDLER_PORT=8080 EVENT_HANDLER_SECRET_KEY= INTERNAL_API= +FOLLOW_ANNOUNCEMENTS=268559149175013376 +FOLLOW_STATUS=621817852726607882 \ No newline at end of file diff --git a/packages/typicalbot-rest/src/commands/general/follow.ts b/packages/typicalbot-rest/src/commands/general/follow.ts new file mode 100644 index 0000000..76b56cf --- /dev/null +++ b/packages/typicalbot-rest/src/commands/general/follow.ts @@ -0,0 +1,100 @@ +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 || !(raw.name === "announcements" || raw.name === "status")) { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:INVALID_ARGUMENT"), + ); + } + + const channelId: bigint = snowflakeToBigint(interaction.channelId!); + const channelToFollow = Deno.env.get( + `FOLLOW_${raw.name.toUpperCase()}`, + ); + + try { + const channelWebhooks = await getChannelWebhooks( + channelId, + ); + + if (channelWebhooks.size >= 10) { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "commands/general/follow:WEBHOOK_LIMIT"), + ); + } + + await followChannel(snowflakeToBigint(channelToFollow!), channelId); + + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, `commands/general/follow:${channelToFollow!}`), + ); + } catch { + return basicInteractionResponse( + interaction.id, + interaction.token, + translate(guildId, "permission:SELF_MISSING_PERMISSION", { + permission: "Manage Webhooks", + }), + ); + } +}; + +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/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); diff --git a/packages/typicalbot-rest/src/languages/en_US/commands/general/follow.json b/packages/typicalbot-rest/src/languages/en_US/commands/general/follow.json new file mode 100644 index 0000000..d632155 --- /dev/null +++ b/packages/typicalbot-rest/src/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.", + "FOLLOW_ANNOUNCEMENTS": "You have successfully followed TypicalBot announcements in this channel.", + "FOLLOW_STATUS": "You have successfully followed TypicalBot status updates in this channel." +}