feat: sanction DM links and per-event colour coding #13

Merged
naomi merged 2 commits from feat/sanction-dm-links into main 2026-03-31 17:33:35 -07:00
6 changed files with 41 additions and 10 deletions
Showing only changes of commit 088f74e559 - Show all commits
+4 -2
View File
@@ -14,7 +14,7 @@ import {
} from "discord.js";
import { logModerationAction } from "../modules/logModAction.js";
import { sendSanction } from "../modules/sendSanction.js";
import { errorReply, successReply } from "../utils/components.js";
import { errorReply, sanctionDmMessage, successReply } from "../utils/components.js";
import { logger } from "../utils/logger.js";
import type { Command } from "../interfaces/command.js";
@@ -103,7 +103,9 @@ const banCommand: Command = {
try {
await target.send(
`You have been banned from **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
sanctionDmMessage(
`You have been banned from **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
),
);
} catch {
// DMs may be closed; continue without failing the command.
+4 -2
View File
@@ -14,7 +14,7 @@ import {
} from "discord.js";
import { logModerationAction } from "../modules/logModAction.js";
import { sendSanction } from "../modules/sendSanction.js";
import { errorReply, successReply } from "../utils/components.js";
import { errorReply, sanctionDmMessage, successReply } from "../utils/components.js";
import { logger } from "../utils/logger.js";
import type { Command } from "../interfaces/command.js";
@@ -98,7 +98,9 @@ const kickCommand: Command = {
try {
await target.send(
`You have been kicked from **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
sanctionDmMessage(
`You have been kicked from **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
),
);
} catch {
// DMs may be closed; continue without failing the command.
+4 -2
View File
@@ -14,7 +14,7 @@ import {
} from "discord.js";
import { logModerationAction } from "../modules/logModAction.js";
import { sendSanction } from "../modules/sendSanction.js";
import { errorReply, successReply } from "../utils/components.js";
import { errorReply, sanctionDmMessage, successReply } from "../utils/components.js";
import { logger } from "../utils/logger.js";
import type { Command } from "../interfaces/command.js";
@@ -155,7 +155,9 @@ const muteCommand: Command = {
try {
await target.send(
`You have been muted in **${interaction.guild?.name ?? "the server"}** for **${durationLabel}**.\n**Reason:** ${reason}`,
sanctionDmMessage(
`You have been muted in **${interaction.guild?.name ?? "the server"}** for **${durationLabel}**.\n**Reason:** ${reason}`,
),
);
} catch {
// DMs may be closed; continue without failing the command.
+4 -2
View File
@@ -14,7 +14,7 @@ import {
} from "discord.js";
import { logModerationAction } from "../modules/logModAction.js";
import { sendSanction } from "../modules/sendSanction.js";
import { errorReply, successReply } from "../utils/components.js";
import { errorReply, sanctionDmMessage, successReply } from "../utils/components.js";
import { logger } from "../utils/logger.js";
import type { Command } from "../interfaces/command.js";
@@ -94,7 +94,9 @@ const softbanCommand: Command = {
try {
await target.send(
`You have been softbanned from **${interaction.guild?.name ?? "the server"}** (your recent messages have been removed).\n**Reason:** ${reason}`,
sanctionDmMessage(
`You have been softbanned from **${interaction.guild?.name ?? "the server"}** (your recent messages have been removed).\n**Reason:** ${reason}`,
),
);
} catch {
// DMs may be closed; continue without failing the command.
+4 -2
View File
@@ -14,7 +14,7 @@ import {
} from "discord.js";
import { logModerationAction } from "../modules/logModAction.js";
import { sendSanction } from "../modules/sendSanction.js";
import { errorReply, successReply } from "../utils/components.js";
import { errorReply, sanctionDmMessage, successReply } from "../utils/components.js";
import { logger } from "../utils/logger.js";
import type { Command } from "../interfaces/command.js";
@@ -99,7 +99,9 @@ const warnCommand: Command = {
try {
await target.send(
`You have received a warning in **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
sanctionDmMessage(
`You have received a warning in **${interaction.guild?.name ?? "the server"}**.\n**Reason:** ${reason}`,
),
);
} catch {
// DMs may be closed; continue without failing the command.
+21
View File
@@ -173,10 +173,31 @@ const memberMessage = (
};
};
const sanctionLinks = [
"**Appeal this sanction:** https://forms.nhcarrigan.com/o/docs/forms/4w5VHsYiEkiS2mewvtuJYL/4",
"**View sanction logs:** https://hikari.nhcarrigan.com/sanctions",
"**Contact us:** https://docs.nhcarrigan.com/about/contact/",
"**Rejoin our community:** https://chat.nhcarrigan.com",
].join("\n");
/**
* Builds a Components v2 DM payload for sanction notifications.
* Includes a separator between the sanction details and the resource links.
* @param sanctionText - The formatted sanction message (action + reason).
* @returns A Discord message payload object.
*/
const sanctionDmMessage = (sanctionText: string): Record<string, unknown> => {
return {
components: [ buildContainer("modAction", sanctionText, sanctionLinks) ],
flags: MessageFlags.IsComponentsV2,
};
};
export {
activityMessage,
errorReply,
memberMessage,
modLogMessage,
sanctionDmMessage,
successReply,
};