(#8) Removed all node stuff. Init Cargo

Signed-off-by: Louis Hollingworth <louis@hollingworth.nl>
This commit is contained in:
Louis Hollingworth 2023-09-19 17:55:01 +01:00
parent 718d4f5e9c
commit dcd94db325
Signed by: lucxjo
GPG key ID: A11415CB3DC7809B
16 changed files with 16 additions and 1984 deletions

View file

@ -1,65 +0,0 @@
name: prisma-migrate
on:
push:
branches: [main]
jobs:
install:
runs-on: ubuntu-latest
steps:
- uses: https://github.com/actions/checkout@v2
- name: Setup Nodejs
uses: https://github.com/actions/setup-node@v2
with:
node-version: 16.x
- name: Install
run: yarn install
- name: Rerun Install
run: yarn install
generate:
runs-on: ubuntu-latest
needs: install
steps:
- uses: https://github.com/actions/checkout@v2
- name: Setup Nodejs
uses: https://github.com/actions/setup-node@v2
with:
node-version: 16.x
- name: Install
run: yarn install
- run: rm -rf node_modules/.prisma
- name: Generate Prisma Client
run: npx prisma generate
migrate:
runs-on: ubuntu-latest
needs: install
steps:
- uses: https://github.com/actions/checkout@v2
- name: Setup Nodejs
uses: https://github.com/actions/setup-node@v2
with:
node-version: 16.x
- name: Install
run: yarn install
- run: rm -rf node_modules/.prisma
- name: Deploy Migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.PROD_DATABASE_URL }}

5
.gitignore vendored
View file

@ -1,3 +1,8 @@
.env .env
node_modules node_modules
.DS_Store .DS_Store
# Added by cargo
/target

8
Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "er"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

BIN
bun.lockb

Binary file not shown.

View file

@ -1,35 +0,0 @@
{
"name": "er",
"version": "1.0.0",
"private": true,
"license": "MIT",
"type": "module",
"main": "build/main.js",
"scripts": {
"build": "tsc",
"build:changelog": "npx @discordx/changelog --src src",
"dev": "node --loader ts-node/esm src/main.ts",
"start": "node build/main.js",
"db:deploy": "prisma migrate deploy",
"watch": "nodemon --exec ts-node-esm src/main.ts"
},
"dependencies": {
"@discordx/importer": "^1.2.3",
"@prisma/client": "5.2.0",
"discord.js": "^14.13.0",
"discordx": "^11.7.6",
"dotenv": "16.3.1"
},
"devDependencies": {
"@types/node": "^20.6.0",
"nodemon": "^3.0.1",
"prettier": "^3.0.3",
"prisma": "^5.2.0",
"ts-node": "^10.9.1",
"typescript": "5.2.2"
},
"engines": {
"node": ">=16.0.0",
"npm": ">=7.0.0"
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,166 +0,0 @@
import {
ApplicationCommandOptionType,
Channel,
CommandInteraction,
GuildMember,
PermissionsBitField,
Role,
} from "discord.js";
import { Discord, Slash, SlashGroup, SlashOption } from "discordx";
import { prisma } from "../main.js";
@Discord()
@SlashGroup({ name: "admin", description: "Admin commands" })
@SlashGroup("admin")
export class AdminCmds {
@Slash({
description: "Set or get the configured channel for reports",
defaultMemberPermissions: PermissionsBitField.Flags.Administrator,
})
async reports(
@SlashOption({
description: "Set where the reports should be sent",
name: "reports_channel",
required: false,
type: ApplicationCommandOptionType.Channel,
})
channel: Channel,
interaction: CommandInteraction
) {
if (channel) {
await prisma.guild
.findUnique({
where: {
id: interaction.guildId!,
},
})
.then(async (data) => {
if (data) {
await prisma.guild.update({
where: {
id: data.id,
},
data: {
reports_channel_id: channel.id,
},
});
} else {
await prisma.guild.create({
data: {
id: interaction.guildId!,
name: interaction.guild!.name,
reports_channel_id: channel.id,
},
});
}
interaction.reply(
`<#${channel.id}> is now setup to receive reports.`
);
});
} else {
await prisma.guild
.findUnique({
where: {
id: interaction.guildId!,
},
})
.then((data) => {
if (data) {
interaction.reply(
`<#${data.reports_channel_id}> is currently receiving reports for this guild.`
);
} else {
interaction.reply("Reports are currently disabled for this guild");
}
});
}
}
@Slash({
description: "Link a user to their booster role",
name: "link_role",
defaultMemberPermissions: PermissionsBitField.Flags.ManageRoles,
})
async link_role(
@SlashOption({
description: "The user account to link",
name: "member",
required: true,
type: ApplicationCommandOptionType.User,
})
member: GuildMember,
@SlashOption({
description: "The role to link",
name: "role",
required: true,
type: ApplicationCommandOptionType.Role,
})
role: Role,
interaction: CommandInteraction
) {
let mem = await prisma.member.findUnique({
where: {
dgid_duid: {
duid: member.id,
dgid: member.guild.id,
},
},
});
if (mem) {
await prisma.member.update({
where: {
id: mem.id,
},
data: {
booster_role_id: role.id,
name: member.displayName,
},
});
} else {
await prisma.member.create({
data: {
duid: member.id,
dgid: interaction.guildId!,
name: member.displayName,
booster_role_id: role.id,
},
});
}
interaction.reply({
content: "Member booster role updated!",
ephemeral: true,
});
}
@Slash({
description: "Enable or disable auto perk roles",
defaultMemberPermissions: PermissionsBitField.Flags.Administrator,
})
async toggle_perk_role_creation(interaction: CommandInteraction) {
if (interaction.guildId) {
const g = await prisma.guild.findUnique({
where: {
id: interaction.guildId,
},
});
await prisma.guild.update({
where: {
id: interaction.guildId,
},
data: {
auto_create_booster_roles: !g?.auto_create_booster_roles,
},
});
interaction.reply({
content: `Booster role creation is now ${
g?.auto_create_booster_roles ? "disabled" : "enabled"
}`,
ephemeral: true,
});
}
}
}

View file

@ -1,69 +0,0 @@
import {
ApplicationCommandOptionType,
Channel,
CommandInteraction,
} from "discord.js";
import { Discord, Slash, SlashGroup, SlashOption } from "discordx";
import { prisma } from "../main.js";
@Discord()
@SlashGroup({ description: "Manage your booster perks", name: "perks" })
@SlashGroup("perks")
export class Perks {
@Slash({ description: "Manage your role" })
async role(
interaction: CommandInteraction,
@SlashOption({
name: "name",
description: "Change the name of your role",
type: ApplicationCommandOptionType.String,
})
name?: string,
@SlashOption({
name: "colour",
description: "Change the colour of your role (in hex)",
type: ApplicationCommandOptionType.String,
})
colour?: string
) {
const m = await prisma.member.findUnique({
where: {
dgid_duid: {
dgid: interaction.guildId!,
duid: interaction.user.id,
},
},
});
if (!m || !m.booster_role_id) {
interaction.reply({
content:
"It appears that you may not be a booster of this guild, contact <@207603534789738496> if you think this is a mistake.",
ephemeral: true,
});
} else {
const r = await interaction.guild?.roles.fetch(m.booster_role_id);
if (r) {
await interaction.guild?.roles.edit(r, {
name: name ?? undefined,
color:
colour != undefined
? colour.startsWith("#")
? parseInt(colour.replace("#", "0x"), 16)
: parseInt(`0x${colour}`)
: undefined,
});
interaction.reply({
content: "Role updated!",
ephemeral: true,
});
} else {
interaction.reply({
content:
"It appears that you may not be a booster of this guild, contact <@207603534789738496> if you think this is a mistake.",
ephemeral: true,
});
}
}
}
}

View file

@ -1,55 +0,0 @@
import {
ApplicationCommandOptionType,
Client,
CommandInteraction,
GuildMember,
TextChannel,
User,
} from "discord.js";
import { Discord, Slash, SlashOption } from "discordx";
import { prisma } from "../main.js";
@Discord()
export class Report {
@Slash({ description: "Report a user to the guild staff", name: "report" })
async report(
@SlashOption({
required: true,
description: "The user to report",
name: "user",
type: ApplicationCommandOptionType.User,
})
user: GuildMember | User,
@SlashOption({
required: true,
description: "Why you are reporting this user",
name: "reason",
type: ApplicationCommandOptionType.String,
})
reason: string,
interaction: CommandInteraction,
client: Client
) {
if (interaction.guild) {
const guild = await prisma.guild.findUnique({
where: {
id: interaction.guild.id,
},
});
if (guild && guild.reports_channel_id) {
await client.channels
.fetch(guild!.reports_channel_id!)
.then((channel) => {
if (channel!.isTextBased()) {
const ct = channel as TextChannel;
ct.send(`${interaction.user} reported ${user} for: ${reason}`);
}
});
}
await interaction.reply({ content: "Report sent!", ephemeral: true });
return;
}
await interaction.reply("You need to be in a guild to use this command");
}
}

View file

@ -1,35 +0,0 @@
import { CommandInteraction } from "discord.js";
import { Discord, Slash } from "discordx";
@Discord()
export class Threads {
@Slash({ description: "Display current threads", name: "threads" })
async threads(interaction: CommandInteraction) {
if (interaction.guild) {
const threads = await fetch(
`https://discord.com/api/v10/guilds/${interaction.guildId}/threads/active`,
{
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${process.env.DISCORD_TOKEN}`,
},
}
);
const body = (await threads.json()).threads as Array<{
flags: number;
guild_id: string;
id: string;
parent_id: string;
}>;
let threadMsg = "The current active threads are:";
body.forEach((thread) => {
threadMsg += `\n- <#${thread.id}>`;
});
interaction.reply({ content: threadMsg, ephemeral: true });
}
}
}

View file

@ -1,15 +0,0 @@
import { ArgsOf, Discord, On } from "discordx";
import { prisma } from "../main.js";
@Discord()
export class GuildJoin {
@On({ event: "guildCreate" })
fn([guild]: ArgsOf<"guildCreate">) {
prisma.guild.create({
data: {
id: guild.id,
name: guild.name,
},
});
}
}

View file

@ -1,107 +0,0 @@
import { ArgsOf, Discord, On } from "discordx";
import { prisma } from "../main.js";
@Discord()
export class MemberEvent {
@On({ event: "guildMemberAdd" })
async memberJoin([member]: ArgsOf<"guildMemberAdd">) {
await prisma.member.create({
data: {
dgid: member.guild.id,
duid: member.id,
name: member.displayName,
},
});
}
@On({ event: "guildMemberRemove" })
async memberRemove([member]: ArgsOf<"guildMemberRemove">) {
await prisma.member.delete({
where: {
dgid_duid: {
duid: member.id,
dgid: member.guild.id,
},
},
});
}
@On({ event: "guildMemberUpdate" })
async memberUpdate([oldM, newM]: ArgsOf<"guildMemberUpdate">) {
const g = await prisma.guild.findUnique({
where: {
id: newM.guild.id,
},
});
if (g?.auto_create_booster_roles) {
if (oldM.premiumSince !== newM.premiumSince) {
if (newM != null) {
const m = await prisma.member.findUnique({
where: {
dgid_duid: {
dgid: newM.guild.id,
duid: newM.id,
},
},
});
if (m?.booster_role_id != null && newM.premiumSince != null) {
return;
} else if (newM.premiumSince == null) {
await prisma.member.update({
where: {
id: m?.id,
},
data: {
booster_role_id: null,
},
});
const r = await newM.guild.roles.fetch(m!.booster_role_id!);
if (r) await newM.guild.roles.delete(r);
return;
} else {
const guild = newM.guild;
const role = await guild.roles.create({
name: newM.nickname ?? newM.displayName,
reason: `${newM.nickname ?? newM.displayName} just boosted!`,
});
await newM.roles.add(role);
const m = await prisma.member.findUnique({
where: {
dgid_duid: {
dgid: guild.id,
duid: newM.id,
},
},
});
if (m) {
await prisma.member.update({
where: {
id: m.id,
},
data: {
booster_role_id: role.id,
},
});
} else {
await prisma.member.create({
data: {
duid: newM.id,
dgid: guild.id,
booster_role_id: role.id,
name: newM.displayName,
},
});
}
return;
}
}
}
}
}
}

3
src/main.rs Normal file
View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -1,77 +0,0 @@
import { dirname, importx } from "@discordx/importer";
import type { Interaction } from "discord.js";
import { IntentsBitField } from "discord.js";
import * as dotenv from "dotenv";
import { Client } from "discordx";
import { PrismaClient } from "@prisma/client";
dotenv.config();
export const prisma = new PrismaClient();
export const bot = new Client({
// To use only guild command
// botGuilds: [(client) => client.guilds.cache.map((guild) => guild.id)],
// Discord intents
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMembers,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.GuildMessageReactions,
IntentsBitField.Flags.GuildVoiceStates,
],
// Debug logs are disabled in silent mode
silent: false,
});
bot.once("ready", async () => {
// Make sure all guilds are cached
await bot.guilds.fetch();
// Synchronize applications commands with Discord
await bot.initApplicationCommands();
// To clear all guild commands, uncomment this line,
// This is useful when moving from guild commands to global commands
// It must only be executed once
//
// await bot.clearApplicationCommands(
// ...bot.guilds.cache.map((g) => g.id)
// );
console.log("Bot started");
});
bot.on("interactionCreate", (interaction: Interaction) => {
bot.executeInteraction(interaction);
});
async function run() {
// The following syntax should be used in the commonjs environment
//
// await importx(__dirname + "/{events,commands}/**/*.{ts,js}");
// The following syntax should be used in the ECMAScript environment
await importx(
`${dirname(import.meta.url)}/{events,commands,menus}/**/*.{ts,js}`
);
// Let's start the bot
if (!process.env.DISCORD_TOKEN) {
throw Error("Could not find DISCORD_TOKEN in your environment");
}
// Log in with your bot token
await bot.login(process.env.DISCORD_TOKEN);
}
run()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

View file

@ -1,103 +0,0 @@
import {
ActionRowBuilder,
ApplicationCommandType,
Client,
MessageContextMenuCommandInteraction,
ModalBuilder,
ModalSubmitInteraction,
TextChannel,
TextInputBuilder,
TextInputStyle,
} from "discord.js";
import { ContextMenu, Discord, ModalComponent } from "discordx";
import { prisma } from "../main.js";
@Discord()
export class Report {
@ContextMenu({
name: "Report user",
type: ApplicationCommandType.User,
})
async reportUser(
interaction: MessageContextMenuCommandInteraction,
client: Client
) {
if (interaction.guildId) {
let data = await prisma.guild.findUnique({
where: {
id: interaction.guildId!,
},
});
if (!data) {
await prisma.guild.create({
data: {
id: interaction.guildId!,
name: interaction.guild!.name,
},
});
data = await prisma.guild.findUnique({
where: {
id: interaction.guildId!,
},
});
}
if (!data!.reports_channel_id) {
interaction.reply(
"It looks like your guild hasn't set up this feature, please speak to the staff."
);
} else {
const modal = new ModalBuilder()
.setTitle("Report user")
.setCustomId("report_user");
const userId = new TextInputBuilder()
.setCustomId("user-id")
.setValue(interaction.targetId)
.setLabel("User ID")
.setStyle(TextInputStyle.Short);
const reason = new TextInputBuilder()
.setCustomId("reason")
.setLabel("Reason")
.setStyle(TextInputStyle.Paragraph);
modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(userId),
new ActionRowBuilder<TextInputBuilder>().addComponents(reason)
);
interaction.showModal(modal);
}
} else {
interaction.reply({
content:
"It looks like you aren't in a guild, you can only report within guilds",
});
}
}
@ModalComponent()
async report_user(interaction: ModalSubmitInteraction, client: Client) {
const [user_id, reason] = ["user-id", "reason"].map((id) =>
interaction.fields.getTextInputValue(id)
);
const data = await prisma.guild.findUnique({
where: {
id: interaction.guildId!,
},
});
client.channels.fetch(data!.reports_channel_id!).then((channel) => {
if (channel?.isTextBased()) {
let ct = channel as TextChannel;
ct.send({
content: `<@${interaction.user.id}> reported <@${user_id}> for: ${reason}`,
});
}
});
interaction.reply({ content: "Reported user.", ephemeral: true });
}
}

View file

@ -1,18 +0,0 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"outDir": "build",
"rootDir": "src",
"strict": true,
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"noImplicitAny": false,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"exclude": ["build", "node_modules"]
}