diff --git a/.github/SECURITY.md b/.github/SECURITY.md index f9f7538cd..8944fa086 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -11,7 +11,7 @@ ## Reporting a Vulnerability If you find a vulnerability in Bastion, join [Bastion HQ] and send a direct -message to **iamtraction#8383** with the details about the vulnerability and +message to **@iamtraction** with the details about the vulnerability and we will fix it as soon as practical. Once fixed, you will be credited with finding the vulnerability in the release diff --git a/commands.json b/commands.json index efd90bcc9..000809eab 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":"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":"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 Role Group.","options":[{"type":3,"name":"id","description":"The Select Role Group ID.","required":true}]}]},{"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":"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 first option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The first option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The first option for the poll's answer."},{"type":3,"name":"option4","description":"The first 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":2,"name":"Blacklist","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":"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 Role Group.","options":[{"type":3,"name":"id","description":"The Select Role Group ID.","required":true}]},{"type":1,"name":"sync","description":"Sync the specified Select Role Group.","options":[{"type":3,"name":"id","description":"The Select Role Group ID.","required":true}]}]},{"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":"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 first option for the poll's answer.","required":true},{"type":3,"name":"option2","description":"The first option for the poll's answer.","required":true},{"type":3,"name":"option3","description":"The first option for the poll's answer."},{"type":3,"name":"option4","description":"The first 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 diff --git a/package.json b/package.json index 892ed2505..56905fac0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bastion", - "version": "10.11.2", + "version": "10.12.0", "description": "Get an enhanced Discord experience!", "type": "module", "homepage": "https://bastion.traction.one", @@ -18,32 +18,32 @@ "test": "eslint src --ext .ts" }, "devDependencies": { - "@types/discord-rpc": "^4.0.4", + "@types/discord-rpc": "^4.0.5", "@types/express": "^4.17.17", "@types/http-errors": "^2.0.1", "@types/jsdom": "^21.1.1", - "@types/node": "^20.1.2", - "@typescript-eslint/eslint-plugin": "^5.57.0", - "@typescript-eslint/parser": "^5.57.0", - "eslint": "^8.37.0", - "typescript": "^5.0.3" + "@types/node": "^20.5.1", + "@typescript-eslint/eslint-plugin": "^6.4.0", + "@typescript-eslint/parser": "^6.4.0", + "eslint": "^8.47.0", + "typescript": "^5.1.6" }, "dependencies": { - "@bastion/tesseract": "^5.0.1", + "@bastion/tesseract": "^5.0.4", "@discordjs/opus": "^0.9.0", "@iamtraction/google-translate": "^2.0.1", "@types/gamedig": "^4.0.1", "discord-rpc": "^4.0.1", - "dotenv": "^16.0.3", + "dotenv": "^16.3.1", "emoji-regex": "^10.2.1", - "gamedig": "^4.0.6", - "jsdom": "^22.0.0", + "gamedig": "^4.0.7", + "jsdom": "^22.1.0", "libsodium-wrappers": "^0.7.11", - "mathjs": "^11.7.0", + "mathjs": "^11.9.1", "play-dl": "^1.9.6", "r6api.js": "^4.4.1", - "undici": "^5.21.0", - "ytdl-core": "^4.11.3", + "undici": "^5.23.0", + "ytdl-core": "^4.11.5", "ytpl": "^2.3.0" }, "optionalDependencies": { diff --git a/settings.example.yaml b/settings.example.yaml index ea5b7dcdf..41c0a537e 100644 --- a/settings.example.yaml +++ b/settings.example.yaml @@ -27,9 +27,9 @@ mongoURI: "mongodb://127.0.0.1:27017/bastion" # Presences # Bastion will cycle through these activities randomly. # status — online / idle / dnd / invisible -# activity — 0 (Playing) / 1 (Streaming) / 2 (Listening) / 3 (Watching) / 5 (Competing) +# activity — 0 (Playing) / 1 (Streaming) / 2 (Listening) / 3 (Watching) / 4 (Custom) / 5 (Competing) # name — string -# url — Twitch URL when `activity` is set to +# url — Twitch URL when `activity` is set to `1` (Streaming) presences: - status: "online" activity: 3 diff --git a/src/commands/comic/xkcd.ts b/src/commands/comic/xkcd.ts index 1e8ce6f83..645babb72 100644 --- a/src/commands/comic/xkcd.ts +++ b/src/commands/comic/xkcd.ts @@ -8,14 +8,14 @@ import { Command } from "@bastion/tesseract"; import * as requests from "../../utils/requests.js"; interface XKCD { - title: string; + title?: string; safe_title?: string; - alt: string; - num: string; - day: number; - month: number; - year: number; - img: string; + alt?: string; + num?: string; + day?: number; + month?: number; + year?: number; + img?: string; } class XKCDCommand extends Command { diff --git a/src/commands/config/filter/emails.ts b/src/commands/config/filter/emails.ts new file mode 100644 index 000000000..32bb9b038 --- /dev/null +++ b/src/commands/config/filter/emails.ts @@ -0,0 +1,87 @@ +/*! + * @author TRACTION (iamtraction) + * @copyright 2023 + */ +import { AutoModerationActionOptions, AutoModerationActionType, AutoModerationRuleEventType, AutoModerationRuleTriggerType, ChatInputCommandInteraction, PermissionFlagsBits } from "discord.js"; +import { Command, Logger } from "@bastion/tesseract"; + +import GuildModel from "../../../models/Guild.js"; + +class FilterEmailsCommand extends Command { + constructor() { + super({ + name: "emails", + description: "Configure Email Filter AutoMod rule in the server.", + userPermissions: [ PermissionFlagsBits.ManageGuild ], + clientPermissions: [ PermissionFlagsBits.ManageGuild ], + }); + } + + public async exec(interaction: ChatInputCommandInteraction<"cached">): Promise { + await interaction.deferReply(); + + // get guild document + const guildDocument = await GuildModel.findById(interaction.guildId); + + // get the email filter rule if it exists + const emailFilterRule = guildDocument.emailFilterRule && await interaction.guild.autoModerationRules.fetch({ + autoModerationRule: guildDocument.emailFilterRule, + cache: false, + }).catch(Logger.ignore); + + // toggle email filter rule if it exists + if (emailFilterRule) { + const newEmailFilterRule = await emailFilterRule.setEnabled(!emailFilterRule.enabled, `${ emailFilterRule.enabled ? "Disable" : "Enable" } Email Filter`); + return await interaction.editReply(`I've ${ newEmailFilterRule.enabled ? "enabled" : "disabled" } the **${ newEmailFilterRule.name }** AutoMod rule.`); + } + + const actions: AutoModerationActionOptions[] = [ + { + type: AutoModerationActionType.BlockMessage, + metadata: { + customMessage: "You are not allowed to send emails in this channel.", + }, + }, + { + type: AutoModerationActionType.Timeout, + metadata: { + durationSeconds: 60, + }, + }, + ]; + + if (interaction.guild.channels.cache.has(guildDocument.moderationLogChannel)) { + actions.push({ + type: AutoModerationActionType.SendAlertMessage, + metadata: { + channel: guildDocument.moderationLogChannel, + }, + }); + } + + // create email filter rule + const newEmailFilterRule = await interaction.guild.autoModerationRules.create({ + enabled: true, + name: "Block Emails", + eventType: AutoModerationRuleEventType.MessageSend, + triggerType: AutoModerationRuleTriggerType.Keyword, + triggerMetadata: { + regexPatterns: [ + "[A-Za-z0-9.+~_-]+\\@[A-Za-z0-9.-]+\\.[A-Za-z0-9.-]+", + ], + }, + actions, + reason: "Configure Email Filter", + }); + + // update email filter rule id + guildDocument.emailFilterRule = newEmailFilterRule.id; + + // save document + await guildDocument.save(); + + return await interaction.editReply("I've configured the email filter AutoMod rule."); + } +} + +export { FilterEmailsCommand as Command }; diff --git a/src/commands/gamestats/aimlab.ts b/src/commands/gamestats/aimlab.ts index 1f4ff695e..cf0adf317 100644 --- a/src/commands/gamestats/aimlab.ts +++ b/src/commands/gamestats/aimlab.ts @@ -8,6 +8,27 @@ import { Command } from "@bastion/tesseract"; import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; +interface AimLabResponse { + data?: { + aimlabProfile: { + username: string; + ranking: { + rank: { + displayName: string; + level: number; + minSkill: number; + maxSkill: number; + }; + skill: number; + }; + skillScores: { + name: string; + score: number; + }[]; + }; + }; +} + class AimLabCommand extends Command { constructor() { super({ @@ -54,15 +75,15 @@ class AimLabCommand extends Command { }, }); - const body = await response.body.json(); + const body: AimLabResponse = await response.body.json(); if (!body?.data?.aimlabProfile) { return await interaction.editReply(`The profile for **${ username }** was not found.`); } - const skillScores = body.data.aimlabProfile?.skillScores?.length ? body.data.aimlabProfile.skillScores.map((skill: { name: string; score: string }) => ({ + const skillScores = body.data.aimlabProfile?.skillScores?.length ? body.data.aimlabProfile.skillScores.map(skill => ({ name: skill.name[0].toUpperCase() + skill.name.slice(1), - value: (skill.score as unknown as number).toFixed(), + value: skill.score.toFixed(), inline: true, })) : []; @@ -83,7 +104,7 @@ class AimLabCommand extends Command { }, { name: "Skill Rating", - value: (body.data.aimlabProfile?.ranking?.skill as unknown as number)?.toFixed(), + value: body.data.aimlabProfile?.ranking?.skill?.toFixed(), inline: true, }, { diff --git a/src/commands/gamestats/apex.ts b/src/commands/gamestats/apex.ts index e3b347ede..4dea69e10 100644 --- a/src/commands/gamestats/apex.ts +++ b/src/commands/gamestats/apex.ts @@ -9,6 +9,30 @@ import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; import Settings from "../../utils/settings.js"; +interface ApexProfileResponse { + data?: { + platformInfo: { + platformUserHandle: string; + avatarUrl: string; + }; + segments: { + type: string; + stats: { + rankScore: { + displayValue: string; + metadata: { + rankName: string; + iconUrl: string; + }; + }; + }; + }[]; + metadata: { + activeLegendName: string; + }; + }; +} + class ApexLegendsCommand extends Command { constructor() { super({ @@ -46,8 +70,8 @@ class ApexLegendsCommand extends Command { "TRN-Api-Key": ((interaction.client as Client).settings as Settings).get("trackerNetworkApiKey"), }); - const body = await response.body.json(); - const overview = body?.data?.segments?.find((s: { type: string }) => s.type === "overview"); + const body: ApexProfileResponse = await response.body.json(); + const overview = body?.data?.segments?.find(s => s.type === "overview"); if (!Object.keys(overview?.stats || {})?.length) return await interaction.editReply(`The profile for **${ username }** was not found in the specified platform.`); diff --git a/src/commands/gamestats/csgo.ts b/src/commands/gamestats/csgo.ts index d87f88949..dd27d0993 100644 --- a/src/commands/gamestats/csgo.ts +++ b/src/commands/gamestats/csgo.ts @@ -9,6 +9,28 @@ import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; import Settings from "../../utils/settings.js"; +interface CSGOProfileResponse { + data?: { + platformInfo: { + platformUserHandle: string; + avatarUrl: string; + }; + segments: { + type: string; + stats: { + timePlayed: { + value: number; + }; + rankScore: { + metadata: { + iconUrl: string; + }; + }; + }; + }[]; + }; +} + class CSGOCommand extends Command { constructor() { super({ @@ -34,8 +56,8 @@ class CSGOCommand extends Command { "TRN-Api-Key": ((interaction.client as Client).settings as Settings).get("trackerNetworkApiKey"), }); - const body = await response.body.json(); - const overview = body?.data?.segments?.find((s: { type: string }) => s.type === "overview"); + const body: CSGOProfileResponse = await response.body.json(); + const overview = body?.data?.segments?.find(s => s.type === "overview"); if (!Object.keys(overview?.stats || {})?.length) return await interaction.editReply(`The profile for **${ username }** was not found.`); diff --git a/src/commands/gamestats/fortnite.ts b/src/commands/gamestats/fortnite.ts index 648eaea86..68422eaea 100644 --- a/src/commands/gamestats/fortnite.ts +++ b/src/commands/gamestats/fortnite.ts @@ -9,6 +9,15 @@ import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; import Settings from "../../utils/settings.js"; +interface FortniteResponse { + lifeTimeStats?: { + key: string; + value: string; + }[]; + epicUserHandle?: string; + platformNameLong?: string; +} + class FortniteCommand extends Command { constructor() { super({ @@ -46,7 +55,7 @@ class FortniteCommand extends Command { "TRN-Api-Key": ((interaction.client as Client).settings as Settings).get("trackerNetworkApiKey"), }); - const body = await response.body.json(); + const body: FortniteResponse = await response.body.json(); if (!body?.lifeTimeStats?.length) return await interaction.editReply(`The profile for **${ username }** was not found in the specified platform.`); @@ -58,7 +67,7 @@ class FortniteCommand extends Command { name: "Fortnite — Player Stats", }, title: body.epicUserHandle, - fields: body.lifeTimeStats.map((stat: { key: string; value: string }) => ({ + fields: body.lifeTimeStats.map(stat => ({ name: stat.key, value: stat.value, inline: true, diff --git a/src/commands/gamestats/overwatch.ts b/src/commands/gamestats/overwatch.ts index 3cfaa1f06..8cf3dcf0c 100644 --- a/src/commands/gamestats/overwatch.ts +++ b/src/commands/gamestats/overwatch.ts @@ -8,6 +8,21 @@ import { Command } from "@bastion/tesseract"; import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; +interface OverwatchResponse { + private?: boolean; + gamesPlayed?: string; + gamesWon?: string; + gamesLost?: string; + ratings?: { + role: string; + group: string; + tier: string; + }[]; + icon?: string; + endorsementIcon?: string; + endorsement?: number; +} + class OverwatchCommand extends Command { constructor() { super({ @@ -53,7 +68,7 @@ class OverwatchCommand extends Command { // get stats const { body } = await requests.get("https://ow-api.com/v1/stats/" + platform + "/" + region + "/" + (username.replace("#", "-")) + "/profile"); - const response = await body.json(); + const response: OverwatchResponse = await body.json(); await interaction.editReply({ embeds: [ diff --git a/src/commands/gamestats/valorant.ts b/src/commands/gamestats/valorant.ts index 44e1d757c..5277d8f01 100644 --- a/src/commands/gamestats/valorant.ts +++ b/src/commands/gamestats/valorant.ts @@ -8,6 +8,36 @@ import { Command } from "@bastion/tesseract"; import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; +interface AccountResponse { + data?: { + name: string; + tag: string; + region: string; + account_level: string; + card: { + wide: string; + }; + last_update_raw: number; + }; +} + +interface MMRResponse { + data?: { + current_data: { + elo: string; + currenttierpatched: string; + ranking_in_tier: string; + games_needed_for_rating: string; + images: { + large: string; + }; + }; + by_season: { + number_of_games: string; + }[]; + }; +} + class ValorantCommand extends Command { constructor() { super({ @@ -45,7 +75,7 @@ class ValorantCommand extends Command { // get account data const accountResponse = await requests.get(`https://api.henrikdev.xyz/valorant/v1/account/${ encodeURIComponent(player[0]) }/${ encodeURIComponent(player[1]) }`); - const account = await accountResponse.body.json(); + const account: AccountResponse = await accountResponse.body.json(); if (accountResponse.statusCode !== 200) { await interaction.editReply(`The profile for **${ username }** was not found in the specified region.`); @@ -53,7 +83,7 @@ class ValorantCommand extends Command { // get mmr data const mmrResponse = await requests.get(`https://api.henrikdev.xyz/valorant/v2/mmr/${ region }/${ encodeURIComponent(player[0]) }/${ encodeURIComponent(player[1]) }`); - const mmr = await mmrResponse.body.json(); + const mmr: MMRResponse = await mmrResponse.body.json(); await interaction.editReply({ embeds: [ diff --git a/src/commands/search/anime.ts b/src/commands/search/anime.ts index 58ebd4b20..162eeb9bf 100644 --- a/src/commands/search/anime.ts +++ b/src/commands/search/anime.ts @@ -23,7 +23,7 @@ interface Anime { } interface AnimeResponse { - data: { + data?: { attributes: Anime; }[]; } diff --git a/src/commands/search/apod.ts b/src/commands/search/apod.ts index c77d6864a..4cfe290b2 100644 --- a/src/commands/search/apod.ts +++ b/src/commands/search/apod.ts @@ -9,14 +9,14 @@ import * as requests from "../../utils/requests.js"; import Settings from "../../utils/settings.js"; interface APOD { - copyright: string; - date: string; - explanation: string; + copyright?: string; + date?: string; + explanation?: string; hdurl?: string; - media_type: string; - service_version: string; - title: string; - url: string; + media_type?: string; + service_version?: string; + title?: string; + url?: string; } class APODCommand extends Command { diff --git a/src/commands/search/cryptocurrency.ts b/src/commands/search/cryptocurrency.ts index fc340bbfa..8ab751f1f 100644 --- a/src/commands/search/cryptocurrency.ts +++ b/src/commands/search/cryptocurrency.ts @@ -18,11 +18,11 @@ interface Currency { } interface CurrencyResponse { - status: { + status?: { error_code: number; error_message: string; }; - data: { + data?: { [key: string]: Currency; }; } diff --git a/src/commands/search/definitions.ts b/src/commands/search/definitions.ts index 7ca09742c..88de13a80 100644 --- a/src/commands/search/definitions.ts +++ b/src/commands/search/definitions.ts @@ -49,7 +49,7 @@ class DefinitionsCommand extends Command { // fetch definitions const { body } = await requests.get(`https://api.wordnik.com/v4/word.json/${ encodeURIComponent(word.toLowerCase()) }/definitions?limit=10&sourceDictionaries=all&useCanonical=false&includeTags=false&api_key=${ ((interaction.client as Client).settings as Settings)?.get("wordnikApiKey") }`); - const definitions: Definition[] = await body.json(); + const definitions: Definition[] = await body.json() as unknown[]; if (definitions?.length) { return await interaction.editReply( diff --git a/src/commands/search/game.ts b/src/commands/search/game.ts index 8983645c2..95357b131 100644 --- a/src/commands/search/game.ts +++ b/src/commands/search/game.ts @@ -10,22 +10,22 @@ import { COLORS } from "../../utils/constants.js"; import Settings from "../../utils/settings.js"; interface Game { - alternative_names: string[]; - artworks: string[]; - cover: { + alternative_names?: string[]; + artworks?: string[]; + cover?: { url: string; }; - first_release_date: number; - game_modes: number[]; - genres: string[]; - name: string; - platforms: string[]; - screenshots: []; - summary: string; - total_rating: number; - url: string; - version_title: string; - websites: { + first_release_date?: number; + game_modes?: number[]; + genres?: string[]; + name?: string; + platforms?: string[]; + screenshots?: []; + summary?: string; + total_rating?: number; + url?: string; + version_title?: string; + websites?: { url: string; }[]; } @@ -59,7 +59,7 @@ class GameCommand extends Command { "authorization": "Bearer " + ((interaction.client as Client).settings as Settings)?.get("twitch")?.accessToken, "client-id": ((interaction.client as Client).settings as Settings)?.get("twitch")?.clientId, }); - const games: Game[] = await body.json(); + const games: Game[] = await body.json() as unknown[]; if (games?.length) { return await interaction.editReply({ diff --git a/src/commands/search/manga.ts b/src/commands/search/manga.ts index 29450df2b..c2cc8db79 100644 --- a/src/commands/search/manga.ts +++ b/src/commands/search/manga.ts @@ -20,7 +20,7 @@ interface Manga { } interface MangaResponse { - data: { + data?: { attributes: Manga; }[]; } diff --git a/src/commands/search/movie.ts b/src/commands/search/movie.ts index a4249d29d..5211f0466 100644 --- a/src/commands/search/movie.ts +++ b/src/commands/search/movie.ts @@ -27,10 +27,10 @@ interface Movie { } interface MovieResponse { - page: number; - total_results: number; - total_pages: number; - results: Movie[]; + page?: number; + total_results?: number; + total_pages?: number; + results?: Movie[]; } class MovieCommand extends Command { diff --git a/src/commands/search/pokemon.ts b/src/commands/search/pokemon.ts index aa84189e6..06a0f8189 100644 --- a/src/commands/search/pokemon.ts +++ b/src/commands/search/pokemon.ts @@ -9,29 +9,44 @@ import * as requests from "../../utils/requests.js"; import { COLORS } from "../../utils/constants.js"; interface Pokemon { - number: string; - name: string; - description?: string; - gen: number; - starter?: boolean; - mega?: boolean; - ultraBeast?: boolean; - legendary?: boolean; - mythical?: boolean; - species: string; - types: string[]; - abilities: { - normal: string[]; - hidden: string[]; + number?: number; + name?: string; + codename?: string; + gen?: number; + species?: string; + types?: string[], + abilities?: { + name: string; + description: string; + hidden: boolean; + }[]; + height?: string; + weight?: string; + mega?: boolean | { + stone: string; + sprite: string; }; - eggGroups: string[]; - gender: [ number, number ] | []; - height: string; - weight: string; - sprite: string; - family: { - evolutionLine: string[]; + baseStats?: { + hp: number; + attack: number; + defense: number; + spAtk: number; + spDef: number; + speed: number; }; + training?: { + evYield: string; + catchRate: string; + baseFriendship: string; + baseExp: string; + growthRate: string; + }; + breeding?: { + gender: string; + eggGroups: string[]; + eggCycles: string; + }; + sprite?: string; } class PokemonCommand extends Command { @@ -55,8 +70,8 @@ class PokemonCommand extends Command { const name = interaction.options.getString("name"); // fetch pokemon - const { body } = await requests.get(`https://pokeapi.glitch.me/v1/pokemon/${ encodeURIComponent(name) }`); - const pokemon: Pokemon[] = await body.json(); + const { body } = await requests.get(`https://ex.traction.one/pokedex/pokemon/${ encodeURIComponent(name) }`); + const pokemon: Pokemon[] = await body.json() as unknown[]; if (pokemon?.length) { return await interaction.editReply({ @@ -64,19 +79,19 @@ class PokemonCommand extends Command { { color: COLORS.PRIMARY, author: { - name: (pokemon[0].mythical ? "Mythical " : "") + (pokemon[0].legendary ? "Legendary " : "") + (pokemon[0].mega ? "Mega" : "") + (pokemon[0].ultraBeast ? "Ultra Beast" : "") + (pokemon[0].starter ? "Starter " : "") + "Pokémon", + name: (pokemon[0].codename ? "Ultra Beast" : "") + "Pokémon", }, title: pokemon[0].name, - description: "Discovered in generation " + pokemon[0].gen, + description: pokemon[0].species, fields: [ { name: "Number", - value: pokemon[0].number, + value: "#" + pokemon[0].number?.toString(), inline: true, }, { - name: "Species", - value: pokemon[0].species, + name: "Generation", + value: pokemon[0].gen?.toString(), inline: true, }, { @@ -86,17 +101,17 @@ class PokemonCommand extends Command { }, { name: "Abilities", - value: `Normal: ${pokemon[0].abilities.normal.join(", ") || "-"}\nHidden: ${pokemon[0].abilities.hidden.join(", ") || "-"}`, + value: pokemon[0].abilities.map(a => a.name).join("\n") || "Undiscovered", inline: true, }, { name: "Egg Groups", - value: pokemon[0].eggGroups.join("\n"), + value: pokemon[0].breeding?.eggGroups.join("\n"), inline: true, }, { name: "Gender Ratio", - value: pokemon[0].gender.length ? `${pokemon[0].gender[0]}:${pokemon[0].gender[1]}` : "Genderless", + value: pokemon[0].breeding?.gender || "Undiscovered", inline: true, }, { @@ -109,14 +124,6 @@ class PokemonCommand extends Command { value: pokemon[0].weight, inline: true, }, - { - name: "Evolution Line", - value: pokemon[0].family.evolutionLine.join(" -> "), - }, - { - name: "Description", - value: pokemon[0].description, - }, ], thumbnail: { url: pokemon[0].sprite, diff --git a/src/commands/search/tv.ts b/src/commands/search/tv.ts index 75807550b..7c29cd982 100644 --- a/src/commands/search/tv.ts +++ b/src/commands/search/tv.ts @@ -26,10 +26,10 @@ interface TVShow { } interface TVShowResponse { - page: number; - total_results: number; - total_pages: number; - results: TVShow[]; + page?: number; + total_results?: number; + total_pages?: number; + results?: TVShow[]; } class TVCommand extends Command { diff --git a/src/commands/search/urbanDictionary.ts b/src/commands/search/urbanDictionary.ts index c8f230948..5b7b31aac 100644 --- a/src/commands/search/urbanDictionary.ts +++ b/src/commands/search/urbanDictionary.ts @@ -18,7 +18,7 @@ interface Definition { } interface UrbanDictionaryResponse { - list: Definition[]; + list?: Definition[]; } class UrbanDictionaryCommand extends Command { diff --git a/src/commands/search/weather.ts b/src/commands/search/weather.ts index fb2711045..8969cf639 100644 --- a/src/commands/search/weather.ts +++ b/src/commands/search/weather.ts @@ -10,15 +10,15 @@ import { COLORS } from "../../utils/constants.js"; import Settings from "../../utils/settings.js"; interface Weather { - coord: { + coord?: { lat: number; lon: number; }; - weather: { + weather?: { main: string; icon: string; }[]; - main: { + main?: { temp: number; feels_like: number; temp_min: number; @@ -28,31 +28,31 @@ interface Weather { sea_level: number; grnd_level: number; }; - wind: { + wind?: { speed: number; deg: number; }; - clouds: { + clouds?: { all: number; }; - rain: { + rain?: { "1h": number; "3h": number; }; - snow: { + snow?: { "1h": number; "3h": number; }; - visibility: number; - dt: number; - sys: { + visibility?: number; + dt?: number; + sys?: { country: string; sunrise: number; sunset: number; }; - timezone: number; - name: string; - cod: number; + timezone?: number; + name?: string; + cod?: number; message?: string; } diff --git a/src/commands/search/wikipedia.ts b/src/commands/search/wikipedia.ts index 6f5b8f7a9..d999068ac 100644 --- a/src/commands/search/wikipedia.ts +++ b/src/commands/search/wikipedia.ts @@ -17,7 +17,7 @@ interface Wiki { } interface WikipediaResponse { - query: { + query?: { pages: Wiki[]; }; } diff --git a/src/models/Guild.ts b/src/models/Guild.ts index 2bce75541..370581284 100644 --- a/src/models/Guild.ts +++ b/src/models/Guild.ts @@ -33,6 +33,7 @@ export interface Guild { infractionsKickThreshold?: number; infractionsBanThreshold?: number; // automod rules + emailFilterRule?: string; inviteFilterRule?: string; linkFilterRule?: string; // starboard @@ -135,6 +136,11 @@ export default mongoose.model("Guild", new mongoose.S infractionsBanThreshold: { type: Number, }, + emailFilterRule: { + type: String, + unique: true, + sparse: true, + }, inviteFilterRule: { type: String, unique: true, diff --git a/src/schedulers/liveStreams.ts b/src/schedulers/liveStreams.ts index 357f1590d..defa57177 100644 --- a/src/schedulers/liveStreams.ts +++ b/src/schedulers/liveStreams.ts @@ -47,7 +47,7 @@ class LiveStreamNotificationScheduler extends Scheduler { "client-id": (this.client.settings as Settings).get("twitch").clientId, }); - const streams: TwitchStream[] = (await body.json())?.data || []; + const streams: TwitchStream[] = (await body.json())?.["data"] || []; // streams that were already notified if (!twitchStreams.has(guild.id)) twitchStreams.set(guild.id, []); diff --git a/src/types.ts b/src/types.ts index 186bde06b..6c15aff6e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -79,13 +79,13 @@ export namespace patreon { } export interface PatreonResponse { - readonly data: PatreonEntity[]; - readonly included: PatreonEntity[]; - readonly links: { + readonly data?: PatreonEntity[]; + readonly included?: PatreonEntity[]; + readonly links?: { readonly prev: string; readonly next: string; }; - readonly meta: { + readonly meta?: { readonly pagination: { readonly total: number; };