128 lines
3.7 KiB
TypeScript
128 lines
3.7 KiB
TypeScript
import axios from 'axios';
|
|
import { WhatsAppMessage, Conversation, Msg, Participant } from '../types';
|
|
import { mapWhatsAppMessageToMsg, processIncomingMessageForConversation } from '../messageProcessor';
|
|
|
|
const conversations = new Map<string, Conversation>();
|
|
|
|
async function loadMessages(
|
|
chatId: string,
|
|
openWaUrl: string
|
|
): Promise<WhatsAppMessage[]> {
|
|
console.log(`[conversationStore] Loading messages for ${chatId}`);
|
|
const { data } = await axios.post(`${openWaUrl}/loadAndGetAllMessagesInChat`, {
|
|
args: {
|
|
chatId,
|
|
includeMe: true,
|
|
includeNotifications: true,
|
|
},
|
|
});
|
|
const msgs: WhatsAppMessage[] = data?.response || data || [];
|
|
return msgs;
|
|
}
|
|
|
|
export async function getConversation(
|
|
chatId: string,
|
|
openWaUrl: string,
|
|
incommingMessage?: WhatsAppMessage
|
|
): Promise<Conversation> {
|
|
console.log(`[conversationStore] Retrieving conversation for ${chatId}`);
|
|
let conv = conversations.get(chatId);
|
|
if (!conv) {
|
|
conv = await buildConversation(chatId, openWaUrl, incommingMessage);
|
|
}
|
|
return conv;
|
|
}
|
|
|
|
export function listConversations(): Conversation[] {
|
|
console.log('[conversationStore] Listing conversations');
|
|
return Array.from(conversations.values());
|
|
}
|
|
|
|
export async function buildConversation(
|
|
chatId: string,
|
|
openWaUrl: string,
|
|
incommingMessage?: WhatsAppMessage
|
|
): Promise<Conversation> {
|
|
console.log(`[conversationStore] Building conversation for ${chatId}`);
|
|
const rawMessages = await loadMessages(chatId, openWaUrl);
|
|
const now = Date.now();
|
|
|
|
const first = rawMessages[0] = incommingMessage || 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.map(mapWhatsAppMessageToMsg);
|
|
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,
|
|
};
|
|
|
|
conversations.set(chatId, conv);
|
|
return conv;
|
|
}
|
|
|
|
export function deleteConversation(chatId: string): boolean {
|
|
console.log(`[conversationStore] Deleting conversation ${chatId}`);
|
|
return conversations.delete(chatId);
|
|
}
|
|
|
|
export async function addMessageToConversation(
|
|
chatId: string,
|
|
msg: WhatsAppMessage,
|
|
openWaUrl: string
|
|
): Promise<Conversation> {
|
|
console.log(`[conversationStore] Adding message to ${chatId}`);
|
|
const conv = await getConversation(chatId, openWaUrl, msg);
|
|
|
|
// Delegate message processing to the new function
|
|
// processIncomingMessageForConversation modifies `conv` directly
|
|
processIncomingMessageForConversation(conv, msg);
|
|
|
|
// Ensure the conversation is updated in the map (though it's by reference as conv is an object)
|
|
|
|
conversations.set(chatId, conv);
|
|
|
|
return conv;
|
|
} |