├── .husky └── pre-commit ├── 4-music-player-ytdl ├── src │ ├── images │ │ ├── 1.jpg │ │ └── 2.jpg │ └── main.ts ├── .gitignore ├── docker-compose.yml ├── tsconfig.json ├── Dockerfile ├── package.json ├── README.md └── LICENSE ├── sandbox.config.json ├── .prettierignore ├── 2-blank ├── .gitignore ├── docker-compose.yml ├── src │ ├── events │ │ └── common.ts │ ├── commands │ │ └── slashes.ts │ └── main.ts ├── tsconfig.json ├── package.json ├── Dockerfile └── README.md ├── .gitignore ├── 1-starter ├── .gitignore ├── docker-compose.yml ├── src │ ├── events │ │ └── common.ts │ ├── commands │ │ ├── context.ts │ │ ├── choices.ts │ │ ├── slashes.ts │ │ ├── slash + button.ts │ │ ├── simple command.ts │ │ ├── menu.ts │ │ └── slash group.ts │ └── main.ts ├── tsconfig.json ├── Dockerfile ├── package.json └── README.md ├── 3-hot-module-reload ├── .gitignore ├── docker-compose.yml ├── src │ ├── events │ │ └── common.ts │ ├── commands │ │ └── slashes.ts │ ├── main.ts │ ├── bot.ts │ └── dev.ts ├── tsconfig.json ├── package.json ├── Dockerfile └── README.md ├── 5-music-player-lavalink ├── .gitignore ├── tsconfig.json ├── Dockerfile ├── package.json ├── docker-compose.yml ├── src │ └── main.ts ├── README.md └── application.yml ├── turbo.json ├── pnpm-workspace.yaml ├── .commitlintrc.json ├── prettier.config.mjs ├── .deepsource.toml ├── .github └── workflows │ └── build.yml ├── eslint.config.mjs ├── package.json ├── README.md └── LICENSE /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | npm run prettier 2 | -------------------------------------------------------------------------------- /4-music-player-ytdl/src/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discordx-ts/templates/HEAD/4-music-player-ytdl/src/images/1.jpg -------------------------------------------------------------------------------- /4-music-player-ytdl/src/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/discordx-ts/templates/HEAD/4-music-player-ytdl/src/images/2.jpg -------------------------------------------------------------------------------- /sandbox.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "node", 3 | "view": "console", 4 | "container": { 5 | "node": "16" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | CHANGELOG.md 6 | 7 | # folders 8 | .turbo 9 | build 10 | node_modules -------------------------------------------------------------------------------- /2-blank/.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | package-lock.json 6 | yarn.lock 7 | 8 | # folders 9 | build 10 | node_modules -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | CHANGELOG.md 6 | *.bat 7 | 8 | # folders 9 | .turbo 10 | build 11 | node_modules 12 | -------------------------------------------------------------------------------- /1-starter/.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | package-lock.json 6 | yarn.lock 7 | 8 | # folders 9 | build 10 | node_modules -------------------------------------------------------------------------------- /3-hot-module-reload/.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | package-lock.json 6 | yarn.lock 7 | 8 | # folders 9 | build 10 | node_modules -------------------------------------------------------------------------------- /4-music-player-ytdl/.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | package-lock.json 6 | yarn.lock 7 | 8 | # folders 9 | build 10 | node_modules -------------------------------------------------------------------------------- /5-music-player-lavalink/.gitignore: -------------------------------------------------------------------------------- 1 | # files 2 | .vscode 3 | .env 4 | .env.local 5 | package-lock.json 6 | yarn.lock 7 | 8 | # folders 9 | build 10 | node_modules -------------------------------------------------------------------------------- /2-blank/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | app: 4 | build: . 5 | command: node build/main.js 6 | environment: 7 | - BOT_TOKEN=${BOT_TOKEN} 8 | -------------------------------------------------------------------------------- /1-starter/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | app: 4 | build: . 5 | command: node build/main.js 6 | environment: 7 | - BOT_TOKEN=${BOT_TOKEN} 8 | -------------------------------------------------------------------------------- /3-hot-module-reload/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | app: 4 | build: . 5 | command: node build/main.js 6 | environment: 7 | - BOT_TOKEN=${BOT_TOKEN} 8 | -------------------------------------------------------------------------------- /4-music-player-ytdl/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | app: 4 | build: . 5 | command: node build/main.js 6 | environment: 7 | - BOT_TOKEN=${BOT_TOKEN} 8 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["build/**"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /3-hot-module-reload/src/events/common.ts: -------------------------------------------------------------------------------- 1 | import { Discord, On, type ArgsOf } from "discordx"; 2 | 3 | @Discord() 4 | export class Example { 5 | @On() 6 | messageCreate([message]: ArgsOf<"messageCreate">): void { 7 | console.log(message.author.username, "said:", message.content); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1-starter/src/events/common.ts: -------------------------------------------------------------------------------- 1 | import { Discord, On, type ArgsOf, type Client } from "discordx"; 2 | 3 | @Discord() 4 | export class Example { 5 | @On() 6 | messageDelete([message]: ArgsOf<"messageDelete">, client: Client): void { 7 | console.log("Message Deleted", client.user?.username, message.content); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /2-blank/src/events/common.ts: -------------------------------------------------------------------------------- 1 | import { Discord, On, type ArgsOf, type Client } from "discordx"; 2 | 3 | @Discord() 4 | export class Example { 5 | @On() 6 | messageDelete([message]: ArgsOf<"messageDelete">, client: Client): void { 7 | console.log("Message Deleted", client.user?.username, message.content); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 1-starter 3 | - 2-blank 4 | - 3-hot-module-reload 5 | - 4-music-player-ytdl 6 | - 5-music-player-lavalink 7 | 8 | minimumReleaseAgeExclude: 9 | - "@discordx/*" 10 | - discordx 11 | 12 | onlyBuiltDependencies: 13 | - esbuild 14 | - "@discordjs/opus" 15 | - ffmpeg-static 16 | -------------------------------------------------------------------------------- /2-blank/src/commands/slashes.ts: -------------------------------------------------------------------------------- 1 | import type { CommandInteraction } from "discord.js"; 2 | import { Discord, Slash } from "discordx"; 3 | 4 | @Discord() 5 | export class Example { 6 | @Slash({ description: "ping" }) 7 | async ping(interaction: CommandInteraction): Promise { 8 | await interaction.reply("pong!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /3-hot-module-reload/src/commands/slashes.ts: -------------------------------------------------------------------------------- 1 | import type { CommandInteraction } from "discord.js"; 2 | import { Discord, Slash } from "discordx"; 3 | 4 | @Discord() 5 | export class Example { 6 | @Slash({ description: "ping" }) 7 | async ping(interaction: CommandInteraction): Promise { 8 | await interaction.reply("pong!"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-angular"], 3 | "rules": { 4 | "scope-case": [2, "always", "pascal-case"], 5 | "type-enum": [ 6 | 2, 7 | "always", 8 | [ 9 | "build", 10 | "chore", 11 | "ci", 12 | "docs", 13 | "feat", 14 | "fix", 15 | "refactor", 16 | "revert", 17 | "test", 18 | "types", 19 | "workflow" 20 | ] 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /prettier.config.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @see https://prettier.io/docs/configuration 3 | * @type {import("prettier").Config} 4 | */ 5 | const config = { 6 | semi: true, 7 | endOfLine: "auto", 8 | plugins: ["@ianvs/prettier-plugin-sort-imports"], 9 | importOrder: ["", "", "", "^[./]"], 10 | importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"], 11 | importOrderTypeScriptVersion: "5.9.2", 12 | }; 13 | 14 | export default config; 15 | -------------------------------------------------------------------------------- /1-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "outDir": "build", 6 | "rootDir": "src", 7 | "strict": true, 8 | "moduleResolution": "Node", 9 | "allowSyntheticDefaultImports": true, 10 | 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": false, 13 | 14 | "skipLibCheck": true, 15 | "forceConsistentCasingInFileNames": true 16 | }, 17 | "exclude": ["build", "node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /2-blank/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "outDir": "build", 6 | "rootDir": "src", 7 | "strict": true, 8 | "moduleResolution": "Node", 9 | "allowSyntheticDefaultImports": true, 10 | 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": false, 13 | 14 | "skipLibCheck": true, 15 | "forceConsistentCasingInFileNames": true 16 | }, 17 | "exclude": ["build", "node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /3-hot-module-reload/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "outDir": "build", 6 | "rootDir": "src", 7 | "strict": true, 8 | "moduleResolution": "Node", 9 | "allowSyntheticDefaultImports": true, 10 | 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": false, 13 | 14 | "skipLibCheck": true, 15 | "forceConsistentCasingInFileNames": true 16 | }, 17 | "exclude": ["build", "node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /5-music-player-lavalink/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "outDir": "build", 6 | "rootDir": "src", 7 | "strict": true, 8 | "moduleResolution": "Node", 9 | "allowSyntheticDefaultImports": true, 10 | 11 | "experimentalDecorators": true, 12 | "emitDecoratorMetadata": false, 13 | 14 | "skipLibCheck": true, 15 | "forceConsistentCasingInFileNames": true 16 | }, 17 | "exclude": ["build", "node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /4-music-player-ytdl/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "outDir": "./build", 6 | "rootDir": "./src", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "moduleResolution": "Node", 10 | 11 | /* Experimental Options */ 12 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */, 13 | "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */, 14 | 15 | /* Advanced Options */ 16 | "skipLibCheck": true, 17 | "forceConsistentCasingInFileNames": true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | exclude_patterns = [ 4 | "**/build/**", 5 | "**/node_modules/**" 6 | ] 7 | 8 | [[analyzers]] 9 | name = "docker" 10 | enabled = true 11 | 12 | [[analyzers]] 13 | name = "secrets" 14 | enabled = true 15 | 16 | [[analyzers]] 17 | name = "javascript" 18 | enabled = true 19 | 20 | [analyzers.meta] 21 | module_system = "es-modules" 22 | environment = [ 23 | "nodejs", 24 | ] 25 | dialect = "typescript" 26 | skip_doc_coverage = ["class-expression", "method-definition", "class-declaration", "function-declaration"] 27 | 28 | [[transformers]] 29 | name = "prettier" 30 | enabled = true 31 | -------------------------------------------------------------------------------- /3-hot-module-reload/src/main.ts: -------------------------------------------------------------------------------- 1 | import { dirname, importx } from "@discordx/importer"; 2 | 3 | import { bot } from "./bot.js"; 4 | 5 | async function run() { 6 | // The following syntax should be used in the commonjs environment 7 | // 8 | // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); 9 | 10 | // The following syntax should be used in the ECMAScript environment 11 | await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); 12 | 13 | // Let's start the bot 14 | if (!process.env.BOT_TOKEN) { 15 | throw Error("Could not find BOT_TOKEN in your environment"); 16 | } 17 | 18 | // Log in with your bot token 19 | await bot.login(process.env.BOT_TOKEN); 20 | } 21 | 22 | void run(); 23 | -------------------------------------------------------------------------------- /3-hot-module-reload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "7-hot-module-reload", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "build/main.js", 8 | "scripts": { 9 | "build": "tsc", 10 | "dev": "tsx src/dev.ts", 11 | "start": "node build/main.js" 12 | }, 13 | "dependencies": { 14 | "@discordx/importer": "^1.3.3", 15 | "discord.js": "^14.22.1", 16 | "discordx": "^11.13.2" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^24.4.0", 20 | "chokidar": "^4.0.3", 21 | "prettier": "^3.6.2", 22 | "tsx": "^4.20.5", 23 | "typescript": "5.9.2" 24 | }, 25 | "engines": { 26 | "node": ">=16.0.0", 27 | "npm": ">=7.0.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /2-blank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "3-blank", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "build/main.js", 8 | "scripts": { 9 | "build": "tsc", 10 | "dev": "tsx src/main.ts", 11 | "start": "node build/main.js", 12 | "watch": "nodemon --exec npm run dev --watch src --ext ts" 13 | }, 14 | "dependencies": { 15 | "@discordx/importer": "^1.3.3", 16 | "discord.js": "^14.22.1", 17 | "discordx": "^11.13.2" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^24.4.0", 21 | "nodemon": "^3.1.10", 22 | "prettier": "^3.6.2", 23 | "tsx": "^4.20.5", 24 | "typescript": "5.9.2" 25 | }, 26 | "engines": { 27 | "node": ">=16.0.0", 28 | "npm": ">=7.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2-blank/Dockerfile: -------------------------------------------------------------------------------- 1 | ## build runner 2 | FROM node:lts-alpine as build-runner 3 | 4 | # Set temp directory 5 | WORKDIR /tmp/app 6 | 7 | # Move package.json 8 | COPY package.json . 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Move source files 14 | COPY src ./src 15 | COPY tsconfig.json . 16 | 17 | # Build project 18 | RUN npm run build 19 | 20 | ## production runner 21 | FROM node:lts-alpine as prod-runner 22 | 23 | # Set work directory 24 | WORKDIR /app 25 | 26 | # Copy package.json from build-runner 27 | COPY --from=build-runner /tmp/app/package.json /app/package.json 28 | 29 | # Install dependencies 30 | RUN npm install --omit=dev 31 | 32 | # Move build files 33 | COPY --from=build-runner /tmp/app/build /app/build 34 | 35 | # Start bot 36 | CMD [ "npm", "run", "start" ] 37 | -------------------------------------------------------------------------------- /1-starter/Dockerfile: -------------------------------------------------------------------------------- 1 | ## build runner 2 | FROM node:lts-alpine as build-runner 3 | 4 | # Set temp directory 5 | WORKDIR /tmp/app 6 | 7 | # Move package.json 8 | COPY package.json . 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Move source files 14 | COPY src ./src 15 | COPY tsconfig.json . 16 | 17 | # Build project 18 | RUN npm run build 19 | 20 | ## production runner 21 | FROM node:lts-alpine as prod-runner 22 | 23 | # Set work directory 24 | WORKDIR /app 25 | 26 | # Copy package.json from build-runner 27 | COPY --from=build-runner /tmp/app/package.json /app/package.json 28 | 29 | # Install dependencies 30 | RUN npm install --omit=dev 31 | 32 | # Move build files 33 | COPY --from=build-runner /tmp/app/build /app/build 34 | 35 | # Start bot 36 | CMD [ "npm", "run", "start" ] 37 | -------------------------------------------------------------------------------- /3-hot-module-reload/Dockerfile: -------------------------------------------------------------------------------- 1 | ## build runner 2 | FROM node:lts-alpine as build-runner 3 | 4 | # Set temp directory 5 | WORKDIR /tmp/app 6 | 7 | # Move package.json 8 | COPY package.json . 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Move source files 14 | COPY src ./src 15 | COPY tsconfig.json . 16 | 17 | # Build project 18 | RUN npm run build 19 | 20 | ## production runner 21 | FROM node:lts-alpine as prod-runner 22 | 23 | # Set work directory 24 | WORKDIR /app 25 | 26 | # Copy package.json from build-runner 27 | COPY --from=build-runner /tmp/app/package.json /app/package.json 28 | 29 | # Install dependencies 30 | RUN npm install --omit=dev 31 | 32 | # Move build files 33 | COPY --from=build-runner /tmp/app/build /app/build 34 | 35 | # Start bot 36 | CMD [ "npm", "run", "start" ] 37 | -------------------------------------------------------------------------------- /4-music-player-ytdl/Dockerfile: -------------------------------------------------------------------------------- 1 | ## build runner 2 | FROM node:lts-alpine as build-runner 3 | 4 | # Set temp directory 5 | WORKDIR /tmp/app 6 | 7 | # Move package.json 8 | COPY package.json . 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Move source files 14 | COPY src ./src 15 | COPY tsconfig.json . 16 | 17 | # Build project 18 | RUN npm run build 19 | 20 | ## production runner 21 | FROM node:lts-alpine as prod-runner 22 | 23 | # Set work directory 24 | WORKDIR /app 25 | 26 | # Copy package.json from build-runner 27 | COPY --from=build-runner /tmp/app/package.json /app/package.json 28 | 29 | # Install dependencies 30 | RUN npm install --omit=dev 31 | 32 | # Move build files 33 | COPY --from=build-runner /tmp/app/build /app/build 34 | 35 | # Start bot 36 | CMD [ "npm", "run", "start" ] 37 | -------------------------------------------------------------------------------- /5-music-player-lavalink/Dockerfile: -------------------------------------------------------------------------------- 1 | ## build runner 2 | FROM node:lts-alpine as build-runner 3 | 4 | # Set temp directory 5 | WORKDIR /tmp/app 6 | 7 | # Move package.json 8 | COPY package.json . 9 | 10 | # Install dependencies 11 | RUN npm install 12 | 13 | # Move source files 14 | COPY src ./src 15 | COPY tsconfig.json . 16 | 17 | # Build project 18 | RUN npm run build 19 | 20 | ## production runner 21 | FROM node:lts-alpine as prod-runner 22 | 23 | # Set work directory 24 | WORKDIR /app 25 | 26 | # Copy package.json from build-runner 27 | COPY --from=build-runner /tmp/app/package.json /app/package.json 28 | 29 | # Install dependencies 30 | RUN npm install --omit=dev 31 | 32 | # Move build files 33 | COPY --from=build-runner /tmp/app/build /app/build 34 | 35 | # Start bot 36 | CMD [ "npm", "run", "start" ] 37 | -------------------------------------------------------------------------------- /1-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "1-starter", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "build/main.js", 8 | "scripts": { 9 | "build": "tsc", 10 | "dev": "tsx src/main.ts", 11 | "start": "node build/main.js", 12 | "watch": "nodemon --exec npm run dev --watch src --ext ts" 13 | }, 14 | "dependencies": { 15 | "@discordx/importer": "^1.3.3", 16 | "@discordx/pagination": "^4.4.0", 17 | "discord.js": "^14.22.1", 18 | "discordx": "^11.13.2" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^24.4.0", 22 | "nodemon": "^3.1.10", 23 | "prettier": "^3.6.2", 24 | "tsx": "^4.20.5", 25 | "typescript": "5.9.2" 26 | }, 27 | "engines": { 28 | "node": ">=16.0.0", 29 | "npm": ">=7.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /1-starter/src/commands/context.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationCommandType, 3 | type MessageContextMenuCommandInteraction, 4 | type UserContextMenuCommandInteraction, 5 | } from "discord.js"; 6 | import { ContextMenu, Discord } from "discordx"; 7 | 8 | @Discord() 9 | export class Example { 10 | @ContextMenu({ 11 | name: "message context", 12 | type: ApplicationCommandType.Message, 13 | }) 14 | async messageHandler( 15 | interaction: MessageContextMenuCommandInteraction, 16 | ): Promise { 17 | await interaction.reply("I am user context handler"); 18 | } 19 | 20 | @ContextMenu({ name: "user context", type: ApplicationCommandType.User }) 21 | async userHandler( 22 | interaction: UserContextMenuCommandInteraction, 23 | ): Promise { 24 | await interaction.reply("I am user context handler"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /4-music-player-ytdl/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "4-music-player-ytdl", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "build/main.js", 8 | "scripts": { 9 | "build": "tsc", 10 | "dev": "tsx src/main.ts", 11 | "start": "node build/main.js", 12 | "watch": "nodemon --exec npm run dev --watch src --ext ts" 13 | }, 14 | "dependencies": { 15 | "@discordx/importer": "^1.3.3", 16 | "@discordx/plugin-ytdl-player": "^2.3.10", 17 | "discord.js": "^14.22.1", 18 | "discordx": "^11.13.2" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^24.4.0", 22 | "nodemon": "^3.1.10", 23 | "prettier": "^3.6.2", 24 | "tsx": "^4.20.5", 25 | "typescript": "5.9.2" 26 | }, 27 | "engines": { 28 | "node": ">=16.0.0", 29 | "npm": ">=7.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | workflow_dispatch: 4 | pull_request: 5 | branches: 6 | - main 7 | push: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | name: Build Monorepo 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: check out code 🛎 17 | uses: actions/checkout@main 18 | 19 | - name: Install pnpm 20 | uses: pnpm/action-setup@master 21 | 22 | - name: Install Node 23 | uses: actions/setup-node@main 24 | with: 25 | node-version: 22 26 | cache: "pnpm" 27 | 28 | - name: Install dependencies 29 | run: pnpm install 30 | 31 | - name: Run prettier 32 | run: pnpm prettier 33 | 34 | - name: Run ESLint 35 | run: pnpm lint 36 | 37 | - name: Build 38 | run: pnpm build 39 | -------------------------------------------------------------------------------- /5-music-player-lavalink/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "5-music-player-lavalink", 3 | "version": "1.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "type": "module", 7 | "main": "build/main.js", 8 | "scripts": { 9 | "build": "tsc", 10 | "dev": "tsx src/main.ts", 11 | "start": "node build/main.js", 12 | "watch": "nodemon --exec npm run dev --watch src --ext ts" 13 | }, 14 | "dependencies": { 15 | "@discordx/importer": "^1.3.3", 16 | "@discordx/plugin-lava-player": "^3.0.0", 17 | "discord.js": "^14.22.1", 18 | "discordx": "^11.13.2" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^24.4.0", 22 | "nodemon": "^3.1.10", 23 | "prettier": "^3.6.2", 24 | "tsx": "^4.20.5", 25 | "typescript": "5.9.2" 26 | }, 27 | "engines": { 28 | "node": ">=16.0.0", 29 | "npm": ">=7.0.0" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /1-starter/src/commands/choices.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationCommandOptionType, 3 | type CommandInteraction, 4 | } from "discord.js"; 5 | import { Discord, Slash, SlashChoice, SlashOption } from "discordx"; 6 | 7 | @Discord() 8 | export class Example { 9 | @Slash({ description: "choose" }) 10 | async choose( 11 | @SlashChoice("Human", "Astronaut", "Dev") 12 | @SlashOption({ 13 | description: "What are you?", 14 | name: "what", 15 | required: true, 16 | type: ApplicationCommandOptionType.String, 17 | }) 18 | what: string, 19 | interaction: CommandInteraction, 20 | ): Promise { 21 | await interaction.reply(what); 22 | } 23 | 24 | @Slash({ description: "choose1" }) 25 | async choose1( 26 | @SlashChoice({ name: "are you okay?", value: "okay" }) 27 | @SlashChoice({ name: "are you good?", value: "good" }) 28 | @SlashOption({ 29 | description: "what1", 30 | name: "what1", 31 | required: true, 32 | type: ApplicationCommandOptionType.String, 33 | }) 34 | what: string, 35 | interaction: CommandInteraction, 36 | ): Promise { 37 | await interaction.reply(what); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /1-starter/src/commands/slashes.ts: -------------------------------------------------------------------------------- 1 | import { Pagination } from "@discordx/pagination"; 2 | import { EmbedBuilder, type CommandInteraction } from "discord.js"; 3 | import { Discord, MetadataStorage, Slash } from "discordx"; 4 | 5 | @Discord() 6 | export class SlashExample { 7 | // example: pagination for all slash command 8 | @Slash({ 9 | description: "Pagination for all slash command", 10 | name: "all-commands", 11 | }) 12 | async pages(interaction: CommandInteraction): Promise { 13 | const commands = MetadataStorage.instance.applicationCommands.map((cmd) => { 14 | return { description: cmd.description, name: cmd.name }; 15 | }); 16 | 17 | const pages = commands.map((cmd, i) => { 18 | const embed = new EmbedBuilder() 19 | .setFooter({ 20 | text: `Page ${String(i + 1)} of ${String(commands.length)}`, 21 | }) 22 | .setTitle("**Slash command info**") 23 | .addFields({ name: "Name", value: cmd.name }) 24 | .addFields({ 25 | name: "Description", 26 | value: cmd.description.length ? cmd.description : "-", 27 | }); 28 | 29 | return { embeds: [embed] }; 30 | }); 31 | 32 | const pagination = new Pagination(interaction, pages); 33 | await pagination.send(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /5-music-player-lavalink/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | networks: 4 | discordx-network: 5 | name: discordx-network 6 | 7 | services: 8 | lavalink: 9 | # pin the image version to Lavalink v4 10 | image: ghcr.io/lavalink-devs/lavalink:4 11 | container_name: lavalink 12 | restart: unless-stopped 13 | environment: 14 | # set Java options here 15 | - _JAVA_OPTIONS=-Xmx6G 16 | # set lavalink server port 17 | - SERVER_PORT=2333 18 | # set password for lavalink 19 | - LAVALINK_SERVER_PASSWORD=youshallnotpass 20 | volumes: 21 | # mount application.yml from the same directory or use environment variables 22 | - ./application.yml:/opt/Lavalink/application.yml 23 | networks: 24 | - discordx-network 25 | expose: 26 | # lavalink exposes port 2333 to connect to for other containers (this is for documentation purposes only) 27 | - 2333 28 | ports: 29 | # you only need this if you want to make your lavalink accessible from outside of containers 30 | - "2333:2333" 31 | 32 | app: 33 | depends_on: 34 | - lavalink 35 | build: 36 | context: . 37 | dockerfile: Dockerfile 38 | environment: 39 | - BOT_TOKEN=${BOT_TOKEN} 40 | - LAVA_HOST=lavalink 41 | - LAVA_PORT=2333 42 | networks: 43 | - discordx-network 44 | command: node build/main.js 45 | -------------------------------------------------------------------------------- /3-hot-module-reload/src/bot.ts: -------------------------------------------------------------------------------- 1 | import { IntentsBitField, type Interaction, type Message } from "discord.js"; 2 | import { Client } from "discordx"; 3 | 4 | export const bot = new Client({ 5 | // To use only guild command 6 | // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], 7 | 8 | // Discord intents 9 | intents: [ 10 | IntentsBitField.Flags.Guilds, 11 | IntentsBitField.Flags.GuildMembers, 12 | IntentsBitField.Flags.GuildMessages, 13 | IntentsBitField.Flags.GuildMessageReactions, 14 | IntentsBitField.Flags.GuildVoiceStates, 15 | IntentsBitField.Flags.MessageContent, 16 | ], 17 | 18 | // Debug logs are disabled in silent mode 19 | silent: false, 20 | 21 | // Configuration for @SimpleCommand 22 | simpleCommand: { 23 | prefix: "!", 24 | }, 25 | }); 26 | 27 | bot.once("ready", () => { 28 | // Make sure all guilds are cached 29 | // await bot.guilds.fetch(); 30 | 31 | // Synchronize applications commands with Discord 32 | void bot.initApplicationCommands(); 33 | 34 | // To clear all guild commands, uncomment this line, 35 | // This is useful when moving from guild commands to global commands 36 | // It must only be executed once 37 | // 38 | // await bot.clearApplicationCommands( 39 | // ...bot.guilds.cache.map((g) => g.id) 40 | // ); 41 | 42 | console.log("Bot started"); 43 | }); 44 | 45 | bot.on("interactionCreate", (interaction: Interaction) => { 46 | bot.executeInteraction(interaction); 47 | }); 48 | 49 | bot.on("messageCreate", (message: Message) => { 50 | void bot.executeCommand(message); 51 | }); 52 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import eslint from "@eslint/js"; 2 | import prettierRecommended from "eslint-plugin-prettier/recommended"; 3 | import { defineConfig } from "eslint/config"; 4 | import tseslint from "typescript-eslint"; 5 | 6 | export default defineConfig([ 7 | { ignores: ["**/build", "**/dist", "**/node_modules"] }, 8 | eslint.configs.recommended, 9 | tseslint.configs.strictTypeChecked, 10 | tseslint.configs.stylisticTypeChecked, 11 | { 12 | files: ["**/*.{ts,mts}"], 13 | languageOptions: { 14 | parserOptions: { 15 | projectService: true, 16 | tsconfigRootDir: import.meta.dirname, 17 | ecmaVersion: "latest", 18 | sourceType: "module", 19 | }, 20 | }, 21 | rules: { 22 | "@typescript-eslint/consistent-return": "error", 23 | "@typescript-eslint/consistent-type-assertions": "error", 24 | "@typescript-eslint/consistent-type-definitions": "error", 25 | "@typescript-eslint/consistent-type-exports": "error", 26 | "@typescript-eslint/consistent-type-imports": "error", 27 | "@typescript-eslint/no-explicit-any": "off", 28 | "@typescript-eslint/no-redundant-type-constituents": "off", 29 | "@typescript-eslint/no-unsafe-argument": "off", 30 | "@typescript-eslint/no-unsafe-assignment": "off", 31 | "@typescript-eslint/no-unsafe-call": "off", 32 | "@typescript-eslint/no-unsafe-member-access": "off", 33 | "@typescript-eslint/no-unsafe-return": "off", 34 | }, 35 | }, 36 | { files: ["**/*.{js,mjs}"], extends: [tseslint.configs.disableTypeChecked] }, 37 | prettierRecommended, 38 | ]); 39 | -------------------------------------------------------------------------------- /1-starter/src/commands/slash + button.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ActionRowBuilder, 3 | ApplicationCommandOptionType, 4 | ButtonBuilder, 5 | ButtonStyle, 6 | GuildMember, 7 | type ButtonInteraction, 8 | type CommandInteraction, 9 | type MessageActionRowComponentBuilder, 10 | type User, 11 | } from "discord.js"; 12 | import { ButtonComponent, Discord, Slash, SlashOption } from "discordx"; 13 | 14 | @Discord() 15 | export class Example { 16 | @Slash({ description: "hello", name: "hello-btn" }) 17 | async hello( 18 | @SlashOption({ 19 | description: "user", 20 | name: "user", 21 | required: true, 22 | type: ApplicationCommandOptionType.User, 23 | }) 24 | user: User | GuildMember | undefined, 25 | interaction: CommandInteraction, 26 | ): Promise { 27 | if (!user) { 28 | return; 29 | } 30 | 31 | await interaction.deferReply(); 32 | 33 | const helloBtn = new ButtonBuilder() 34 | .setLabel("Hello") 35 | .setEmoji("👋") 36 | .setStyle(ButtonStyle.Primary) 37 | .setCustomId("hello-btn"); 38 | 39 | const row = 40 | new ActionRowBuilder().addComponents( 41 | helloBtn, 42 | ); 43 | 44 | await interaction.editReply({ 45 | components: [row], 46 | content: `${user.toString()}, Say hello to bot`, 47 | }); 48 | } 49 | 50 | @ButtonComponent({ id: "hello-btn" }) 51 | async helloBtn(interaction: ButtonInteraction): Promise { 52 | if (!(interaction.member instanceof GuildMember)) { 53 | return; 54 | } 55 | 56 | await interaction.reply(`👋 ${interaction.member.toString()}`); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /1-starter/src/commands/simple command.ts: -------------------------------------------------------------------------------- 1 | import type { CommandInteraction, Message } from "discord.js"; 2 | import { 3 | Discord, 4 | SimpleCommand, 5 | SimpleCommandOption, 6 | SimpleCommandOptionType, 7 | Slash, 8 | type SimpleCommandMessage, 9 | } from "discordx"; 10 | 11 | @Discord() 12 | export class Example { 13 | @SimpleCommand({ aliases: ["hi"] }) 14 | async hello(command: SimpleCommandMessage): Promise { 15 | const member = command.message.member; 16 | if (member) { 17 | await command.message.reply(`👋 ${member.toString()}`); 18 | } else { 19 | await command.message.reply("👋 hello"); 20 | } 21 | } 22 | 23 | @SimpleCommand({ argSplitter: "+" }) 24 | async sum( 25 | @SimpleCommandOption({ name: "num1", type: SimpleCommandOptionType.Number }) 26 | num1: number | undefined, 27 | @SimpleCommandOption({ name: "num2", type: SimpleCommandOptionType.Number }) 28 | num2: number | undefined, 29 | command: SimpleCommandMessage, 30 | ): Promise { 31 | if (!num1 || !num2) { 32 | await command.sendUsageSyntax(); 33 | return; 34 | } 35 | 36 | await command.message.reply(`total = ${String(num1 + num2)}`); 37 | } 38 | 39 | // make single handler for simple and slash command 40 | async likeIt(command: CommandInteraction | Message): Promise { 41 | await command.reply("I like it, Thanks"); 42 | } 43 | 44 | @SimpleCommand({ name: "like-it" }) 45 | async simpleLikeIt(command: SimpleCommandMessage): Promise { 46 | await this.likeIt(command.message); 47 | } 48 | 49 | @Slash({ description: "like-ite", name: "like-it" }) 50 | async slashLikeIt(command: CommandInteraction): Promise { 51 | await this.likeIt(command); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /1-starter/src/commands/menu.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ActionRowBuilder, 3 | StringSelectMenuBuilder, 4 | type CommandInteraction, 5 | type MessageActionRowComponentBuilder, 6 | type StringSelectMenuInteraction, 7 | } from "discord.js"; 8 | import { Discord, SelectMenuComponent, Slash } from "discordx"; 9 | 10 | const roles = [ 11 | { label: "Principal", value: "principal" }, 12 | { label: "Teacher", value: "teacher" }, 13 | { label: "Student", value: "student" }, 14 | ]; 15 | 16 | @Discord() 17 | export class Example { 18 | @SelectMenuComponent({ id: "role-menu" }) 19 | async handle(interaction: StringSelectMenuInteraction): Promise { 20 | await interaction.deferReply(); 21 | 22 | // extract selected value by member 23 | const roleValue = interaction.values[0]; 24 | 25 | // if value not found 26 | if (!roleValue) { 27 | await interaction.followUp("invalid role id, select again"); 28 | return; 29 | } 30 | 31 | await interaction.followUp( 32 | `you have selected role: ${ 33 | roles.find((r) => r.value === roleValue)?.label ?? "unknown" 34 | }`, 35 | ); 36 | } 37 | 38 | @Slash({ description: "roles menu", name: "my_roles" }) 39 | async myRoles(interaction: CommandInteraction): Promise { 40 | await interaction.deferReply(); 41 | 42 | // create menu for roles 43 | const menu = new StringSelectMenuBuilder() 44 | .addOptions(roles) 45 | .setCustomId("role-menu"); 46 | 47 | // create a row for message actions 48 | const buttonRow = 49 | new ActionRowBuilder().addComponents( 50 | menu, 51 | ); 52 | 53 | // send it 54 | await interaction.editReply({ 55 | components: [buttonRow], 56 | content: "select your role!", 57 | }); 58 | return; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discordx", 3 | "version": "0.0.0", 4 | "private": true, 5 | "packageManager": "pnpm@10.17.0+sha512.fce8a3dd29a4ed2ec566fb53efbb04d8c44a0f05bc6f24a73046910fb9c3ce7afa35a0980500668fa3573345bd644644fa98338fa168235c80f4aa17aa17fbef", 6 | "description": "Create a discord bot with TypeScript and Decorators!", 7 | "keywords": [ 8 | "typescript", 9 | "discord", 10 | "bot", 11 | "client", 12 | "api", 13 | "library", 14 | "framework", 15 | "tool", 16 | "decorators" 17 | ], 18 | "homepage": "https://discordx.js.org", 19 | "bugs": { 20 | "url": "https://github.com/discordx-ts/templates/issue", 21 | "email": "vijayymmeena@gmail.com" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/discordx-ts/templates" 26 | }, 27 | "license": "Apache-2.0", 28 | "contributors": [ 29 | "Vijay Meena (https://github.com/vijayymmeena)" 30 | ], 31 | "scripts": { 32 | "build": "turbo run build --parallel", 33 | "format": "prettier --write .", 34 | "prettier": "prettier --check .", 35 | "lint": "eslint .", 36 | "prepare": "is-ci || husky install", 37 | "test": "turbo run test --parallel" 38 | }, 39 | "devDependencies": { 40 | "@commitlint/cli": "^19.8.1", 41 | "@commitlint/config-angular": "^19.8.1", 42 | "@eslint/js": "^9.35.0", 43 | "@ianvs/prettier-plugin-sort-imports": "^4.7.0", 44 | "eslint": "^9.35.0", 45 | "eslint-config-prettier": "^10.1.8", 46 | "eslint-plugin-prettier": "^5.5.4", 47 | "husky": "^9.1.7", 48 | "is-ci": "^4.1.0", 49 | "prettier": "^3.6.2", 50 | "turbo": "^2.5.6", 51 | "typescript": "5.9.2", 52 | "typescript-eslint": "^8.43.0" 53 | }, 54 | "engines": { 55 | "node": ">=16.0.0", 56 | "npm": ">=7.0.0" 57 | }, 58 | "publishConfig": { 59 | "access": "restricted" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /1-starter/src/commands/slash group.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApplicationCommandOptionType, 3 | type CommandInteraction, 4 | } from "discord.js"; 5 | import { Discord, Slash, SlashGroup, SlashOption } from "discordx"; 6 | 7 | @Discord() 8 | @SlashGroup({ description: "testing", name: "testing" }) 9 | @SlashGroup({ description: "maths", name: "maths", root: "testing" }) 10 | export class GroupExample { 11 | @Slash({ description: "add" }) 12 | @SlashGroup("maths", "testing") 13 | async add( 14 | @SlashOption({ 15 | description: "x value", 16 | name: "x", 17 | required: true, 18 | type: ApplicationCommandOptionType.Number, 19 | }) 20 | x: number, 21 | @SlashOption({ 22 | description: "y value", 23 | name: "y", 24 | required: true, 25 | type: ApplicationCommandOptionType.Number, 26 | }) 27 | y: number, 28 | interaction: CommandInteraction, 29 | ): Promise { 30 | await interaction.reply(String(x + y)); 31 | } 32 | 33 | @Slash({ description: "multiply" }) 34 | @SlashGroup("maths", "testing") 35 | async multiply( 36 | @SlashOption({ 37 | description: "x value", 38 | name: "x", 39 | required: true, 40 | type: ApplicationCommandOptionType.Number, 41 | }) 42 | x: number, 43 | @SlashOption({ 44 | description: "y value", 45 | name: "y", 46 | required: true, 47 | type: ApplicationCommandOptionType.Number, 48 | }) 49 | y: number, 50 | interaction: CommandInteraction, 51 | ): Promise { 52 | await interaction.reply(String(x * y)); 53 | } 54 | 55 | @Slash({ description: "root" }) 56 | @SlashGroup("testing") 57 | async root( 58 | @SlashOption({ 59 | description: "text", 60 | name: "text", 61 | required: true, 62 | type: ApplicationCommandOptionType.String, 63 | }) 64 | text: string, 65 | interaction: CommandInteraction, 66 | ): Promise { 67 | await interaction.reply(text); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /2-blank/src/main.ts: -------------------------------------------------------------------------------- 1 | import { dirname, importx } from "@discordx/importer"; 2 | import { IntentsBitField, type Interaction, type Message } from "discord.js"; 3 | import { Client } from "discordx"; 4 | 5 | export const bot = new Client({ 6 | // To use only guild command 7 | // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], 8 | 9 | // Discord intents 10 | intents: [ 11 | IntentsBitField.Flags.Guilds, 12 | IntentsBitField.Flags.GuildMembers, 13 | IntentsBitField.Flags.GuildMessages, 14 | IntentsBitField.Flags.GuildMessageReactions, 15 | IntentsBitField.Flags.GuildVoiceStates, 16 | ], 17 | 18 | // Debug logs are disabled in silent mode 19 | silent: false, 20 | 21 | // Configuration for @SimpleCommand 22 | simpleCommand: { 23 | prefix: "!", 24 | }, 25 | }); 26 | 27 | bot.once("ready", () => { 28 | // Make sure all guilds are cached 29 | // await bot.guilds.fetch(); 30 | 31 | // Synchronize applications commands with Discord 32 | void bot.initApplicationCommands(); 33 | 34 | // To clear all guild commands, uncomment this line, 35 | // This is useful when moving from guild commands to global commands 36 | // It must only be executed once 37 | // 38 | // await bot.clearApplicationCommands( 39 | // ...bot.guilds.cache.map((g) => g.id) 40 | // ); 41 | 42 | console.log("Bot started"); 43 | }); 44 | 45 | bot.on("interactionCreate", (interaction: Interaction) => { 46 | bot.executeInteraction(interaction); 47 | }); 48 | 49 | bot.on("messageCreate", (message: Message) => { 50 | void bot.executeCommand(message); 51 | }); 52 | 53 | async function run() { 54 | // The following syntax should be used in the commonjs environment 55 | // 56 | // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); 57 | 58 | // The following syntax should be used in the ECMAScript environment 59 | await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); 60 | 61 | // Let's start the bot 62 | if (!process.env.BOT_TOKEN) { 63 | throw Error("Could not find BOT_TOKEN in your environment"); 64 | } 65 | 66 | // Log in with your bot token 67 | await bot.login(process.env.BOT_TOKEN); 68 | } 69 | 70 | void run(); 71 | -------------------------------------------------------------------------------- /1-starter/src/main.ts: -------------------------------------------------------------------------------- 1 | import { dirname, importx } from "@discordx/importer"; 2 | import { IntentsBitField, type Interaction, type Message } from "discord.js"; 3 | import { Client } from "discordx"; 4 | 5 | export const bot = new Client({ 6 | // To use only guild command 7 | // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], 8 | 9 | // Discord intents 10 | intents: [ 11 | IntentsBitField.Flags.Guilds, 12 | IntentsBitField.Flags.GuildMembers, 13 | IntentsBitField.Flags.GuildMessages, 14 | IntentsBitField.Flags.GuildMessageReactions, 15 | IntentsBitField.Flags.GuildVoiceStates, 16 | IntentsBitField.Flags.MessageContent, 17 | ], 18 | 19 | // Debug logs are disabled in silent mode 20 | silent: false, 21 | 22 | // Configuration for @SimpleCommand 23 | simpleCommand: { 24 | prefix: "!", 25 | }, 26 | }); 27 | 28 | bot.once("ready", () => { 29 | // Make sure all guilds are cached 30 | // await bot.guilds.fetch(); 31 | 32 | // Synchronize applications commands with Discord 33 | void bot.initApplicationCommands(); 34 | 35 | // To clear all guild commands, uncomment this line, 36 | // This is useful when moving from guild commands to global commands 37 | // It must only be executed once 38 | // 39 | // await bot.clearApplicationCommands( 40 | // ...bot.guilds.cache.map((g) => g.id) 41 | // ); 42 | 43 | console.log("Bot started"); 44 | }); 45 | 46 | bot.on("interactionCreate", (interaction: Interaction) => { 47 | bot.executeInteraction(interaction); 48 | }); 49 | 50 | bot.on("messageCreate", (message: Message) => { 51 | void bot.executeCommand(message); 52 | }); 53 | 54 | async function run() { 55 | // The following syntax should be used in the commonjs environment 56 | // 57 | // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); 58 | 59 | // The following syntax should be used in the ECMAScript environment 60 | await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); 61 | 62 | // Let's start the bot 63 | if (!process.env.BOT_TOKEN) { 64 | throw Error("Could not find BOT_TOKEN in your environment"); 65 | } 66 | 67 | // Log in with your bot token 68 | await bot.login(process.env.BOT_TOKEN); 69 | } 70 | 71 | void run(); 72 | -------------------------------------------------------------------------------- /4-music-player-ytdl/src/main.ts: -------------------------------------------------------------------------------- 1 | import "@discordx/plugin-ytdl-player"; 2 | 3 | import { dirname, importx } from "@discordx/importer"; 4 | import { IntentsBitField, type Interaction, type Message } from "discord.js"; 5 | import { Client } from "discordx"; 6 | 7 | export const bot = new Client({ 8 | // To use only guild command 9 | // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], 10 | 11 | // Discord intents 12 | intents: [ 13 | IntentsBitField.Flags.Guilds, 14 | IntentsBitField.Flags.GuildMembers, 15 | IntentsBitField.Flags.GuildMessages, 16 | IntentsBitField.Flags.GuildMessageReactions, 17 | IntentsBitField.Flags.GuildVoiceStates, 18 | ], 19 | 20 | // Debug logs are disabled in silent mode 21 | silent: false, 22 | 23 | // Configuration for @SimpleCommand 24 | simpleCommand: { 25 | prefix: "!", 26 | }, 27 | }); 28 | 29 | bot.once("ready", () => { 30 | // Make sure all guilds are cached 31 | // await bot.guilds.fetch(); 32 | 33 | // Synchronize applications commands with Discord 34 | void bot.initApplicationCommands(); 35 | 36 | // To clear all guild commands, uncomment this line, 37 | // This is useful when moving from guild commands to global commands 38 | // It must only be executed once 39 | // 40 | // await bot.clearApplicationCommands( 41 | // ...bot.guilds.cache.map((g) => g.id) 42 | // ); 43 | 44 | console.log("Bot started"); 45 | }); 46 | 47 | bot.on("interactionCreate", (interaction: Interaction) => { 48 | bot.executeInteraction(interaction); 49 | }); 50 | 51 | bot.on("messageCreate", (message: Message) => { 52 | void bot.executeCommand(message); 53 | }); 54 | 55 | async function run() { 56 | // The following syntax should be used in the commonjs environment 57 | // 58 | // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); 59 | 60 | // The following syntax should be used in the ECMAScript environment 61 | await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); 62 | 63 | // Let's start the bot 64 | if (!process.env.BOT_TOKEN) { 65 | throw Error("Could not find BOT_TOKEN in your environment"); 66 | } 67 | 68 | // Log in with your bot token 69 | await bot.login(process.env.BOT_TOKEN); 70 | } 71 | 72 | void run(); 73 | -------------------------------------------------------------------------------- /5-music-player-lavalink/src/main.ts: -------------------------------------------------------------------------------- 1 | import "@discordx/plugin-lava-player"; 2 | 3 | import { dirname, importx } from "@discordx/importer"; 4 | import { IntentsBitField, type Interaction, type Message } from "discord.js"; 5 | import { Client } from "discordx"; 6 | 7 | export const bot = new Client({ 8 | // To use only guild command 9 | // botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)], 10 | 11 | // Discord intents 12 | intents: [ 13 | IntentsBitField.Flags.Guilds, 14 | IntentsBitField.Flags.GuildMembers, 15 | IntentsBitField.Flags.GuildMessages, 16 | IntentsBitField.Flags.GuildMessageReactions, 17 | IntentsBitField.Flags.GuildVoiceStates, 18 | ], 19 | 20 | // Debug logs are disabled in silent mode 21 | silent: false, 22 | 23 | // Configuration for @SimpleCommand 24 | simpleCommand: { 25 | prefix: "!", 26 | }, 27 | }); 28 | 29 | bot.once("ready", () => { 30 | // Make sure all guilds are cached 31 | // await bot.guilds.fetch(); 32 | 33 | // Synchronize applications commands with Discord 34 | void bot.initApplicationCommands(); 35 | 36 | // To clear all guild commands, uncomment this line, 37 | // This is useful when moving from guild commands to global commands 38 | // It must only be executed once 39 | // 40 | // await bot.clearApplicationCommands( 41 | // ...bot.guilds.cache.map((g) => g.id) 42 | // ); 43 | 44 | console.log("Bot started"); 45 | }); 46 | 47 | bot.on("interactionCreate", (interaction: Interaction) => { 48 | bot.executeInteraction(interaction); 49 | }); 50 | 51 | bot.on("messageCreate", (message: Message) => { 52 | void bot.executeCommand(message); 53 | }); 54 | 55 | async function run() { 56 | // The following syntax should be used in the commonjs environment 57 | // 58 | // await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); 59 | 60 | // The following syntax should be used in the ECMAScript environment 61 | await importx(`${dirname(import.meta.url)}/{events,commands}/**/*.{ts,js}`); 62 | 63 | // Let's start the bot 64 | if (!process.env.BOT_TOKEN) { 65 | throw Error("Could not find BOT_TOKEN in your environment"); 66 | } 67 | 68 | // Log in with your bot token 69 | await bot.login(process.env.BOT_TOKEN); 70 | } 71 | 72 | void run(); 73 | -------------------------------------------------------------------------------- /3-hot-module-reload/src/dev.ts: -------------------------------------------------------------------------------- 1 | import { dirname, resolve } from "@discordx/importer"; 2 | import chokidar from "chokidar"; 3 | import { DIService, MetadataStorage } from "discordx"; 4 | 5 | import { bot } from "./bot.js"; 6 | 7 | // The following syntax should be used in the commonjs environment 8 | // const importPattern = __dirname + "/{events,commands}/**/*.{ts,js}" 9 | 10 | // The following syntax should be used in the ECMAScript environment 11 | const importPattern = `${dirname( 12 | import.meta.url, 13 | )}/{events,commands}/**/*.{ts,js}`; 14 | 15 | /** 16 | * Import files 17 | * 18 | * (This is a work around for imports, if it is possible to delete cache from ESM, let me know.) 19 | * 20 | * @param src glob pattern 21 | */ 22 | export async function LoadFiles(src: string): Promise { 23 | const files = await resolve(src); 24 | await Promise.all( 25 | files.map((file) => import(`${file}?version=${Date.now().toString()}`)), 26 | ); 27 | } 28 | 29 | /** 30 | * Reload commands for discordx 31 | */ 32 | async function Reload() { 33 | console.log("> Reloading modules\n"); 34 | 35 | // Remove events 36 | bot.removeEvents(); 37 | 38 | // cleanup 39 | MetadataStorage.clear(); 40 | DIService.engine.clearAllServices(); 41 | 42 | // reload files 43 | await LoadFiles(importPattern); 44 | 45 | // rebuild 46 | await MetadataStorage.instance.build(); 47 | await bot.initApplicationCommands(); 48 | bot.initEvents(); 49 | 50 | console.log("> Reload success\n"); 51 | } 52 | 53 | /** 54 | * Initialize 55 | */ 56 | async function run() { 57 | const watcher = chokidar.watch(importPattern); 58 | 59 | // Load commands 60 | await LoadFiles(importPattern); 61 | 62 | // Let's start the bot 63 | if (!process.env.BOT_TOKEN) { 64 | throw Error("Could not find BOT_TOKEN in your environment"); 65 | } 66 | 67 | // Log in with your bot token 68 | await bot.login(process.env.BOT_TOKEN); 69 | 70 | // Hot Module reload 71 | if (process.env.NODE_ENV !== "production") { 72 | console.log( 73 | "> Hot-Module-Reload enabled in development. Commands will automatically reload.", 74 | ); 75 | 76 | // Watch changed files using chikidar 77 | watcher.on("add", () => void Reload()); 78 | watcher.on("change", () => void Reload()); 79 | watcher.on("unlink", () => void Reload()); 80 | } 81 | } 82 | 83 | void run(); 84 | -------------------------------------------------------------------------------- /1-starter/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | A starter template equipped with several interaction commands and one event. 42 | 43 | # 🏗 Development 44 | 45 | ``` 46 | npm install 47 | npm run dev 48 | ``` 49 | 50 | If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: 51 | 52 | ``` 53 | npm run watch 54 | ``` 55 | 56 | # 💻 Production 57 | 58 | ``` 59 | npm install --production 60 | npm run build 61 | npm run start 62 | ``` 63 | 64 | # 🐋 Docker 65 | 66 | To start your application: 67 | 68 | ``` 69 | docker-compose up -d 70 | ``` 71 | 72 | To shut down your application: 73 | 74 | ``` 75 | docker-compose down 76 | ``` 77 | 78 | To view your application's logs: 79 | 80 | ``` 81 | docker-compose logs 82 | ``` 83 | 84 | For the full command list please view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). 85 | 86 | # 📜 Documentation 87 | 88 | - [discordx.js.org](https://discordx.js.org) 89 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 90 | 91 | # ☎️ Need help? 92 | 93 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 94 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 95 | - Ask in the community [Discord server](https://discordx.js.org/discord) 96 | 97 | # 💖 Thank you 98 | 99 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 100 | -------------------------------------------------------------------------------- /4-music-player-ytdl/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | A music template using YTDL (YouTube-Download), equipped with a few music-related commands. 42 | 43 | # 🏗 Development 44 | 45 | ``` 46 | npm install 47 | npm run dev 48 | ``` 49 | 50 | If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: 51 | 52 | ``` 53 | npm run watch 54 | ``` 55 | 56 | # 💻 Production 57 | 58 | ``` 59 | npm install --production 60 | npm run build 61 | npm run start 62 | ``` 63 | 64 | # 🐋 Docker 65 | 66 | To start your application: 67 | 68 | ``` 69 | docker-compose up -d 70 | ``` 71 | 72 | To shut down your application: 73 | 74 | ``` 75 | docker-compose down 76 | ``` 77 | 78 | To view your application's logs: 79 | 80 | ``` 81 | docker-compose logs 82 | ``` 83 | 84 | For the full command list please view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). 85 | 86 | # 📜 Documentation 87 | 88 | - [discordx.js.org](https://discordx.js.org) 89 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 90 | 91 | # ☎️ Need help? 92 | 93 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 94 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 95 | - Ask in the community [Discord server](https://discordx.js.org/discord) 96 | 97 | # 💖 Thank you 98 | 99 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 100 | -------------------------------------------------------------------------------- /2-blank/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | A blank template with one command and one event, This is a useful template if you want to quickly spin up a project. 42 | 43 | # 🏗 Development 44 | 45 | ``` 46 | npm install 47 | npm run dev 48 | ``` 49 | 50 | If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: 51 | 52 | ``` 53 | npm run watch 54 | ``` 55 | 56 | # 💻 Production 57 | 58 | ``` 59 | npm install --production 60 | npm run build 61 | npm run start 62 | ``` 63 | 64 | # 🐋 Docker 65 | 66 | To start your application: 67 | 68 | ``` 69 | docker-compose up -d 70 | ``` 71 | 72 | To shut down your application: 73 | 74 | ``` 75 | docker-compose down 76 | ``` 77 | 78 | To view your application's logs: 79 | 80 | ``` 81 | docker-compose logs 82 | ``` 83 | 84 | For the full command list please view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). 85 | 86 | # 📜 Documentation 87 | 88 | - [discordx.js.org](https://discordx.js.org) 89 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 90 | 91 | # ☎️ Need help? 92 | 93 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 94 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 95 | - Ask in the community [Discord server](https://discordx.js.org/discord) 96 | 97 | # 💖 Thank you 98 | 99 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 100 | -------------------------------------------------------------------------------- /5-music-player-lavalink/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | A music template using Lavalink, equipped with a few music-related commands. 42 | 43 | # 🏗 Development 44 | 45 | ``` 46 | npm install 47 | npm run dev 48 | ``` 49 | 50 | If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: 51 | 52 | ``` 53 | npm run watch 54 | ``` 55 | 56 | # 💻 Production 57 | 58 | ``` 59 | npm install --production 60 | npm run build 61 | npm run start 62 | ``` 63 | 64 | # 🐋 Docker 65 | 66 | To start your application: 67 | 68 | ``` 69 | docker-compose up -d 70 | ``` 71 | 72 | To shut down your application: 73 | 74 | ``` 75 | docker-compose down 76 | ``` 77 | 78 | To view your application's logs: 79 | 80 | ``` 81 | docker-compose logs 82 | ``` 83 | 84 | For the full command list along with how to properly utilize Docker view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). 85 | 86 | # 📜 Documentation 87 | 88 | - [discordx.js.org](https://discordx.js.org) 89 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 90 | 91 | # ☎️ Need help? 92 | 93 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 94 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 95 | - Ask in the community [Discord server](https://discordx.js.org/discord) 96 | 97 | # 💖 Thank you 98 | 99 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 100 | -------------------------------------------------------------------------------- /3-hot-module-reload/README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | A blank template with one command and one event, This is a useful template if you want to quickly spin up a project. 42 | 43 | # 🏗 Development 44 | 45 | ``` 46 | npm install 47 | npm run dev 48 | ``` 49 | 50 | If you want to use [Nodemon](https://nodemon.io/) to auto-reload while in development: 51 | 52 | ``` 53 | npm run watch 54 | ``` 55 | 56 | # 💻 Production 57 | 58 | ``` 59 | npm install --production 60 | npm run build 61 | npm run start 62 | ``` 63 | 64 | # 🐋 Docker 65 | 66 | To start your application: 67 | 68 | ``` 69 | docker-compose up -d 70 | ``` 71 | 72 | To shut down your application: 73 | 74 | ``` 75 | docker-compose down 76 | ``` 77 | 78 | To view your application's logs: 79 | 80 | ``` 81 | docker-compose logs 82 | ``` 83 | 84 | For the full command list please view the [Docker Documentation](https://docs.docker.com/engine/reference/commandline/cli/). 85 | 86 | # 📜 Documentation 87 | 88 | - [discordx.js.org](https://discordx.js.org) 89 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 90 | 91 | # ☎️ Need help? 92 | 93 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 94 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 95 | - Ask in the community [Discord server](https://discordx.js.org/discord) 96 | 97 | # 💖 Thank you 98 | 99 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | 4 | 5 | 6 |

7 |

8 | Discord server 13 | NPM version 18 | NPM downloads 23 | Build status 28 | paypal 33 |

34 |

35 | Create a discord bot with TypeScript and Decorators! 36 |

37 |
38 | 39 | # 📖 Introduction 40 | 41 | This repository contains all the starter bot templates used by [create-discordx](https://www.npmjs.com/package/create-discordx), To get started using one of these templates simply run the following command: 42 | 43 | ``` 44 | npx create-discordx 45 | ``` 46 | 47 | # 🗂 Templates 48 | 49 | | Template | From | 50 | | ---------------------------------------------------- | ------------------------------------------------ | 51 | | [1-starter](./1-starter) | [@vijayymmeena](https://github.com/vijayymmeena) | 52 | | [2-blank](./2-blank) | [@vijayymmeena](https://github.com/vijayymmeena) | 53 | | [3-hot-module-reload](./3-hot-module-reload) | [@vijayymmeena](https://github.com/vijayymmeena) | 54 | | [4-music-player-ytdl](./4-music-player-ytdl) | [@vijayymmeena](https://github.com/vijayymmeena) | 55 | | [5-music-player-lavalink](./5-music-player-lavalink) | [@vijayymmeena](https://github.com/vijayymmeena) | 56 | 57 | # 📜 Documentation 58 | 59 | - [discordx.js.org](https://discordx.js.org) 60 | - [Tutorials (dev.to)](https://dev.to/vijayymmeena/series/14317) 61 | 62 | # ☎️ Need help? 63 | 64 | - [Check frequently asked questions](https://discordx.js.org/docs/faq) 65 | - [Check examples](https://github.com/discordx-ts/discordx/tree/main/packages/discordx/examples) 66 | - Ask in the community [Discord server](https://discordx.js.org/discord) 67 | 68 | # 💖 Thank you 69 | 70 | You can support [discordx](https://www.npmjs.com/package/discordx) by giving it a [GitHub](https://github.com/discordx-ts/discordx) star. 71 | -------------------------------------------------------------------------------- /5-music-player-lavalink/application.yml: -------------------------------------------------------------------------------- 1 | server: # REST and WS server 2 | port: 2333 3 | address: 0.0.0.0 4 | http2: 5 | enabled: false # Whether to enable HTTP/2 support 6 | plugins: 7 | youtube: 8 | enabled: true # Whether this source can be used. 9 | allowSearch: true # Whether "ytsearch:" and "ytmsearch:" can be used. 10 | allowDirectVideoIds: true # Whether just video IDs can match. If false, only complete URLs will be loaded. 11 | allowDirectPlaylistIds: true # Whether just playlist IDs can match. If false, only complete URLs will be loaded. 12 | # The clients to use for track loading. See below for a list of valid clients. 13 | # Clients are queried in the order they are given (so the first client is queried first and so on...) 14 | clients: 15 | - MUSIC 16 | - ANDROID 17 | - WEB 18 | # You can configure individual clients with the following. 19 | # Any options or clients left unspecified will use their default values, 20 | # which enables everything for all clients. 21 | WEB: # names are specified as they are written below under "Available Clients". 22 | # This will disable using the WEB client for video playback. 23 | playback: false 24 | TVHTML5EMBEDDED: 25 | # The below config disables everything except playback for this client. 26 | playlistLoading: false # Disables loading of playlists and mixes for this client. 27 | videoLoading: false # Disables loading of videos for this client (playback is still allowed). 28 | searching: false # Disables the ability to search for videos for this client. 29 | # name: # Name of the plugin 30 | # some_key: some_value # Some key-value pair for the plugin 31 | # another_key: another_value 32 | lavalink: 33 | plugins: 34 | - dependency: "dev.lavalink.youtube:youtube-plugin:1.3.0" 35 | snapshot: false # Set to true if you want to use a snapshot version. 36 | # - dependency: "com.github.example:example-plugin:1.0.0" # required, the coordinates of your plugin 37 | # repository: "https://maven.example.com/releases" # optional, defaults to the Lavalink releases repository by default 38 | # snapshot: false # optional, defaults to false, used to tell Lavalink to use the snapshot repository instead of the release repository 39 | # pluginsDir: "./plugins" # optional, defaults to "./plugins" 40 | # defaultPluginRepository: "https://maven.lavalink.dev/releases" # optional, defaults to the Lavalink release repository 41 | # defaultPluginSnapshotRepository: "https://maven.lavalink.dev/snapshots" # optional, defaults to the Lavalink snapshot repository 42 | 43 | server: 44 | password: "youshallnotpass" 45 | sources: 46 | # The default Youtube source is now deprecated and won't receive further updates. Please use https://github.com/lavalink-devs/youtube-source#plugin instead. 47 | youtube: false 48 | bandcamp: true 49 | soundcloud: true 50 | twitch: true 51 | vimeo: true 52 | nico: true 53 | http: true # warning: keeping HTTP enabled without a proxy configured could expose your server's IP address. 54 | local: false 55 | filters: # All filters are enabled by default 56 | volume: true 57 | equalizer: true 58 | karaoke: true 59 | timescale: true 60 | tremolo: true 61 | vibrato: true 62 | distortion: true 63 | rotation: true 64 | channelMix: true 65 | lowPass: true 66 | bufferDurationMs: 400 # The duration of the NAS buffer. Higher values fare better against longer GC pauses. Duration <= 0 to disable JDA-NAS. Minimum of 40ms, lower values may introduce pauses. 67 | frameBufferDurationMs: 5000 # How many milliseconds of audio to keep buffered 68 | opusEncodingQuality: 10 # Opus encoder quality. Valid values range from 0 to 10, where 10 is best quality but is the most expensive on the CPU. 69 | resamplingQuality: LOW # Quality of resampling operations. Valid values are LOW, MEDIUM and HIGH, where HIGH uses the most CPU. 70 | trackStuckThresholdMs: 10000 # The threshold for how long a track can be stuck. A track is stuck if does not return any audio data. 71 | useSeekGhosting: true # Seek ghosting is the effect where whilst a seek is in progress, the audio buffer is read from until empty, or until seek is ready. 72 | youtubePlaylistLoadLimit: 6 # Number of pages at 100 each 73 | playerUpdateInterval: 5 # How frequently to send player updates to clients, in seconds 74 | youtubeSearchEnabled: true 75 | soundcloudSearchEnabled: true 76 | gc-warnings: true 77 | #ratelimit: 78 | #ipBlocks: ["1.0.0.0/8", "..."] # list of ip blocks 79 | #excludedIps: ["...", "..."] # ips which should be explicit excluded from usage by lavalink 80 | #strategy: "RotateOnBan" # RotateOnBan | LoadBalance | NanoSwitch | RotatingNanoSwitch 81 | #searchTriggersFail: true # Whether a search 429 should trigger marking the ip as failing 82 | #retryLimit: -1 # -1 = use default lavaplayer value | 0 = infinity | >0 = retry will happen this numbers times 83 | #youtubeConfig: # Required for avoiding all age restrictions by YouTube, some restricted videos still can be played without. 84 | #email: "" # Email of Google account 85 | #password: "" # Password of Google account 86 | #httpConfig: # Useful for blocking bad-actors from ip-grabbing your music node and attacking it, this way only the http proxy will be attacked 87 | #proxyHost: "localhost" # Hostname of the proxy, (ip or domain) 88 | #proxyPort: 3128 # Proxy port, 3128 is the default for squidProxy 89 | #proxyUser: "" # Optional user for basic authentication fields, leave blank if you don't use basic auth 90 | #proxyPassword: "" # Password for basic authentication 91 | 92 | metrics: 93 | prometheus: 94 | enabled: false 95 | endpoint: /metrics 96 | 97 | sentry: 98 | dsn: "" 99 | environment: "" 100 | # tags: 101 | # some_key: some_value 102 | # another_key: another_value 103 | 104 | logging: 105 | file: 106 | path: ./logs/ 107 | 108 | level: 109 | root: INFO 110 | lavalink: INFO 111 | 112 | request: 113 | enabled: true 114 | includeClientInfo: true 115 | includeHeaders: false 116 | includeQueryString: true 117 | includePayload: true 118 | maxPayloadLength: 10000 119 | 120 | logback: 121 | rollingpolicy: 122 | max-file-size: 1GB 123 | max-history: 30 124 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2022 Vijay Meena 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. -------------------------------------------------------------------------------- /4-music-player-ytdl/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2022 Vijay Meena 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. --------------------------------------------------------------------------------