You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
vore-rpg/src/bin/bot.ts

136 lines
4.3 KiB

import {BaseInteraction, Client} from "discord.js"
import {config} from "dotenv"
import {isAutocomplete, isChatInputCommand} from "../types/interactions.js"
import {Commands} from "../commands/index.js"
import {checkIsRestart, reportFailed, reportReady, reportStarted} from "../ipc/restart.js"
import {defaultPresence} from "../defaultPresence.js"
import {Pool} from "pg"
import {Database, DatabaseImpl} from "../database/database.js"
async function bot() {
await checkIsRestart()
config()
const c = new Client({
intents: [],
})
const p = new Pool({
application_name: "VoreRPG Bot",
})
async function cleanUp() {
await p.end()
c.destroy()
}
const db: Database = new DatabaseImpl(p.query.bind(p))
const cmd = new Commands({users: db.users, cleanUp})
c.on("ready", async () => {
try {
await db.users.createBotOwnerAsAdmin(process.env.BOT_OWNER_ID || "")
} catch (ex) {
await reportFailed(c, ex)
return
}
const app = c.application
if (!app) {
c.destroy()
await reportFailed(c, "No application was given")
return
} else {
try {
cmd.setCache(await app.commands.set(cmd.definitions))
const g = await c.guilds.fetch()
for (const guild of g.values()) {
cmd.setCache(await app.commands.set(cmd.definitions, guild.id))
}
} catch (ex) {
c.destroy()
await reportFailed(c, ex)
return
}
}
const user = c.user
if (!user) {
c.destroy()
await reportFailed(c, "No user found")
return
} else {
user.setPresence(defaultPresence)
}
try {
await reportReady(c)
} catch (ex) {
console.log(ex)
}
})
c.on("error", async (ex) => {
c.destroy()
await reportFailed(c, ex)
})
c.on("interactionCreate", async (ev: BaseInteraction) => {
if (ev.client.user.presence.status !== "online") {
if (ev.isRepliable()) {
try {
await ev.reply({
content: "Shhh... I'm sleeping!! Try again later.",
ephemeral: true,
})
} catch (ex) {
console.log("failed sending busy reply", ex)
}
}
return
}
if (isChatInputCommand(ev)) {
try {
await cmd.execute(ev)
} catch (ex) {
console.log("failed executing command", ev, ex)
}
if (!ev.replied) {
console.log("never replied to command", ev)
try {
await ev.reply({
ephemeral: true,
content: "Uuguuu... I can't think straight... try again later, 'kay?",
})
} catch (ex) {
console.log("failed sending error reply", ex)
}
}
} else if (isAutocomplete(ev)) {
try {
await cmd.autocomplete(ev)
} catch (ex) {
console.log("failed autocompleting for command", ev, ex)
}
if (!ev.responded) {
console.log("never autocompleted for command", ev)
try {
await ev.respond([])
} catch (ex) {
console.log("failed sending error response", ex)
}
}
} else if (ev.isRepliable()) {
try {
console.log("unknown command", ev)
await ev.reply({
ephemeral: true,
content: "Huuuuuuuh? ... I don't know what to do with that yet.",
})
} catch (ex) {
console.log("failed sending unknown command reply", ex)
}
} else {
console.log("got an interaction but can't reply to it")
}
})
await reportStarted()
await c.login(process.env.DISCORD_TOKEN || "")
}
bot().catch((ex) => {
console.log("main thread failed", ex)
})