corregidas imcompativilidades despues del merge
All checks were successful
Deploy conversation layer / deploy (push) Successful in 2m4s

This commit is contained in:
2025-06-06 14:57:53 -06:00
parent 3bd2922e9d
commit 603322258a
2 changed files with 73 additions and 53 deletions

View File

@@ -41,4 +41,4 @@ export function registerConversationRoutes(app: Application, openWaUrl: string |
const deleted = deleteConversation(req.params.id); const deleted = deleteConversation(req.params.id);
res.json({ success: deleted }); res.json({ success: deleted });
}); });
} }

View File

@@ -3,81 +3,108 @@ import { WhatsAppMessage, Conversation, Msg, Participant } from '../types';
const conversations = new Map<string, Conversation>(); const conversations = new Map<string, Conversation>();
// ──────────────────────────── Helpers ───────────────────────────── async function loadMessages(
chatId: string,
async function fetchChatMessages(chatId: string, openWaUrl: string): Promise<WhatsAppMessage[]> { openWaUrl: string
): Promise<WhatsAppMessage[]> {
console.log(`[conversationStore] Loading messages for ${chatId}`);
const { data } = await axios.post(`${openWaUrl}/loadAndGetAllMessagesInChat`, { const { data } = await axios.post(`${openWaUrl}/loadAndGetAllMessagesInChat`, {
args: { chatId, includeMe: true, includeNotifications: true }, args: {
chatId,
includeMe: true,
includeNotifications: true,
},
}); });
return data?.response ?? data ?? []; const msgs: WhatsAppMessage[] = data?.response || data || [];
return msgs;
} }
function toMsg(m: WhatsAppMessage): Msg { function mapMessage(m: WhatsAppMessage): Msg {
const anyMsg = m as any;
return { return {
id: m.id, id: m.id,
from: m.from, from: m.from,
to: m.to, to: m.to,
ts: anyMsg.timestamp ?? anyMsg.t ?? Date.now(), ts: (m as any).timestamp || (m as any).t,
type: anyMsg.type ?? 'chat', type: ((m as any).type as any) || 'chat',
text: anyMsg.text ?? anyMsg.caption ?? anyMsg.body ?? '', text: (m as any).text || (m as any).caption || (m as any).body,
mediaUrl: anyMsg.cloudUrl ?? anyMsg.clientUrl, mediaUrl: (m as any).cloudUrl || (m as any).clientUrl,
mentions: anyMsg.mentionedJidList ?? [], mentions: ((m as any).mentionedJidList as any) || [],
meta: { meta: {
ack: anyMsg.ack ?? 0, ack: (m as any).ack || 0,
hasReaction: Boolean(anyMsg.hasReaction), hasReaction: (m as any).hasReaction || false,
isQuoted: Boolean(anyMsg.quotedMsg), isQuoted: !!(m as any).quotedMsg,
}, },
}; };
} }
function buildParticipants(messages: WhatsAppMessage[], chat?: any): Participant[] { export async function getConversation(
const map = new Map<string, Participant>(); chatId: string,
openWaUrl: string
): Promise<Conversation> {
console.log(`[conversationStore] Retrieving conversation for ${chatId}`);
let conv = conversations.get(chatId);
if (!conv) {
conv = await buildConversation(chatId, openWaUrl);
}
return conv;
}
export function listConversations(): Conversation[] {
console.log('[conversationStore] Listing conversations');
return Array.from(conversations.values());
}
export async function buildConversation(
chatId: string,
openWaUrl: string
): Promise<Conversation> {
console.log(`[conversationStore] Building conversation for ${chatId}`);
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) { if (chat?.contact) {
const c = chat.contact; const c = chat.contact;
map.set(c.id, { participantsMap.set(c.id, {
id: c.id, id: c.id,
name: c.pushname || c.name || '', name: c.pushname || c.name || '',
isMe: Boolean(c.isMe), isMe: c.isMe,
}); });
} }
if (isGroup && chat?.groupMetadata?.participants) {
if (chat?.isGroup && chat.groupMetadata?.participants) {
for (const p of chat.groupMetadata.participants as any[]) { for (const p of chat.groupMetadata.participants as any[]) {
const c = p.contact || {}; const c = p.contact || {};
const id = c.id || p.id; const id = c.id || p.id;
map.set(id, { participantsMap.set(id, {
id, id,
name: c.pushname || c.name || '', name: c.pushname || c.name || '',
isMe: Boolean(c.isMe), isMe: c.isMe || false,
isAdmin: Boolean(p.isAdmin || p.isSuperAdmin), isAdmin: p.isAdmin || p.isSuperAdmin,
}); });
} }
} }
for (const m of messages) { for (const m of rawMessages) {
const s = m.sender; const s = m.sender;
if (s && !map.has(s.id)) { if (s && !participantsMap.has(s.id)) {
map.set(s.id, { participantsMap.set(s.id, {
id: s.id, id: s.id,
name: s.pushname || s.name || '', name: s.pushname || s.name || '',
isMe: Boolean(s.isMe), isMe: s.isMe,
}); });
} }
} }
return [...map.values()]; const messages: Msg[] = rawMessages.slice(-20).map(mapMessage);
} messages.sort((a, b) => a.ts - b.ts);
// ──────────────────────────── Public API ───────────────────────────── const conv: Conversation = {
export async function buildConversation(chatId: string, openWaUrl: string): Promise<Conversation> {
const raw = await fetchChatMessages(chatId, openWaUrl);
const chat = raw[0]?.chat;
const now = Date.now();
const conversation: Conversation = {
chatId, chatId,
title, title,
isGroup, isGroup,
@@ -87,21 +114,12 @@ export async function buildConversation(chatId: string, openWaUrl: string): Prom
createdAt: conversations.get(chatId)?.createdAt || now, createdAt: conversations.get(chatId)?.createdAt || now,
}; };
conversations.set(chatId, conversation); conversations.set(chatId, conv);
return conversation;
}
export async function getConversation(chatId: string, openWaUrl: string): Promise<Conversation> {
let conv = conversations.get(chatId);
if (!conv) conv = await buildConversation(chatId, openWaUrl);
return conv; return conv;
} }
export function listConversations(): Conversation[] {
return [...conversations.values()];
}
export function deleteConversation(chatId: string): boolean { export function deleteConversation(chatId: string): boolean {
console.log(`[conversationStore] Deleting conversation ${chatId}`);
return conversations.delete(chatId); return conversations.delete(chatId);
} }
@@ -110,8 +128,10 @@ export async function addMessageToConversation(
msg: WhatsAppMessage, msg: WhatsAppMessage,
openWaUrl: string openWaUrl: string
): Promise<Conversation> { ): Promise<Conversation> {
console.log(`[conversationStore] Adding message to ${chatId}`);
const conv = await getConversation(chatId, openWaUrl); const conv = await getConversation(chatId, openWaUrl);
const mapped = toMsg(msg); const mapped = mapMessage(msg);
// avoid duplicates if multiple webhook events deliver the same message
if (!conv.messages.some((m) => m.id === mapped.id)) { if (!conv.messages.some((m) => m.id === mapped.id)) {
conv.messages.push(mapped); conv.messages.push(mapped);
if (conv.messages.length > 20) conv.messages.shift(); if (conv.messages.length > 20) conv.messages.shift();
@@ -121,9 +141,9 @@ export async function addMessageToConversation(
conv.participants.push({ conv.participants.push({
id: s.id, id: s.id,
name: s.pushname || s.name || '', name: s.pushname || s.name || '',
isMe: Boolean(s.isMe), isMe: s.isMe,
}); });
} }
return conv; return conv;
} }