56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
|
|
@Injectable()
|
|
export class WhatsappDebounceService {
|
|
private pendingMessages: Map<
|
|
string,
|
|
{
|
|
timer: NodeJS.Timeout;
|
|
texts: string[];
|
|
}
|
|
> = new Map();
|
|
|
|
private readonly DEBOUNCE_MS = 3000;
|
|
|
|
/**
|
|
* Agrega un mensaje al buffer del usuario.
|
|
* @param userId Identificador único del usuario (ej. JID)
|
|
* @param messageText Texto del mensaje
|
|
* @param callback Función a ejecutar cuando se complete el debounce (recibe el texto combinado)
|
|
*/
|
|
async add(
|
|
userId: string,
|
|
messageText: string,
|
|
callback: (combinedMessage: string) => Promise<void>,
|
|
): Promise<void> {
|
|
if (this.pendingMessages.has(userId)) {
|
|
const pending = this.pendingMessages.get(userId)!;
|
|
clearTimeout(pending.timer);
|
|
pending.texts.push(messageText);
|
|
|
|
pending.timer = setTimeout(async () => {
|
|
await this.flush(userId, callback);
|
|
}, this.DEBOUNCE_MS);
|
|
} else {
|
|
this.pendingMessages.set(userId, {
|
|
timer: setTimeout(async () => {
|
|
await this.flush(userId, callback);
|
|
}, this.DEBOUNCE_MS),
|
|
texts: [messageText],
|
|
});
|
|
}
|
|
}
|
|
|
|
private async flush(
|
|
userId: string,
|
|
callback: (combinedMessage: string) => Promise<void>,
|
|
): Promise<void> {
|
|
const pending = this.pendingMessages.get(userId);
|
|
if (!pending) return;
|
|
|
|
this.pendingMessages.delete(userId);
|
|
const combinedMessage = pending.texts.join(' ');
|
|
await callback(combinedMessage);
|
|
}
|
|
}
|