Refactor: Modularize whatsapp-router interactions

This commit introduces a significant refactoring to the whatsapp-router service to improve modularity and extend its capabilities for interacting with OpenWA (nucleo-whatsapp).

Key changes include:

1.  **Message Processing Logic**:
    *   Created a new `messageProcessor.ts` module.
    *   Moved message mapping (`mapWhatsAppMessageToMsg`), message addition to conversations (`processIncomingMessageForConversation`), and audio transcription handling (`handleAudioMessageTranscription`) into this new module.
    *   Updated `store/conversation.ts` and `webhook.ts` to utilize `messageProcessor.ts`, streamlining their responsibilities.

2.  **OpenWA Client (`nucleoClient.ts`)**:
    *   Introduced `nucleoClient.ts`, a dedicated module for encapsulating API calls to OpenWA.
    *   Implemented functions for various OpenWA commands:
        *   Sending text, image, and file messages.
        *   Fetching chat and contact information.
        *   Creating groups.
        *   Managing the blocklist (get, block, unblock).
        *   Listing all chats and fetching messages for a specific chat.
    *   Includes error handling and basic typing for API responses.

3.  **New API Endpoints (`routes/nucleoActions.ts`)**:
    *   Created `nucleoActions.ts` to expose the functionalities of `nucleoClient.ts` via a new set of HTTP API endpoints.
    *   Endpoints cover all implemented client functions, with request validation and robust error handling.
    *   These routes are grouped under the `/nucleo` base path.

4.  **Route Registration**:
    *   Registered the new `/nucleo` routes in the main `index.ts` file.

5.  **Conversation Store and Routes Review**:
    *   Reviewed and confirmed that `store/conversation.ts` and `routes/conversations.ts` are correctly integrated with the new `messageProcessor.ts` and remain focused on their core responsibilities.

This refactoring enhances the structure of `whatsapp-router`, making it easier to maintain and extend. It also provides a comprehensive set of API endpoints for more granular control over OpenWA functionalities.
This commit is contained in:
google-labs-jules[bot]
2025-06-07 02:49:50 +00:00
parent b39db9ad06
commit 2ea837c2ae
6 changed files with 695 additions and 64 deletions

View File

@@ -1,5 +1,6 @@
import axios from 'axios';
import { WhatsAppMessage, Conversation, Msg, Participant } from '../types';
import { mapWhatsAppMessageToMsg, processIncomingMessageForConversation } from '../messageProcessor';
const conversations = new Map<string, Conversation>();
@@ -19,24 +20,6 @@ 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
@@ -101,7 +84,7 @@ export async function buildConversation(
}
}
const messages: Msg[] = rawMessages.slice(-20).map(mapMessage);
const messages: Msg[] = rawMessages.slice(-20).map(mapWhatsAppMessageToMsg);
messages.sort((a, b) => a.ts - b.ts);
const conv: Conversation = {
@@ -130,20 +113,13 @@ export async function addMessageToConversation(
): Promise<Conversation> {
console.log(`[conversationStore] Adding message to ${chatId}`);
const conv = await getConversation(chatId, openWaUrl);
const mapped = mapMessage(msg);
// avoid duplicates if multiple webhook events deliver the same message
if (!conv.messages.some((m) => m.id === mapped.id)) {
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,
});
}
// 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;
}