feat: detect reply/forward/crosspost in message capture + inject into AI moderation

- Add is_reply, is_forward, is_crosspost, reference_message_id,
  reference_channel_id, reference_guild_id columns to messages table
- Update MessageRecord type with reference fields
- Extract reply/forward/crosspost from Discord message type/flags
- Track reference.type (DEFAULT=reply, FORWARD) and CROSSPOSTED flag
- Inject <reference> XML with parent content into LLM moderation prompt
- Add reply/forward/crosspost rules to moderation prompt rules
- Format context messages with [reply_to], [forward_from], [crosspost]
- Add migration 0009

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-13 00:55:42 +07:00
co-authored by Claude
parent 0ac056dc8a
commit e3249edb6c
9 changed files with 133 additions and 8 deletions
@@ -81,7 +81,9 @@ export interface RichMessageMetadata {
messageId: string | null;
channelId: string | null;
guildId: string | null;
type: string | null;
} | null;
isCrosspost: boolean;
}
export function getMessageLocation(message: Message): MessageLocation {
@@ -235,8 +237,10 @@ export function getMessageMetadata(message: Message): RichMessageMetadata {
messageId: message.reference.messageId ?? null,
channelId: message.reference.channelId ?? null,
guildId: message.reference.guildId ?? null,
type: (message.reference.type as unknown as string | undefined) ?? null,
}
: null,
isCrosspost: message.flags?.has(1 << 1) ?? false,
};
}
@@ -258,6 +262,7 @@ export function parseRichMessageMetadata(
member: (parsed.member ?? null) as RichMessageMetadata["member"],
channel: parsed.channel as RichMessageMetadata["channel"],
reference: (parsed.reference ?? null) as RichMessageMetadata["reference"],
isCrosspost: Boolean(parsed.isCrosspost),
};
} catch {
return null;