mirror of
				https://github.com/keanuplayz/TravBot-v3.git
				synced 2024-08-15 02:33:12 +00:00 
			
		
		
		
	Added example of temporary solution for slash commands
This commit is contained in:
		
							parent
							
								
									69a8452574
								
							
						
					
					
						commit
						533ce58647
					
				
					 10 changed files with 309 additions and 30 deletions
				
			
		|  | @ -5,6 +5,7 @@ | ||||||
| .husky/ | .husky/ | ||||||
| Dockerfile | Dockerfile | ||||||
| LICENSE | LICENSE | ||||||
|  | *.txt | ||||||
| 
 | 
 | ||||||
| # Specific to this repository | # Specific to this repository | ||||||
| dist/ | dist/ | ||||||
|  |  | ||||||
							
								
								
									
										65
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										65
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -10,9 +10,11 @@ | ||||||
|             "hasInstallScript": true, |             "hasInstallScript": true, | ||||||
|             "license": "MIT", |             "license": "MIT", | ||||||
|             "dependencies": { |             "dependencies": { | ||||||
|  |                 "@discordjs/builders": "^0.8.2", | ||||||
|                 "canvas": "^2.8.0", |                 "canvas": "^2.8.0", | ||||||
|                 "chalk": "^4.1.2", |                 "chalk": "^4.1.2", | ||||||
|                 "discord.js": "^13.3.0", |                 "discord.js": "^13.3.0", | ||||||
|  |                 "dotenv": "^10.0.0", | ||||||
|                 "figlet": "^1.5.2", |                 "figlet": "^1.5.2", | ||||||
|                 "glob": "^7.2.0", |                 "glob": "^7.2.0", | ||||||
|                 "inquirer": "^8.2.0", |                 "inquirer": "^8.2.0", | ||||||
|  | @ -653,13 +655,13 @@ | ||||||
|             "dev": true |             "dev": true | ||||||
|         }, |         }, | ||||||
|         "node_modules/@discordjs/builders": { |         "node_modules/@discordjs/builders": { | ||||||
|             "version": "0.8.1", |             "version": "0.8.2", | ||||||
|             "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.1.tgz", |             "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz", | ||||||
|             "integrity": "sha512-kYJMvZ/BjRD1/6G2t1pQop2yoJNUmYvvKeG4mOBUCHFmfb7WIeBFmN/eSiP3cVSfRx3lbNiyxkdd5JzhjQnGbg==", |             "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==", | ||||||
|             "dependencies": { |             "dependencies": { | ||||||
|                 "@sindresorhus/is": "^4.2.0", |                 "@sindresorhus/is": "^4.2.0", | ||||||
|                 "discord-api-types": "^0.24.0", |                 "discord-api-types": "^0.24.0", | ||||||
|                 "ow": "^0.28.1", |                 "ow": "^0.27.0", | ||||||
|                 "ts-mixer": "^6.0.0", |                 "ts-mixer": "^6.0.0", | ||||||
|                 "tslib": "^2.3.1" |                 "tslib": "^2.3.1" | ||||||
|             }, |             }, | ||||||
|  | @ -2172,6 +2174,14 @@ | ||||||
|                 "url": "https://github.com/sponsors/sindresorhus" |                 "url": "https://github.com/sponsors/sindresorhus" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "node_modules/dotenv": { | ||||||
|  |             "version": "10.0.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", | ||||||
|  |             "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", | ||||||
|  |             "engines": { | ||||||
|  |                 "node": ">=10" | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "node_modules/duplexer": { |         "node_modules/duplexer": { | ||||||
|             "version": "0.1.2", |             "version": "0.1.2", | ||||||
|             "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", |             "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", | ||||||
|  | @ -4523,15 +4533,15 @@ | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "node_modules/ow": { |         "node_modules/ow": { | ||||||
|             "version": "0.28.1", |             "version": "0.27.0", | ||||||
|             "resolved": "https://registry.npmjs.org/ow/-/ow-0.28.1.tgz", |             "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", | ||||||
|             "integrity": "sha512-1EZTywPZeUKac9gD7q8np3Aj+V54kvfIcjNEVNDSbG2Ys5xA5foW2HquvMMqgyWGLqIFMlc0Iq/HmyMHqN48sA==", |             "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", | ||||||
|             "dependencies": { |             "dependencies": { | ||||||
|                 "@sindresorhus/is": "^4.2.0", |                 "@sindresorhus/is": "^4.0.1", | ||||||
|                 "callsites": "^3.1.0", |                 "callsites": "^3.1.0", | ||||||
|                 "dot-prop": "^6.0.1", |                 "dot-prop": "^6.0.1", | ||||||
|                 "lodash.isequal": "^4.5.0", |                 "lodash.isequal": "^4.5.0", | ||||||
|                 "type-fest": "^2.3.4", |                 "type-fest": "^1.2.1", | ||||||
|                 "vali-date": "^1.0.0" |                 "vali-date": "^1.0.0" | ||||||
|             }, |             }, | ||||||
|             "engines": { |             "engines": { | ||||||
|  | @ -4542,11 +4552,11 @@ | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "node_modules/ow/node_modules/type-fest": { |         "node_modules/ow/node_modules/type-fest": { | ||||||
|             "version": "2.5.2", |             "version": "1.4.0", | ||||||
|             "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.5.2.tgz", |             "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", | ||||||
|             "integrity": "sha512-WMbytmAs5PUTqwGJRE+WoRrD2S0bYFtHX8k4Y/1l18CG5kqA3keJud9pPQ/r30FE9n8XRFCXF9BbccHIZzRYJw==", |             "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", | ||||||
|             "engines": { |             "engines": { | ||||||
|                 "node": ">=12.20" |                 "node": ">=10" | ||||||
|             }, |             }, | ||||||
|             "funding": { |             "funding": { | ||||||
|                 "url": "https://github.com/sponsors/sindresorhus" |                 "url": "https://github.com/sponsors/sindresorhus" | ||||||
|  | @ -6378,13 +6388,13 @@ | ||||||
|             "dev": true |             "dev": true | ||||||
|         }, |         }, | ||||||
|         "@discordjs/builders": { |         "@discordjs/builders": { | ||||||
|             "version": "0.8.1", |             "version": "0.8.2", | ||||||
|             "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.1.tgz", |             "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.8.2.tgz", | ||||||
|             "integrity": "sha512-kYJMvZ/BjRD1/6G2t1pQop2yoJNUmYvvKeG4mOBUCHFmfb7WIeBFmN/eSiP3cVSfRx3lbNiyxkdd5JzhjQnGbg==", |             "integrity": "sha512-/YRd11SrcluqXkKppq/FAVzLIPRVlIVmc6X8ZklspzMIHDtJ+A4W37D43SHvLdH//+NnK+SHW/WeOF4Ts54PeQ==", | ||||||
|             "requires": { |             "requires": { | ||||||
|                 "@sindresorhus/is": "^4.2.0", |                 "@sindresorhus/is": "^4.2.0", | ||||||
|                 "discord-api-types": "^0.24.0", |                 "discord-api-types": "^0.24.0", | ||||||
|                 "ow": "^0.28.1", |                 "ow": "^0.27.0", | ||||||
|                 "ts-mixer": "^6.0.0", |                 "ts-mixer": "^6.0.0", | ||||||
|                 "tslib": "^2.3.1" |                 "tslib": "^2.3.1" | ||||||
|             } |             } | ||||||
|  | @ -7576,6 +7586,11 @@ | ||||||
|                 "is-obj": "^2.0.0" |                 "is-obj": "^2.0.0" | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "dotenv": { | ||||||
|  |             "version": "10.0.0", | ||||||
|  |             "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", | ||||||
|  |             "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" | ||||||
|  |         }, | ||||||
|         "duplexer": { |         "duplexer": { | ||||||
|             "version": "0.1.2", |             "version": "0.1.2", | ||||||
|             "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", |             "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", | ||||||
|  | @ -9265,22 +9280,22 @@ | ||||||
|             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" |             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" | ||||||
|         }, |         }, | ||||||
|         "ow": { |         "ow": { | ||||||
|             "version": "0.28.1", |             "version": "0.27.0", | ||||||
|             "resolved": "https://registry.npmjs.org/ow/-/ow-0.28.1.tgz", |             "resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz", | ||||||
|             "integrity": "sha512-1EZTywPZeUKac9gD7q8np3Aj+V54kvfIcjNEVNDSbG2Ys5xA5foW2HquvMMqgyWGLqIFMlc0Iq/HmyMHqN48sA==", |             "integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==", | ||||||
|             "requires": { |             "requires": { | ||||||
|                 "@sindresorhus/is": "^4.2.0", |                 "@sindresorhus/is": "^4.0.1", | ||||||
|                 "callsites": "^3.1.0", |                 "callsites": "^3.1.0", | ||||||
|                 "dot-prop": "^6.0.1", |                 "dot-prop": "^6.0.1", | ||||||
|                 "lodash.isequal": "^4.5.0", |                 "lodash.isequal": "^4.5.0", | ||||||
|                 "type-fest": "^2.3.4", |                 "type-fest": "^1.2.1", | ||||||
|                 "vali-date": "^1.0.0" |                 "vali-date": "^1.0.0" | ||||||
|             }, |             }, | ||||||
|             "dependencies": { |             "dependencies": { | ||||||
|                 "type-fest": { |                 "type-fest": { | ||||||
|                     "version": "2.5.2", |                     "version": "1.4.0", | ||||||
|                     "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.5.2.tgz", |                     "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", | ||||||
|                     "integrity": "sha512-WMbytmAs5PUTqwGJRE+WoRrD2S0bYFtHX8k4Y/1l18CG5kqA3keJud9pPQ/r30FE9n8XRFCXF9BbccHIZzRYJw==" |                     "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==" | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |  | ||||||
|  | @ -5,19 +5,21 @@ | ||||||
|     "main": "dist/index.js", |     "main": "dist/index.js", | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "build": "rimraf dist && tsc --project tsconfig.prod.json && npm prune --production", |         "build": "rimraf dist && tsc --project tsconfig.prod.json && npm prune --production", | ||||||
|         "start": "node .", |         "start": "node -r dotenv/config .", | ||||||
|         "once": "tsc && npm start", |         "once": "tsc && npm start", | ||||||
|         "dev": "tsc-watch --onSuccess \"npm run dev-instance\"", |         "dev": "tsc-watch --onSuccess \"npm run dev-instance\"", | ||||||
|         "dev-fast": "tsc-watch --onSuccess \"node . dev\"", |         "dev-fast": "tsc-watch --onSuccess \"node -r dotenv/config . dev\"", | ||||||
|         "dev-instance": "rimraf dist && tsc && node . dev", |         "dev-instance": "rimraf dist && tsc && node -r dotenv/config . dev", | ||||||
|         "test": "jest", |         "test": "jest", | ||||||
|         "format": "prettier --write **/*", |         "format": "prettier --write **/*", | ||||||
|         "postinstall": "husky install" |         "postinstall": "husky install" | ||||||
|     }, |     }, | ||||||
|     "dependencies": { |     "dependencies": { | ||||||
|  |         "@discordjs/builders": "^0.8.2", | ||||||
|         "canvas": "^2.8.0", |         "canvas": "^2.8.0", | ||||||
|         "chalk": "^4.1.2", |         "chalk": "^4.1.2", | ||||||
|         "discord.js": "^13.3.0", |         "discord.js": "^13.3.0", | ||||||
|  |         "dotenv": "^10.0.0", | ||||||
|         "figlet": "^1.5.2", |         "figlet": "^1.5.2", | ||||||
|         "glob": "^7.2.0", |         "glob": "^7.2.0", | ||||||
|         "inquirer": "^8.2.0", |         "inquirer": "^8.2.0", | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ module.exports = { | ||||||
|     jsxSingleQuote: false, |     jsxSingleQuote: false, | ||||||
|     trailingComma: "none", |     trailingComma: "none", | ||||||
|     bracketSpacing: false, |     bracketSpacing: false, | ||||||
|     jsxBracketSameLine: false, |     bracketSameLine: false, | ||||||
|     arrowParens: "always", |     arrowParens: "always", | ||||||
|     endOfLine: "auto" // Apparently, the GitHub repository still uses CRLF. I don't know how to force it to use LF, and until someone figures that out, I'm changing this to auto because I don't want more than one line ending commit.
 |     endOfLine: "auto" // Apparently, the GitHub repository still uses CRLF. I don't know how to force it to use LF, and until someone figures that out, I'm changing this to auto because I don't want more than one line ending commit.
 | ||||||
| }; | }; | ||||||
|  |  | ||||||
							
								
								
									
										91
									
								
								slash-cmd-brainstorming.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								slash-cmd-brainstorming.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,91 @@ | ||||||
|  | -= [Fun] =- | ||||||
|  | /8ball <question: string> | ||||||
|  | /cookie all | ||||||
|  | /cookie (<@user>) | ||||||
|  | /eco show (<@user>) | ||||||
|  | /eco daily - "... Same as /eco get." | ||||||
|  | /eco get - "... Same as /eco daily." | ||||||
|  | /eco pay <@user> <amount: int> | ||||||
|  | /eco guild | ||||||
|  | /eco leaderboard - "... Same as /eco top." | ||||||
|  | /eco top - "... Same as /eco leaderboard." | ||||||
|  | /eco buy <item: string> | ||||||
|  | /eco shop | ||||||
|  | /eco monday | ||||||
|  | /eco bet <@user> <amount: int> <duration: string> | ||||||
|  | /eco award <@user> (<amount: int>) | ||||||
|  | /eco post | ||||||
|  | /eco delete --- "Operation successful. 5000 rows affected." | ||||||
|  | /figlet <input: string> | ||||||
|  | /insult | ||||||
|  | /love | ||||||
|  | /ok | ||||||
|  | /owoify <input> | ||||||
|  | /party | ||||||
|  | /pat (<@user>) | ||||||
|  | /poll <question: string> (<seconds: int>) | ||||||
|  | /ravi (<index: int>) | ||||||
|  | /thonk (<text: string>) | ||||||
|  | /urban <word: string> | ||||||
|  | /vaporwave <text: string> | ||||||
|  | /weather <city: string> | ||||||
|  | /whoami | ||||||
|  | /whois <@user> | ||||||
|  | 
 | ||||||
|  | -= [System] =- ("/admin other ..." if needed) | ||||||
|  | /admin prefix (<prefix: string>) | ||||||
|  | /admin messageembeds <enabled: boolean> | ||||||
|  | /admin welcome type <[none, text, graphical]: string> | ||||||
|  | /admin welcome channel <#channel> | ||||||
|  | /admin stream <#channel> | ||||||
|  | /admin defaultname (<name: string>) | ||||||
|  | /admin logs (<verbosity: string>) | ||||||
|  | /admin status | ||||||
|  | /admin clear <amount: int> | ||||||
|  | /admin nickname <nickname: string> | ||||||
|  | /admin guilds | ||||||
|  | /admin activity <type: string> (<description: string>) | ||||||
|  | /admin syslog | ||||||
|  | /admin autoroles list | ||||||
|  | /admin autoroles reset | ||||||
|  | /admin autoroles add <@role> | ||||||
|  | /admin autoroles remove <@role> | ||||||
|  | /admin streamroles set <@role> <category: string> | ||||||
|  | /admin streamroles remove <@role> | ||||||
|  | /webhook register <url: string> | ||||||
|  | /webhook delete <url: string> | ||||||
|  | 
 | ||||||
|  | -= [Utility] =- | ||||||
|  | /calc <expression: string> | ||||||
|  | /code | ||||||
|  | /desc <name: string> | ||||||
|  | /docs <query: string> | ||||||
|  | /emote <emotes: string> | ||||||
|  | /info | ||||||
|  | /info avatar (<@user>) | ||||||
|  | /info bot | ||||||
|  | /info guild <name: string> | ||||||
|  | /info guild <id: int> | ||||||
|  | /info <@user> | ||||||
|  | /invite (<flag: int>) | ||||||
|  | /lsemotes <regex: string> (<isCaseSensitive: boolean>) | ||||||
|  | /purge | ||||||
|  | /react <emotes: string> (<target: string>) | ||||||
|  | /say <message: string> | ||||||
|  | /scanemotes (<forceReset: boolean>) | ||||||
|  | /shorten <url: string> | ||||||
|  | /stream description set (<description: string>) | ||||||
|  | /stream description remove | ||||||
|  | /stream thumbnail set (<link: string>) | ||||||
|  | /stream thumbnail remove | ||||||
|  | /stream category set (<category: string>) | ||||||
|  | /stream category remove | ||||||
|  | /time show (<@user>) | ||||||
|  | /time setup | ||||||
|  | /time delete | ||||||
|  | /time utc | ||||||
|  | /time daylight | ||||||
|  | /todo show | ||||||
|  | /todo add <note: string> | ||||||
|  | /todo remove <note: string> | ||||||
|  | /todo clear | ||||||
							
								
								
									
										16
									
								
								src/commands/fun/whoami.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/commands/fun/whoami.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | import {SlashCommandBuilder} from "@discordjs/builders"; | ||||||
|  | import {CommandInteraction} from "discord.js"; | ||||||
|  | import {registry} from "./whois"; | ||||||
|  | 
 | ||||||
|  | export const header = new SlashCommandBuilder().setDescription("Tells you who you are"); | ||||||
|  | 
 | ||||||
|  | export function handler(interaction: CommandInteraction) { | ||||||
|  |     const {user} = interaction; | ||||||
|  |     const id = user.id; | ||||||
|  | 
 | ||||||
|  |     if (id in registry) { | ||||||
|  |         interaction.reply({content: `${user} ${registry[id]}`, allowedMentions: {parse: []}}); | ||||||
|  |     } else { | ||||||
|  |         interaction.reply("You haven't been added to the registry yet!"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,8 +1,10 @@ | ||||||
| import {User} from "discord.js"; | import {User} from "discord.js"; | ||||||
| import {Command, NamedCommand, getUserByNickname, RestCommand} from "onion-lasers"; | import {Command, NamedCommand, getUserByNickname, RestCommand} from "onion-lasers"; | ||||||
|  | import {SlashCommandBuilder} from "@discordjs/builders"; | ||||||
|  | import {CommandInteraction} from "discord.js"; | ||||||
| 
 | 
 | ||||||
| // Quotes must be used here or the numbers will change
 | // Quotes must be used here or the numbers will change
 | ||||||
| const registry: {[id: string]: string} = { | export const registry: {[id: string]: string} = { | ||||||
|     "465662909645848577": "You're an idiot, that's what.", |     "465662909645848577": "You're an idiot, that's what.", | ||||||
|     "306499531665833984": |     "306499531665833984": | ||||||
|         "Kuma, you eldritch fuck, I demand you to release me from this Discord bot and let me see my Chromebook!", |         "Kuma, you eldritch fuck, I demand you to release me from this Discord bot and let me see my Chromebook!", | ||||||
|  | @ -50,6 +52,24 @@ const registry: {[id: string]: string} = { | ||||||
|     "138840343855497216": "your face is a whois entry" |     "138840343855497216": "your face is a whois entry" | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | export const header = new SlashCommandBuilder() | ||||||
|  |     .setDescription("Tells you who the specified user is") | ||||||
|  |     .addUserOption((option) => | ||||||
|  |         option.setName("target").setDescription("The person to inquire about").setRequired(true) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  | export function handler(interaction: CommandInteraction) { | ||||||
|  |     const {options} = interaction; | ||||||
|  |     const user = options.getUser("target", true); | ||||||
|  |     const id = user.id; | ||||||
|  | 
 | ||||||
|  |     if (id in registry) { | ||||||
|  |         interaction.reply({content: `${user} ${registry[id]}`, allowedMentions: {parse: []}}); | ||||||
|  |     } else { | ||||||
|  |         interaction.reply({content: `${user} hasn't been added to the registry yet!`, allowedMentions: {parse: []}}); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export default new NamedCommand({ | export default new NamedCommand({ | ||||||
|     description: "Tells you who you or the specified user is.", |     description: "Tells you who you or the specified user is.", | ||||||
|     aliases: ["whoami"], |     aliases: ["whoami"], | ||||||
|  |  | ||||||
|  | @ -14,6 +14,9 @@ export const client = new Client({ | ||||||
|         Intents.FLAGS.GUILD_MESSAGES, |         Intents.FLAGS.GUILD_MESSAGES, | ||||||
|         Intents.FLAGS.GUILD_MESSAGE_REACTIONS, |         Intents.FLAGS.GUILD_MESSAGE_REACTIONS, | ||||||
|         Intents.FLAGS.DIRECT_MESSAGES |         Intents.FLAGS.DIRECT_MESSAGES | ||||||
|  |     ], | ||||||
|  |     partials: [ | ||||||
|  |         "CHANNEL" // Needed so the bot can receive DM messages
 | ||||||
|     ] |     ] | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | @ -76,6 +79,7 @@ launch(client, path.join(__dirname, "commands"), { | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| // Initialize Modules //
 | // Initialize Modules //
 | ||||||
|  | import "./modules/slashCommands"; | ||||||
| import "./modules/ready"; | import "./modules/ready"; | ||||||
| import "./modules/presence"; | import "./modules/presence"; | ||||||
| // TODO: Reimplement entire music system, contact Sink
 | // TODO: Reimplement entire music system, contact Sink
 | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								src/modules/slashCommands.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/modules/slashCommands.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | ||||||
|  | import {client} from "../index"; | ||||||
|  | import {join} from "path"; | ||||||
|  | import {loadCommands} from "../modules/slashCommandsLoader"; | ||||||
|  | 
 | ||||||
|  | loadCommands(join(__dirname, "..", "commands")).then((result) => { | ||||||
|  |     const [headers, handlers] = result; | ||||||
|  |     const useDevGuild = IS_DEV_MODE && !!process.env.DEV_GUILD; | ||||||
|  | 
 | ||||||
|  |     // Send slash command data to Discord
 | ||||||
|  | 
 | ||||||
|  |     client.on("ready", async () => { | ||||||
|  |         try { | ||||||
|  |             if (useDevGuild) { | ||||||
|  |                 await client.guilds.cache | ||||||
|  |                     .get(process.env.DEV_GUILD!)! | ||||||
|  |                     .commands.set(headers.map((header) => header.toJSON())); | ||||||
|  |             } else { | ||||||
|  |                 await client.application!.commands.set(headers.map((header) => header.toJSON())); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             console.log( | ||||||
|  |                 `Successfully loaded command definitions into Discord using ${ | ||||||
|  |                     useDevGuild ? "development" : "production" | ||||||
|  |                 } mode.` | ||||||
|  |             ); | ||||||
|  |         } catch (error) { | ||||||
|  |             console.error(error); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // Listen for slash commands
 | ||||||
|  | 
 | ||||||
|  |     client.on("interactionCreate", async (interaction) => { | ||||||
|  |         if (interaction.isCommand()) { | ||||||
|  |             if (handlers.has(interaction.commandName)) { | ||||||
|  |                 try { | ||||||
|  |                     await handlers.get(interaction.commandName)!(interaction); | ||||||
|  |                 } catch (error) { | ||||||
|  |                     console.error(error); | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // Use these when implementing subcommands and subcommand groups
 | ||||||
|  |                 // interaction.options.getSubcommandGroup(false); // string if exists, null if not
 | ||||||
|  |                 // interaction.options.getSubcommand(false); // string if exists, null if not
 | ||||||
|  |             } else { | ||||||
|  |                 interaction.reply({ | ||||||
|  |                     content: | ||||||
|  |                         "**Error:** Invalid command name! This probably means that the command definitions forgot to be updated.", | ||||||
|  |                     ephemeral: true | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | }); | ||||||
							
								
								
									
										76
									
								
								src/modules/slashCommandsLoader.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/modules/slashCommandsLoader.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | import {Collection, CommandInteraction} from "discord.js"; | ||||||
|  | import {SlashCommandBuilder} from "@discordjs/builders"; | ||||||
|  | import glob from "glob"; | ||||||
|  | import path from "path"; | ||||||
|  | 
 | ||||||
|  | export async function loadCommands( | ||||||
|  |     commandsDir: string | ||||||
|  | ): Promise< | ||||||
|  |     [Collection<string, SlashCommandBuilder>, Collection<string, (interaction: CommandInteraction) => Promise<any>>] | ||||||
|  | > { | ||||||
|  |     // Add a trailing separator so that the reduced filename list will reliably cut off the starting part.
 | ||||||
|  |     // "C:/some/path/to/commands" --> "C:/some/path/to/commands/" (and likewise for \)
 | ||||||
|  |     commandsDir = path.normalize(commandsDir); | ||||||
|  |     if (!commandsDir.endsWith(path.sep)) commandsDir += path.sep; | ||||||
|  | 
 | ||||||
|  |     const headers = new Collection<string, SlashCommandBuilder>(); | ||||||
|  |     const handlers = new Collection<string, () => Promise<any>>(); | ||||||
|  |     const files = await globP(path.join(commandsDir, "**", "*.js")); // This stage filters out source maps (.js.map).
 | ||||||
|  |     // Because glob will use / regardless of platform, the following regex pattern can rely on / being the case.
 | ||||||
|  |     const filesClean = files.map((filename) => filename.substring(commandsDir.length)); | ||||||
|  |     // Extract the usable parts from commands directory if the path is 1 to 2 subdirectories (a or a/b, not a/b/c).
 | ||||||
|  |     // No further checks will be made to exclude template command files or test command files, keeping it structure-agnostic.
 | ||||||
|  |     const pattern = /^([^/]+(?:\/[^/]+)?)\.js$/; | ||||||
|  | 
 | ||||||
|  |     for (let i = 0; i < files.length; i++) { | ||||||
|  |         const match = pattern.exec(filesClean[i]); | ||||||
|  |         if (!match) continue; | ||||||
|  |         const commandID = match[1]; // e.g. "utilities/info"
 | ||||||
|  |         const slashIndex = commandID.indexOf("/"); | ||||||
|  |         const isMiscCommand = slashIndex !== -1; | ||||||
|  |         const commandName = isMiscCommand ? commandID.substring(slashIndex + 1) : commandID; // e.g. "info"
 | ||||||
|  | 
 | ||||||
|  |         // This try-catch block MUST be here or Node.js' dynamic require() will silently fail.
 | ||||||
|  |         try { | ||||||
|  |             // If the dynamic import works, it must be an object at the very least. Then, just test to see if it's a proper instance.
 | ||||||
|  |             const {header, handler} = (await import(files[i])) as {header: unknown; handler: unknown}; | ||||||
|  | 
 | ||||||
|  |             if (header instanceof SlashCommandBuilder && handler instanceof Function) { | ||||||
|  |                 if (headers.has(commandName) || handlers.has(commandName)) { | ||||||
|  |                     console.warn( | ||||||
|  |                         `Command "${commandID}" already exists! Make sure to make each command uniquely identifiable across categories!` | ||||||
|  |                     ); | ||||||
|  |                 } else { | ||||||
|  |                     // Set the slash command name to the filename only if there isn't already a name set
 | ||||||
|  |                     if (header.name === undefined) { | ||||||
|  |                         header.setName(commandName); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     headers.set(header.name, header); | ||||||
|  |                     handlers.set(header.name, handler as any); // Just got to hope that the user puts in good data
 | ||||||
|  |                     console.log(`Loaded Command: "${commandID}" as "${header.name}"`); // Use header.name to show what the slash command name is (should be the same)
 | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 console.warn( | ||||||
|  |                     `Command "${commandID}" doesn't export a "header" property (SlashCommandBuilder instance) or a "handler" property (function)!` | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         } catch (error) { | ||||||
|  |             console.error(error); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return [headers, handlers]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function globP(path: string) { | ||||||
|  |     return new Promise<string[]>((resolve, reject) => { | ||||||
|  |         glob(path, (error, files) => { | ||||||
|  |             if (error) { | ||||||
|  |                 reject(error); | ||||||
|  |             } else { | ||||||
|  |                 resolve(files); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |     }); | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue