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:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user