Implement conversation snapshot structure
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import { WhatsAppMessage, Conversation } from '../types';
|
||||
import { WhatsAppMessage, Conversation, Msg, Participant } from '../types';
|
||||
|
||||
const conversations = new Map<string, Conversation>();
|
||||
|
||||
@@ -19,6 +19,24 @@ async function loadMessages(
|
||||
return msgs;
|
||||
}
|
||||
|
||||
function mapMessage(m: WhatsAppMessage): Msg {
|
||||
return {
|
||||
id: m.id,
|
||||
from: m.from,
|
||||
to: m.to,
|
||||
ts: (m as any).timestamp || (m as any).t,
|
||||
type: ((m as any).type as any) || 'chat',
|
||||
text: (m as any).text || (m as any).caption || (m as any).body,
|
||||
mediaUrl: (m as any).cloudUrl || (m as any).clientUrl,
|
||||
mentions: ((m as any).mentionedJidList as any) || [],
|
||||
meta: {
|
||||
ack: (m as any).ack || 0,
|
||||
hasReaction: (m as any).hasReaction || false,
|
||||
isQuoted: !!(m as any).quotedMsg,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function getConversation(
|
||||
chatId: string,
|
||||
openWaUrl: string
|
||||
@@ -41,15 +59,61 @@ export async function buildConversation(
|
||||
openWaUrl: string
|
||||
): Promise<Conversation> {
|
||||
console.log(`[conversationStore] Building conversation for ${chatId}`);
|
||||
const messages = await loadMessages(chatId, openWaUrl);
|
||||
const rawMessages = await loadMessages(chatId, openWaUrl);
|
||||
const now = Date.now();
|
||||
|
||||
const first = rawMessages[0];
|
||||
const chat = first?.chat;
|
||||
const title = chat?.formattedTitle || chat?.name || chatId;
|
||||
const isGroup = chat?.isGroup || false;
|
||||
const unreadCount = chat?.unreadCount || 0;
|
||||
|
||||
const participantsMap = new Map<string, Participant>();
|
||||
if (chat?.contact) {
|
||||
const c = chat.contact;
|
||||
participantsMap.set(c.id, {
|
||||
id: c.id,
|
||||
name: c.pushname || c.name || '',
|
||||
isMe: c.isMe,
|
||||
});
|
||||
}
|
||||
if (isGroup && chat?.groupMetadata?.participants) {
|
||||
for (const p of chat.groupMetadata.participants as any[]) {
|
||||
const c = p.contact || {};
|
||||
const id = c.id || p.id;
|
||||
participantsMap.set(id, {
|
||||
id,
|
||||
name: c.pushname || c.name || '',
|
||||
isMe: c.isMe || false,
|
||||
isAdmin: p.isAdmin || p.isSuperAdmin,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const m of rawMessages) {
|
||||
const s = m.sender;
|
||||
if (s && !participantsMap.has(s.id)) {
|
||||
participantsMap.set(s.id, {
|
||||
id: s.id,
|
||||
name: s.pushname || s.name || '',
|
||||
isMe: s.isMe,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const messages: Msg[] = rawMessages.slice(-20).map(mapMessage);
|
||||
messages.sort((a, b) => a.ts - b.ts);
|
||||
|
||||
const conv: Conversation = {
|
||||
chatId,
|
||||
title,
|
||||
isGroup,
|
||||
unreadCount,
|
||||
participants: Array.from(participantsMap.values()),
|
||||
messages,
|
||||
createdAt: conversations.get(chatId)?.createdAt || now,
|
||||
updatedAt: now,
|
||||
messageCount: messages.length,
|
||||
};
|
||||
|
||||
conversations.set(chatId, conv);
|
||||
return conv;
|
||||
}
|
||||
@@ -66,8 +130,16 @@ export async function addMessageToConversation(
|
||||
): Promise<Conversation> {
|
||||
console.log(`[conversationStore] Adding message to ${chatId}`);
|
||||
const conv = await getConversation(chatId, openWaUrl);
|
||||
conv.messages.push(msg);
|
||||
conv.messageCount = conv.messages.length;
|
||||
conv.updatedAt = Date.now();
|
||||
const mapped = mapMessage(msg);
|
||||
conv.messages.push(mapped);
|
||||
if (conv.messages.length > 20) conv.messages.shift();
|
||||
const s = msg.sender;
|
||||
if (s && !conv.participants.some((p) => p.id === s.id)) {
|
||||
conv.participants.push({
|
||||
id: s.id,
|
||||
name: s.pushname || s.name || '',
|
||||
isMe: s.isMe,
|
||||
});
|
||||
}
|
||||
return conv;
|
||||
}
|
||||
|
||||
@@ -193,10 +193,35 @@ export interface WhatsAppMessage {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface Participant {
|
||||
id: string;
|
||||
name: string;
|
||||
isMe: boolean;
|
||||
isAdmin?: boolean;
|
||||
}
|
||||
|
||||
export interface Msg {
|
||||
id: string;
|
||||
from: string;
|
||||
to: string;
|
||||
ts: number;
|
||||
type: 'chat' | 'image' | 'audio' | 'sticker' | 'doc';
|
||||
text?: string;
|
||||
mediaUrl?: string;
|
||||
mentions?: string[];
|
||||
meta: {
|
||||
ack: number;
|
||||
hasReaction: boolean;
|
||||
isQuoted: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Conversation {
|
||||
chatId: string;
|
||||
messages: WhatsAppMessage[];
|
||||
title: string;
|
||||
isGroup: boolean;
|
||||
unreadCount: number;
|
||||
participants: Participant[];
|
||||
messages: Msg[];
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
messageCount: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user