fix(bots): intercept /confess so original never hits chat

Root cause of "not anonymous":
1. Confess deleted via raw SQL with no MESSAGE_DELETE broadcast
2. Frontend extractIds only accepted message_id, but deletes send id
   so live clients never removed deleted messages without refresh

Fix:
- Intercept /confess at message create: never store or broadcast the
  original; post only the anonymous bot message
- Accept both id and message_id on MESSAGE_DELETE in the WS store
- Include both fields on delete broadcasts
This commit is contained in:
2026-07-15 20:28:47 -04:00
parent 13bd4478f6
commit 7bf1eaf845
5 changed files with 165 additions and 78 deletions
+11 -3
View File
@@ -52,9 +52,17 @@ function isRecord(value: unknown): value is Record<string, unknown> {
}
function extractIds(payload: UnknownPayload | undefined): { channel_id?: string; conversation_id?: string; message_id: string } | null {
if (!payload || typeof payload.message_id !== 'string') return null;
if (typeof payload.channel_id === 'string') return { channel_id: payload.channel_id, message_id: payload.message_id };
if (typeof payload.conversation_id === 'string') return { conversation_id: payload.conversation_id, message_id: payload.message_id };
if (!payload) return null;
// Backend MESSAGE_DELETE uses "id"; some other events use "message_id".
const messageId =
typeof payload.message_id === 'string'
? payload.message_id
: typeof payload.id === 'string'
? payload.id
: null;
if (!messageId) return null;
if (typeof payload.channel_id === 'string') return { channel_id: payload.channel_id, message_id: messageId };
if (typeof payload.conversation_id === 'string') return { conversation_id: payload.conversation_id, message_id: messageId };
return null;
}