Skip to content

Commit 13fbddd

Browse files
authored
Merge pull request #559 from seeyebe/feat/log-replied-message
feat: add reply info in message delete log
2 parents 26bbe55 + 8039edf commit 13fbddd

File tree

9 files changed

+117
-15
lines changed

9 files changed

+117
-15
lines changed

backend/src/data/DefaultLogMessages.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
"ROLE_UPDATE": "{timestamp} 🖊 Role **{newRole.name}** (`{newRole.id}`) was edited. Changes:\n{differenceString}",
3636

3737
"MESSAGE_EDIT": "{timestamp} ✏ {userMention(user)} edited their message (`{after.id}`) in {channelMention(channel)}:\n**Before:**{messageSummary(before)}**After:**{messageSummary(after)}",
38-
"MESSAGE_DELETE": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
38+
"MESSAGE_DELETE": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
3939
"MESSAGE_DELETE_BULK": "{timestamp} 🗑 **{count}** messages by {authorIds} deleted in {channelMention(channel)} ({archiveUrl})",
4040
"MESSAGE_DELETE_BARE": "{timestamp} 🗑 Message (`{messageId}`) deleted in {channelMention(channel)} (no more info available)",
41-
"MESSAGE_DELETE_AUTO": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
41+
"MESSAGE_DELETE_AUTO": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
4242

4343
"VOICE_CHANNEL_JOIN": "{timestamp} 🎙 🔵 {userMention(member)} joined {channelMention(channel)}",
4444
"VOICE_CHANNEL_MOVE": "{timestamp} 🎙 ↔ {userMention(member)} moved from {channelMention(oldChannel)} to {channelMention(newChannel)}",

backend/src/data/GuildSavedMessages.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ export class GuildSavedMessages extends BaseGuildRepository<SavedMessage> {
119119
}));
120120
}
121121

122+
if (msg.reference && (msg.reference.messageId || msg.reference.channelId || msg.reference.guildId)) {
123+
data.reference = {
124+
messageId: msg.reference.messageId ?? null,
125+
channelId: msg.reference.channelId ?? null,
126+
guildId: msg.reference.guildId ?? null,
127+
};
128+
}
129+
122130
return data;
123131
}
124132

backend/src/data/entities/SavedMessage.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ export interface ISavedMessageData {
7575
embeds?: ISavedMessageEmbedData[];
7676
stickers?: ISavedMessageStickerData[];
7777
timestamp: number;
78+
reference?: {
79+
messageId?: Snowflake | null;
80+
channelId?: Snowflake | null;
81+
guildId?: Snowflake | null;
82+
};
7883
}
7984

8085
@Entity("messages")

backend/src/plugins/Logs/logFunctions/logMessageDelete.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@ import {
1414
import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin.js";
1515
import { LogsPluginType } from "../types.js";
1616
import { log } from "../util/log.js";
17+
import { getMessageReplyLogInfo } from "../util/getMessageReplyLogInfo.js";
1718

1819
export interface LogMessageDeleteData {
1920
user: User | UnknownUser;
2021
channel: GuildTextBasedChannel;
2122
message: SavedMessage;
2223
}
2324

24-
export function logMessageDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteData) {
25+
export async function logMessageDelete(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteData) {
2526
// Replace attachment URLs with media URLs
2627
if (data.message.data.attachments) {
2728
for (const attachment of data.message.data.attachments as ISavedMessageAttachmentData[]) {
@@ -33,6 +34,8 @@ export function logMessageDelete(pluginData: GuildPluginData<LogsPluginType>, da
3334
const config = pluginData.config.get();
3435
const timestampFormat = config.timestamp_format ?? undefined;
3536

37+
const { replyInfo, reply } = await getMessageReplyLogInfo(pluginData, data.message);
38+
3639
return log(
3740
pluginData,
3841
LogType.MESSAGE_DELETE,
@@ -44,6 +47,8 @@ export function logMessageDelete(pluginData: GuildPluginData<LogsPluginType>, da
4447
.getPlugin(TimeAndDatePlugin)
4548
.inGuildTz(moment.utc(data.message.data.timestamp, "x"))
4649
.format(timestampFormat),
50+
replyInfo,
51+
reply,
4752
}),
4853
{
4954
userId: data.user.id,

backend/src/plugins/Logs/logFunctions/logMessageDeleteAuto.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { GuildBasedChannel, User } from "discord.js";
22
import { GuildPluginData } from "vety";
33
import { LogType } from "../../../data/LogType.js";
4-
import { SavedMessage } from "../../../data/entities/SavedMessage.js";
4+
import { ISavedMessageAttachmentData, SavedMessage } from "../../../data/entities/SavedMessage.js";
55
import { createTypedTemplateSafeValueContainer } from "../../../templateFormatter.js";
6-
import { UnknownUser } from "../../../utils.js";
6+
import { UnknownUser, useMediaUrls } from "../../../utils.js";
77
import { resolveChannelIds } from "../../../utils/resolveChannelIds.js";
88
import {
99
channelToTemplateSafeChannel,
@@ -12,6 +12,7 @@ import {
1212
} from "../../../utils/templateSafeObjects.js";
1313
import { LogsPluginType } from "../types.js";
1414
import { log } from "../util/log.js";
15+
import { getMessageReplyLogInfo } from "../util/getMessageReplyLogInfo.js";
1516

1617
export interface LogMessageDeleteAutoData {
1718
message: SavedMessage;
@@ -20,7 +21,15 @@ export interface LogMessageDeleteAutoData {
2021
messageDate: string;
2122
}
2223

23-
export function logMessageDeleteAuto(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteAutoData) {
24+
export async function logMessageDeleteAuto(pluginData: GuildPluginData<LogsPluginType>, data: LogMessageDeleteAutoData) {
25+
if (data.message.data.attachments) {
26+
for (const attachment of data.message.data.attachments as ISavedMessageAttachmentData[]) {
27+
attachment.url = useMediaUrls(attachment.url);
28+
}
29+
}
30+
31+
const { replyInfo, reply } = await getMessageReplyLogInfo(pluginData, data.message);
32+
2433
return log(
2534
pluginData,
2635
LogType.MESSAGE_DELETE_AUTO,
@@ -29,6 +38,8 @@ export function logMessageDeleteAuto(pluginData: GuildPluginData<LogsPluginType>
2938
user: userToTemplateSafeUser(data.user),
3039
channel: channelToTemplateSafeChannel(data.channel),
3140
messageDate: data.messageDate,
41+
replyInfo,
42+
reply,
3243
}),
3344
{
3445
userId: data.user.id,

backend/src/plugins/Logs/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ export const LogTypeData = z.object({
239239
channel: z.instanceof(TemplateSafeChannel),
240240
messageDate: z.string(),
241241
message: z.instanceof(TemplateSafeSavedMessage),
242+
replyInfo: z.string(),
243+
reply: z.instanceof(TemplateSafeValueContainer).nullable(),
242244
}),
243245

244246
[LogType.MESSAGE_DELETE_BULK]: z.object({
@@ -489,6 +491,8 @@ export const LogTypeData = z.object({
489491
user: z.instanceof(TemplateSafeUser),
490492
channel: z.instanceof(TemplateSafeChannel),
491493
messageDate: z.string(),
494+
replyInfo: z.string(),
495+
reply: z.instanceof(TemplateSafeValueContainer).nullable(),
492496
}),
493497

494498
[LogType.SET_ANTIRAID_USER]: z.object({
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { GuildPluginData } from "knub";
2+
import { ISavedMessageAttachmentData, SavedMessage } from "../../../data/entities/SavedMessage.js";
3+
import { messageLink, messageSummary, useMediaUrls } from "../../../utils.js";
4+
import { TemplateSafeValueContainer } from "../../../templateFormatter.js";
5+
import { savedMessageToTemplateSafeSavedMessage, TemplateSafeSavedMessage } from "../../../utils/templateSafeObjects.js";
6+
import { LogsPluginType } from "../types.js";
7+
8+
export interface MessageReplyLogInfo {
9+
replyInfo: string;
10+
reply: TemplateSafeValueContainer | null;
11+
}
12+
13+
export async function getMessageReplyLogInfo(
14+
pluginData: GuildPluginData<LogsPluginType>,
15+
message: SavedMessage,
16+
): Promise<MessageReplyLogInfo> {
17+
const reference = message.data.reference;
18+
if (!reference?.messageId || !reference.channelId) {
19+
return { replyInfo: "", reply: null };
20+
}
21+
22+
const link = messageLink(reference.guildId ?? message.guild_id, reference.channelId, reference.messageId);
23+
let replyInfo = `\n**Replied To:** [Jump to message](${link})`;
24+
25+
const referencedMessage = await pluginData.state.savedMessages.find(reference.messageId, true);
26+
27+
let timestamp: string | null = null;
28+
let summary: string | null = null;
29+
let timestampMs: number | null = null;
30+
let templateSafeMessage: TemplateSafeSavedMessage | null = null;
31+
32+
if (referencedMessage) {
33+
if (referencedMessage.data.attachments) {
34+
for (const attachment of referencedMessage.data.attachments as ISavedMessageAttachmentData[]) {
35+
attachment.url = useMediaUrls(attachment.url);
36+
}
37+
}
38+
39+
timestampMs = referencedMessage.data.timestamp;
40+
timestamp = `<t:${Math.floor(timestampMs / 1000)}>`;
41+
replyInfo += ` (posted at ${timestamp})`;
42+
43+
summary = messageSummary(referencedMessage);
44+
if (summary) {
45+
replyInfo += `\n${summary}`;
46+
}
47+
48+
templateSafeMessage = savedMessageToTemplateSafeSavedMessage(referencedMessage);
49+
}
50+
51+
const reply = new TemplateSafeValueContainer({
52+
link,
53+
timestamp,
54+
timestampMs,
55+
summary,
56+
message: templateSafeMessage,
57+
});
58+
59+
return { replyInfo, reply };
60+
}

backend/src/utils/templateSafeObjects.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ export class TemplateSafeSavedMessageData extends TemplateSafeValueContainer {
191191
embeds?: Array<TypedTemplateSafeValueContainer<ISavedMessageEmbedData>>;
192192
stickers?: Array<TypedTemplateSafeValueContainer<ISavedMessageStickerData>>;
193193
timestamp: number;
194+
reference?: TypedTemplateSafeValueContainer<ISavedMessageData["reference"]>;
194195

195196
constructor(data: InputProps<TemplateSafeSavedMessageData>) {
196197
super();
@@ -445,6 +446,14 @@ export function savedMessageToTemplateSafeSavedMessage(savedMessage: SavedMessag
445446
),
446447

447448
timestamp: savedMessage.data.timestamp,
449+
450+
reference: savedMessage.data.reference
451+
? (new TemplateSafeValueContainer({
452+
messageId: savedMessage.data.reference.messageId ?? null,
453+
channelId: savedMessage.data.reference.channelId ?? null,
454+
guildId: savedMessage.data.reference.guildId ?? null,
455+
}) as TypedTemplateSafeValueContainer<ISavedMessageData["reference"]>)
456+
: undefined,
448457
}),
449458
});
450459
}

config-checker/public/config-schema.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9210,7 +9210,7 @@
92109210
]
92119211
},
92129212
"MESSAGE_DELETE": {
9213-
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
9213+
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
92149214
"anyOf": [
92159215
{
92169216
"type": "string"
@@ -9650,7 +9650,7 @@
96509650
]
96519651
},
96529652
"MESSAGE_DELETE_AUTO": {
9653-
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
9653+
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
96549654
"anyOf": [
96559655
{
96569656
"type": "string"
@@ -10037,7 +10037,7 @@
1003710037
]
1003810038
},
1003910039
"MESSAGE_DELETE": {
10040-
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
10040+
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1004110041
"anyOf": [
1004210042
{
1004310043
"type": "string"
@@ -10477,7 +10477,7 @@
1047710477
]
1047810478
},
1047910479
"MESSAGE_DELETE_AUTO": {
10480-
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
10480+
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1048110481
"anyOf": [
1048210482
{
1048310483
"type": "string"
@@ -11153,7 +11153,7 @@
1115311153
]
1115411154
},
1115511155
"MESSAGE_DELETE": {
11156-
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
11156+
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1115711157
"anyOf": [
1115811158
{
1115911159
"type": "string"
@@ -11593,7 +11593,7 @@
1159311593
]
1159411594
},
1159511595
"MESSAGE_DELETE_AUTO": {
11596-
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
11596+
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1159711597
"anyOf": [
1159811598
{
1159911599
"type": "string"
@@ -11980,7 +11980,7 @@
1198011980
]
1198111981
},
1198211982
"MESSAGE_DELETE": {
11983-
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
11983+
"default": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1198411984
"anyOf": [
1198511985
{
1198611986
"type": "string"
@@ -12420,7 +12420,7 @@
1242012420
]
1242112421
},
1242212422
"MESSAGE_DELETE_AUTO": {
12423-
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
12423+
"default": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
1242412424
"anyOf": [
1242512425
{
1242612426
"type": "string"
@@ -20882,4 +20882,4 @@
2088220882
}
2088320883
},
2088420884
"$schema": "https://json-schema.org/draft-2020-12/schema"
20885-
}
20885+
}

0 commit comments

Comments
 (0)