summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-09-11 18:13:31 -0700
committerFuwn <[email protected]>2025-09-11 18:13:31 -0700
commit1257d1419d04678296441904a5576464ad86ac27 (patch)
tree244a3759dcdac1dac71e6714b7be9317f2a30d70
parentstyle: Use base prettier:recommended rules (diff)
downloadumabotdiscord-1257d1419d04678296441904a5576464ad86ac27.tar.xz
umabotdiscord-1257d1419d04678296441904a5576464ad86ac27.zip
feat: Add complaint system
-rw-r--r--src/discord/commands.ts13
-rw-r--r--src/discord/embeds.ts35
-rw-r--r--src/discord/interfaces.ts24
-rw-r--r--src/register.ts2
-rw-r--r--src/server.ts99
5 files changed, 166 insertions, 7 deletions
diff --git a/src/discord/commands.ts b/src/discord/commands.ts
index b4436d6..bcf8cba 100644
--- a/src/discord/commands.ts
+++ b/src/discord/commands.ts
@@ -57,3 +57,16 @@ export const TOP_COMMAND: DiscordCommand = {
},
],
};
+
+export const COMPLAIN_COMMAND: DiscordCommand = {
+ name: "complain",
+ description: "Submit a complaint to the moderators",
+ options: [
+ {
+ type: 3,
+ name: "message",
+ description: "Your complaint message",
+ required: true,
+ },
+ ],
+};
diff --git a/src/discord/embeds.ts b/src/discord/embeds.ts
index 1fad102..db23f80 100644
--- a/src/discord/embeds.ts
+++ b/src/discord/embeds.ts
@@ -88,3 +88,38 @@ export const createPostEmbed = (post: RedditPost): DiscordEmbed => {
return embed;
};
+
+export const createComplaintEmbed = (
+ complaintContent: string,
+ complainant: { username: string; id: string; avatar?: string },
+ timestamp: number,
+ isDM: boolean = true,
+): DiscordEmbed => {
+ return {
+ title: "🚨 New Complaint",
+ description: complaintContent,
+ color: 0xff6b6b,
+ fields: [
+ {
+ name: "Complainant",
+ value: `${complainant.username} (${complainant.id})`,
+ inline: true,
+ },
+ {
+ name: "Timestamp",
+ value: `<t:${Math.floor(timestamp / 1000)}:F>`,
+ inline: true,
+ },
+ ],
+ thumbnail: complainant.avatar
+ ? {
+ url: `https://cdn.discordapp.com/avatars/${complainant.id}/${complainant.avatar}.png?size=256`,
+ }
+ : undefined,
+ footer: {
+ text: isDM
+ ? "Complaint submitted via DM"
+ : "Complaint submitted from server",
+ },
+ };
+};
diff --git a/src/discord/interfaces.ts b/src/discord/interfaces.ts
index 3eb81eb..6b26876 100644
--- a/src/discord/interfaces.ts
+++ b/src/discord/interfaces.ts
@@ -17,27 +17,41 @@ export interface DiscordInteraction {
channel?: {
nsfw: boolean;
};
+ guild_id?: string;
+ user?: {
+ id: string;
+ username: string;
+ avatar?: string;
+ };
+ member?: {
+ user?: {
+ id: string;
+ username: string;
+ avatar?: string;
+ };
+ };
}
export interface DiscordEmbed {
title: string;
description: string;
- url: string;
+ url?: string;
color: number;
- author: {
+ author?: {
name: string;
url: string;
};
- fields: Array<{
+ fields?: Array<{
name: string;
value: string;
inline: boolean;
}>;
- timestamp: string;
- footer: {
+ timestamp?: string;
+ footer?: {
text: string;
};
image?: { url: string };
+ thumbnail?: { url: string };
}
export interface DiscordResponse {
diff --git a/src/register.ts b/src/register.ts
index 6cd2bac..8e0202f 100644
--- a/src/register.ts
+++ b/src/register.ts
@@ -3,6 +3,7 @@ import {
NSFW_COMMAND,
ROLEPLAY_COMMAND,
TOP_COMMAND,
+ COMPLAIN_COMMAND,
type DiscordCommand,
} from "./discord/commands.ts";
import dotenv from "dotenv";
@@ -28,6 +29,7 @@ const commands: DiscordCommand[] = [
ROLEPLAY_COMMAND,
NSFW_COMMAND,
TOP_COMMAND,
+ COMPLAIN_COMMAND,
];
const response = await fetch(url, {
diff --git a/src/server.ts b/src/server.ts
index bf3acf2..8925bdc 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -5,6 +5,7 @@ import {
ROLEPLAY_COMMAND,
NSFW_COMMAND,
TOP_COMMAND,
+ COMPLAIN_COMMAND,
} from "./discord/commands.ts";
import {
getCutePost,
@@ -13,12 +14,39 @@ import {
getTopPost,
} from "./reddit.ts";
import type { TimePeriod } from "./discord/types.ts";
-import type { Environment } from "./discord/interfaces.ts";
-import { createPostEmbed } from "./discord/embeds.ts";
+import type { Environment, DiscordEmbed } from "./discord/interfaces.ts";
+import { createPostEmbed, createComplaintEmbed } from "./discord/embeds.ts";
import { JSONResponse } from "./discord/responses.ts";
import { verifyDiscordRequest } from "./discord/verification.ts";
const router = AutoRouter();
+const COMPLAINT_CHANNEL_ID = "1406422617724026901";
+
+const sendComplaintToChannel = async (
+ environment: Environment,
+ embed: DiscordEmbed,
+): Promise<boolean> => {
+ const url = `https://discord.com/api/v10/channels/${COMPLAINT_CHANNEL_ID}/messages`;
+
+ try {
+ const response = await fetch(url, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bot ${environment.DISCORD_TOKEN}`,
+ },
+ body: JSON.stringify({
+ embeds: [embed],
+ }),
+ });
+
+ return response.ok;
+ } catch (error) {
+ console.error("Error sending complaint to channel:", error);
+
+ return false;
+ }
+};
router.get("/", (_request: Request, environment: Environment) => {
return new Response(`👋 ${environment.DISCORD_APPLICATION_ID}`);
@@ -148,6 +176,73 @@ router.post("/", async (request: Request, environment: Environment) => {
}
}
+ case COMPLAIN_COMMAND.name.toLowerCase(): {
+ try {
+ const complaintMessage = interaction.data.options?.[0]
+ ?.value as string;
+
+ if (!complaintMessage)
+ return new JSONResponse({
+ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
+ data: {
+ content: "❌ Please provide a message for your complaint.",
+ flags: 64,
+ },
+ });
+
+ const complainant = {
+ username:
+ interaction.member?.user?.username ||
+ interaction.user?.username ||
+ "Unknown",
+ id:
+ interaction.member?.user?.id || interaction.user?.id || "Unknown",
+ avatar:
+ interaction.member?.user?.avatar || interaction.user?.avatar,
+ };
+ const isDM = !interaction.guild_id;
+ const complaintEmbed = createComplaintEmbed(
+ complaintMessage,
+ complainant,
+ Date.now(),
+ isDM,
+ );
+ const success = await sendComplaintToChannel(
+ environment,
+ complaintEmbed,
+ );
+
+ if (success) {
+ return new JSONResponse({
+ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
+ data: {
+ content: "✅ Your complaint has been submitted successfully!",
+ flags: 64,
+ },
+ });
+ } else {
+ return new JSONResponse({
+ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
+ data: {
+ content:
+ "❌ Failed to submit your complaint. Please try again later.",
+ flags: 64,
+ },
+ });
+ }
+ } catch (error) {
+ console.error("Error in complain command:", error);
+
+ return new JSONResponse({
+ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
+ data: {
+ content: "❌ An error occurred while processing your complaint.",
+ flags: 64,
+ },
+ });
+ }
+ }
+
default:
return new JSONResponse({ error: "Unknown Type" }, { status: 400 });
}