├── .gitignore ├── README.md ├── package.json ├── src ├── Client │ └── index.ts ├── Commands │ └── ping.ts ├── Events │ └── ready.ts ├── Interfaces │ ├── Commands.ts │ ├── Config.ts │ ├── Events.ts │ └── index.ts ├── Models │ ├── Example.ts │ └── index.ts ├── Utils │ ├── Presence.ts │ └── index.ts ├── config.json └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

Discord.js with TypeScript

3 |
Developed with 🖤 by Swôth
4 |
5 | 6 | # 📜 Usage 7 | > Install packages: \ 8 | > $ `npm install` 9 | > 10 | > Development mode: \ 11 | > $ `npm run dev` 12 | > 13 | > Production mode: \ 14 | > $ `npm run start` 15 | > 16 | > for JS output: \ 17 | > $ `npx tsc` 18 | 19 | # ⭐ Star 20 | > Don't forget to star if you like it. 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts-bot", 3 | "version": "1.0.0", 4 | "description": "Bot", 5 | "main": "src/index.ts", 6 | "scripts": { 7 | "start": "ts-node ./src/index.ts", 8 | "dev": "ts-node-dev --respawn --transpile-only --poll ./src/index.ts" 9 | }, 10 | "author": "Swôth", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "ts-node": "^10.7.0", 14 | "ts-node-dev": "^1.1.8", 15 | "typescript": "^4.6.2" 16 | }, 17 | "dependencies": { 18 | "@discordjs/rest": "^0.3.0", 19 | "discord-api-types": "^0.26.1", 20 | "discord.js": "^13.6.0", 21 | "mongoose": "^6.2.6" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Client/index.ts: -------------------------------------------------------------------------------- 1 | import { Config, Commands, Events } from '../Interfaces'; 2 | import { Client, Collection } from 'discord.js'; 3 | import { Routes } from 'discord-api-types/v9'; 4 | import configFile from '../config.json'; 5 | import { REST } from '@discordjs/rest'; 6 | import { connect } from 'mongoose'; 7 | import path from 'path'; 8 | import fs from 'fs'; 9 | 10 | export default class Bot extends Client { 11 | public commands: Collection = new Collection(); 12 | public events: Collection = new Collection(); 13 | public config: Config = configFile; 14 | 15 | public async init() { 16 | const rest = new REST({ version: "9" }) 17 | .setToken(this.config.bot.token); 18 | 19 | this.login(this.config.bot.token).then(() => { 20 | console.log(`(*) Connected to Discord as ${this.user.username}!`); 21 | }).catch((err: Error) => { 22 | console.error(err); 23 | process.exit(1); 24 | }); 25 | 26 | connect(this.config.database.url).then(async () => { 27 | console.log('(*) Connected to database!'); 28 | }).catch((err: Error) => { 29 | console.error(err); 30 | process.exit(1); 31 | }); 32 | 33 | fs.readdir(path.join(__dirname, '../Commands'), (err, commands: string[]) => { 34 | if (err) throw new Error(err.message); 35 | commands 36 | .filter((command: string) => command.endsWith('.ts')) 37 | .forEach(async (command: string) => { 38 | try { 39 | const { Command }: { Command: Commands } = await import(`../Commands/${command}`); 40 | this.commands.set(Command.name, Command); 41 | } catch(err) { 42 | console.error(err); 43 | }; 44 | }); 45 | }); 46 | 47 | fs.readdir(path.join(__dirname, '../Events'), (err, events: string[]) => { 48 | if (err) throw new Error(err.message); 49 | events 50 | .filter((event: string) => event.endsWith('.ts')) 51 | .forEach(async (event: string) => { 52 | try { 53 | const { Event }: { Event: Events } = await import(`../Events/${event}`); 54 | this.events.set(Event.name, Event); 55 | this[Event.type](Event.name, Event.run.bind(null, this)); 56 | } catch(err) { 57 | console.error(err); 58 | }; 59 | }); 60 | }); 61 | 62 | this.once('ready', async () => { 63 | try { 64 | console.log('(*) Started loading application [/] commands...'); 65 | await rest.put(Routes.applicationCommands(this.user.id), { body: this.commands.toJSON() }); 66 | console.log(`(*) Successfully loaded application [${this.commands.size}] commands!`); 67 | } catch(err) { 68 | console.error(err); 69 | }; 70 | }); 71 | 72 | this.on('interactionCreate', async interaction => { 73 | try { 74 | if (!interaction.isCommand()) return; 75 | const command = this.commands.find(cmd => cmd.name == interaction.commandName); 76 | if (!command) return; 77 | command.run(this, interaction); 78 | } catch(err) { 79 | console.error(err); 80 | }; 81 | }); 82 | }; 83 | }; -------------------------------------------------------------------------------- /src/Commands/ping.ts: -------------------------------------------------------------------------------- 1 | import { MessageEmbed } from 'discord.js'; 2 | import { Commands } from '../Interfaces'; 3 | 4 | export const Command: Commands = { 5 | name: 'ping', 6 | description: 'Pong.', 7 | options: [], 8 | run: async (client, interaction) => { 9 | await interaction.reply({ 10 | embeds: [ 11 | new MessageEmbed() 12 | .setColor('#FFFFFF') 13 | .setDescription(`${client.user.username} ~~-->~~ ${client.ws.ping}ms`) 14 | ] 15 | }); 16 | } 17 | }; -------------------------------------------------------------------------------- /src/Events/ready.ts: -------------------------------------------------------------------------------- 1 | import { Presence } from '../Utils'; 2 | import { Events } from '../Interfaces' 3 | 4 | export const Event: Events = { 5 | name: 'ready', 6 | type: 'once', 7 | run: async client => { 8 | Presence(client); 9 | } 10 | }; -------------------------------------------------------------------------------- /src/Interfaces/Commands.ts: -------------------------------------------------------------------------------- 1 | import { CommandInteraction } from 'discord.js'; 2 | import Client from '../Client'; 3 | 4 | interface Options { 5 | type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; 6 | name: string; 7 | description: string; 8 | required?: boolean; 9 | options?: Options[]; 10 | }; 11 | 12 | export interface Commands { 13 | name: string; 14 | description: string; 15 | options?: Options[], 16 | run: (client: Client, interaction: CommandInteraction) => Promise | any; 17 | }; -------------------------------------------------------------------------------- /src/Interfaces/Config.ts: -------------------------------------------------------------------------------- 1 | export interface Config { 2 | bot: { 3 | token: string; 4 | owners: string[]; 5 | }; 6 | database: { 7 | url: string; 8 | }; 9 | }; -------------------------------------------------------------------------------- /src/Interfaces/Events.ts: -------------------------------------------------------------------------------- 1 | import { ClientEvents } from 'discord.js'; 2 | import Client from '../Client'; 3 | 4 | export interface Events { 5 | name: keyof ClientEvents; 6 | type: 'on' | 'once'; 7 | run: (client: Client, ...args: any) => Promise | any; 8 | }; -------------------------------------------------------------------------------- /src/Interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export { Commands } from './Commands'; 2 | export { Events } from './Events'; 3 | export { Config } from './Config'; -------------------------------------------------------------------------------- /src/Models/Example.ts: -------------------------------------------------------------------------------- 1 | import { model, Schema } from 'mongoose'; 2 | 3 | export const Example = model('example', new Schema({ 4 | lorem: { type: String, required: true }, 5 | ipsum: { type: Number, required: true } 6 | })); 7 | 8 | export interface IExample { 9 | lorem: string; 10 | ipsum: number; 11 | }; -------------------------------------------------------------------------------- /src/Models/index.ts: -------------------------------------------------------------------------------- 1 | export { Example, IExample } from './Example'; -------------------------------------------------------------------------------- /src/Utils/Presence.ts: -------------------------------------------------------------------------------- 1 | import Client from '../Client'; 2 | 3 | export function Presence(client: Client) { 4 | client.user.setActivity({ 5 | type: 'WATCHING', 6 | name: `hello!` 7 | }); 8 | }; -------------------------------------------------------------------------------- /src/Utils/index.ts: -------------------------------------------------------------------------------- 1 | export { Presence } from './Presence'; -------------------------------------------------------------------------------- /src/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bot": { 3 | "token": "discord-bot-token", 4 | "owners": [ 5 | "owner-id-one", 6 | "owner-id-two" 7 | ] 8 | }, 9 | "database": { 10 | "url": "mongodb-url" 11 | } 12 | } -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Intents } from 'discord.js'; 2 | import Client from './Client'; 3 | 4 | const client = new Client({ 5 | intents: [ 6 | Intents.FLAGS.GUILDS, 7 | Intents.FLAGS.GUILD_MEMBERS 8 | ] 9 | }); 10 | 11 | client.init(); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ "ESNext" ], 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "allowSyntheticDefaultImports": true, 7 | "target": "ESNext", 8 | "noImplicitAny": true, 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "outDir": "dist", 12 | "baseUrl": ".", 13 | "resolveJsonModule": true, 14 | "declaration": true, 15 | "skipDefaultLibCheck": true, 16 | "skipLibCheck": true, 17 | "experimentalDecorators": true, 18 | "emitDecoratorMetadata": true 19 | }, 20 | "include": [ 21 | "src/**/*" 22 | ], 23 | "exclude": [ 24 | "node_modules" 25 | ] 26 | } --------------------------------------------------------------------------------