Skip to content

Commit f786263

Browse files
committed
fix(chatwoot): otimizar lógica de reabertura de conversas e notificação de conexão
Este commit introduz melhorias na integração com o Chatwoot, focando na reabertura de conversas e na notificação de conexão. A lógica foi refatorada para centralizar a busca por conversas abertas e a reabertura de conversas resolvidas, garantindo que interações não sejam perdidas. Além disso, foi implementado um intervalo mínimo para notificações de conexão, evitando mensagens excessivas e melhorando a experiência do usuário.
1 parent 0d8e8bc commit f786263

File tree

1 file changed

+71
-57
lines changed

1 file changed

+71
-57
lines changed

src/api/integrations/chatbot/chatwoot/services/chatwoot.service.ts

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import mimeTypes from 'mime-types';
3333
import path from 'path';
3434
import { Readable } from 'stream';
3535

36+
const MIN_CONNECTION_NOTIFICATION_INTERVAL_MS = 30000; // 30 seconds
37+
3638
interface ChatwootMessage {
3739
messageId?: number;
3840
inboxId?: number;
@@ -747,43 +749,14 @@ export class ChatwootService {
747749
return null;
748750
}
749751

750-
let inboxConversation = null;
751-
752-
if (this.provider.reopenConversation) {
753-
inboxConversation = contactConversations.payload.find(
754-
(conversation) =>
755-
conversation && conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id,
756-
);
757-
758-
if (inboxConversation) {
759-
this.logger.verbose(
760-
`Found open conversation in reopenConversation mode: ${JSON.stringify(inboxConversation)}`,
761-
);
762-
} else {
763-
inboxConversation = contactConversations.payload.find(
764-
(conversation) => conversation.inbox_id == filterInbox.id,
765-
);
752+
let inboxConversation = this.findOpenConversation(contactConversations.payload, filterInbox.id);
766753

767-
if (inboxConversation) {
768-
this.logger.verbose(`Found resolved conversation to reopen: ${JSON.stringify(inboxConversation)}`);
769-
if (this.provider.conversationPending && inboxConversation.status !== 'open') {
770-
await client.conversations.toggleStatus({
771-
accountId: this.provider.accountId,
772-
conversationId: inboxConversation.id,
773-
data: {
774-
status: 'pending',
775-
},
776-
});
777-
this.logger.verbose(`Reopened resolved conversation ID: ${inboxConversation.id}`);
778-
}
779-
}
780-
}
781-
} else {
782-
inboxConversation = contactConversations.payload.find(
783-
(conversation) =>
784-
conversation && conversation.status !== 'resolved' && conversation.inbox_id == filterInbox.id,
754+
if (!inboxConversation && this.provider.reopenConversation) {
755+
inboxConversation = await this.findAndReopenResolvedConversation(
756+
client,
757+
contactConversations.payload,
758+
filterInbox.id,
785759
);
786-
this.logger.verbose(`Found conversation: ${JSON.stringify(inboxConversation)}`);
787760
}
788761

789762
if (inboxConversation) {
@@ -832,6 +805,45 @@ export class ChatwootService {
832805
}
833806
}
834807

808+
private findOpenConversation(conversations: any[], inboxId: number): any | null {
809+
const openConversation = conversations.find(
810+
(conversation) => conversation && conversation.status !== 'resolved' && conversation.inbox_id == inboxId,
811+
);
812+
813+
if (openConversation) {
814+
this.logger.verbose(`Found open conversation: ${JSON.stringify(openConversation)}`);
815+
}
816+
817+
return openConversation || null;
818+
}
819+
820+
private async findAndReopenResolvedConversation(
821+
client: any,
822+
conversations: any[],
823+
inboxId: number,
824+
): Promise<any | null> {
825+
const resolvedConversation = conversations.find(
826+
(conversation) => conversation && conversation.status === 'resolved' && conversation.inbox_id == inboxId,
827+
);
828+
829+
if (resolvedConversation) {
830+
this.logger.verbose(`Found resolved conversation to reopen: ${JSON.stringify(resolvedConversation)}`);
831+
if (this.provider.conversationPending && resolvedConversation.status !== 'open') {
832+
await client.conversations.toggleStatus({
833+
accountId: this.provider.accountId,
834+
conversationId: resolvedConversation.id,
835+
data: {
836+
status: 'pending',
837+
},
838+
});
839+
this.logger.verbose(`Reopened resolved conversation ID: ${resolvedConversation.id}`);
840+
}
841+
return resolvedConversation;
842+
}
843+
844+
return null;
845+
}
846+
835847
public async getInbox(instance: InstanceDto): Promise<inbox | null> {
836848
const cacheKey = `${instance.instanceName}:getInbox`;
837849
if (await this.cache.has(cacheKey)) {
@@ -2420,28 +2432,30 @@ export class ChatwootService {
24202432
await this.createBotMessage(instance, msgStatus, 'incoming');
24212433
}
24222434

2423-
if (event === 'connection.update') {
2424-
if (body.status === 'open') {
2425-
const waInstance = this.waMonitor.waInstances[instance.instanceName];
2426-
// if we have qrcode count then we understand that a new connection was established
2427-
if (waInstance && waInstance.qrCode.count > 0) {
2428-
const msgConnection = i18next.t('cw.inbox.connected');
2429-
await this.createBotMessage(instance, msgConnection, 'incoming');
2430-
waInstance.qrCode.count = 0;
2431-
2432-
waInstance.lastConnectionNotification = Date.now();
2433-
2434-
chatwootImport.clearAll(instance);
2435-
} else if (waInstance) {
2436-
const timeSinceLastNotification = Date.now() - (waInstance.lastConnectionNotification || 0);
2437-
const minIntervalMs = 30000; // 30 seconds
2438-
2439-
if (timeSinceLastNotification < minIntervalMs) {
2440-
this.logger.warn(
2441-
`Connection notification skipped for ${instance.instanceName} - too frequent (${timeSinceLastNotification}ms since last)`,
2442-
);
2443-
}
2444-
}
2435+
if (event === 'connection.update' && body.status === 'open') {
2436+
const waInstance = this.waMonitor.waInstances[instance.instanceName];
2437+
if (!waInstance) return;
2438+
2439+
const now = Date.now();
2440+
const timeSinceLastNotification = now - (waInstance.lastConnectionNotification || 0);
2441+
2442+
// Se a conexão foi estabelecida via QR code, notifica imediatamente.
2443+
if (waInstance.qrCode && waInstance.qrCode.count > 0) {
2444+
const msgConnection = i18next.t('cw.inbox.connected');
2445+
await this.createBotMessage(instance, msgConnection, 'incoming');
2446+
waInstance.qrCode.count = 0;
2447+
waInstance.lastConnectionNotification = now;
2448+
chatwootImport.clearAll(instance);
2449+
}
2450+
// Se não foi via QR code, verifica o throttling.
2451+
else if (timeSinceLastNotification >= MIN_CONNECTION_NOTIFICATION_INTERVAL_MS) {
2452+
const msgConnection = i18next.t('cw.inbox.connected');
2453+
await this.createBotMessage(instance, msgConnection, 'incoming');
2454+
waInstance.lastConnectionNotification = now;
2455+
} else {
2456+
this.logger.warn(
2457+
`Connection notification skipped for ${instance.instanceName} - too frequent (${timeSinceLastNotification}ms since last)`,
2458+
);
24452459
}
24462460
}
24472461

0 commit comments

Comments
 (0)