(#1) User reporting now complete

closes #1

Signed-off-by: Louis Hollingworth <louis@hollingworth.ch>
This commit is contained in:
Louis Hollingworth 2023-06-14 18:43:50 +01:00
parent faca0b2fda
commit 6770bd8d35
Signed by: lucxjo
GPG key ID: A11415CB3DC7809B
7 changed files with 856 additions and 349 deletions

View file

@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our Examples of behavior that contributes to a positive environment for our
community include: community include:
* Demonstrating empathy and kindness toward other people - Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences - Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback - Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, - Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience and learning from the experience
* Focusing on what is best not just for us as individuals, but for the - Focusing on what is best not just for us as individuals, but for the
overall community overall community
Examples of unacceptable behavior include: Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or - The use of sexualized language or imagery, and sexual attention or
advances of any kind advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks - Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or email - Publishing others' private information, such as a physical or email
address, without their explicit permission address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Enforcement Responsibilities ## Enforcement Responsibilities

View file

@ -1,6 +1,7 @@
# How to contribute # How to contribute
<!-- TODO: Change <PROJECT_NAME> --> <!-- TODO: Change <PROJECT_NAME> -->
Contributions to ER are highly encouraged and desired. Below are some guidelines that will help make the process as smooth as possible. Contributions to ER are highly encouraged and desired. Below are some guidelines that will help make the process as smooth as possible.
## Getting Started ## Getting Started
@ -62,6 +63,7 @@ We are not infallible and as such the documentation may need corrections. Please
- Celebrate - Celebrate
## DCO ## DCO
```text ```text
Developer Certificate of Origin Developer Certificate of Origin
Version 1.1 Version 1.1
@ -101,6 +103,7 @@ By making a contribution to this project, I certify that:
maintained indefinitely and may be redistributed consistent with maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved. this project or the open source license(s) involved.
``` ```
## Additional Resources ## Additional Resources
- [General GitHub documentation](https://help.github.com/) - [General GitHub documentation](https://help.github.com/)

View file

@ -1,4 +1,5 @@
# ER - Edvin Rydburg # ER - Edvin Rydburg
A Discord bot designed around the [Young Royals](https://discord.gg/youngroyals) A Discord bot designed around the [Young Royals](https://discord.gg/youngroyals)
Discord guild. This bot is the first generation of what will become Klara. Discord guild. This bot is the first generation of what will become Klara.
@ -6,11 +7,13 @@ The intent for this bot is as a playground for features of the future Klara bot
that will be written in Rust or Go. that will be written in Rust or Go.
## Why TS/JS then Rust or Go? ## Why TS/JS then Rust or Go?
Discordx makes it extremely easy to build a bot, so while I'm figuring things Discordx makes it extremely easy to build a bot, so while I'm figuring things
out, this will ensure that I can quickly realise what will be needed. Once what out, this will ensure that I can quickly realise what will be needed. Once what
is needed is known, a more stable version can be made that, in Rust or Go, will is needed is known, a more stable version can be made that, in Rust or Go, will
consume far less resources. consume far less resources.
## Will the future Klara still be open-source? ## Will the future Klara still be open-source?
Yes! Of course! Practically everything I do is open-source, I don't believe that Yes! Of course! Practically everything I do is open-source, I don't believe that
hiding work particularly helps anyone. hiding work particularly helps anyone.

File diff suppressed because it is too large Load diff

75
src/commands/admin.ts Normal file
View file

@ -0,0 +1,75 @@
import { ApplicationCommandOptionType, Channel, CommandInteraction, GuildMember, PermissionsBitField } from "discord.js";
import { Discord, Guard, GuardFunction, Slash, SlashGroup, SlashOption } from "discordx";
import { prisma } from "../main.js";
const AdminOnly: GuardFunction<CommandInteraction> = async (
arg,
client,
next
) => {
const argObj = arg instanceof Array ? arg[0] : arg;
const user = argObj.user as GuildMember
if (user.permissions.has(PermissionsBitField.Flags.Administrator)) await next();
}
@Discord()
@SlashGroup({ name: "admin", description: "Admin commands" })
@SlashGroup("admin")
@Guard(AdminOnly)
class AdminCmds {
@Slash({description: "Set or get the configured channel for reports"})
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")
}
})
}
}
}

View file

@ -61,9 +61,9 @@ bot.on("guildCreate", (guild: Guild) => {
data: { data: {
id: guild.id, id: guild.id,
name: guild.name, name: guild.name,
} },
}) });
}) });
async function run() { async function run() {
// The following syntax should be used in the commonjs environment // The following syntax should be used in the commonjs environment
@ -71,7 +71,9 @@ async function run() {
// await importx(__dirname + "/{events,commands}/**/*.{ts,js}"); // await importx(__dirname + "/{events,commands}/**/*.{ts,js}");
// The following syntax should be used in the ECMAScript environment // The following syntax should be used in the ECMAScript environment
await importx(`${dirname(import.meta.url)}/{events,commands,menus}/**/*.{ts,js}`); await importx(
`${dirname(import.meta.url)}/{events,commands,menus}/**/*.{ts,js}`
);
// Let's start the bot // Let's start the bot
if (!process.env.DISCORD_TOKEN) { if (!process.env.DISCORD_TOKEN) {
@ -82,9 +84,11 @@ async function run() {
await bot.login(process.env.DISCORD_TOKEN); await bot.login(process.env.DISCORD_TOKEN);
} }
run().then(async () => { run()
.then(async () => {
await prisma.$disconnect(); await prisma.$disconnect();
}).catch(async (e) => { })
.catch(async (e) => {
console.error(e); console.error(e);
await prisma.$disconnect(); await prisma.$disconnect();
process.exit(1); process.exit(1);

View file

@ -1,5 +1,15 @@
import { ActionRowBuilder, ApplicationCommandType, Client, MessageContextMenuCommandInteraction, ModalBuilder, TextChannel, TextInputBuilder, TextInputStyle } from "discord.js"; import {
import { ContextMenu, Discord } from "discordx"; ActionRowBuilder,
ApplicationCommandType,
Client,
MessageContextMenuCommandInteraction,
ModalBuilder,
ModalSubmitInteraction,
TextChannel,
TextInputBuilder,
TextInputStyle,
} from "discord.js";
import { ContextMenu, Discord, ModalComponent } from "discordx";
import { prisma } from "../main.js"; import { prisma } from "../main.js";
@Discord() @Discord()
@ -8,33 +18,40 @@ export class Report {
name: "Report user", name: "Report user",
type: ApplicationCommandType.User, type: ApplicationCommandType.User,
}) })
async reportUser(interaction: MessageContextMenuCommandInteraction, client: Client) { async reportUser(
interaction: MessageContextMenuCommandInteraction,
client: Client
) {
if (interaction.guildId) { if (interaction.guildId) {
let data = await prisma.guild.findUnique({ let data = await prisma.guild.findUnique({
where: { where: {
id: interaction.guildId! id: interaction.guildId!,
} },
}) });
if (!data) { if (!data) {
await prisma.guild.create({ await prisma.guild.create({
data: { data: {
id: interaction.guildId!, id: interaction.guildId!,
name: interaction.guild!.name name: interaction.guild!.name,
} },
}) });
data = await prisma.guild.findUnique({ data = await prisma.guild.findUnique({
where: { where: {
id: interaction.guildId! 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() const modal = new ModalBuilder()
.setTitle("Report user") .setTitle("Report user")
.setCustomId("report-user"); .setCustomId("report_user");
const userId = new TextInputBuilder() const userId = new TextInputBuilder()
.setCustomId("user-id") .setCustomId("user-id")
@ -49,28 +66,38 @@ export class Report {
modal.addComponents( modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(userId), new ActionRowBuilder<TextInputBuilder>().addComponents(userId),
new ActionRowBuilder<TextInputBuilder>().addComponents(reason), new ActionRowBuilder<TextInputBuilder>().addComponents(reason)
); );
interaction.showModal(modal).then(() => { interaction.showModal(modal)
interaction.editReply({ }
content: "Reported user.",
});
// client.channels.fetch("channel-id").then((channel) => {
// if (channel?.isTextBased()) {
// let ct = channel as TextChannel;
// ct.send({
// content: `User <@${interaction.user.id}> reported <@${interaction.targetId}> for: ${reason.data.value ?? ""}`,
// });
// }
//})
})
} else { } else {
interaction.reply({ interaction.reply({
content: "It looks like you aren't in a guild, you can only report within guilds" 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})
}
}