From eb7f89f924163c3ad63f30fa666122c1db19494a Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:19:12 +0530 Subject: [PATCH 01/28] commands(select-roles-update): implement roles update Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/config/select-roles/update.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/commands/config/select-roles/update.ts b/src/commands/config/select-roles/update.ts index 548b45715..ac262dc56 100644 --- a/src/commands/config/select-roles/update.ts +++ b/src/commands/config/select-roles/update.ts @@ -29,6 +29,11 @@ class SelectRolesUpdateCommand extends Command { name: "message", description: "The new message content.", }, + { + type: ApplicationCommandOptionType.Boolean, + name: "roles", + description: "Reset the roles so you can add them again.", + }, ], userPermissions: [ PermissionFlagsBits.ManageGuild ], }); @@ -38,6 +43,7 @@ class SelectRolesUpdateCommand extends Command { await interaction.deferReply(); const id = interaction.options.getString("id"); const message = generateEmbed(interaction.options.getString("message") || ""); + const resetRoles = interaction.options.getBoolean("roles"); // get the select roles group document const selectRoleGroup = await SelectRoleGroupModel.findById(id); @@ -95,7 +101,19 @@ class SelectRolesUpdateCommand extends Command { await selectRolesMessage.edit({ content: message ? typeof message === "string" ? message : "" : undefined, embeds: message ? typeof message === "string" ? [] : [ message ] : undefined, - components: arrays.chunks(selectRoles, 5).map(roles => ({ + components: resetRoles ? [ + { + type: ComponentType.ActionRow, + components: [ + { + type: ComponentType.Button, + customId: MessageComponents.SelectRolesNoRolesButton, + style: ButtonStyle.Danger, + label: "Add Roles", + }, + ], + }, + ] : arrays.chunks(selectRoles, 5).map(roles => ({ type: ComponentType.ActionRow, components: roles.map(role => ({ customId: MessageComponents.SelectRolesButton + ":" + role.value, @@ -108,7 +126,7 @@ class SelectRolesUpdateCommand extends Command { }); } - return interaction.editReply(`I've updated the Select Roles Group **${ id }**.`); + return interaction.editReply(`I've updated the Select Roles Group [**${ id }**](${ selectRolesMessage.url }).`); } await interaction.editReply(`The Select Roles Group **${ id }** doesn't exist anymore.`); From d62b072085aff7350623224f9372371988d23e77 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:19:47 +0530 Subject: [PATCH 02/28] version: 10.16.0 Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02accf2bc..6dfe1ca83 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bastion", - "version": "10.15.1", + "version": "10.16.0", "description": "Get an enhanced Discord experience!", "type": "module", "homepage": "https://bastion.traction.one", From aeae60f894ce421c30b817c0f36c4dbb6f3ec1fb Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:40:52 +0530 Subject: [PATCH 03/28] deps: update Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 6dfe1ca83..d19be50fa 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,14 @@ "devDependencies": { "@types/discord-rpc": "^4.0.8", "@types/express": "^4.17.21", - "@types/gamedig": "^5.0.2", + "@types/gamedig": "^5.0.3", "@types/http-errors": "^2.0.4", - "@types/jsdom": "^21.1.6", - "@types/node": "^20.12.12", + "@types/jsdom": "^21.1.7", + "@types/node": "^22.7.4", "@typescript-eslint/eslint-plugin": "^7.9.0", "@typescript-eslint/parser": "^7.9.0", "eslint": "^8.57.0", - "typescript": "^5.4.5" + "typescript": "^5.6.2" }, "dependencies": { "@bastion/tesseract": "^5.2.0", @@ -35,15 +35,15 @@ "@iamtraction/google-translate": "^2.0.1", "@iamtraction/play-dl": "^1.9.8", "discord-rpc": "^4.0.1", - "dotenv": "^16.3.1", - "emoji-regex": "^10.3.0", - "gamedig": "^5.0.0", - "jsdom": "^24.0.0", - "libsodium-wrappers": "^0.7.13", - "mathjs": "^13.0.0", - "openai": "^4.47.1", + "dotenv": "^16.4.5", + "emoji-regex": "^10.4.0", + "gamedig": "^5.1.3", + "jsdom": "^25.0.1", + "libsodium-wrappers": "^0.7.15", + "mathjs": "^13.1.1", + "openai": "^4.65.0", "r6api.js": "^4.4.1", - "undici": "^6.18.0", + "undici": "^6.19.8", "ytdl-core": "^4.11.5", "ytpl": "^2.3.0" }, From e0545719ea2b5d5c31619e46caf02dacfd3c1a49 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:42:41 +0530 Subject: [PATCH 04/28] settings: update example Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- settings.example.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/settings.example.yaml b/settings.example.yaml index adac2bef7..8bca5e035 100644 --- a/settings.example.yaml +++ b/settings.example.yaml @@ -84,8 +84,9 @@ nasaApiKey: "DEMO_KEY" # For more details, check https://openai.com/pricing openai: apiKey: "" - # If you want to use GPT-4, set `model` to `gpt-4`. - model: "gpt-3.5-turbo" + # If you want to use GPT-4o, set `model` to `gpt-4o`. + # https://openai.com/api/pricing + model: "gpt-4o-mini" # Change the `maxTokens` value to set the length of ChatGPT's responses. # https://platform.openai.com/tokenizer maxTokens: 100 From 6bda47dad708a5ae2a2b85ae2eac4e0b6539bdc8 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:55:41 +0530 Subject: [PATCH 05/28] eslint: upgrade to v9 Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d19be50fa..bfad27b31 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "commands": "tesseract publish", "migrate": "node ./dist/migrate.js", "start": "node .", - "test": "eslint src --ext .ts" + "test": "eslint ." }, "devDependencies": { "@types/discord-rpc": "^4.0.8", @@ -24,9 +24,8 @@ "@types/http-errors": "^2.0.4", "@types/jsdom": "^21.1.7", "@types/node": "^22.7.4", - "@typescript-eslint/eslint-plugin": "^7.9.0", - "@typescript-eslint/parser": "^7.9.0", - "eslint": "^8.57.0", + "typescript-eslint": "^8.7.0", + "eslint": "^9.11.1", "typescript": "^5.6.2" }, "dependencies": { From 2b9f2276d63eb9e276fa3e55688cd390d202377a Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:56:34 +0530 Subject: [PATCH 06/28] eslint: remove old config Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- .eslintrc.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 .eslintrc.yml diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index 80d4aa1ed..000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,30 +0,0 @@ -env: - es6: true - node: true -extends: - - "eslint:recommended" - - "plugin:@typescript-eslint/eslint-recommended" - - "plugin:@typescript-eslint/recommended" -globals: - Atomics: readonly - SharedArrayBuffer: readonly -parser: "@typescript-eslint/parser" -parserOptions: - ecmaVersion: 2022 - sourceType: module -plugins: - - "@typescript-eslint" -rules: - indent: - - error - - 4 - linebreak-style: - - error - - unix - quotes: - - error - - double - semi: - - error - - always - "@typescript-eslint/no-namespace": off From b427194d41b865b6f5cb5eb6f002c8d5e8e91d64 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:56:49 +0530 Subject: [PATCH 07/28] eslint(config): add new config Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- eslint.config.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 eslint.config.js diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..921abe915 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,25 @@ +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default tseslint.config({ + extends: [ + eslint.configs.recommended, + ...tseslint.configs.recommended, + ], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + sourceType: "module", + }, + files: [ "src/**/*.ts" ], + rules: { + indent: [ "warn", 4 ], + "linebreak-style": [ "warn", "unix" ], + quotes: [ "warn", "double" ], + semi: [ "warn", "always" ], + "@typescript-eslint/no-namespace": "off", + }, +}); From 0a352bec162e834de33ce8f2243a36dcbc6aae56 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:57:27 +0530 Subject: [PATCH 08/28] chore: linting Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/music/play.ts | 2 ++ src/commands/translate.ts | 1 + src/utils/strings.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/src/commands/music/play.ts b/src/commands/music/play.ts index 1d3140a9b..09099a836 100644 --- a/src/commands/music/play.ts +++ b/src/commands/music/play.ts @@ -52,6 +52,8 @@ class PlayCommand extends Command { entersState(connection, VoiceConnectionStatus.Connecting, 5_000), ]); } catch (error) { + Logger.error(error); + // seems to be a real disconnect which SHOULDN'T be recovered from connection.destroy(); diff --git a/src/commands/translate.ts b/src/commands/translate.ts index cb968d135..095fe821a 100644 --- a/src/commands/translate.ts +++ b/src/commands/translate.ts @@ -4,6 +4,7 @@ */ import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; import { Command } from "@bastion/tesseract"; +// eslint-disable-next-line @typescript-eslint/no-require-imports import translate = require("@iamtraction/google-translate"); class TranslateCommand extends Command { diff --git a/src/utils/strings.ts b/src/utils/strings.ts index 84b711ba9..745c8c256 100644 --- a/src/utils/strings.ts +++ b/src/utils/strings.ts @@ -2,6 +2,7 @@ * @author TRACTION (iamtraction) * @copyright 2022 */ +// eslint-disable-next-line no-constant-binary-expression const frequency = (string: string): { [key: string]: number } => [ ...string ].reduce((a: { [key: string]: number }, c) => (a[c] = a[c] + 1 || 1) && a, {}); const toTitleCase = (string: string, splitSeparator = " ", joinSeprator = " "): string => { From ee1d92c30d7cc1a200b79d0690a1ebeadb2089b7 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:34:45 +0530 Subject: [PATCH 09/28] workflows(nodejs): use node 20.x Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- .github/workflows/nodejs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index f7d3c3ce8..e402295f5 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - node-version: [ 18.x ] + node-version: [ 20.x ] steps: - name: Checkout From 611b00a80c96fccb09f5783f01ab234eeba24c48 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:56:59 +0530 Subject: [PATCH 10/28] deps: update tesseract Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfad27b31..2f874d2f2 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "typescript": "^5.6.2" }, "dependencies": { - "@bastion/tesseract": "^5.2.0", + "@bastion/tesseract": "^5.2.1", "@discordjs/opus": "^0.9.0", "@iamtraction/google-translate": "^2.0.1", "@iamtraction/play-dl": "^1.9.8", From 195880dc11a05d1509ce5a540fad3c174b236d1c Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sat, 28 Sep 2024 17:57:27 +0530 Subject: [PATCH 11/28] listeners(messageDeleteBulk): update typings Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/listeners/messageDeleteBulk.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/listeners/messageDeleteBulk.ts b/src/listeners/messageDeleteBulk.ts index 542b8f4ec..10440fbdb 100644 --- a/src/listeners/messageDeleteBulk.ts +++ b/src/listeners/messageDeleteBulk.ts @@ -2,7 +2,7 @@ * @author TRACTION (iamtraction) * @copyright 2022 */ -import { Collection, GuildTextBasedChannel, Message, PartialMessage } from "discord.js"; +import { GuildTextBasedChannel, Message, OmitPartialGroupDMChannel, PartialMessage, ReadonlyCollection } from "discord.js"; import { Listener } from "@bastion/tesseract"; import { logGuildEvent } from "../utils/guilds.js"; @@ -12,7 +12,7 @@ class MessageDeleteBulkListener extends Listener<"messageDeleteBulk"> { super("messageDeleteBulk"); } - public async exec(messages: Collection | PartialMessage>, channel: GuildTextBasedChannel): Promise { + public async exec(messages: ReadonlyCollection | PartialMessage>>, channel: GuildTextBasedChannel): Promise { await logGuildEvent(channel.guild, { title: "Messages Cleared", fields: [ From d641f80defb52e1966b7181c3abd282ea4d3c614 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 13:13:26 +0530 Subject: [PATCH 12/28] deps: update Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 2f874d2f2..b42cad13d 100644 --- a/package.json +++ b/package.json @@ -24,12 +24,12 @@ "@types/http-errors": "^2.0.4", "@types/jsdom": "^21.1.7", "@types/node": "^22.7.4", - "typescript-eslint": "^8.7.0", - "eslint": "^9.11.1", + "typescript-eslint": "^8.8.0", + "eslint": "^9.12.0", "typescript": "^5.6.2" }, "dependencies": { - "@bastion/tesseract": "^5.2.1", + "@bastion/tesseract": "^5.2.2", "@discordjs/opus": "^0.9.0", "@iamtraction/google-translate": "^2.0.1", "@iamtraction/play-dl": "^1.9.8", @@ -39,8 +39,8 @@ "gamedig": "^5.1.3", "jsdom": "^25.0.1", "libsodium-wrappers": "^0.7.15", - "mathjs": "^13.1.1", - "openai": "^4.65.0", + "mathjs": "^13.2.0", + "openai": "^4.67.1", "r6api.js": "^4.4.1", "undici": "^6.19.8", "ytdl-core": "^4.11.5", From ecc7906e571d975c597567368eabd82e2adef68c Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 13:14:04 +0530 Subject: [PATCH 13/28] chore: linting Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/music/play.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/music/play.ts b/src/commands/music/play.ts index 09099a836..65e1d3416 100644 --- a/src/commands/music/play.ts +++ b/src/commands/music/play.ts @@ -3,7 +3,7 @@ * @copyright 2022 */ import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; -import { AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, entersState, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice"; +import { AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, DiscordGatewayAdapterCreator, entersState, getVoiceConnection, joinVoiceChannel, NoSubscriberBehavior, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice"; import { Client, Command, Logger } from "@bastion/tesseract"; import { music } from "@bastion/tesseract/typings/types.js"; import playDL from "@iamtraction/play-dl"; @@ -39,7 +39,7 @@ class PlayCommand extends Command { selfMute: false, guildId: interaction.guildId, channelId: interaction.channelId, - adapterCreator: interaction.guild.voiceAdapterCreator, + adapterCreator: interaction.guild.voiceAdapterCreator as DiscordGatewayAdapterCreator, }); // voice connection events From 40493e1f2408b8829275f4858553016387cb5a38 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:54:26 +0530 Subject: [PATCH 14/28] deps: add google gen ai lib Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b42cad13d..dd0513fc9 100644 --- a/package.json +++ b/package.json @@ -24,13 +24,14 @@ "@types/http-errors": "^2.0.4", "@types/jsdom": "^21.1.7", "@types/node": "^22.7.4", - "typescript-eslint": "^8.8.0", "eslint": "^9.12.0", - "typescript": "^5.6.2" + "typescript": "^5.6.2", + "typescript-eslint": "^8.8.0" }, "dependencies": { "@bastion/tesseract": "^5.2.2", "@discordjs/opus": "^0.9.0", + "@google/generative-ai": "^0.21.0", "@iamtraction/google-translate": "^2.0.1", "@iamtraction/play-dl": "^1.9.8", "discord-rpc": "^4.0.1", From c4f63b12f11bfd282d0cec13e03cf6142742485b Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:56:13 +0530 Subject: [PATCH 15/28] types: add typings for gemini settings Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types.ts b/src/types.ts index 9390513d4..213c86937 100644 --- a/src/types.ts +++ b/src/types.ts @@ -17,6 +17,11 @@ export namespace bastion { model?: string; maxTokens?: number; }; + gemini?: { + apiKey?: string; + model?: string; + maxOutputTokens?: number; + }; openWeatherMapApiKey?: string; tmdbApiKey?: string; trackerNetworkApiKey?: string; From 9f0a3cdfded80e13809bae56c53d1b9302bc2955 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:56:34 +0530 Subject: [PATCH 16/28] settings: update example Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- settings.example.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/settings.example.yaml b/settings.example.yaml index 8bca5e035..b4aba51da 100644 --- a/settings.example.yaml +++ b/settings.example.yaml @@ -90,6 +90,17 @@ openai: # Change the `maxTokens` value to set the length of ChatGPT's responses. # https://platform.openai.com/tokenizer maxTokens: 100 +# Required for `chat` command to use the Google's Gemini APIs. +# API pricing depends on these values. +# For more details, check https://ai.google.dev/pricing +gemini: + apiKey: "" + # If you want to use Gemini 1.5 Pro, set `model` to `gemini-1.5-pro`. + # https://ai.google.dev/gemini-api/docs/models/gemini + model: "gemini-1.5-flash" + # Change the `maxOutputTokens` value to set the length of ChatGPT's responses. + # https://ai.google.dev/gemini-api/docs/tokens + maxOutputTokens: 256 # Required for `weather` command. openWeatherMapApiKey: "" # Required for `movie` and `tv` commands. From b300490958426a599bf41d11f4d2f9a57e88d9ee Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:58:43 +0530 Subject: [PATCH 17/28] commands(chat): implement gemini support Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/chat.ts | 57 +++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/commands/chat.ts b/src/commands/chat.ts index 8fd4d7bd3..2608b9eb2 100644 --- a/src/commands/chat.ts +++ b/src/commands/chat.ts @@ -5,6 +5,7 @@ import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; import { Client, Command } from "@bastion/tesseract"; import OpenAI from "openai"; +import { GoogleGenerativeAI } from "@google/generative-ai"; import Settings from "../utils/settings.js"; @@ -25,29 +26,53 @@ class ChatCommand extends Command { }); } - public async exec(interaction: ChatInputCommandInteraction<"cached">): Promise { + public async exec(interaction: ChatInputCommandInteraction<"cached">): Promise { await interaction.deferReply(); const message = interaction.options.getString("message"); - const openai = new OpenAI({ - apiKey: ((interaction.client as Client).settings as Settings).get("openai").apiKey, - }); + // use ChatGPT if OpenAI API key is present + if (((interaction.client as Client).settings as Settings).get("openai").apiKey) { + const openai = new OpenAI({ + apiKey: ((interaction.client as Client).settings as Settings).get("openai").apiKey, + }); - const response = await openai.chat.completions.create({ - model: ((interaction.client as Client).settings as Settings).get("openai").model || "gpt-3.5-turbo", - messages: [ - { - role: "user", - content: message, + const response = await openai.chat.completions.create({ + model: ((interaction.client as Client).settings as Settings).get("openai").model, + messages: [ + { + role: "user", + content: message, + }, + ], + max_tokens: ((interaction.client as Client).settings as Settings).get("openai").maxTokens || 100, + user: interaction.member.id, + }); + + return await interaction.editReply({ + content: response.choices[0].message.content, + }); + } + + // use Gemini if Gemini API key is present + if (((interaction.client as Client).settings as Settings).get("gemini").apiKey) { + const gemini = new GoogleGenerativeAI(((interaction.client as Client).settings as Settings).get("gemini").apiKey); + const geminiModel = gemini.getGenerativeModel({ + model: ((interaction.client as Client).settings as Settings).get("gemini").model, + generationConfig: { + maxOutputTokens: ((interaction.client as Client).settings as Settings).get("gemini").maxOutputTokens, }, - ], - max_tokens: ((interaction.client as Client).settings as Settings).get("openai").maxTokens || 100, - user: interaction.member.id, - }); + }); + + const result = await geminiModel.generateContent(message); + + return await interaction.editReply({ + content: result.response.text(), + }); + } - await interaction.editReply({ - content: response.choices[0].message.content, + return await interaction.editReply({ + content: "You haven't set up API keys for any gen AI APIs.", }); } } From 80f562abe695147562d20075077f730f4c1727d9 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 15:48:12 +0530 Subject: [PATCH 18/28] deps: add anthropic sdk Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index dd0513fc9..aed7fdb43 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "typescript-eslint": "^8.8.0" }, "dependencies": { + "@anthropic-ai/sdk": "^0.28.0", "@bastion/tesseract": "^5.2.2", "@discordjs/opus": "^0.9.0", "@google/generative-ai": "^0.21.0", From 5f1e1f2b0f85906883e2af31908b5477ac057fe1 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 15:48:46 +0530 Subject: [PATCH 19/28] types: add typings for anthropic settings Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types.ts b/src/types.ts index 213c86937..b5b447963 100644 --- a/src/types.ts +++ b/src/types.ts @@ -22,6 +22,11 @@ export namespace bastion { model?: string; maxOutputTokens?: number; }; + anthropic?: { + apiKey?: string; + model?: string; + maxTokens?: number; + }; openWeatherMapApiKey?: string; tmdbApiKey?: string; trackerNetworkApiKey?: string; From 84893e18bb553e7c232c17095ccd17c57a71aa04 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 15:49:25 +0530 Subject: [PATCH 20/28] settings: update example Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- settings.example.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/settings.example.yaml b/settings.example.yaml index b4aba51da..4910f6c7d 100644 --- a/settings.example.yaml +++ b/settings.example.yaml @@ -101,6 +101,17 @@ gemini: # Change the `maxOutputTokens` value to set the length of ChatGPT's responses. # https://ai.google.dev/gemini-api/docs/tokens maxOutputTokens: 256 +# Required for `chat` command to use the Anthropic's APIs. +# API pricing depends on these values. +# For more details, check https://www.anthropic.com/pricing#anthropic-api +anthropic: + apiKey: "" + # If you want to use Claude 3.5 Sonnet, set `model` to `claude-3-5-sonnet-20240620`. + # https://docs.anthropic.com/en/docs/about-claude/models + model: "claude-3-haiku-20240307" + # Change the `maxTokens` value to set the length of Claude's responses. + # https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table + maxTokens: 128 # Required for `weather` command. openWeatherMapApiKey: "" # Required for `movie` and `tv` commands. From 3fcb61078343891c62ff32e623152bec808c8c07 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 15:49:59 +0530 Subject: [PATCH 21/28] commands(chat): implement claude support Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/chat.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/commands/chat.ts b/src/commands/chat.ts index 2608b9eb2..2e8856804 100644 --- a/src/commands/chat.ts +++ b/src/commands/chat.ts @@ -4,6 +4,7 @@ */ import { ApplicationCommandOptionType, ChatInputCommandInteraction } from "discord.js"; import { Client, Command } from "@bastion/tesseract"; +import Anthropic from "@anthropic-ai/sdk"; import OpenAI from "openai"; import { GoogleGenerativeAI } from "@google/generative-ai"; @@ -71,6 +72,33 @@ class ChatCommand extends Command { }); } + // use Claude if Anthropic API key is present + if (((interaction.client as Client).settings as Settings).get("anthropic").apiKey) { + const anthropic = new Anthropic({ + apiKey: ((interaction.client as Client).settings as Settings).get("anthropic").apiKey, + }); + + const result = await anthropic.messages.create({ + model: ((interaction.client as Client).settings as Settings).get("anthropic").model, + max_tokens: ((interaction.client as Client).settings as Settings).get("anthropic").maxTokens, + messages: [ + { + role: "user", + content: [ + { + type: "text", + text: message, + }, + ], + }, + ], + }); + + return await interaction.editReply({ + content: result.content[0].type === "text" && result.content[0].text, + }); + } + return await interaction.editReply({ content: "You haven't set up API keys for any gen AI APIs.", }); From 8a9690f84761f8c9e5a4beecf8ba48e3ad8ac514 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:12:34 +0530 Subject: [PATCH 22/28] commands(chat): update description Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/chat.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/chat.ts b/src/commands/chat.ts index 2e8856804..19b1b5a22 100644 --- a/src/commands/chat.ts +++ b/src/commands/chat.ts @@ -14,7 +14,7 @@ class ChatCommand extends Command { constructor() { super({ name: "chat", - description: "Ask questions or chat with ChatGPT from OpenAI.", + description: "Ask questions or chat with Bastion.", owner: true, options: [ { From 4ab51a2699ee9c2f643cb725452c7ca9ef23edea Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 16:12:59 +0530 Subject: [PATCH 23/28] chore: generate command descriptions Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- commands.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands.json b/commands.json index d26ad2fbf..28f0d36f5 100644 --- a/commands.json +++ b/commands.json @@ -1 +1 @@ -[{"type":1,"name":"about","description":"Displays some basic information to help you get started with Bastion.","options":[]},{"type":1,"name":"calculate","description":"Evaluates the specified mathematical expression.","options":[{"type":3,"name":"expression","description":"The expression you want to evaluate.","required":true}]},{"type":1,"name":"changes","description":"See the changes introduced in the current version of Bastion.","options":[]},{"type":1,"name":"channel","description":"Command Group - channel","options":[{"type":1,"name":"create","description":"Create a new channel in the server.","options":[{"type":3,"name":"name","description":"The name of the new channel.","required":true},{"type":4,"name":"type","description":"The type of the new channel.","choices":[{"name":"Text","value":0},{"name":"Voice","value":2},{"name":"Announcement","value":5},{"name":"Stage","value":13},{"name":"Category","value":4}],"required":true},{"type":3,"name":"topic","description":"The topic for the new channel."},{"type":4,"name":"limit","description":"Limit the number of users for the new (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"Enable slowmode with the specified interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for creating the channel."}]},{"type":1,"name":"delete","description":"Delete the current (or the specified) channel.","options":[{"type":7,"name":"channel","description":"The channel you want to delete."},{"type":3,"name":"reason","description":"The reason for deleting the channel."}]},{"type":1,"name":"info","description":"Displays information on the current (or specified) channel.","options":[{"type":7,"name":"channel","description":"The channel whose information you want to display."}]},{"type":1,"name":"update","description":"Update the specified channel in the server.","options":[{"type":7,"name":"channel","description":"The channel you want to update."},{"type":3,"name":"name","description":"The new name for the channel."},{"type":3,"name":"topic","description":"The new topic for the channel."},{"type":4,"name":"limit","description":"The new limit of users for the (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"The new slowmode interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for updating the channel."}]}]},{"type":1,"name":"chat","description":"Ask questions or chat with ChatGPT from OpenAI.","options":[{"type":3,"name":"message","description":"Your message.","required":true}]},{"type":1,"name":"claim","description":"Claim any rewards available to you.","options":[]},{"type":1,"name":"comic","description":"Command Group - comic","options":[{"type":1,"name":"garfield","description":"Check the latest Garfield comic.","options":[]},{"type":1,"name":"phd","description":"Check the latest PHD comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]},{"type":1,"name":"xkcd","description":"Check the latest xkcd comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]}]},{"type":1,"name":"config","description":"Command Group - config","options":[{"type":1,"name":"auto-roles","description":"Configure roles that will be auto assigned to members when they join the server.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as an auto role."},{"type":5,"name":"bots","description":"Whether this role should be auto assigned to bots."}]},{"type":1,"name":"auto-threads","description":"Configure auto threads in the server.","options":[]},{"type":1,"name":"farewell","description":"Configure farewell messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the farewell messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom farewell message."},{"type":4,"name":"timeout","description":"The interval after which the farewell message will be deleted.","min_value":1,"max_value":30}]},{"type":2,"name":"filter","description":"Subcommand Group - filter","options":[{"type":1,"name":"emails","description":"Configure Email Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"invites","description":"Configure Invite Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"links","description":"Configure Link Filter AutoMod rule in the server.","options":[]}]},{"type":1,"name":"gambling","description":"Configure gambling in the server.","options":[{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"gamification","description":"Configure gamification in the server.","options":[{"type":5,"name":"messages","description":"Should it show the level up messages."},{"type":7,"name":"channel","description":"The channel where the level up messages will be sent.","channel_types":[0]},{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"greeting","description":"Configure greeting messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the greeting messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom greeting message."},{"type":4,"name":"timeout","description":"The interval after which the greeting message will be deleted.","min_value":1,"max_value":30}]},{"type":1,"name":"live-streams","description":"Follow streamers and get notified in the specified channel when they go live.","options":[{"type":3,"name":"twitch","description":"The twitch channel you want to follow."},{"type":7,"name":"channel","description":"The channel where the notifications will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom message for notification."}]},{"type":2,"name":"logs","description":"Subcommand Group - logs","options":[{"type":1,"name":"content","description":"Configure whether deleted and edited message content should be shown in server logs.","options":[]},{"type":1,"name":"mod","description":"Configure channel for logging moderation events.","options":[{"type":7,"name":"channel","description":"The channel where moderation events will be logged.","channel_types":[0]}]},{"type":1,"name":"server","description":"Configure channel for logging server events.","options":[{"type":7,"name":"channel","description":"The channel where server events will be logged.","channel_types":[0]}]}]},{"type":1,"name":"music","description":"Configure music in the server.","options":[]},{"type":1,"name":"reports","description":"Configure user reports in the server.","options":[{"type":7,"name":"channel","description":"The channel where user reports will be sent.","channel_types":[0]}]},{"type":2,"name":"select-roles","description":"Subcommand Group - select-roles","options":[{"type":1,"name":"add","description":"Create a new Select Role Group.","options":[{"type":3,"name":"message","description":"The content of the Select Role Message for users.","required":true},{"type":7,"name":"channel","description":"The channel where you want to send the Select Role Message.","channel_types":[5,0,2]},{"type":4,"name":"type","description":"The behavior of the Select Role Group.","choices":[{"name":"Add Only","value":1},{"name":"Remove Only","value":2}]},{"type":4,"name":"ui","description":"The variant of Select Role UI.","choices":[{"name":"Buttons","value":0},{"name":"Select Menu","value":1}]},{"type":4,"name":"min","description":"The minimum number of roles users are allowed to select.","min_value":0,"max_value":25},{"type":4,"name":"max","description":"The maximum number of roles users are allowed to select.","min_value":1,"max_value":25}]},{"type":1,"name":"list","description":"List all the Select Role Groups.","options":[{"type":7,"name":"channel","description":"List Select Role Groups only from this channel.","channel_types":[5,0,2]}]},{"type":1,"name":"remove","description":"Remove the specified Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true}]},{"type":1,"name":"update","description":"Update the roles and message for the Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true},{"type":3,"name":"message","description":"The new message content."}]}]},{"type":1,"name":"self-roles","description":"Configure roles that users can assign to themselves.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as a self role."}]},{"type":1,"name":"starboard","description":"Configure starboard in the server.","options":[{"type":7,"name":"channel","description":"The channel where starred messages will be logged.","channel_types":[0]},{"type":4,"name":"threshold","description":"The minimum number of stars a message needs.","min_value":2}]},{"type":1,"name":"streamer-role","description":"Set the role someone is assigned in the server when they start streaming.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."}]},{"type":1,"name":"suggestions","description":"Configure suggestions in the server.","options":[{"type":7,"name":"channel","description":"The channel where suggestions will be sent.","channel_types":[0]}]},{"type":1,"name":"triggers","description":"Configure triggers and responses in the server.","options":[{"type":3,"name":"add","description":"The pattern that will trigger the response."},{"type":3,"name":"remove","description":"The trigger that you want to remove."},{"type":3,"name":"message","description":"The message response for the trigger."},{"type":3,"name":"emoji","description":"The reaction emoji response for the trigger."}]},{"type":1,"name":"verification","description":"Configure verification in the server.","options":[{"type":8,"name":"role","description":"The role users are assigned when are verified."},{"type":3,"name":"text","description":"Type a text message that will be shown to the users trying to verify."}]},{"type":1,"name":"voice-sessions","description":"Configure voice sessions in the server.","options":[{"type":3,"name":"create","description":"Name of the new voice session category."}]},{"type":1,"name":"voting-channels","description":"Configure voting channels in the server.","options":[{"type":7,"name":"add","description":"The channel you want to add as a voting channel.","channel_types":[0]},{"type":7,"name":"remove","description":"The channel you want to remove as a voting channel.","channel_types":[0]}]}]},{"type":1,"name":"donate","description":"See the ways you can contribute to support the Bastion bot project.","options":[]},{"type":1,"name":"emoji","description":"Command Group - emoji","options":[{"type":1,"name":"info","description":"Displays information on the specified custom emoji.","options":[{"type":3,"name":"emoji","description":"The emoji you want to display.","required":true}]}]},{"type":1,"name":"games","description":"Command Group - games","options":[{"type":1,"name":"8ball","description":"Ask any question to the magic 8 ball and get answers.","options":[{"type":3,"name":"question","description":"The question you want to ask the magic 8 ball.","required":true}]},{"type":1,"name":"flip","description":"Flip coins and see the result.","options":[{"type":4,"name":"coins","description":"The number of coins to flip.","min_value":1,"max_value":128}]},{"type":1,"name":"roll","description":"Roll dice and see the result. Supports dice notation.","options":[{"type":3,"name":"notation","description":"The dice notation."}]},{"type":1,"name":"rps","description":"Play rock paper scissor with Bastion.","options":[{"type":3,"name":"choice","description":"Your choice.","choices":[{"name":"Rock","value":"ROCK"},{"name":"Paper","value":"PAPER"},{"name":"Scissor","value":"SCISSOR"}],"required":true}]},{"type":1,"name":"russian-roulette","description":"Play a game of Russian roulette.","options":[{"type":4,"name":"rounds","description":"The number rounds you want to play.","min_value":1,"max_value":6}]}]},{"type":1,"name":"game-server","description":"Fetch information from nearly any game server that makes its status publicly available.","options":[{"type":3,"name":"game","description":"The game ID for the game server.","required":true},{"type":3,"name":"hostname","description":"The IP address or domain name of the game server.","required":true},{"type":4,"name":"port","description":"The connection port number of the game server. Use the query port if connection port doesn't work.","min_value":1,"max_value":65535}]},{"type":1,"name":"gamestats","description":"Command Group - gamestats","options":[{"type":1,"name":"aimlab","description":"Check stats of any Aim Lab player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"apex","description":"Check stats of any Apex Legends player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"origin"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"csgo","description":"Check stats of any Counter-Strike: Global Offensive player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"fortnite","description":"Check stats of any Fortnite player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"kbm"},{"name":"Console","value":"gamepad"},{"name":"Mobile","value":"touch"}],"required":true}]},{"type":1,"name":"overwatch","description":"Check stats of any Overwatch 2 player.","options":[{"type":3,"name":"username","description":"The BattleTag or username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"pc"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"},{"name":"Nintendo Switch","value":"nintendo-switch"}]},{"type":3,"name":"region","description":"The region of the player.","choices":[{"name":"Americas","value":"us"},{"name":"Europe","value":"eu"},{"name":"Asia","value":"asia"}]}]},{"type":1,"name":"rainbow6","description":"Check stats of any Rainbow 6 player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"uplay"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"valorant","description":"Check stats of any Valorant player.","options":[{"type":3,"name":"username","description":"The name tag of the player.","required":true},{"type":3,"name":"region","description":"The region of the account.","choices":[{"name":"Americas","value":"na"},{"name":"Europe","value":"eu"},{"name":"Asia-Pacific","value":"ap"},{"name":"Korea","value":"kr"}],"required":true}]}]},{"type":1,"name":"give","description":"Give Bastion Coins and Experience Points to server members or take it from them.","options":[{"type":6,"name":"user","description":"The user whose coins and XP will be updated.","required":true},{"type":4,"name":"coins","description":"The amount of coins you want to give or take.","required":true},{"type":4,"name":"xp","description":"The amount of XP you want to give or take.","required":true}]},{"type":1,"name":"giveaway","description":"Run giveaways in the server.","options":[{"type":3,"name":"title","description":"The title for the giveaway.","required":true},{"type":3,"name":"description","description":"The description for the giveaway."},{"type":4,"name":"winners","description":"The number of winners for the giveaway.","min_value":1,"max_value":9007199254740991},{"type":4,"name":"timer","description":"Number of hours the giveaway should run.","min_value":1,"max_value":720}]},{"type":1,"name":"iam","description":"Assign a self assignable role to yourself.","options":[{"type":8,"name":"role","description":"The role you want to assign yourself."}]},{"type":1,"name":"image","description":"Command Group - image","options":[{"type":1,"name":"generate","description":"Generate an image with DALL-E from OpenAI.","options":[{"type":3,"name":"prompt","description":"A description of the desired image.","required":true},{"type":3,"name":"size","description":"The size of the generated image.","choices":[{"name":"Square","value":"1024x1024"},{"name":"Portrait","value":"1024x1792"},{"name":"Landscape","value":"1792x1024"}]}]}]},{"type":1,"name":"invite","description":"Generates an instant invite for the server.","options":[{"type":5,"name":"temporary","description":"Kick the members if they aren't assigned a role within 24 hours."}]},{"type":1,"name":"leaderboard","description":"Displays the server's leaderboard. You're ranked based on their level, XP, karma, and Bastion Coins.","options":[]},{"type":1,"name":"lmgtfy","description":"Send a LMGTFY link for the search query that teaches people how to do an internet search.","options":[{"type":3,"name":"query","description":"The search query.","required":true},{"type":3,"name":"site","description":"The search engine to use.","choices":[{"name":"DuckDuckGo","value":"d"},{"name":"Google","value":"g"},{"name":"Bing","value":"b"}]}]},{"type":1,"name":"message","description":"Command Group - message","options":[{"type":1,"name":"clear","description":"Clear recent messages (newer than two weeks) in the channel.","options":[{"type":4,"name":"limit","description":"Limit the numbers of messages that should be deleted.","min_value":1},{"type":5,"name":"bots","description":"Should it delete messages from bots."},{"type":5,"name":"pinned","description":"Should it delete messages that are pinned."},{"type":5,"name":"system","description":"Should it delete system messages."},{"type":6,"name":"user","description":"Only delete messages from this user."}]}]},{"type":1,"name":"music","description":"Command Group - music","options":[{"type":1,"name":"join","description":"Moves you to the voice channel where Bastion is currently connected.","options":[]},{"type":1,"name":"now","description":"Shows the song playing right now.","options":[]},{"type":1,"name":"pause","description":"Pause the music playback in the voice channel.","options":[]},{"type":1,"name":"play","description":"Play a specified song in the server.","options":[{"type":3,"name":"song","description":"The song name or link you want to play.","required":true}]},{"type":1,"name":"queue","description":"Displays the current music queue in the server.","options":[{"type":3,"name":"remove","description":"Remove songs matching the specified text from the music queue."},{"type":5,"name":"clear","description":"Remove all songs from the music queue."}]},{"type":1,"name":"resume","description":"Resume the music playback in the voice channel.","options":[]},{"type":1,"name":"shuffle","description":"Shuffle the current music queue.","options":[]},{"type":1,"name":"skip","description":"Skip the current music track that's being played in the voice channel.","options":[]},{"type":1,"name":"stop","description":"Stop the music playback and disconnect from the voice channel.","options":[]}]},{"type":1,"name":"poll","description":"Run polls in the server.","options":[{"type":3,"name":"question","description":"The question for the poll.","required":true},{"type":3,"name":"option1","description":"The 1st option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The 2nd option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The 3rd option for the poll's answer."},{"type":3,"name":"option4","description":"The 4th option for the poll's answer."},{"type":3,"name":"option5","description":"The 5th option for the poll's answer."},{"type":3,"name":"option6","description":"The 6th option for the poll's answer."},{"type":3,"name":"option7","description":"The 7th option for the poll's answer."},{"type":3,"name":"option8","description":"The 8th option for the poll's answer."},{"type":3,"name":"option9","description":"The 9th option for the poll's answer."},{"type":3,"name":"option10","description":"The 10th option for the poll's answer."},{"type":4,"name":"timer","description":"Number of hours the poll should run.","min_value":1,"max_value":720}]},{"type":1,"name":"profile","description":"Displays the Bastion profile of the specified user.","options":[{"type":6,"name":"user","description":"The user whose profile you want to display."}]},{"type":1,"name":"report","description":"Report a server member to the moderators of the server.","options":[{"type":6,"name":"user","description":"The user you want to report.","required":true},{"type":3,"name":"reason","description":"The reason you want to report the user.","required":true}]},{"type":1,"name":"role","description":"Command Group - role","options":[{"type":1,"name":"config","description":"Set the description & emoji of the specified role.","options":[{"type":8,"name":"role","description":"The role which you want to configure.","required":true},{"type":3,"name":"emoji","description":"The emoji you want to set as the role emoji."},{"type":3,"name":"description","description":"A description for the role (max 100 characters)."}]},{"type":1,"name":"create","description":"Create a new role in the server.","options":[{"type":3,"name":"name","description":"The name of the new role.","required":true},{"type":3,"name":"color","description":"The color for the new role (in HEX code)."},{"type":5,"name":"icon","description":"The icon for the new role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for creating the role."}]},{"type":1,"name":"delete","description":"Delete the specified role.","options":[{"type":8,"name":"role","description":"The role you want to delete.","required":true},{"type":3,"name":"reason","description":"The reason for deleting the role."}]},{"type":1,"name":"info","description":"Displays information on the specified role.","options":[{"type":8,"name":"role","description":"The role whose information you want to display.","required":true}]},{"type":1,"name":"levels","description":"Configure level roles. When members reach a level, they get assigned to roles in the level.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."},{"type":4,"name":"level","description":"The level at which the role should be assigned.","min_value":0},{"type":4,"name":"remove","description":"The level which you want to remove.","min_value":0}]},{"type":1,"name":"update","description":"Update the specified role in the server.","options":[{"type":8,"name":"role","description":"The role you want to update.","required":true},{"type":3,"name":"name","description":"The new name for the role."},{"type":3,"name":"color","description":"The new color for the role (in HEX code)."},{"type":5,"name":"icon","description":"The new icon for the role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for updating the role."}]}]},{"type":1,"name":"say","description":"Replies with the message you ask it to say.","options":[{"type":3,"name":"message","description":"The message you want Bastion to say.","required":true}]},{"type":1,"name":"search","description":"Command Group - search","options":[{"type":1,"name":"anime","description":"Searches for information on the specified anime.","options":[{"type":3,"name":"name","description":"The name of the anime.","required":true}]},{"type":1,"name":"apod","description":"Displays the astronomy picture of the day from NASA.","options":[]},{"type":1,"name":"cryptocurrency","description":"Searches for information on the specified crypto currency.","options":[{"type":3,"name":"symbol","description":"The symbol of the crypto currency.","required":true}]},{"type":1,"name":"definitions","description":"Displays the definitions for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"game","description":"Searches for information on the specified game.","options":[{"type":3,"name":"name","description":"The name of the game.","required":true}]},{"type":1,"name":"manga","description":"Searches for information on the specified manga.","options":[{"type":3,"name":"name","description":"The name of the manga.","required":true}]},{"type":1,"name":"movie","description":"Searches for information on the specified movie.","options":[{"type":3,"name":"name","description":"The name of the movie.","required":true}]},{"type":1,"name":"pokemon","description":"Searches for information on the specified pokémon.","options":[{"type":3,"name":"name","description":"The name (or number) of the Pokémon.","required":true}]},{"type":1,"name":"redirects","description":"Follows all the redirects in the specified URL and displays the final URL.","options":[{"type":3,"name":"url","description":"The URL you want to follow.","required":true}]},{"type":1,"name":"tv","description":"Searches for information on the specified TV show.","options":[{"type":3,"name":"name","description":"The name of the TV show.","required":true}]},{"type":1,"name":"urban-dictionary","description":"Searches Urban Dictionary for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"weather","description":"Displays the weather forcast of the specified location.","options":[{"type":3,"name":"location","description":"The location for the weather forcast.","required":true}]},{"type":1,"name":"wikipedia","description":"Searches Wikipedia for the specified query.","options":[{"type":3,"name":"query","description":"The search query.","required":true}]}]},{"type":1,"name":"server","description":"Command Group - server","options":[{"type":1,"name":"info","description":"Displays information on the server.","options":[]},{"type":1,"name":"prune","description":"Kicks the inactive members (without any roles) from the server.","options":[{"type":4,"name":"days","description":"The number of days of inactivity required for kicking.","min_value":1},{"type":8,"name":"role","description":"Inactive members check includes this role."},{"type":3,"name":"reason","description":"The reason for pruning the inactive members."}]}]},{"type":1,"name":"status","description":"Displays Bastion's status. You can also see Discord's status.","options":[{"type":5,"name":"shard","description":"Displays the status of the current shard."}]},{"type":1,"name":"su","description":"Command Group - su","options":[{"type":1,"name":"eval","description":"Evaluate JavaScript code in Bastion's context.","options":[{"type":3,"name":"code","description":"The code you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"exec","description":"Execute terminal commands on the system where Bastion is running.","options":[{"type":3,"name":"command","description":"The command you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"reload","description":"Reload Bastion's settings.","options":[]},{"type":1,"name":"shutdown","description":"Shutdown Bastion directly from Discord.","options":[]}]},{"type":1,"name":"suggest","description":"Send a suggestion to the server staff.","options":[{"type":3,"name":"suggestion","description":"What do you want to suggest?","required":true}]},{"type":1,"name":"thread","description":"Command Group - thread","options":[{"type":1,"name":"close","description":"Close and lock the thread.","options":[]},{"type":1,"name":"name","description":"Change the name of the thread.","options":[{"type":3,"name":"name","description":"The new name for the thread.","required":true}]}]},{"type":1,"name":"translate","description":"Translates the specified text from one language to another.","options":[{"type":3,"name":"text","description":"The text you want to translate.","required":true},{"type":3,"name":"to","description":"The language you want to translate to."},{"type":3,"name":"from","description":"The language you want to translate from."}]},{"type":1,"name":"user","description":"Command Group - user","options":[{"type":1,"name":"avatar","description":"Displays the avatar of the specified user.","options":[{"type":6,"name":"user","description":"The user whose avatar you want to display."}]},{"type":1,"name":"info","description":"Displays information on the specified user.","options":[{"type":6,"name":"user","description":"The user whose information you want to display."}]},{"type":1,"name":"infractions","description":"Configure infraction actions and displays infractions of the specified user.","options":[{"type":4,"name":"timeout","description":"Number of violations after which a user is timed out.","min_value":1},{"type":4,"name":"kick","description":"Number of violations after which a user is kicked.","min_value":1},{"type":4,"name":"ban","description":"Number of violations after which a user is banned.","min_value":1},{"type":6,"name":"user","description":"The user whose infractions you want to display."},{"type":4,"name":"remove","description":"The infraction you want to remove from the user.","min_value":1}]}]},{"type":1,"name":"warn","description":"Warn server members and add infractions to their server profile.","options":[{"type":6,"name":"user","description":"The user you want to warn.","required":true},{"type":3,"name":"reason","description":"The reason for the warning.","required":true}]}] \ No newline at end of file +[{"type":1,"name":"about","description":"Displays some basic information to help you get started with Bastion.","options":[]},{"type":1,"name":"calculate","description":"Evaluates the specified mathematical expression.","options":[{"type":3,"name":"expression","description":"The expression you want to evaluate.","required":true}]},{"type":1,"name":"changes","description":"See the changes introduced in the current version of Bastion.","options":[]},{"type":1,"name":"channel","description":"Command Group - channel","options":[{"type":1,"name":"create","description":"Create a new channel in the server.","options":[{"type":3,"name":"name","description":"The name of the new channel.","required":true},{"type":4,"name":"type","description":"The type of the new channel.","choices":[{"name":"Text","value":0},{"name":"Voice","value":2},{"name":"Announcement","value":5},{"name":"Stage","value":13},{"name":"Category","value":4}],"required":true},{"type":3,"name":"topic","description":"The topic for the new channel."},{"type":4,"name":"limit","description":"Limit the number of users for the new (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"Enable slowmode with the specified interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for creating the channel."}]},{"type":1,"name":"delete","description":"Delete the current (or the specified) channel.","options":[{"type":7,"name":"channel","description":"The channel you want to delete."},{"type":3,"name":"reason","description":"The reason for deleting the channel."}]},{"type":1,"name":"info","description":"Displays information on the current (or specified) channel.","options":[{"type":7,"name":"channel","description":"The channel whose information you want to display."}]},{"type":1,"name":"update","description":"Update the specified channel in the server.","options":[{"type":7,"name":"channel","description":"The channel you want to update."},{"type":3,"name":"name","description":"The new name for the channel."},{"type":3,"name":"topic","description":"The new topic for the channel."},{"type":4,"name":"limit","description":"The new limit of users for the (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"The new slowmode interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for updating the channel."}]}]},{"type":1,"name":"chat","description":"Ask questions or chat with Bastion.","options":[{"type":3,"name":"message","description":"Your message.","required":true}]},{"type":1,"name":"claim","description":"Claim any rewards available to you.","options":[]},{"type":1,"name":"comic","description":"Command Group - comic","options":[{"type":1,"name":"garfield","description":"Check the latest Garfield comic.","options":[]},{"type":1,"name":"phd","description":"Check the latest PHD comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]},{"type":1,"name":"xkcd","description":"Check the latest xkcd comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]}]},{"type":1,"name":"config","description":"Command Group - config","options":[{"type":1,"name":"auto-roles","description":"Configure roles that will be auto assigned to members when they join the server.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as an auto role."},{"type":5,"name":"bots","description":"Whether this role should be auto assigned to bots."}]},{"type":1,"name":"auto-threads","description":"Configure auto threads in the server.","options":[]},{"type":1,"name":"farewell","description":"Configure farewell messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the farewell messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom farewell message."},{"type":4,"name":"timeout","description":"The interval after which the farewell message will be deleted.","min_value":1,"max_value":30}]},{"type":2,"name":"filter","description":"Subcommand Group - filter","options":[{"type":1,"name":"emails","description":"Configure Email Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"invites","description":"Configure Invite Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"links","description":"Configure Link Filter AutoMod rule in the server.","options":[]}]},{"type":1,"name":"gambling","description":"Configure gambling in the server.","options":[{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"gamification","description":"Configure gamification in the server.","options":[{"type":5,"name":"messages","description":"Should it show the level up messages."},{"type":7,"name":"channel","description":"The channel where the level up messages will be sent.","channel_types":[0]},{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"greeting","description":"Configure greeting messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the greeting messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom greeting message."},{"type":4,"name":"timeout","description":"The interval after which the greeting message will be deleted.","min_value":1,"max_value":30}]},{"type":1,"name":"live-streams","description":"Follow streamers and get notified in the specified channel when they go live.","options":[{"type":3,"name":"twitch","description":"The twitch channel you want to follow."},{"type":7,"name":"channel","description":"The channel where the notifications will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom message for notification."}]},{"type":2,"name":"logs","description":"Subcommand Group - logs","options":[{"type":1,"name":"content","description":"Configure whether deleted and edited message content should be shown in server logs.","options":[]},{"type":1,"name":"mod","description":"Configure channel for logging moderation events.","options":[{"type":7,"name":"channel","description":"The channel where moderation events will be logged.","channel_types":[0]}]},{"type":1,"name":"server","description":"Configure channel for logging server events.","options":[{"type":7,"name":"channel","description":"The channel where server events will be logged.","channel_types":[0]}]}]},{"type":1,"name":"music","description":"Configure music in the server.","options":[]},{"type":1,"name":"reports","description":"Configure user reports in the server.","options":[{"type":7,"name":"channel","description":"The channel where user reports will be sent.","channel_types":[0]}]},{"type":2,"name":"select-roles","description":"Subcommand Group - select-roles","options":[{"type":1,"name":"add","description":"Create a new Select Role Group.","options":[{"type":3,"name":"message","description":"The content of the Select Role Message for users.","required":true},{"type":7,"name":"channel","description":"The channel where you want to send the Select Role Message.","channel_types":[5,0,2]},{"type":4,"name":"type","description":"The behavior of the Select Role Group.","choices":[{"name":"Add Only","value":1},{"name":"Remove Only","value":2}]},{"type":4,"name":"ui","description":"The variant of Select Role UI.","choices":[{"name":"Buttons","value":0},{"name":"Select Menu","value":1}]},{"type":4,"name":"min","description":"The minimum number of roles users are allowed to select.","min_value":0,"max_value":25},{"type":4,"name":"max","description":"The maximum number of roles users are allowed to select.","min_value":1,"max_value":25}]},{"type":1,"name":"list","description":"List all the Select Role Groups.","options":[{"type":7,"name":"channel","description":"List Select Role Groups only from this channel.","channel_types":[5,0,2]}]},{"type":1,"name":"remove","description":"Remove the specified Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true}]},{"type":1,"name":"update","description":"Update the roles and message for the Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true},{"type":3,"name":"message","description":"The new message content."},{"type":5,"name":"roles","description":"Reset the roles so you can add them again."}]}]},{"type":1,"name":"self-roles","description":"Configure roles that users can assign to themselves.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as a self role."}]},{"type":1,"name":"starboard","description":"Configure starboard in the server.","options":[{"type":7,"name":"channel","description":"The channel where starred messages will be logged.","channel_types":[0]},{"type":4,"name":"threshold","description":"The minimum number of stars a message needs.","min_value":2}]},{"type":1,"name":"streamer-role","description":"Set the role someone is assigned in the server when they start streaming.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."}]},{"type":1,"name":"suggestions","description":"Configure suggestions in the server.","options":[{"type":7,"name":"channel","description":"The channel where suggestions will be sent.","channel_types":[0]}]},{"type":1,"name":"triggers","description":"Configure triggers and responses in the server.","options":[{"type":3,"name":"add","description":"The pattern that will trigger the response."},{"type":3,"name":"remove","description":"The trigger that you want to remove."},{"type":3,"name":"message","description":"The message response for the trigger."},{"type":3,"name":"emoji","description":"The reaction emoji response for the trigger."}]},{"type":1,"name":"verification","description":"Configure verification in the server.","options":[{"type":8,"name":"role","description":"The role users are assigned when are verified."},{"type":3,"name":"text","description":"Type a text message that will be shown to the users trying to verify."}]},{"type":1,"name":"voice-sessions","description":"Configure voice sessions in the server.","options":[{"type":3,"name":"create","description":"Name of the new voice session category."}]},{"type":1,"name":"voting-channels","description":"Configure voting channels in the server.","options":[{"type":7,"name":"add","description":"The channel you want to add as a voting channel.","channel_types":[0]},{"type":7,"name":"remove","description":"The channel you want to remove as a voting channel.","channel_types":[0]}]}]},{"type":1,"name":"donate","description":"See the ways you can contribute to support the Bastion bot project.","options":[]},{"type":1,"name":"emoji","description":"Command Group - emoji","options":[{"type":1,"name":"info","description":"Displays information on the specified custom emoji.","options":[{"type":3,"name":"emoji","description":"The emoji you want to display.","required":true}]}]},{"type":1,"name":"games","description":"Command Group - games","options":[{"type":1,"name":"8ball","description":"Ask any question to the magic 8 ball and get answers.","options":[{"type":3,"name":"question","description":"The question you want to ask the magic 8 ball.","required":true}]},{"type":1,"name":"flip","description":"Flip coins and see the result.","options":[{"type":4,"name":"coins","description":"The number of coins to flip.","min_value":1,"max_value":128}]},{"type":1,"name":"roll","description":"Roll dice and see the result. Supports dice notation.","options":[{"type":3,"name":"notation","description":"The dice notation."}]},{"type":1,"name":"rps","description":"Play rock paper scissor with Bastion.","options":[{"type":3,"name":"choice","description":"Your choice.","choices":[{"name":"Rock","value":"ROCK"},{"name":"Paper","value":"PAPER"},{"name":"Scissor","value":"SCISSOR"}],"required":true}]},{"type":1,"name":"russian-roulette","description":"Play a game of Russian roulette.","options":[{"type":4,"name":"rounds","description":"The number rounds you want to play.","min_value":1,"max_value":6}]}]},{"type":1,"name":"game-server","description":"Fetch information from nearly any game server that makes its status publicly available.","options":[{"type":3,"name":"game","description":"The game ID for the game server.","required":true},{"type":3,"name":"hostname","description":"The IP address or domain name of the game server.","required":true},{"type":4,"name":"port","description":"The connection port number of the game server. Use the query port if connection port doesn't work.","min_value":1,"max_value":65535}]},{"type":1,"name":"gamestats","description":"Command Group - gamestats","options":[{"type":1,"name":"aimlab","description":"Check stats of any Aim Lab player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"apex","description":"Check stats of any Apex Legends player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"origin"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"csgo","description":"Check stats of any Counter-Strike: Global Offensive player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"fortnite","description":"Check stats of any Fortnite player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"kbm"},{"name":"Console","value":"gamepad"},{"name":"Mobile","value":"touch"}],"required":true}]},{"type":1,"name":"overwatch","description":"Check stats of any Overwatch 2 player.","options":[{"type":3,"name":"username","description":"The BattleTag or username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"pc"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"},{"name":"Nintendo Switch","value":"nintendo-switch"}]},{"type":3,"name":"region","description":"The region of the player.","choices":[{"name":"Americas","value":"us"},{"name":"Europe","value":"eu"},{"name":"Asia","value":"asia"}]}]},{"type":1,"name":"rainbow6","description":"Check stats of any Rainbow 6 player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"uplay"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"valorant","description":"Check stats of any Valorant player.","options":[{"type":3,"name":"username","description":"The name tag of the player.","required":true},{"type":3,"name":"region","description":"The region of the account.","choices":[{"name":"Americas","value":"na"},{"name":"Europe","value":"eu"},{"name":"Asia-Pacific","value":"ap"},{"name":"Korea","value":"kr"}],"required":true}]}]},{"type":1,"name":"give","description":"Give Bastion Coins and Experience Points to server members or take it from them.","options":[{"type":6,"name":"user","description":"The user whose coins and XP will be updated.","required":true},{"type":4,"name":"coins","description":"The amount of coins you want to give or take.","required":true},{"type":4,"name":"xp","description":"The amount of XP you want to give or take.","required":true}]},{"type":1,"name":"giveaway","description":"Run giveaways in the server.","options":[{"type":3,"name":"title","description":"The title for the giveaway.","required":true},{"type":3,"name":"description","description":"The description for the giveaway."},{"type":4,"name":"winners","description":"The number of winners for the giveaway.","min_value":1,"max_value":9007199254740991},{"type":4,"name":"timer","description":"Number of hours the giveaway should run.","min_value":1,"max_value":720}]},{"type":1,"name":"iam","description":"Assign a self assignable role to yourself.","options":[{"type":8,"name":"role","description":"The role you want to assign yourself."}]},{"type":1,"name":"image","description":"Command Group - image","options":[{"type":1,"name":"generate","description":"Generate an image with DALL-E from OpenAI.","options":[{"type":3,"name":"prompt","description":"A description of the desired image.","required":true},{"type":3,"name":"size","description":"The size of the generated image.","choices":[{"name":"Square","value":"1024x1024"},{"name":"Portrait","value":"1024x1792"},{"name":"Landscape","value":"1792x1024"}]}]}]},{"type":1,"name":"invite","description":"Generates an instant invite for the server.","options":[{"type":5,"name":"temporary","description":"Kick the members if they aren't assigned a role within 24 hours."}]},{"type":1,"name":"leaderboard","description":"Displays the server's leaderboard. You're ranked based on their level, XP, karma, and Bastion Coins.","options":[]},{"type":1,"name":"lmgtfy","description":"Send a LMGTFY link for the search query that teaches people how to do an internet search.","options":[{"type":3,"name":"query","description":"The search query.","required":true},{"type":3,"name":"site","description":"The search engine to use.","choices":[{"name":"DuckDuckGo","value":"d"},{"name":"Google","value":"g"},{"name":"Bing","value":"b"}]}]},{"type":1,"name":"message","description":"Command Group - message","options":[{"type":1,"name":"clear","description":"Clear recent messages (newer than two weeks) in the channel.","options":[{"type":4,"name":"limit","description":"Limit the numbers of messages that should be deleted.","min_value":1},{"type":5,"name":"bots","description":"Should it delete messages from bots."},{"type":5,"name":"pinned","description":"Should it delete messages that are pinned."},{"type":5,"name":"system","description":"Should it delete system messages."},{"type":6,"name":"user","description":"Only delete messages from this user."}]}]},{"type":1,"name":"music","description":"Command Group - music","options":[{"type":1,"name":"join","description":"Moves you to the voice channel where Bastion is currently connected.","options":[]},{"type":1,"name":"now","description":"Shows the song playing right now.","options":[]},{"type":1,"name":"pause","description":"Pause the music playback in the voice channel.","options":[]},{"type":1,"name":"play","description":"Play a specified song in the server.","options":[{"type":3,"name":"song","description":"The song name or link you want to play.","required":true}]},{"type":1,"name":"queue","description":"Displays the current music queue in the server.","options":[{"type":3,"name":"remove","description":"Remove songs matching the specified text from the music queue."},{"type":5,"name":"clear","description":"Remove all songs from the music queue."}]},{"type":1,"name":"resume","description":"Resume the music playback in the voice channel.","options":[]},{"type":1,"name":"shuffle","description":"Shuffle the current music queue.","options":[]},{"type":1,"name":"skip","description":"Skip the current music track that's being played in the voice channel.","options":[]},{"type":1,"name":"stop","description":"Stop the music playback and disconnect from the voice channel.","options":[]}]},{"type":1,"name":"poll","description":"Run polls in the server.","options":[{"type":3,"name":"question","description":"The question for the poll.","required":true},{"type":3,"name":"option1","description":"The 1st option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The 2nd option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The 3rd option for the poll's answer."},{"type":3,"name":"option4","description":"The 4th option for the poll's answer."},{"type":3,"name":"option5","description":"The 5th option for the poll's answer."},{"type":3,"name":"option6","description":"The 6th option for the poll's answer."},{"type":3,"name":"option7","description":"The 7th option for the poll's answer."},{"type":3,"name":"option8","description":"The 8th option for the poll's answer."},{"type":3,"name":"option9","description":"The 9th option for the poll's answer."},{"type":3,"name":"option10","description":"The 10th option for the poll's answer."},{"type":4,"name":"timer","description":"Number of hours the poll should run.","min_value":1,"max_value":720}]},{"type":1,"name":"profile","description":"Displays the Bastion profile of the specified user.","options":[{"type":6,"name":"user","description":"The user whose profile you want to display."}]},{"type":1,"name":"report","description":"Report a server member to the moderators of the server.","options":[{"type":6,"name":"user","description":"The user you want to report.","required":true},{"type":3,"name":"reason","description":"The reason you want to report the user.","required":true}]},{"type":1,"name":"role","description":"Command Group - role","options":[{"type":1,"name":"config","description":"Set the description & emoji of the specified role.","options":[{"type":8,"name":"role","description":"The role which you want to configure.","required":true},{"type":3,"name":"emoji","description":"The emoji you want to set as the role emoji."},{"type":3,"name":"description","description":"A description for the role (max 100 characters)."}]},{"type":1,"name":"create","description":"Create a new role in the server.","options":[{"type":3,"name":"name","description":"The name of the new role.","required":true},{"type":3,"name":"color","description":"The color for the new role (in HEX code)."},{"type":5,"name":"icon","description":"The icon for the new role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for creating the role."}]},{"type":1,"name":"delete","description":"Delete the specified role.","options":[{"type":8,"name":"role","description":"The role you want to delete.","required":true},{"type":3,"name":"reason","description":"The reason for deleting the role."}]},{"type":1,"name":"info","description":"Displays information on the specified role.","options":[{"type":8,"name":"role","description":"The role whose information you want to display.","required":true}]},{"type":1,"name":"levels","description":"Configure level roles. When members reach a level, they get assigned to roles in the level.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."},{"type":4,"name":"level","description":"The level at which the role should be assigned.","min_value":0},{"type":4,"name":"remove","description":"The level which you want to remove.","min_value":0}]},{"type":1,"name":"update","description":"Update the specified role in the server.","options":[{"type":8,"name":"role","description":"The role you want to update.","required":true},{"type":3,"name":"name","description":"The new name for the role."},{"type":3,"name":"color","description":"The new color for the role (in HEX code)."},{"type":5,"name":"icon","description":"The new icon for the role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for updating the role."}]}]},{"type":1,"name":"say","description":"Replies with the message you ask it to say.","options":[{"type":3,"name":"message","description":"The message you want Bastion to say.","required":true}]},{"type":1,"name":"search","description":"Command Group - search","options":[{"type":1,"name":"anime","description":"Searches for information on the specified anime.","options":[{"type":3,"name":"name","description":"The name of the anime.","required":true}]},{"type":1,"name":"apod","description":"Displays the astronomy picture of the day from NASA.","options":[]},{"type":1,"name":"cryptocurrency","description":"Searches for information on the specified crypto currency.","options":[{"type":3,"name":"symbol","description":"The symbol of the crypto currency.","required":true}]},{"type":1,"name":"definitions","description":"Displays the definitions for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"game","description":"Searches for information on the specified game.","options":[{"type":3,"name":"name","description":"The name of the game.","required":true}]},{"type":1,"name":"manga","description":"Searches for information on the specified manga.","options":[{"type":3,"name":"name","description":"The name of the manga.","required":true}]},{"type":1,"name":"movie","description":"Searches for information on the specified movie.","options":[{"type":3,"name":"name","description":"The name of the movie.","required":true}]},{"type":1,"name":"pokemon","description":"Searches for information on the specified pokémon.","options":[{"type":3,"name":"name","description":"The name (or number) of the Pokémon.","required":true}]},{"type":1,"name":"redirects","description":"Follows all the redirects in the specified URL and displays the final URL.","options":[{"type":3,"name":"url","description":"The URL you want to follow.","required":true}]},{"type":1,"name":"tv","description":"Searches for information on the specified TV show.","options":[{"type":3,"name":"name","description":"The name of the TV show.","required":true}]},{"type":1,"name":"urban-dictionary","description":"Searches Urban Dictionary for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"weather","description":"Displays the weather forcast of the specified location.","options":[{"type":3,"name":"location","description":"The location for the weather forcast.","required":true}]},{"type":1,"name":"wikipedia","description":"Searches Wikipedia for the specified query.","options":[{"type":3,"name":"query","description":"The search query.","required":true}]}]},{"type":1,"name":"server","description":"Command Group - server","options":[{"type":1,"name":"info","description":"Displays information on the server.","options":[]},{"type":1,"name":"prune","description":"Kicks the inactive members (without any roles) from the server.","options":[{"type":4,"name":"days","description":"The number of days of inactivity required for kicking.","min_value":1},{"type":8,"name":"role","description":"Inactive members check includes this role."},{"type":3,"name":"reason","description":"The reason for pruning the inactive members."}]}]},{"type":1,"name":"status","description":"Displays Bastion's status. You can also see Discord's status.","options":[{"type":5,"name":"shard","description":"Displays the status of the current shard."}]},{"type":1,"name":"su","description":"Command Group - su","options":[{"type":1,"name":"eval","description":"Evaluate JavaScript code in Bastion's context.","options":[{"type":3,"name":"code","description":"The code you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"exec","description":"Execute terminal commands on the system where Bastion is running.","options":[{"type":3,"name":"command","description":"The command you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"reload","description":"Reload Bastion's settings.","options":[]},{"type":1,"name":"shutdown","description":"Shutdown Bastion directly from Discord.","options":[]}]},{"type":1,"name":"suggest","description":"Send a suggestion to the server staff.","options":[{"type":3,"name":"suggestion","description":"What do you want to suggest?","required":true}]},{"type":1,"name":"thread","description":"Command Group - thread","options":[{"type":1,"name":"close","description":"Close and lock the thread.","options":[]},{"type":1,"name":"name","description":"Change the name of the thread.","options":[{"type":3,"name":"name","description":"The new name for the thread.","required":true}]}]},{"type":1,"name":"translate","description":"Translates the specified text from one language to another.","options":[{"type":3,"name":"text","description":"The text you want to translate.","required":true},{"type":3,"name":"to","description":"The language you want to translate to."},{"type":3,"name":"from","description":"The language you want to translate from."}]},{"type":1,"name":"user","description":"Command Group - user","options":[{"type":1,"name":"avatar","description":"Displays the avatar of the specified user.","options":[{"type":6,"name":"user","description":"The user whose avatar you want to display."}]},{"type":1,"name":"info","description":"Displays information on the specified user.","options":[{"type":6,"name":"user","description":"The user whose information you want to display."}]},{"type":1,"name":"infractions","description":"Configure infraction actions and displays infractions of the specified user.","options":[{"type":4,"name":"timeout","description":"Number of violations after which a user is timed out.","min_value":1},{"type":4,"name":"kick","description":"Number of violations after which a user is kicked.","min_value":1},{"type":4,"name":"ban","description":"Number of violations after which a user is banned.","min_value":1},{"type":6,"name":"user","description":"The user whose infractions you want to display."},{"type":4,"name":"remove","description":"The infraction you want to remove from the user.","min_value":1}]}]},{"type":1,"name":"warn","description":"Warn server members and add infractions to their server profile.","options":[{"type":6,"name":"user","description":"The user you want to warn.","required":true},{"type":3,"name":"reason","description":"The reason for the warning.","required":true}]}] \ No newline at end of file From db1da65a309ae231bf74ae481ae02121be2597d4 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:07:01 +0530 Subject: [PATCH 24/28] commands(chat): add user metadata Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/chat.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/commands/chat.ts b/src/commands/chat.ts index 19b1b5a22..93cd987fa 100644 --- a/src/commands/chat.ts +++ b/src/commands/chat.ts @@ -92,6 +92,9 @@ class ChatCommand extends Command { ], }, ], + metadata: { + user_id: interaction.member.id, + }, }); return await interaction.editReply({ From 1191a9f5ae54b952b32ae792cd1f3c050d5bc8b0 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:30:01 +0530 Subject: [PATCH 25/28] commands(translate): add metadata Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/commands/translate.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commands/translate.ts b/src/commands/translate.ts index 095fe821a..ececb1c8b 100644 --- a/src/commands/translate.ts +++ b/src/commands/translate.ts @@ -42,7 +42,10 @@ class TranslateCommand extends Command { // fetch the translation const response = await translate(text, { from, to }); - await interaction.editReply(response.text); + await interaction.editReply({ + content: `${ response.text } +-# Translated from ${ response.from.language.iso?.toUpperCase() } to ${ to.toUpperCase() }`, + }); } } From 16cf016c9431e46b4118d0da1306a6ba2f53df40 Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:30:38 +0530 Subject: [PATCH 26/28] actions: add Translate context menu command Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/actions/Translate.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/actions/Translate.ts diff --git a/src/actions/Translate.ts b/src/actions/Translate.ts new file mode 100644 index 000000000..b290a83e0 --- /dev/null +++ b/src/actions/Translate.ts @@ -0,0 +1,32 @@ +/*! + * @author TRACTION (iamtraction) + * @copyright 2024 + */ +import { ApplicationCommandType, MessageContextMenuCommandInteraction } from "discord.js"; +import { Command } from "@bastion/tesseract"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +import translate = require("@iamtraction/google-translate"); + +class TranslateCommand extends Command { + constructor() { + super({ + type: ApplicationCommandType.Message, + name: "Translate", + description: "", + }); + } + + public async exec(interaction: MessageContextMenuCommandInteraction<"cached">): Promise { + if (!interaction.targetMessage.content) return; + + // fetch the translation + const response = await translate(interaction.targetMessage.content, { to: "en" }); + + return await interaction.reply({ + content: `${ response.text } +-# Translated from ${ response.from.language.iso?.toUpperCase() } to English`, + }); + } +} + +export { TranslateCommand as Command }; From 412fa9019d7425cbc8e92c7f8d85711a692e3bbc Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:35:37 +0530 Subject: [PATCH 27/28] actions: add Sentiment command Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- src/actions/Sentiment.ts | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/actions/Sentiment.ts diff --git a/src/actions/Sentiment.ts b/src/actions/Sentiment.ts new file mode 100644 index 000000000..822c61ecd --- /dev/null +++ b/src/actions/Sentiment.ts @@ -0,0 +1,110 @@ +/*! + * @author TRACTION (iamtraction) + * @copyright 2024 + */ +import { ApplicationCommandType, MessageContextMenuCommandInteraction } from "discord.js"; +import { Client, Command } from "@bastion/tesseract"; +import Anthropic from "@anthropic-ai/sdk"; +import OpenAI from "openai"; +import { GoogleGenerativeAI } from "@google/generative-ai"; + +import Settings from "../utils/settings.js"; + +class SentimentCommand extends Command { + constructor() { + super({ + type: ApplicationCommandType.Message, + name: "Sentiment", + description: "", + owner: true, + }); + } + + public async exec(interaction: MessageContextMenuCommandInteraction<"cached">): Promise { + if (!interaction.targetMessage.content) return; + + const systemPrompt = "You are a helpful and informative AI assistant. You will analyze the given text and provide an assessment of its sentiment. Consider the overall tone, specific words and phrases used, and any contextual clues. Your response should be short, concise, objective, and informative."; + const sentimentPrompt = `Please analyze the following text and provide a assessment of its sentiment: ${ interaction.targetMessage.content }`; + + // use ChatGPT if OpenAI API key is present + if (((interaction.client as Client).settings as Settings).get("openai").apiKey) { + const openai = new OpenAI({ + apiKey: ((interaction.client as Client).settings as Settings).get("openai").apiKey, + }); + + const response = await openai.chat.completions.create({ + model: ((interaction.client as Client).settings as Settings).get("openai").model, + messages: [ + { + role: "system", + content: systemPrompt, + }, + { + role: "user", + content: sentimentPrompt, + }, + ], + max_tokens: ((interaction.client as Client).settings as Settings).get("openai").maxTokens, + user: interaction.member.id, + }); + + return await interaction.reply({ + content: response.choices[0].message.content, + ephemeral: true, + }); + } + + // use Gemini if Gemini API key is present + if (((interaction.client as Client).settings as Settings).get("gemini").apiKey) { + const gemini = new GoogleGenerativeAI(((interaction.client as Client).settings as Settings).get("gemini").apiKey); + const geminiModel = gemini.getGenerativeModel({ + model: ((interaction.client as Client).settings as Settings).get("gemini").model, + systemInstruction: systemPrompt, + generationConfig: { + maxOutputTokens: ((interaction.client as Client).settings as Settings).get("gemini").maxOutputTokens, + }, + }); + + const result = await geminiModel.generateContent(sentimentPrompt); + + return await interaction.reply({ + content: result.response.text(), + ephemeral: true, + }); + } + + // use Claude if Anthropic API key is present + if (((interaction.client as Client).settings as Settings).get("anthropic").apiKey) { + const anthropic = new Anthropic({ + apiKey: ((interaction.client as Client).settings as Settings).get("anthropic").apiKey, + }); + + const result = await anthropic.messages.create({ + model: ((interaction.client as Client).settings as Settings).get("anthropic").model, + system: systemPrompt, + max_tokens: ((interaction.client as Client).settings as Settings).get("anthropic").maxTokens, + messages: [ + { + role: "user", + content: [ + { + type: "text", + text: sentimentPrompt, + }, + ], + }, + ], + metadata: { + user_id: interaction.member.id, + }, + }); + + return await interaction.reply({ + content: result.content[0].type === "text" && result.content[0].text, + ephemeral: true, + }); + } + } +} + +export { SentimentCommand as Command }; From 66d8955c079ea7b47e533af58a58a73d8b5c632c Mon Sep 17 00:00:00 2001 From: TRACTION <19631364+iamtraction@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:36:36 +0530 Subject: [PATCH 28/28] chore: generate commands data Signed-off-by: TRACTION <19631364+iamtraction@users.noreply.github.com> --- commands.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands.json b/commands.json index 28f0d36f5..f9356777d 100644 --- a/commands.json +++ b/commands.json @@ -1 +1 @@ -[{"type":1,"name":"about","description":"Displays some basic information to help you get started with Bastion.","options":[]},{"type":1,"name":"calculate","description":"Evaluates the specified mathematical expression.","options":[{"type":3,"name":"expression","description":"The expression you want to evaluate.","required":true}]},{"type":1,"name":"changes","description":"See the changes introduced in the current version of Bastion.","options":[]},{"type":1,"name":"channel","description":"Command Group - channel","options":[{"type":1,"name":"create","description":"Create a new channel in the server.","options":[{"type":3,"name":"name","description":"The name of the new channel.","required":true},{"type":4,"name":"type","description":"The type of the new channel.","choices":[{"name":"Text","value":0},{"name":"Voice","value":2},{"name":"Announcement","value":5},{"name":"Stage","value":13},{"name":"Category","value":4}],"required":true},{"type":3,"name":"topic","description":"The topic for the new channel."},{"type":4,"name":"limit","description":"Limit the number of users for the new (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"Enable slowmode with the specified interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for creating the channel."}]},{"type":1,"name":"delete","description":"Delete the current (or the specified) channel.","options":[{"type":7,"name":"channel","description":"The channel you want to delete."},{"type":3,"name":"reason","description":"The reason for deleting the channel."}]},{"type":1,"name":"info","description":"Displays information on the current (or specified) channel.","options":[{"type":7,"name":"channel","description":"The channel whose information you want to display."}]},{"type":1,"name":"update","description":"Update the specified channel in the server.","options":[{"type":7,"name":"channel","description":"The channel you want to update."},{"type":3,"name":"name","description":"The new name for the channel."},{"type":3,"name":"topic","description":"The new topic for the channel."},{"type":4,"name":"limit","description":"The new limit of users for the (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"The new slowmode interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for updating the channel."}]}]},{"type":1,"name":"chat","description":"Ask questions or chat with Bastion.","options":[{"type":3,"name":"message","description":"Your message.","required":true}]},{"type":1,"name":"claim","description":"Claim any rewards available to you.","options":[]},{"type":1,"name":"comic","description":"Command Group - comic","options":[{"type":1,"name":"garfield","description":"Check the latest Garfield comic.","options":[]},{"type":1,"name":"phd","description":"Check the latest PHD comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]},{"type":1,"name":"xkcd","description":"Check the latest xkcd comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]}]},{"type":1,"name":"config","description":"Command Group - config","options":[{"type":1,"name":"auto-roles","description":"Configure roles that will be auto assigned to members when they join the server.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as an auto role."},{"type":5,"name":"bots","description":"Whether this role should be auto assigned to bots."}]},{"type":1,"name":"auto-threads","description":"Configure auto threads in the server.","options":[]},{"type":1,"name":"farewell","description":"Configure farewell messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the farewell messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom farewell message."},{"type":4,"name":"timeout","description":"The interval after which the farewell message will be deleted.","min_value":1,"max_value":30}]},{"type":2,"name":"filter","description":"Subcommand Group - filter","options":[{"type":1,"name":"emails","description":"Configure Email Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"invites","description":"Configure Invite Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"links","description":"Configure Link Filter AutoMod rule in the server.","options":[]}]},{"type":1,"name":"gambling","description":"Configure gambling in the server.","options":[{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"gamification","description":"Configure gamification in the server.","options":[{"type":5,"name":"messages","description":"Should it show the level up messages."},{"type":7,"name":"channel","description":"The channel where the level up messages will be sent.","channel_types":[0]},{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"greeting","description":"Configure greeting messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the greeting messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom greeting message."},{"type":4,"name":"timeout","description":"The interval after which the greeting message will be deleted.","min_value":1,"max_value":30}]},{"type":1,"name":"live-streams","description":"Follow streamers and get notified in the specified channel when they go live.","options":[{"type":3,"name":"twitch","description":"The twitch channel you want to follow."},{"type":7,"name":"channel","description":"The channel where the notifications will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom message for notification."}]},{"type":2,"name":"logs","description":"Subcommand Group - logs","options":[{"type":1,"name":"content","description":"Configure whether deleted and edited message content should be shown in server logs.","options":[]},{"type":1,"name":"mod","description":"Configure channel for logging moderation events.","options":[{"type":7,"name":"channel","description":"The channel where moderation events will be logged.","channel_types":[0]}]},{"type":1,"name":"server","description":"Configure channel for logging server events.","options":[{"type":7,"name":"channel","description":"The channel where server events will be logged.","channel_types":[0]}]}]},{"type":1,"name":"music","description":"Configure music in the server.","options":[]},{"type":1,"name":"reports","description":"Configure user reports in the server.","options":[{"type":7,"name":"channel","description":"The channel where user reports will be sent.","channel_types":[0]}]},{"type":2,"name":"select-roles","description":"Subcommand Group - select-roles","options":[{"type":1,"name":"add","description":"Create a new Select Role Group.","options":[{"type":3,"name":"message","description":"The content of the Select Role Message for users.","required":true},{"type":7,"name":"channel","description":"The channel where you want to send the Select Role Message.","channel_types":[5,0,2]},{"type":4,"name":"type","description":"The behavior of the Select Role Group.","choices":[{"name":"Add Only","value":1},{"name":"Remove Only","value":2}]},{"type":4,"name":"ui","description":"The variant of Select Role UI.","choices":[{"name":"Buttons","value":0},{"name":"Select Menu","value":1}]},{"type":4,"name":"min","description":"The minimum number of roles users are allowed to select.","min_value":0,"max_value":25},{"type":4,"name":"max","description":"The maximum number of roles users are allowed to select.","min_value":1,"max_value":25}]},{"type":1,"name":"list","description":"List all the Select Role Groups.","options":[{"type":7,"name":"channel","description":"List Select Role Groups only from this channel.","channel_types":[5,0,2]}]},{"type":1,"name":"remove","description":"Remove the specified Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true}]},{"type":1,"name":"update","description":"Update the roles and message for the Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true},{"type":3,"name":"message","description":"The new message content."},{"type":5,"name":"roles","description":"Reset the roles so you can add them again."}]}]},{"type":1,"name":"self-roles","description":"Configure roles that users can assign to themselves.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as a self role."}]},{"type":1,"name":"starboard","description":"Configure starboard in the server.","options":[{"type":7,"name":"channel","description":"The channel where starred messages will be logged.","channel_types":[0]},{"type":4,"name":"threshold","description":"The minimum number of stars a message needs.","min_value":2}]},{"type":1,"name":"streamer-role","description":"Set the role someone is assigned in the server when they start streaming.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."}]},{"type":1,"name":"suggestions","description":"Configure suggestions in the server.","options":[{"type":7,"name":"channel","description":"The channel where suggestions will be sent.","channel_types":[0]}]},{"type":1,"name":"triggers","description":"Configure triggers and responses in the server.","options":[{"type":3,"name":"add","description":"The pattern that will trigger the response."},{"type":3,"name":"remove","description":"The trigger that you want to remove."},{"type":3,"name":"message","description":"The message response for the trigger."},{"type":3,"name":"emoji","description":"The reaction emoji response for the trigger."}]},{"type":1,"name":"verification","description":"Configure verification in the server.","options":[{"type":8,"name":"role","description":"The role users are assigned when are verified."},{"type":3,"name":"text","description":"Type a text message that will be shown to the users trying to verify."}]},{"type":1,"name":"voice-sessions","description":"Configure voice sessions in the server.","options":[{"type":3,"name":"create","description":"Name of the new voice session category."}]},{"type":1,"name":"voting-channels","description":"Configure voting channels in the server.","options":[{"type":7,"name":"add","description":"The channel you want to add as a voting channel.","channel_types":[0]},{"type":7,"name":"remove","description":"The channel you want to remove as a voting channel.","channel_types":[0]}]}]},{"type":1,"name":"donate","description":"See the ways you can contribute to support the Bastion bot project.","options":[]},{"type":1,"name":"emoji","description":"Command Group - emoji","options":[{"type":1,"name":"info","description":"Displays information on the specified custom emoji.","options":[{"type":3,"name":"emoji","description":"The emoji you want to display.","required":true}]}]},{"type":1,"name":"games","description":"Command Group - games","options":[{"type":1,"name":"8ball","description":"Ask any question to the magic 8 ball and get answers.","options":[{"type":3,"name":"question","description":"The question you want to ask the magic 8 ball.","required":true}]},{"type":1,"name":"flip","description":"Flip coins and see the result.","options":[{"type":4,"name":"coins","description":"The number of coins to flip.","min_value":1,"max_value":128}]},{"type":1,"name":"roll","description":"Roll dice and see the result. Supports dice notation.","options":[{"type":3,"name":"notation","description":"The dice notation."}]},{"type":1,"name":"rps","description":"Play rock paper scissor with Bastion.","options":[{"type":3,"name":"choice","description":"Your choice.","choices":[{"name":"Rock","value":"ROCK"},{"name":"Paper","value":"PAPER"},{"name":"Scissor","value":"SCISSOR"}],"required":true}]},{"type":1,"name":"russian-roulette","description":"Play a game of Russian roulette.","options":[{"type":4,"name":"rounds","description":"The number rounds you want to play.","min_value":1,"max_value":6}]}]},{"type":1,"name":"game-server","description":"Fetch information from nearly any game server that makes its status publicly available.","options":[{"type":3,"name":"game","description":"The game ID for the game server.","required":true},{"type":3,"name":"hostname","description":"The IP address or domain name of the game server.","required":true},{"type":4,"name":"port","description":"The connection port number of the game server. Use the query port if connection port doesn't work.","min_value":1,"max_value":65535}]},{"type":1,"name":"gamestats","description":"Command Group - gamestats","options":[{"type":1,"name":"aimlab","description":"Check stats of any Aim Lab player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"apex","description":"Check stats of any Apex Legends player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"origin"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"csgo","description":"Check stats of any Counter-Strike: Global Offensive player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"fortnite","description":"Check stats of any Fortnite player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"kbm"},{"name":"Console","value":"gamepad"},{"name":"Mobile","value":"touch"}],"required":true}]},{"type":1,"name":"overwatch","description":"Check stats of any Overwatch 2 player.","options":[{"type":3,"name":"username","description":"The BattleTag or username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"pc"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"},{"name":"Nintendo Switch","value":"nintendo-switch"}]},{"type":3,"name":"region","description":"The region of the player.","choices":[{"name":"Americas","value":"us"},{"name":"Europe","value":"eu"},{"name":"Asia","value":"asia"}]}]},{"type":1,"name":"rainbow6","description":"Check stats of any Rainbow 6 player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"uplay"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"valorant","description":"Check stats of any Valorant player.","options":[{"type":3,"name":"username","description":"The name tag of the player.","required":true},{"type":3,"name":"region","description":"The region of the account.","choices":[{"name":"Americas","value":"na"},{"name":"Europe","value":"eu"},{"name":"Asia-Pacific","value":"ap"},{"name":"Korea","value":"kr"}],"required":true}]}]},{"type":1,"name":"give","description":"Give Bastion Coins and Experience Points to server members or take it from them.","options":[{"type":6,"name":"user","description":"The user whose coins and XP will be updated.","required":true},{"type":4,"name":"coins","description":"The amount of coins you want to give or take.","required":true},{"type":4,"name":"xp","description":"The amount of XP you want to give or take.","required":true}]},{"type":1,"name":"giveaway","description":"Run giveaways in the server.","options":[{"type":3,"name":"title","description":"The title for the giveaway.","required":true},{"type":3,"name":"description","description":"The description for the giveaway."},{"type":4,"name":"winners","description":"The number of winners for the giveaway.","min_value":1,"max_value":9007199254740991},{"type":4,"name":"timer","description":"Number of hours the giveaway should run.","min_value":1,"max_value":720}]},{"type":1,"name":"iam","description":"Assign a self assignable role to yourself.","options":[{"type":8,"name":"role","description":"The role you want to assign yourself."}]},{"type":1,"name":"image","description":"Command Group - image","options":[{"type":1,"name":"generate","description":"Generate an image with DALL-E from OpenAI.","options":[{"type":3,"name":"prompt","description":"A description of the desired image.","required":true},{"type":3,"name":"size","description":"The size of the generated image.","choices":[{"name":"Square","value":"1024x1024"},{"name":"Portrait","value":"1024x1792"},{"name":"Landscape","value":"1792x1024"}]}]}]},{"type":1,"name":"invite","description":"Generates an instant invite for the server.","options":[{"type":5,"name":"temporary","description":"Kick the members if they aren't assigned a role within 24 hours."}]},{"type":1,"name":"leaderboard","description":"Displays the server's leaderboard. You're ranked based on their level, XP, karma, and Bastion Coins.","options":[]},{"type":1,"name":"lmgtfy","description":"Send a LMGTFY link for the search query that teaches people how to do an internet search.","options":[{"type":3,"name":"query","description":"The search query.","required":true},{"type":3,"name":"site","description":"The search engine to use.","choices":[{"name":"DuckDuckGo","value":"d"},{"name":"Google","value":"g"},{"name":"Bing","value":"b"}]}]},{"type":1,"name":"message","description":"Command Group - message","options":[{"type":1,"name":"clear","description":"Clear recent messages (newer than two weeks) in the channel.","options":[{"type":4,"name":"limit","description":"Limit the numbers of messages that should be deleted.","min_value":1},{"type":5,"name":"bots","description":"Should it delete messages from bots."},{"type":5,"name":"pinned","description":"Should it delete messages that are pinned."},{"type":5,"name":"system","description":"Should it delete system messages."},{"type":6,"name":"user","description":"Only delete messages from this user."}]}]},{"type":1,"name":"music","description":"Command Group - music","options":[{"type":1,"name":"join","description":"Moves you to the voice channel where Bastion is currently connected.","options":[]},{"type":1,"name":"now","description":"Shows the song playing right now.","options":[]},{"type":1,"name":"pause","description":"Pause the music playback in the voice channel.","options":[]},{"type":1,"name":"play","description":"Play a specified song in the server.","options":[{"type":3,"name":"song","description":"The song name or link you want to play.","required":true}]},{"type":1,"name":"queue","description":"Displays the current music queue in the server.","options":[{"type":3,"name":"remove","description":"Remove songs matching the specified text from the music queue."},{"type":5,"name":"clear","description":"Remove all songs from the music queue."}]},{"type":1,"name":"resume","description":"Resume the music playback in the voice channel.","options":[]},{"type":1,"name":"shuffle","description":"Shuffle the current music queue.","options":[]},{"type":1,"name":"skip","description":"Skip the current music track that's being played in the voice channel.","options":[]},{"type":1,"name":"stop","description":"Stop the music playback and disconnect from the voice channel.","options":[]}]},{"type":1,"name":"poll","description":"Run polls in the server.","options":[{"type":3,"name":"question","description":"The question for the poll.","required":true},{"type":3,"name":"option1","description":"The 1st option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The 2nd option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The 3rd option for the poll's answer."},{"type":3,"name":"option4","description":"The 4th option for the poll's answer."},{"type":3,"name":"option5","description":"The 5th option for the poll's answer."},{"type":3,"name":"option6","description":"The 6th option for the poll's answer."},{"type":3,"name":"option7","description":"The 7th option for the poll's answer."},{"type":3,"name":"option8","description":"The 8th option for the poll's answer."},{"type":3,"name":"option9","description":"The 9th option for the poll's answer."},{"type":3,"name":"option10","description":"The 10th option for the poll's answer."},{"type":4,"name":"timer","description":"Number of hours the poll should run.","min_value":1,"max_value":720}]},{"type":1,"name":"profile","description":"Displays the Bastion profile of the specified user.","options":[{"type":6,"name":"user","description":"The user whose profile you want to display."}]},{"type":1,"name":"report","description":"Report a server member to the moderators of the server.","options":[{"type":6,"name":"user","description":"The user you want to report.","required":true},{"type":3,"name":"reason","description":"The reason you want to report the user.","required":true}]},{"type":1,"name":"role","description":"Command Group - role","options":[{"type":1,"name":"config","description":"Set the description & emoji of the specified role.","options":[{"type":8,"name":"role","description":"The role which you want to configure.","required":true},{"type":3,"name":"emoji","description":"The emoji you want to set as the role emoji."},{"type":3,"name":"description","description":"A description for the role (max 100 characters)."}]},{"type":1,"name":"create","description":"Create a new role in the server.","options":[{"type":3,"name":"name","description":"The name of the new role.","required":true},{"type":3,"name":"color","description":"The color for the new role (in HEX code)."},{"type":5,"name":"icon","description":"The icon for the new role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for creating the role."}]},{"type":1,"name":"delete","description":"Delete the specified role.","options":[{"type":8,"name":"role","description":"The role you want to delete.","required":true},{"type":3,"name":"reason","description":"The reason for deleting the role."}]},{"type":1,"name":"info","description":"Displays information on the specified role.","options":[{"type":8,"name":"role","description":"The role whose information you want to display.","required":true}]},{"type":1,"name":"levels","description":"Configure level roles. When members reach a level, they get assigned to roles in the level.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."},{"type":4,"name":"level","description":"The level at which the role should be assigned.","min_value":0},{"type":4,"name":"remove","description":"The level which you want to remove.","min_value":0}]},{"type":1,"name":"update","description":"Update the specified role in the server.","options":[{"type":8,"name":"role","description":"The role you want to update.","required":true},{"type":3,"name":"name","description":"The new name for the role."},{"type":3,"name":"color","description":"The new color for the role (in HEX code)."},{"type":5,"name":"icon","description":"The new icon for the role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for updating the role."}]}]},{"type":1,"name":"say","description":"Replies with the message you ask it to say.","options":[{"type":3,"name":"message","description":"The message you want Bastion to say.","required":true}]},{"type":1,"name":"search","description":"Command Group - search","options":[{"type":1,"name":"anime","description":"Searches for information on the specified anime.","options":[{"type":3,"name":"name","description":"The name of the anime.","required":true}]},{"type":1,"name":"apod","description":"Displays the astronomy picture of the day from NASA.","options":[]},{"type":1,"name":"cryptocurrency","description":"Searches for information on the specified crypto currency.","options":[{"type":3,"name":"symbol","description":"The symbol of the crypto currency.","required":true}]},{"type":1,"name":"definitions","description":"Displays the definitions for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"game","description":"Searches for information on the specified game.","options":[{"type":3,"name":"name","description":"The name of the game.","required":true}]},{"type":1,"name":"manga","description":"Searches for information on the specified manga.","options":[{"type":3,"name":"name","description":"The name of the manga.","required":true}]},{"type":1,"name":"movie","description":"Searches for information on the specified movie.","options":[{"type":3,"name":"name","description":"The name of the movie.","required":true}]},{"type":1,"name":"pokemon","description":"Searches for information on the specified pokémon.","options":[{"type":3,"name":"name","description":"The name (or number) of the Pokémon.","required":true}]},{"type":1,"name":"redirects","description":"Follows all the redirects in the specified URL and displays the final URL.","options":[{"type":3,"name":"url","description":"The URL you want to follow.","required":true}]},{"type":1,"name":"tv","description":"Searches for information on the specified TV show.","options":[{"type":3,"name":"name","description":"The name of the TV show.","required":true}]},{"type":1,"name":"urban-dictionary","description":"Searches Urban Dictionary for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"weather","description":"Displays the weather forcast of the specified location.","options":[{"type":3,"name":"location","description":"The location for the weather forcast.","required":true}]},{"type":1,"name":"wikipedia","description":"Searches Wikipedia for the specified query.","options":[{"type":3,"name":"query","description":"The search query.","required":true}]}]},{"type":1,"name":"server","description":"Command Group - server","options":[{"type":1,"name":"info","description":"Displays information on the server.","options":[]},{"type":1,"name":"prune","description":"Kicks the inactive members (without any roles) from the server.","options":[{"type":4,"name":"days","description":"The number of days of inactivity required for kicking.","min_value":1},{"type":8,"name":"role","description":"Inactive members check includes this role."},{"type":3,"name":"reason","description":"The reason for pruning the inactive members."}]}]},{"type":1,"name":"status","description":"Displays Bastion's status. You can also see Discord's status.","options":[{"type":5,"name":"shard","description":"Displays the status of the current shard."}]},{"type":1,"name":"su","description":"Command Group - su","options":[{"type":1,"name":"eval","description":"Evaluate JavaScript code in Bastion's context.","options":[{"type":3,"name":"code","description":"The code you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"exec","description":"Execute terminal commands on the system where Bastion is running.","options":[{"type":3,"name":"command","description":"The command you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"reload","description":"Reload Bastion's settings.","options":[]},{"type":1,"name":"shutdown","description":"Shutdown Bastion directly from Discord.","options":[]}]},{"type":1,"name":"suggest","description":"Send a suggestion to the server staff.","options":[{"type":3,"name":"suggestion","description":"What do you want to suggest?","required":true}]},{"type":1,"name":"thread","description":"Command Group - thread","options":[{"type":1,"name":"close","description":"Close and lock the thread.","options":[]},{"type":1,"name":"name","description":"Change the name of the thread.","options":[{"type":3,"name":"name","description":"The new name for the thread.","required":true}]}]},{"type":1,"name":"translate","description":"Translates the specified text from one language to another.","options":[{"type":3,"name":"text","description":"The text you want to translate.","required":true},{"type":3,"name":"to","description":"The language you want to translate to."},{"type":3,"name":"from","description":"The language you want to translate from."}]},{"type":1,"name":"user","description":"Command Group - user","options":[{"type":1,"name":"avatar","description":"Displays the avatar of the specified user.","options":[{"type":6,"name":"user","description":"The user whose avatar you want to display."}]},{"type":1,"name":"info","description":"Displays information on the specified user.","options":[{"type":6,"name":"user","description":"The user whose information you want to display."}]},{"type":1,"name":"infractions","description":"Configure infraction actions and displays infractions of the specified user.","options":[{"type":4,"name":"timeout","description":"Number of violations after which a user is timed out.","min_value":1},{"type":4,"name":"kick","description":"Number of violations after which a user is kicked.","min_value":1},{"type":4,"name":"ban","description":"Number of violations after which a user is banned.","min_value":1},{"type":6,"name":"user","description":"The user whose infractions you want to display."},{"type":4,"name":"remove","description":"The infraction you want to remove from the user.","min_value":1}]}]},{"type":1,"name":"warn","description":"Warn server members and add infractions to their server profile.","options":[{"type":6,"name":"user","description":"The user you want to warn.","required":true},{"type":3,"name":"reason","description":"The reason for the warning.","required":true}]}] \ No newline at end of file +[{"type":3,"name":"Sentiment","description":""},{"type":3,"name":"Translate","description":""},{"type":1,"name":"about","description":"Displays some basic information to help you get started with Bastion.","options":[]},{"type":1,"name":"calculate","description":"Evaluates the specified mathematical expression.","options":[{"type":3,"name":"expression","description":"The expression you want to evaluate.","required":true}]},{"type":1,"name":"changes","description":"See the changes introduced in the current version of Bastion.","options":[]},{"type":1,"name":"channel","description":"Command Group - channel","options":[{"type":1,"name":"create","description":"Create a new channel in the server.","options":[{"type":3,"name":"name","description":"The name of the new channel.","required":true},{"type":4,"name":"type","description":"The type of the new channel.","choices":[{"name":"Text","value":0},{"name":"Voice","value":2},{"name":"Announcement","value":5},{"name":"Stage","value":13},{"name":"Category","value":4}],"required":true},{"type":3,"name":"topic","description":"The topic for the new channel."},{"type":4,"name":"limit","description":"Limit the number of users for the new (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"Enable slowmode with the specified interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for creating the channel."}]},{"type":1,"name":"delete","description":"Delete the current (or the specified) channel.","options":[{"type":7,"name":"channel","description":"The channel you want to delete."},{"type":3,"name":"reason","description":"The reason for deleting the channel."}]},{"type":1,"name":"info","description":"Displays information on the current (or specified) channel.","options":[{"type":7,"name":"channel","description":"The channel whose information you want to display."}]},{"type":1,"name":"update","description":"Update the specified channel in the server.","options":[{"type":7,"name":"channel","description":"The channel you want to update."},{"type":3,"name":"name","description":"The new name for the channel."},{"type":3,"name":"topic","description":"The new topic for the channel."},{"type":4,"name":"limit","description":"The new limit of users for the (voice) channel.","min_value":1,"max_value":99},{"type":4,"name":"slowmode","description":"The new slowmode interval (in seconds).","min_value":0,"max_value":21600},{"type":5,"name":"nsfw","description":"Should the channel be NSFW."},{"type":3,"name":"reason","description":"The reason for updating the channel."}]}]},{"type":1,"name":"chat","description":"Ask questions or chat with Bastion.","options":[{"type":3,"name":"message","description":"Your message.","required":true}]},{"type":1,"name":"claim","description":"Claim any rewards available to you.","options":[]},{"type":1,"name":"comic","description":"Command Group - comic","options":[{"type":1,"name":"garfield","description":"Check the latest Garfield comic.","options":[]},{"type":1,"name":"phd","description":"Check the latest PHD comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]},{"type":1,"name":"xkcd","description":"Check the latest xkcd comic, or the specified issue.","options":[{"type":4,"name":"issue","description":"Issue number to see the comic.","min_value":1}]}]},{"type":1,"name":"config","description":"Command Group - config","options":[{"type":1,"name":"auto-roles","description":"Configure roles that will be auto assigned to members when they join the server.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as an auto role."},{"type":5,"name":"bots","description":"Whether this role should be auto assigned to bots."}]},{"type":1,"name":"auto-threads","description":"Configure auto threads in the server.","options":[]},{"type":1,"name":"farewell","description":"Configure farewell messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the farewell messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom farewell message."},{"type":4,"name":"timeout","description":"The interval after which the farewell message will be deleted.","min_value":1,"max_value":30}]},{"type":2,"name":"filter","description":"Subcommand Group - filter","options":[{"type":1,"name":"emails","description":"Configure Email Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"invites","description":"Configure Invite Filter AutoMod rule in the server.","options":[]},{"type":1,"name":"links","description":"Configure Link Filter AutoMod rule in the server.","options":[]}]},{"type":1,"name":"gambling","description":"Configure gambling in the server.","options":[{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"gamification","description":"Configure gamification in the server.","options":[{"type":5,"name":"messages","description":"Should it show the level up messages."},{"type":7,"name":"channel","description":"The channel where the level up messages will be sent.","channel_types":[0]},{"type":10,"name":"multiplier","description":"The reward multiplier."}]},{"type":1,"name":"greeting","description":"Configure greeting messages in the server.","options":[{"type":7,"name":"channel","description":"The channel where the greeting messages will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom greeting message."},{"type":4,"name":"timeout","description":"The interval after which the greeting message will be deleted.","min_value":1,"max_value":30}]},{"type":1,"name":"live-streams","description":"Follow streamers and get notified in the specified channel when they go live.","options":[{"type":3,"name":"twitch","description":"The twitch channel you want to follow."},{"type":7,"name":"channel","description":"The channel where the notifications will be sent.","channel_types":[0]},{"type":3,"name":"message","description":"The custom message for notification."}]},{"type":2,"name":"logs","description":"Subcommand Group - logs","options":[{"type":1,"name":"content","description":"Configure whether deleted and edited message content should be shown in server logs.","options":[]},{"type":1,"name":"mod","description":"Configure channel for logging moderation events.","options":[{"type":7,"name":"channel","description":"The channel where moderation events will be logged.","channel_types":[0]}]},{"type":1,"name":"server","description":"Configure channel for logging server events.","options":[{"type":7,"name":"channel","description":"The channel where server events will be logged.","channel_types":[0]}]}]},{"type":1,"name":"music","description":"Configure music in the server.","options":[]},{"type":1,"name":"reports","description":"Configure user reports in the server.","options":[{"type":7,"name":"channel","description":"The channel where user reports will be sent.","channel_types":[0]}]},{"type":2,"name":"select-roles","description":"Subcommand Group - select-roles","options":[{"type":1,"name":"add","description":"Create a new Select Role Group.","options":[{"type":3,"name":"message","description":"The content of the Select Role Message for users.","required":true},{"type":7,"name":"channel","description":"The channel where you want to send the Select Role Message.","channel_types":[5,0,2]},{"type":4,"name":"type","description":"The behavior of the Select Role Group.","choices":[{"name":"Add Only","value":1},{"name":"Remove Only","value":2}]},{"type":4,"name":"ui","description":"The variant of Select Role UI.","choices":[{"name":"Buttons","value":0},{"name":"Select Menu","value":1}]},{"type":4,"name":"min","description":"The minimum number of roles users are allowed to select.","min_value":0,"max_value":25},{"type":4,"name":"max","description":"The maximum number of roles users are allowed to select.","min_value":1,"max_value":25}]},{"type":1,"name":"list","description":"List all the Select Role Groups.","options":[{"type":7,"name":"channel","description":"List Select Role Groups only from this channel.","channel_types":[5,0,2]}]},{"type":1,"name":"remove","description":"Remove the specified Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true}]},{"type":1,"name":"update","description":"Update the roles and message for the Select Roles Group.","options":[{"type":3,"name":"id","description":"The Select Roles Group ID.","required":true},{"type":3,"name":"message","description":"The new message content."},{"type":5,"name":"roles","description":"Reset the roles so you can add them again."}]}]},{"type":1,"name":"self-roles","description":"Configure roles that users can assign to themselves.","options":[{"type":8,"name":"role","description":"The role you want to add or remove as a self role."}]},{"type":1,"name":"starboard","description":"Configure starboard in the server.","options":[{"type":7,"name":"channel","description":"The channel where starred messages will be logged.","channel_types":[0]},{"type":4,"name":"threshold","description":"The minimum number of stars a message needs.","min_value":2}]},{"type":1,"name":"streamer-role","description":"Set the role someone is assigned in the server when they start streaming.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."}]},{"type":1,"name":"suggestions","description":"Configure suggestions in the server.","options":[{"type":7,"name":"channel","description":"The channel where suggestions will be sent.","channel_types":[0]}]},{"type":1,"name":"triggers","description":"Configure triggers and responses in the server.","options":[{"type":3,"name":"add","description":"The pattern that will trigger the response."},{"type":3,"name":"remove","description":"The trigger that you want to remove."},{"type":3,"name":"message","description":"The message response for the trigger."},{"type":3,"name":"emoji","description":"The reaction emoji response for the trigger."}]},{"type":1,"name":"verification","description":"Configure verification in the server.","options":[{"type":8,"name":"role","description":"The role users are assigned when are verified."},{"type":3,"name":"text","description":"Type a text message that will be shown to the users trying to verify."}]},{"type":1,"name":"voice-sessions","description":"Configure voice sessions in the server.","options":[{"type":3,"name":"create","description":"Name of the new voice session category."}]},{"type":1,"name":"voting-channels","description":"Configure voting channels in the server.","options":[{"type":7,"name":"add","description":"The channel you want to add as a voting channel.","channel_types":[0]},{"type":7,"name":"remove","description":"The channel you want to remove as a voting channel.","channel_types":[0]}]}]},{"type":1,"name":"donate","description":"See the ways you can contribute to support the Bastion bot project.","options":[]},{"type":1,"name":"emoji","description":"Command Group - emoji","options":[{"type":1,"name":"info","description":"Displays information on the specified custom emoji.","options":[{"type":3,"name":"emoji","description":"The emoji you want to display.","required":true}]}]},{"type":1,"name":"games","description":"Command Group - games","options":[{"type":1,"name":"8ball","description":"Ask any question to the magic 8 ball and get answers.","options":[{"type":3,"name":"question","description":"The question you want to ask the magic 8 ball.","required":true}]},{"type":1,"name":"flip","description":"Flip coins and see the result.","options":[{"type":4,"name":"coins","description":"The number of coins to flip.","min_value":1,"max_value":128}]},{"type":1,"name":"roll","description":"Roll dice and see the result. Supports dice notation.","options":[{"type":3,"name":"notation","description":"The dice notation."}]},{"type":1,"name":"rps","description":"Play rock paper scissor with Bastion.","options":[{"type":3,"name":"choice","description":"Your choice.","choices":[{"name":"Rock","value":"ROCK"},{"name":"Paper","value":"PAPER"},{"name":"Scissor","value":"SCISSOR"}],"required":true}]},{"type":1,"name":"russian-roulette","description":"Play a game of Russian roulette.","options":[{"type":4,"name":"rounds","description":"The number rounds you want to play.","min_value":1,"max_value":6}]}]},{"type":1,"name":"game-server","description":"Fetch information from nearly any game server that makes its status publicly available.","options":[{"type":3,"name":"game","description":"The game ID for the game server.","required":true},{"type":3,"name":"hostname","description":"The IP address or domain name of the game server.","required":true},{"type":4,"name":"port","description":"The connection port number of the game server. Use the query port if connection port doesn't work.","min_value":1,"max_value":65535}]},{"type":1,"name":"gamestats","description":"Command Group - gamestats","options":[{"type":1,"name":"aimlab","description":"Check stats of any Aim Lab player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"apex","description":"Check stats of any Apex Legends player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"origin"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"csgo","description":"Check stats of any Counter-Strike: Global Offensive player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true}]},{"type":1,"name":"fortnite","description":"Check stats of any Fortnite player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"kbm"},{"name":"Console","value":"gamepad"},{"name":"Mobile","value":"touch"}],"required":true}]},{"type":1,"name":"overwatch","description":"Check stats of any Overwatch 2 player.","options":[{"type":3,"name":"username","description":"The BattleTag or username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"pc"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"},{"name":"Nintendo Switch","value":"nintendo-switch"}]},{"type":3,"name":"region","description":"The region of the player.","choices":[{"name":"Americas","value":"us"},{"name":"Europe","value":"eu"},{"name":"Asia","value":"asia"}]}]},{"type":1,"name":"rainbow6","description":"Check stats of any Rainbow 6 player.","options":[{"type":3,"name":"username","description":"The username of the player.","required":true},{"type":3,"name":"platform","description":"The platform of the player.","choices":[{"name":"PC","value":"uplay"},{"name":"PlayStation","value":"psn"},{"name":"Xbox","value":"xbl"}],"required":true}]},{"type":1,"name":"valorant","description":"Check stats of any Valorant player.","options":[{"type":3,"name":"username","description":"The name tag of the player.","required":true},{"type":3,"name":"region","description":"The region of the account.","choices":[{"name":"Americas","value":"na"},{"name":"Europe","value":"eu"},{"name":"Asia-Pacific","value":"ap"},{"name":"Korea","value":"kr"}],"required":true}]}]},{"type":1,"name":"give","description":"Give Bastion Coins and Experience Points to server members or take it from them.","options":[{"type":6,"name":"user","description":"The user whose coins and XP will be updated.","required":true},{"type":4,"name":"coins","description":"The amount of coins you want to give or take.","required":true},{"type":4,"name":"xp","description":"The amount of XP you want to give or take.","required":true}]},{"type":1,"name":"giveaway","description":"Run giveaways in the server.","options":[{"type":3,"name":"title","description":"The title for the giveaway.","required":true},{"type":3,"name":"description","description":"The description for the giveaway."},{"type":4,"name":"winners","description":"The number of winners for the giveaway.","min_value":1,"max_value":9007199254740991},{"type":4,"name":"timer","description":"Number of hours the giveaway should run.","min_value":1,"max_value":720}]},{"type":1,"name":"iam","description":"Assign a self assignable role to yourself.","options":[{"type":8,"name":"role","description":"The role you want to assign yourself."}]},{"type":1,"name":"image","description":"Command Group - image","options":[{"type":1,"name":"generate","description":"Generate an image with DALL-E from OpenAI.","options":[{"type":3,"name":"prompt","description":"A description of the desired image.","required":true},{"type":3,"name":"size","description":"The size of the generated image.","choices":[{"name":"Square","value":"1024x1024"},{"name":"Portrait","value":"1024x1792"},{"name":"Landscape","value":"1792x1024"}]}]}]},{"type":1,"name":"invite","description":"Generates an instant invite for the server.","options":[{"type":5,"name":"temporary","description":"Kick the members if they aren't assigned a role within 24 hours."}]},{"type":1,"name":"leaderboard","description":"Displays the server's leaderboard. You're ranked based on their level, XP, karma, and Bastion Coins.","options":[]},{"type":1,"name":"lmgtfy","description":"Send a LMGTFY link for the search query that teaches people how to do an internet search.","options":[{"type":3,"name":"query","description":"The search query.","required":true},{"type":3,"name":"site","description":"The search engine to use.","choices":[{"name":"DuckDuckGo","value":"d"},{"name":"Google","value":"g"},{"name":"Bing","value":"b"}]}]},{"type":1,"name":"message","description":"Command Group - message","options":[{"type":1,"name":"clear","description":"Clear recent messages (newer than two weeks) in the channel.","options":[{"type":4,"name":"limit","description":"Limit the numbers of messages that should be deleted.","min_value":1},{"type":5,"name":"bots","description":"Should it delete messages from bots."},{"type":5,"name":"pinned","description":"Should it delete messages that are pinned."},{"type":5,"name":"system","description":"Should it delete system messages."},{"type":6,"name":"user","description":"Only delete messages from this user."}]}]},{"type":1,"name":"music","description":"Command Group - music","options":[{"type":1,"name":"join","description":"Moves you to the voice channel where Bastion is currently connected.","options":[]},{"type":1,"name":"now","description":"Shows the song playing right now.","options":[]},{"type":1,"name":"pause","description":"Pause the music playback in the voice channel.","options":[]},{"type":1,"name":"play","description":"Play a specified song in the server.","options":[{"type":3,"name":"song","description":"The song name or link you want to play.","required":true}]},{"type":1,"name":"queue","description":"Displays the current music queue in the server.","options":[{"type":3,"name":"remove","description":"Remove songs matching the specified text from the music queue."},{"type":5,"name":"clear","description":"Remove all songs from the music queue."}]},{"type":1,"name":"resume","description":"Resume the music playback in the voice channel.","options":[]},{"type":1,"name":"shuffle","description":"Shuffle the current music queue.","options":[]},{"type":1,"name":"skip","description":"Skip the current music track that's being played in the voice channel.","options":[]},{"type":1,"name":"stop","description":"Stop the music playback and disconnect from the voice channel.","options":[]}]},{"type":1,"name":"poll","description":"Run polls in the server.","options":[{"type":3,"name":"question","description":"The question for the poll.","required":true},{"type":3,"name":"option1","description":"The 1st option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The 2nd option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The 3rd option for the poll's answer."},{"type":3,"name":"option4","description":"The 4th option for the poll's answer."},{"type":3,"name":"option5","description":"The 5th option for the poll's answer."},{"type":3,"name":"option6","description":"The 6th option for the poll's answer."},{"type":3,"name":"option7","description":"The 7th option for the poll's answer."},{"type":3,"name":"option8","description":"The 8th option for the poll's answer."},{"type":3,"name":"option9","description":"The 9th option for the poll's answer."},{"type":3,"name":"option10","description":"The 10th option for the poll's answer."},{"type":4,"name":"timer","description":"Number of hours the poll should run.","min_value":1,"max_value":720}]},{"type":1,"name":"profile","description":"Displays the Bastion profile of the specified user.","options":[{"type":6,"name":"user","description":"The user whose profile you want to display."}]},{"type":1,"name":"report","description":"Report a server member to the moderators of the server.","options":[{"type":6,"name":"user","description":"The user you want to report.","required":true},{"type":3,"name":"reason","description":"The reason you want to report the user.","required":true}]},{"type":1,"name":"role","description":"Command Group - role","options":[{"type":1,"name":"config","description":"Set the description & emoji of the specified role.","options":[{"type":8,"name":"role","description":"The role which you want to configure.","required":true},{"type":3,"name":"emoji","description":"The emoji you want to set as the role emoji."},{"type":3,"name":"description","description":"A description for the role (max 100 characters)."}]},{"type":1,"name":"create","description":"Create a new role in the server.","options":[{"type":3,"name":"name","description":"The name of the new role.","required":true},{"type":3,"name":"color","description":"The color for the new role (in HEX code)."},{"type":5,"name":"icon","description":"The icon for the new role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for creating the role."}]},{"type":1,"name":"delete","description":"Delete the specified role.","options":[{"type":8,"name":"role","description":"The role you want to delete.","required":true},{"type":3,"name":"reason","description":"The reason for deleting the role."}]},{"type":1,"name":"info","description":"Displays information on the specified role.","options":[{"type":8,"name":"role","description":"The role whose information you want to display.","required":true}]},{"type":1,"name":"levels","description":"Configure level roles. When members reach a level, they get assigned to roles in the level.","options":[{"type":8,"name":"role","description":"The role that should be assigned to users."},{"type":4,"name":"level","description":"The level at which the role should be assigned.","min_value":0},{"type":4,"name":"remove","description":"The level which you want to remove.","min_value":0}]},{"type":1,"name":"update","description":"Update the specified role in the server.","options":[{"type":8,"name":"role","description":"The role you want to update.","required":true},{"type":3,"name":"name","description":"The new name for the role."},{"type":3,"name":"color","description":"The new color for the role (in HEX code)."},{"type":5,"name":"icon","description":"The new icon for the role (Image URL or Emoji)."},{"type":5,"name":"hoist","description":"Should the members be displayed separately from others."},{"type":5,"name":"mentionable","description":"Should the role be mentionable."},{"type":3,"name":"reason","description":"The reason for updating the role."}]}]},{"type":1,"name":"say","description":"Replies with the message you ask it to say.","options":[{"type":3,"name":"message","description":"The message you want Bastion to say.","required":true}]},{"type":1,"name":"search","description":"Command Group - search","options":[{"type":1,"name":"anime","description":"Searches for information on the specified anime.","options":[{"type":3,"name":"name","description":"The name of the anime.","required":true}]},{"type":1,"name":"apod","description":"Displays the astronomy picture of the day from NASA.","options":[]},{"type":1,"name":"cryptocurrency","description":"Searches for information on the specified crypto currency.","options":[{"type":3,"name":"symbol","description":"The symbol of the crypto currency.","required":true}]},{"type":1,"name":"definitions","description":"Displays the definitions for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"game","description":"Searches for information on the specified game.","options":[{"type":3,"name":"name","description":"The name of the game.","required":true}]},{"type":1,"name":"manga","description":"Searches for information on the specified manga.","options":[{"type":3,"name":"name","description":"The name of the manga.","required":true}]},{"type":1,"name":"movie","description":"Searches for information on the specified movie.","options":[{"type":3,"name":"name","description":"The name of the movie.","required":true}]},{"type":1,"name":"pokemon","description":"Searches for information on the specified pokémon.","options":[{"type":3,"name":"name","description":"The name (or number) of the Pokémon.","required":true}]},{"type":1,"name":"redirects","description":"Follows all the redirects in the specified URL and displays the final URL.","options":[{"type":3,"name":"url","description":"The URL you want to follow.","required":true}]},{"type":1,"name":"tv","description":"Searches for information on the specified TV show.","options":[{"type":3,"name":"name","description":"The name of the TV show.","required":true}]},{"type":1,"name":"urban-dictionary","description":"Searches Urban Dictionary for the specified word.","options":[{"type":3,"name":"word","description":"The word you want to lookup.","required":true}]},{"type":1,"name":"weather","description":"Displays the weather forcast of the specified location.","options":[{"type":3,"name":"location","description":"The location for the weather forcast.","required":true}]},{"type":1,"name":"wikipedia","description":"Searches Wikipedia for the specified query.","options":[{"type":3,"name":"query","description":"The search query.","required":true}]}]},{"type":1,"name":"server","description":"Command Group - server","options":[{"type":1,"name":"info","description":"Displays information on the server.","options":[]},{"type":1,"name":"prune","description":"Kicks the inactive members (without any roles) from the server.","options":[{"type":4,"name":"days","description":"The number of days of inactivity required for kicking.","min_value":1},{"type":8,"name":"role","description":"Inactive members check includes this role."},{"type":3,"name":"reason","description":"The reason for pruning the inactive members."}]}]},{"type":1,"name":"status","description":"Displays Bastion's status. You can also see Discord's status.","options":[{"type":5,"name":"shard","description":"Displays the status of the current shard."}]},{"type":1,"name":"su","description":"Command Group - su","options":[{"type":1,"name":"eval","description":"Evaluate JavaScript code in Bastion's context.","options":[{"type":3,"name":"code","description":"The code you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"exec","description":"Execute terminal commands on the system where Bastion is running.","options":[{"type":3,"name":"command","description":"The command you want to execute.","required":true},{"type":5,"name":"public","description":"Display the output to everyone."}]},{"type":1,"name":"reload","description":"Reload Bastion's settings.","options":[]},{"type":1,"name":"shutdown","description":"Shutdown Bastion directly from Discord.","options":[]}]},{"type":1,"name":"suggest","description":"Send a suggestion to the server staff.","options":[{"type":3,"name":"suggestion","description":"What do you want to suggest?","required":true}]},{"type":1,"name":"thread","description":"Command Group - thread","options":[{"type":1,"name":"close","description":"Close and lock the thread.","options":[]},{"type":1,"name":"name","description":"Change the name of the thread.","options":[{"type":3,"name":"name","description":"The new name for the thread.","required":true}]}]},{"type":1,"name":"translate","description":"Translates the specified text from one language to another.","options":[{"type":3,"name":"text","description":"The text you want to translate.","required":true},{"type":3,"name":"to","description":"The language you want to translate to."},{"type":3,"name":"from","description":"The language you want to translate from."}]},{"type":1,"name":"user","description":"Command Group - user","options":[{"type":1,"name":"avatar","description":"Displays the avatar of the specified user.","options":[{"type":6,"name":"user","description":"The user whose avatar you want to display."}]},{"type":1,"name":"info","description":"Displays information on the specified user.","options":[{"type":6,"name":"user","description":"The user whose information you want to display."}]},{"type":1,"name":"infractions","description":"Configure infraction actions and displays infractions of the specified user.","options":[{"type":4,"name":"timeout","description":"Number of violations after which a user is timed out.","min_value":1},{"type":4,"name":"kick","description":"Number of violations after which a user is kicked.","min_value":1},{"type":4,"name":"ban","description":"Number of violations after which a user is banned.","min_value":1},{"type":6,"name":"user","description":"The user whose infractions you want to display."},{"type":4,"name":"remove","description":"The infraction you want to remove from the user.","min_value":1}]}]},{"type":1,"name":"warn","description":"Warn server members and add infractions to their server profile.","options":[{"type":6,"name":"user","description":"The user you want to warn.","required":true},{"type":3,"name":"reason","description":"The reason for the warning.","required":true}]}] \ No newline at end of file