(#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
@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within

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
@ -14,7 +15,7 @@ Contributions to ER are highly encouraged and desired. Below are some guidelines
## Suggesting Enhancements
- When submitting an issue for an enhancement, please be as clear as possible about why you think the enhancement is needed and what the benefit of
it would be.
it would be.
## Making Changes
@ -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,10 +84,12 @@ async function run() {
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);
});
run()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});

View file

@ -1,76 +1,103 @@
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()
export class Report {
@ContextMenu({
name: "Report user",
type: ApplicationCommandType.User,
})
async reportUser(interaction: MessageContextMenuCommandInteraction, client: Client) {
@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 (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,
},
});
if (!data) {
await prisma.guild.create({
data: {
id: interaction.guildId!,
name: interaction.guild!.name
}
})
data = await prisma.guild.findUnique({
where: {
id: interaction.guildId!
}
})
}
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");
.setTitle("Report user")
.setCustomId("report_user");
const userId = new TextInputBuilder()
.setCustomId("user-id")
.setValue(interaction.targetId)
.setLabel("User ID")
.setStyle(TextInputStyle.Short);
.setCustomId("user-id")
.setValue(interaction.targetId)
.setLabel("User ID")
.setStyle(TextInputStyle.Short);
const reason = new TextInputBuilder()
.setCustomId("reason")
.setLabel("Reason")
.setStyle(TextInputStyle.Paragraph);
.setCustomId("reason")
.setLabel("Reason")
.setStyle(TextInputStyle.Paragraph);
modal.addComponents(
new ActionRowBuilder<TextInputBuilder>().addComponents(userId),
new ActionRowBuilder<TextInputBuilder>().addComponents(reason),
new ActionRowBuilder<TextInputBuilder>().addComponents(userId),
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 ?? ""}`,
// });
// }
//})
})
} else {
interaction.reply({
content: "It looks like you aren't in a guild, you can only report within guilds"
})
}
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})
}
}