(#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
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
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
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
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
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
## Enforcement Responsibilities

View file

@ -1,6 +1,7 @@
# How to contribute
<!-- 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.
## Getting Started
@ -62,6 +63,7 @@ We are not infallible and as such the documentation may need corrections. Please
- Celebrate
## DCO
```text
Developer Certificate of Origin
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
this project or the open source license(s) involved.
```
## Additional Resources
- [General GitHub documentation](https://help.github.com/)

View file

@ -1,4 +1,5 @@
# ER - Edvin Rydburg
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.
@ -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.
## Why TS/JS then Rust or Go?
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
is needed is known, a more stable version can be made that, in Rust or Go, will
consume far less resources.
## Will the future Klara still be open-source?
Yes! Of course! Practically everything I do is open-source, I don't believe that
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: {
id: guild.id,
name: guild.name,
}
})
})
},
});
});
async function run() {
// The following syntax should be used in the commonjs environment
@ -71,7 +71,9 @@ async function run() {
// 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}`);
await importx(
`${dirname(import.meta.url)}/{events,commands,menus}/**/*.{ts,js}`
);
// Let's start the bot
if (!process.env.DISCORD_TOKEN) {
@ -82,9 +84,11 @@ async function run() {
await bot.login(process.env.DISCORD_TOKEN);
}
run().then(async () => {
run()
.then(async () => {
await prisma.$disconnect();
}).catch(async (e) => {
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);

View file

@ -1,5 +1,15 @@
import { ActionRowBuilder, ApplicationCommandType, Client, MessageContextMenuCommandInteraction, ModalBuilder, TextChannel, TextInputBuilder, TextInputStyle } from "discord.js";
import { ContextMenu, Discord } from "discordx";
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()
@ -8,33 +18,40 @@ export class Report {
name: "Report user",
type: ApplicationCommandType.User,
})
async reportUser(interaction: MessageContextMenuCommandInteraction, client: Client) {
async reportUser(
interaction: MessageContextMenuCommandInteraction,
client: Client
) {
if (interaction.guildId) {
let data = await prisma.guild.findUnique({
where: {
id: interaction.guildId!
}
})
id: interaction.guildId!,
},
});
if (!data) {
await prisma.guild.create({
data: {
id: interaction.guildId!,
name: interaction.guild!.name
}
})
name: interaction.guild!.name,
},
});
data = await prisma.guild.findUnique({
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()
.setTitle("Report user")
.setCustomId("report-user");
.setCustomId("report_user");
const userId = new TextInputBuilder()
.setCustomId("user-id")
@ -49,28 +66,38 @@ export class Report {
modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(userId),
new ActionRowBuilder<TextInputBuilder>().addComponents(reason),
new ActionRowBuilder<TextInputBuilder>().addComponents(reason)
);
interaction.showModal(modal).then(() => {
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 ?? ""}`,
// });
// }
//})
})
interaction.showModal(modal)
}
} else {
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})
}
}