Skip to content

Instantly share code, notes, and snippets.

@lylythechosenone
Last active November 22, 2021 00:40
Show Gist options
  • Save lylythechosenone/6e7deb3c281256a7d94d1ea0c010b4cc to your computer and use it in GitHub Desktop.
Save lylythechosenone/6e7deb3c281256a7d94d1ea0c010b4cc to your computer and use it in GitHub Desktop.
import { Client, Intents, Message, MessageEmbed, User } from 'discord.js'
import { readFileSync, lstatSync, readdirSync } from 'fs'
import { join, extname, resolve } from 'path'
export class Bot {
private client: Client
private commands: object = {}
constructor(token: string, commandPrefix = ",", loggedIn: (r: string) => void = () => {}) {
this.client = new Client({intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MEMBERS]})
this.reloadCommands()
this.client.on('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return
if (this.commands[interaction.commandName]) {
let command = this.commands[interaction.commandName]
if (command["reply"]) {
await interaction.reply(command["code"].run())
} else {
await interaction.channel.send(command["code"].run())
}
}
})
this.client.on('messageCreate', (msg: Message) => {
this.onMessage(msg, commandPrefix)
})
this.client.login(token).then(loggedIn)
}
private async onMessage(msg: Message, commandPrefix: string) {
if (msg.author == this.client.user) return
let msgStr = msg.content
if (msgStr.startsWith(commandPrefix)) {
let args = msgStr.replace(commandPrefix, "").split(" ")
let commandStr = args[0]
if (this.commands[commandStr]) {
let command: {code: Function, arguments: string[], permissions: string[], reply: boolean} =
this.commands[commandStr]
let member = msg.guild.members.cache.find(member => member.id === msg.author.id)
let hasPerms = true
command.permissions.forEach((value, index, array) => {
// @ts-ignore IDEA likes to complain about this line
if (!member.permissions.has(value)) {
msg.reply(`You do not have the necessary permissions to run ${commandStr}.`)
hasPerms = false
return
}
})
if (!hasPerms) return
let argsParsed: unknown[] = []
for (let i = 1; i < args.length; i++) {
if (i - 1 < command.arguments.length) {
let parsed = await this.parseToType(args[i], command["arguments"][i - 1])
if (typeof parsed === "string") {
console.log(parsed)
await msg.reply(parsed)
return
}
argsParsed[argsParsed.length] = parsed
}
}
let result = command.code(msg, argsParsed)
if (command.reply) {
if (result instanceof MessageEmbed) {
await msg.reply({embeds: [result] })
} else {
await msg.reply(result)
}
} else {
if (result instanceof MessageEmbed) {
await msg.channel.send({embeds: [result] })
} else {
await msg.channel.send(result)
}
}
}
}
}
private async parseToType<T>(thing: string, type: string): Promise<string | unknown> {
switch (type) {
case "USER":
let user: User
if (thing.match(/^[0-9]{17,}$/)) {
user = await this.client.users.fetch(thing)
} else if (thing.match(/^<@[0-9]{17,}>$/)) {
user = await this.client.users.fetch(thing.substr(2, thing.length - 3))
} else if (thing.match(/^<@![0-9]{17,}>$/)) {
user = await this.client.users.fetch(thing.substr(3, thing.length - 4))
} else if (thing.match(/^[A-z]+#[0-9]{4}$/)) {
user = await this.client.users.fetch(await this.client.users.cache.find(u => u.tag === thing).id)
} else {
return `Cannot convert ${thing} to a user.`
}
return user
}
}
reloadCommands(dir = "commands"): void {
let files: string[] = readdirSync(dir)
files.forEach(async (value, index, array) => {
if (lstatSync(join(dir, value)).isDirectory()) {
this.reloadCommands(join(dir, value))
} else if (extname(value) === ".json") {
let json = JSON.parse(readFileSync(join(dir, value)).toString())
this.commands[json["name"]] = {
code: (await import(join(resolve(dir), json["file"])))[json["name"]],
arguments: json["arguments"],
permissions: json["permissions"],
reply: json["reply"]
}
console.log(this.commands)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment