architecture besides db setup, say+roll
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.env
|
||||
node_modules
|
||||
*.js
|
||||
2
commands/error.ts
Normal file
2
commands/error.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export class BotError extends Error {};
|
||||
|
||||
78
commands/index.ts
Normal file
78
commands/index.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { EmbedBuilder } from "discord.js";
|
||||
import type { ChatInputCommandInteraction } from "discord.js";
|
||||
|
||||
import { BotError } from "./error";
|
||||
|
||||
import say from "./say";
|
||||
import roll from "./roll";
|
||||
|
||||
|
||||
export interface CommandData {
|
||||
name: string;
|
||||
description: string;
|
||||
ephemeral: boolean;
|
||||
admin_only: boolean;
|
||||
run: (interaction: ChatInputCommandInteraction) => Promise<any>;
|
||||
//
|
||||
};
|
||||
|
||||
const commands: CommandData[] = [say, roll];
|
||||
|
||||
//todo: look from config. also, have a config
|
||||
function is_admin(interaction: ChatInputCommandInteraction): boolean {
|
||||
//
|
||||
//placeholder
|
||||
return true;
|
||||
}
|
||||
|
||||
export default async function run(interaction: ChatInputCommandInteraction) {
|
||||
const name = interaction.commandName;
|
||||
|
||||
//help command is "auto-generated"
|
||||
if (name === "help") {
|
||||
//max of 25 fields per embed, so if too many commands, this section needs a rewrite
|
||||
let embeds = [];
|
||||
let help_embed = new EmbedBuilder();
|
||||
help_embed.setTitle("Help");
|
||||
for (const c of commands.filter((c) => !c.admin_only)) {
|
||||
help_embed.addFields([{
|
||||
name: `/${c.name}`,
|
||||
value: c.description,
|
||||
}]);
|
||||
}
|
||||
embeds.push(help_embed);
|
||||
if (is_admin(interaction)) {
|
||||
let admin_help_embed = new EmbedBuilder();
|
||||
admin_help_embed.setTitle("Help (admin only)");
|
||||
for (const c of commands.filter((c) => c.admin_only)) {
|
||||
admin_help_embed.addFields([{
|
||||
name: `/${c.name}`,
|
||||
value: c.description,
|
||||
}]);
|
||||
}
|
||||
embeds.push(admin_help_embed);
|
||||
}
|
||||
return await interaction.reply({ embeds, ephemeral: true });
|
||||
}
|
||||
|
||||
const found = commands.find((c) => c.name === name);
|
||||
try {
|
||||
//admin stuff should be ideally handled by register.ts, but this is a fallback
|
||||
if (found.admin_only && !is_admin(interaction)) throw new BotError("Admin permission needed to run that command");
|
||||
await found.run(interaction);
|
||||
} catch (e) {
|
||||
if (e instanceof BotError) {
|
||||
//send error message to that channel
|
||||
if (interaction.deferred) {
|
||||
return await interaction.editReply(String(e));
|
||||
} else {
|
||||
return await interaction.reply({ content: String(e), ephemeral: found.ephemeral });
|
||||
}
|
||||
} else {
|
||||
//an actual error
|
||||
//console.log(e);
|
||||
throw e; //crash it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
commands/roll.ts
Normal file
39
commands/roll.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import type { ChatInputCommandInteraction } from "discord.js";
|
||||
import { randomInt } from "crypto";
|
||||
|
||||
import type { CommandData } from "./index";
|
||||
import { BotError } from "./error";
|
||||
|
||||
const MAX_DICE: number = 100;
|
||||
const MAX_FACES: number = 9999;
|
||||
|
||||
async function run(interaction: ChatInputCommandInteraction) {
|
||||
await interaction.deferReply(); //do these options.get things need to be await?? kinda stupid
|
||||
const options = interaction.options;
|
||||
const dice_num: number = (await options.get("dice_num")).value as number;
|
||||
const dice_faces: number = (await options.get("dice_faces")).value as number;
|
||||
const show_calc: boolean = ((await options.get("show_calc"))?.value ?? true) as boolean;
|
||||
const include_zero: boolean = ((await options.get("include_zero"))?.value ?? false) as boolean;
|
||||
if (dice_num < 1) throw new BotError("Must roll at least 1 dice, obviously");
|
||||
//semi-arbitrary limits, discord messages can be max 2000 chars long
|
||||
if (dice_num > MAX_DICE) throw new BotError(`Max of ${MAX_DICE} dice`);
|
||||
if (dice_faces > 9999) throw new BotError(`Max of ${MAX_FACES} faces`);
|
||||
let rolls: number[] = [];
|
||||
for (let i = 0; i < dice_num; i++) {
|
||||
rolls.push(randomInt(include_zero ? 0 : 1, dice_faces + 1));
|
||||
}
|
||||
const result: number = rolls.reduce((accum, roll) => accum + roll, 0);
|
||||
return await interaction.editReply(`Result: **${result}** ${ show_calc ? `(${ rolls.join(" + ")} = ${result})` : "" }`);
|
||||
}
|
||||
|
||||
const data: CommandData = {
|
||||
name: "roll",
|
||||
description: "Roll dice",
|
||||
ephemeral: false,
|
||||
admin_only: false,
|
||||
run,
|
||||
//
|
||||
};
|
||||
|
||||
export default data;
|
||||
|
||||
35
commands/say.ts
Normal file
35
commands/say.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { ChatInputCommandInteraction } from "discord.js";
|
||||
|
||||
import type { CommandData } from "./index";
|
||||
import { BotError } from "./error";
|
||||
import { is_text_channel } from "../guards";
|
||||
|
||||
async function run(interaction: ChatInputCommandInteraction) {
|
||||
const options = interaction.options;
|
||||
const text: string = (await options.get("text")).value as string; //100% this is a string
|
||||
const channel = (await options.get("channel")).channel;
|
||||
//screw threads, news, announcements and shit, at least for now
|
||||
if (is_text_channel(channel)) {
|
||||
try {
|
||||
await channel.send(text);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw new BotError("Couldn't send message");
|
||||
}
|
||||
return await interaction.reply({ content: "Sent", ephemeral: true });
|
||||
} else {
|
||||
throw new BotError("Must be guild text channel"); //I don't think DM channels are valid to pass in here so no worries there, probably
|
||||
}
|
||||
}
|
||||
|
||||
const data: CommandData = {
|
||||
name: "say",
|
||||
description: "Have the bot say something in a channel",
|
||||
ephemeral: true,
|
||||
admin_only: true,
|
||||
run,
|
||||
//
|
||||
};
|
||||
|
||||
export default data;
|
||||
|
||||
12
db.ts
Normal file
12
db.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { MongoClient } from "mongodb";
|
||||
|
||||
//figure out the options and whatnot later
|
||||
const client = new MongoClient(process.env.MONGO_CONNECTION_STRING);
|
||||
|
||||
let store, users, income;
|
||||
|
||||
client.connect().then(() => {
|
||||
console.log("Connected to the database");
|
||||
//
|
||||
});
|
||||
|
||||
7
guards.ts
Normal file
7
guards.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { TextChannel } from "discord.js";
|
||||
import { ChannelType } from "discord.js";
|
||||
|
||||
export function is_text_channel(channel: any): channel is TextChannel {
|
||||
return channel.type === ChannelType.GuildText;
|
||||
}
|
||||
|
||||
24
index.ts
Normal file
24
index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Client, BaseInteraction } from "discord.js";
|
||||
import { config } from "dotenv";
|
||||
|
||||
//import db from "./db";
|
||||
import run from "./commands";
|
||||
|
||||
config();
|
||||
|
||||
const client = new Client({ intents: [] });
|
||||
|
||||
client.on("ready", async () => {
|
||||
console.log(`Logged in as ${client.user.tag}`);
|
||||
//
|
||||
});
|
||||
|
||||
client.on("interactionCreate", async (interaction: BaseInteraction) => {
|
||||
//
|
||||
if (interaction.isChatInputCommand()) {
|
||||
return await run(interaction);
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(() => client.login(process.env.DISCORD_TOKEN), 2000);
|
||||
|
||||
486
package-lock.json
generated
Normal file
486
package-lock.json
generated
Normal file
@@ -0,0 +1,486 @@
|
||||
{
|
||||
"name": "arvalddos-bot",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "arvalddos-bot",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.15.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"mongodb": "^6.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.8.2.tgz",
|
||||
"integrity": "sha512-6wvG3QaCjtMu0xnle4SoOIeFB4y6fKMN6WZfy3BMKJdQQtPLik8KGzDwBVL/+wTtcE/ZlFjgEk74GublyEVZ7g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.4.0",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@sapphire/shapeshift": "^3.9.7",
|
||||
"discord-api-types": "0.37.83",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.4",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
|
||||
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.4.0.tgz",
|
||||
"integrity": "sha512-fJ06TLC1NiruF35470q3Nr1bi95BdvKFAF+T5bNfZJ4bNdqZ3VZ+Ttg6SThqTxm6qumSG3choxLBHMC69WXNXQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"discord-api-types": "0.37.83"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.3.0.tgz",
|
||||
"integrity": "sha512-C1kAJK8aSYRv3ZwMG8cvrrW4GN0g5eMdP8AuN8ODH5DyOCbHgJspze1my3xHOAgwLJdKUbWNVyAeJ9cEdduqIg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.0",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@sapphire/async-queue": "^1.5.2",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.4",
|
||||
"discord-api-types": "0.37.83",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.2",
|
||||
"undici": "6.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
|
||||
"integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.0.tgz",
|
||||
"integrity": "sha512-IndcI5hzlNZ7GS96RV3Xw1R2kaDuXEp7tRIy/KlhidpN/BQ1qh1NZt3377dMLTa44xDUNKT7hnXkA/oUAzD/lg==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.1.1.tgz",
|
||||
"integrity": "sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.0",
|
||||
"@discordjs/rest": "^2.3.0",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@sapphire/async-queue": "^1.5.2",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.4",
|
||||
"discord-api-types": "0.37.83",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.0.tgz",
|
||||
"integrity": "sha512-mLcTACtXUuVgutoznkh6hS3UFqYirDYAg5Dc1m8xn6OvPjetnUlf/xjtqnnc47OwWdaoCQnHmHh9KofhD6uRqw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@mongodb-js/saslprep": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz",
|
||||
"integrity": "sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/async-queue": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.2.tgz",
|
||||
"integrity": "sha512-7X7FFAA4DngXUl95+hYbUF19bp1LGiffjJtu7ygrZrbdCSsdDDBaSjB7Akw0ZbOu6k0xpXyljnJ6/RZUvLfRdg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "3.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.9.7.tgz",
|
||||
"integrity": "sha512-4It2mxPSr4OGn4HSQWGmhFMsNFGfFVhWeRPCRwbH972Ek2pzfGRZtb0pJ4Ze6oIzcyh2jw7nUDa6qGlWofgd9g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v16"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz",
|
||||
"integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.14.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
|
||||
"integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/webidl-conversions": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz",
|
||||
"integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/whatwg-url": {
|
||||
"version": "11.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz",
|
||||
"integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/webidl-conversions": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ws": {
|
||||
"version": "8.5.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz",
|
||||
"integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vladfrangu/async_event_emitter": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.4.tgz",
|
||||
"integrity": "sha512-ZL62PFXEIeGUI8btfJ5S8Flc286eU1ZUSjwyFQtIGXfRUDPZKO+CDJMYb1R71LjGWRZ4n202O+a6FGjsgTw58g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bson": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz",
|
||||
"integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.20.1"
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.37.83",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.83.tgz",
|
||||
"integrity": "sha512-urGGYeWtWNYMKnYlZnOnDHm8fVRffQs3U0SpE8RHeiuLKb/u92APS8HoQnPTFbnXmY1vVnXjXO4dOxcAn3J+DA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.15.3",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.15.3.tgz",
|
||||
"integrity": "sha512-/UJDQO10VuU6wQPglA4kz2bw2ngeeSbogiIPx/TsnctfzV/tNf+q+i1HlgtX1OGpeOBpJH9erZQNO5oRM2uAtQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.8.2",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.4.0",
|
||||
"@discordjs/rest": "^2.3.0",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@discordjs/ws": "^1.1.1",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "0.37.83",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"tslib": "2.6.2",
|
||||
"undici": "6.13.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.4.5",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
|
||||
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.snakecase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
||||
"integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-bytes.js": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.10.0.tgz",
|
||||
"integrity": "sha512-/k20Lg2q8LE5xiaaSkMXk4sfvI+9EGEykFS4b0CHHGWqDYU0bGUFSwchNOMA56D7TCs9GwVTkqe9als1/ns8UQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mongodb": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz",
|
||||
"integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@mongodb-js/saslprep": "^1.1.5",
|
||||
"bson": "^6.7.0",
|
||||
"mongodb-connection-string-url": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.20.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/credential-providers": "^3.188.0",
|
||||
"@mongodb-js/zstd": "^1.1.0",
|
||||
"gcp-metadata": "^5.2.0",
|
||||
"kerberos": "^2.0.1",
|
||||
"mongodb-client-encryption": ">=6.0.0 <7",
|
||||
"snappy": "^7.2.2",
|
||||
"socks": "^2.7.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@aws-sdk/credential-providers": {
|
||||
"optional": true
|
||||
},
|
||||
"@mongodb-js/zstd": {
|
||||
"optional": true
|
||||
},
|
||||
"gcp-metadata": {
|
||||
"optional": true
|
||||
},
|
||||
"kerberos": {
|
||||
"optional": true
|
||||
},
|
||||
"mongodb-client-encryption": {
|
||||
"optional": true
|
||||
},
|
||||
"snappy": {
|
||||
"optional": true
|
||||
},
|
||||
"socks": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/mongodb-connection-string-url": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz",
|
||||
"integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/whatwg-url": "^11.0.2",
|
||||
"whatwg-url": "^13.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
"integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
|
||||
"integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"punycode": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-mixer": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
|
||||
"integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
|
||||
"integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.13.0.tgz",
|
||||
"integrity": "sha512-Q2rtqmZWrbP8nePMq7mOJIN98M0fYvSgV89vwl/BQRT4mDOeY2GXZngfGpcBBhtky3woM7G24wZV3Q304Bv6cw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz",
|
||||
"integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tr46": "^4.1.1",
|
||||
"webidl-conversions": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": ">=5.0.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"bufferutil": {
|
||||
"optional": true
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
package.json
Normal file
21
package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "arvalddos-bot",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"compile": "tsc -p .",
|
||||
"register": "npm run compile && node register.js",
|
||||
"start": "npm run compile && node index.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"discord.js": "^14.15.3",
|
||||
"dotenv": "^16.4.5",
|
||||
"mongodb": "^6.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
}
|
||||
63
register.ts
Normal file
63
register.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { REST, Routes } from "discord.js";
|
||||
import { config } from "dotenv";
|
||||
|
||||
config();
|
||||
|
||||
//description in two places is annoying but length limits are different (100 vs 1024 [but sum of all chars in embed cannot be >6000])
|
||||
const commands = [
|
||||
{
|
||||
name: "help",
|
||||
description: "Get a list of commands for this bot",
|
||||
},
|
||||
{
|
||||
name: "say",
|
||||
description: "Have bot say something in a channel (admin only)",
|
||||
options: [
|
||||
{
|
||||
type: 3,
|
||||
name: "text",
|
||||
description: "What the bot should say",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 7,
|
||||
name: "channel",
|
||||
description: "What guild text channel the bot should say the text in",
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "roll",
|
||||
description: "Roll dice",
|
||||
options: [
|
||||
{
|
||||
type: 4,
|
||||
name: "dice_num",
|
||||
description: "Amount of dice to roll",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 4,
|
||||
name: "dice_faces",
|
||||
description: "Max value of each dice",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
type: 5,
|
||||
name: "show_calc",
|
||||
description: "Show the calculations and each dice roll (default: true)",
|
||||
required: false,
|
||||
},
|
||||
{
|
||||
type: 5,
|
||||
name: "include_zero",
|
||||
description: "Make it possible for the dice to roll 0 (default: false)",
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
(new REST().setToken(process.env.DISCORD_TOKEN)).put(Routes.applicationCommands(process.env.CLIENT_ID), { body: commands }).then(() => console.log("Finished reloading slash commands"));
|
||||
|
||||
13
tsconfig.json
Normal file
13
tsconfig.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2020",
|
||||
"module": "node16",
|
||||
"moduleResolution": "node16",
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"lib": ["ES2020"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user