Chatwoot review and improvements

This commit is contained in:
Davidson Gomes 2024-06-09 08:44:06 -03:00
parent 3342a22cc7
commit 72de0a6e4d
16 changed files with 106 additions and 317 deletions

View File

@ -49,6 +49,7 @@ RABBITMQ_EVENTS_INSTANCE_DELETE=false
RABBITMQ_EVENTS_QRCODE_UPDATED=false RABBITMQ_EVENTS_QRCODE_UPDATED=false
RABBITMQ_EVENTS_MESSAGES_SET=false RABBITMQ_EVENTS_MESSAGES_SET=false
RABBITMQ_EVENTS_MESSAGES_UPSERT=false RABBITMQ_EVENTS_MESSAGES_UPSERT=false
RABBITMQ_EVENTS_MESSAGES_EDITED=false
RABBITMQ_EVENTS_MESSAGES_UPDATE=false RABBITMQ_EVENTS_MESSAGES_UPDATE=false
RABBITMQ_EVENTS_MESSAGES_DELETE=false RABBITMQ_EVENTS_MESSAGES_DELETE=false
RABBITMQ_EVENTS_SEND_MESSAGE=false RABBITMQ_EVENTS_SEND_MESSAGE=false
@ -89,6 +90,7 @@ WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_EDITED=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true WEBHOOK_EVENTS_SEND_MESSAGE=true

View File

@ -51,6 +51,7 @@ RABBITMQ_EVENTS_APPLICATION_STARTUP=false
RABBITMQ_EVENTS_QRCODE_UPDATED=true RABBITMQ_EVENTS_QRCODE_UPDATED=true
RABBITMQ_EVENTS_MESSAGES_SET=true RABBITMQ_EVENTS_MESSAGES_SET=true
RABBITMQ_EVENTS_MESSAGES_UPSERT=true RABBITMQ_EVENTS_MESSAGES_UPSERT=true
RABBITMQ_EVENTS_MESSAGES_EDITED=true
RABBITMQ_EVENTS_MESSAGES_UPDATE=true RABBITMQ_EVENTS_MESSAGES_UPDATE=true
RABBITMQ_EVENTS_MESSAGES_DELETE=true RABBITMQ_EVENTS_MESSAGES_DELETE=true
RABBITMQ_EVENTS_SEND_MESSAGE=true RABBITMQ_EVENTS_SEND_MESSAGE=true
@ -98,6 +99,7 @@ WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_EDITED=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true WEBHOOK_EVENTS_SEND_MESSAGE=true

View File

@ -58,6 +58,7 @@ WEBHOOK_EVENTS_APPLICATION_STARTUP=false
WEBHOOK_EVENTS_QRCODE_UPDATED=true WEBHOOK_EVENTS_QRCODE_UPDATED=true
WEBHOOK_EVENTS_MESSAGES_SET=true WEBHOOK_EVENTS_MESSAGES_SET=true
WEBHOOK_EVENTS_MESSAGES_UPSERT=true WEBHOOK_EVENTS_MESSAGES_UPSERT=true
WEBHOOK_EVENTS_MESSAGES_EDITED=true
WEBHOOK_EVENTS_MESSAGES_UPDATE=true WEBHOOK_EVENTS_MESSAGES_UPDATE=true
WEBHOOK_EVENTS_MESSAGES_DELETE=true WEBHOOK_EVENTS_MESSAGES_DELETE=true
WEBHOOK_EVENTS_SEND_MESSAGE=true WEBHOOK_EVENTS_SEND_MESSAGE=true

View File

@ -68,6 +68,7 @@ ENV RABBITMQ_EVENTS_INSTANCE_DELETE=false
ENV RABBITMQ_EVENTS_QRCODE_UPDATED=true ENV RABBITMQ_EVENTS_QRCODE_UPDATED=true
ENV RABBITMQ_EVENTS_MESSAGES_SET=true ENV RABBITMQ_EVENTS_MESSAGES_SET=true
ENV RABBITMQ_EVENTS_MESSAGES_UPSERT=true ENV RABBITMQ_EVENTS_MESSAGES_UPSERT=true
ENV RABBITMQ_EVENTS_MESSAGES_EDITED=true
ENV RABBITMQ_EVENTS_MESSAGES_UPDATE=true ENV RABBITMQ_EVENTS_MESSAGES_UPDATE=true
ENV RABBITMQ_EVENTS_MESSAGES_DELETE=true ENV RABBITMQ_EVENTS_MESSAGES_DELETE=true
ENV RABBITMQ_EVENTS_SEND_MESSAGE=true ENV RABBITMQ_EVENTS_SEND_MESSAGE=true
@ -114,6 +115,7 @@ ENV WEBHOOK_EVENTS_INSTANCE_DELETE=false
ENV WEBHOOK_EVENTS_QRCODE_UPDATED=true ENV WEBHOOK_EVENTS_QRCODE_UPDATED=true
ENV WEBHOOK_EVENTS_MESSAGES_SET=true ENV WEBHOOK_EVENTS_MESSAGES_SET=true
ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=true ENV WEBHOOK_EVENTS_MESSAGES_UPSERT=true
ENV WEBHOOK_EVENTS_MESSAGES_EDITED=true
ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=true ENV WEBHOOK_EVENTS_MESSAGES_UPDATE=true
ENV WEBHOOK_EVENTS_MESSAGES_DELETE=true ENV WEBHOOK_EVENTS_MESSAGES_DELETE=true
ENV WEBHOOK_EVENTS_SEND_MESSAGE=true ENV WEBHOOK_EVENTS_SEND_MESSAGE=true

View File

@ -4,14 +4,14 @@ import { isURL } from 'class-validator';
import EventEmitter2 from 'eventemitter2'; import EventEmitter2 from 'eventemitter2';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { Auth, Chatwoot, ConfigService, HttpServer, Typebot, WaBusiness } from '../../config/env.config'; import { Auth, Chatwoot, ConfigService, HttpServer, WaBusiness } from '../../config/env.config';
import { Logger } from '../../config/logger.config'; import { Logger } from '../../config/logger.config';
import { BadRequestException, InternalServerErrorException, UnauthorizedException } from '../../exceptions'; import { BadRequestException, InternalServerErrorException, UnauthorizedException } from '../../exceptions';
import { Events as EventsArray } from '../../validate/validate.schema';
import { InstanceDto, SetPresenceDto } from '../dto/instance.dto'; import { InstanceDto, SetPresenceDto } from '../dto/instance.dto';
import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service'; import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service';
import { RabbitmqService } from '../integrations/rabbitmq/services/rabbitmq.service'; import { RabbitmqService } from '../integrations/rabbitmq/services/rabbitmq.service';
import { SqsService } from '../integrations/sqs/services/sqs.service'; import { SqsService } from '../integrations/sqs/services/sqs.service';
import { TypebotService } from '../integrations/typebot/services/typebot.service';
import { WebsocketService } from '../integrations/websocket/services/websocket.service'; import { WebsocketService } from '../integrations/websocket/services/websocket.service';
import { ProviderFiles } from '../provider/sessions'; import { ProviderFiles } from '../provider/sessions';
import { PrismaRepository } from '../repository/repository.service'; import { PrismaRepository } from '../repository/repository.service';
@ -38,7 +38,6 @@ export class InstanceController {
private readonly websocketService: WebsocketService, private readonly websocketService: WebsocketService,
private readonly rabbitmqService: RabbitmqService, private readonly rabbitmqService: RabbitmqService,
private readonly sqsService: SqsService, private readonly sqsService: SqsService,
private readonly typebotService: TypebotService,
private readonly proxyService: ProxyController, private readonly proxyService: ProxyController,
private readonly cache: CacheService, private readonly cache: CacheService,
private readonly chatwootCache: CacheService, private readonly chatwootCache: CacheService,
@ -87,13 +86,6 @@ export class InstanceController {
chatwootMergeBrazilContacts, chatwootMergeBrazilContacts,
chatwootImportMessages, chatwootImportMessages,
chatwootDaysLimitImportMessages, chatwootDaysLimitImportMessages,
typebotUrl,
typebot,
typebotExpire,
typebotKeywordFinish,
typebotDelayMessage,
typebotUnknownMessage,
typebotListeningFromMe,
}: InstanceDto) { }: InstanceDto) {
try { try {
await this.authService.checkDuplicateToken(token); await this.authService.checkDuplicateToken(token);
@ -160,32 +152,7 @@ export class InstanceController {
try { try {
let newEvents: string[] = []; let newEvents: string[] = [];
if (webhookEvents.length === 0) { if (webhookEvents.length === 0) {
newEvents = [ newEvents = EventsArray;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else { } else {
newEvents = webhookEvents; newEvents = webhookEvents;
} }
@ -211,32 +178,7 @@ export class InstanceController {
try { try {
let newEvents: string[] = []; let newEvents: string[] = [];
if (websocketEvents.length === 0) { if (websocketEvents.length === 0) {
newEvents = [ newEvents = EventsArray;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else { } else {
newEvents = websocketEvents; newEvents = websocketEvents;
} }
@ -261,32 +203,7 @@ export class InstanceController {
try { try {
let newEvents: string[] = []; let newEvents: string[] = [];
if (rabbitmqEvents.length === 0) { if (rabbitmqEvents.length === 0) {
newEvents = [ newEvents = EventsArray;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else { } else {
newEvents = rabbitmqEvents; newEvents = rabbitmqEvents;
} }
@ -311,32 +228,7 @@ export class InstanceController {
try { try {
let newEvents: string[] = []; let newEvents: string[] = [];
if (sqsEvents.length === 0) { if (sqsEvents.length === 0) {
newEvents = [ newEvents = EventsArray;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} else { } else {
newEvents = sqsEvents; newEvents = sqsEvents;
} }
@ -377,27 +269,6 @@ export class InstanceController {
}); });
} }
if (this.configService.get<Typebot>('TYPEBOT').ENABLED && typebotUrl) {
try {
if (!isURL(typebotUrl, { require_tld: false })) {
throw new BadRequestException('Invalid "url" property in typebotUrl');
}
this.typebotService.create(instance, {
enabled: true,
url: typebotUrl,
typebot: typebot,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
});
} catch (error) {
this.logger.log(error);
}
}
const settings: wa.LocalSettings = { const settings: wa.LocalSettings = {
rejectCall: rejectCall || false, rejectCall: rejectCall || false,
msgCall: msgCall || '', msgCall: msgCall || '',
@ -459,16 +330,6 @@ export class InstanceController {
enabled: sqsEnabled, enabled: sqsEnabled,
events: getSqsEvents, events: getSqsEvents,
}, },
typebot: {
enabled: typebotUrl ? true : false,
url: typebotUrl,
typebot,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
},
settings, settings,
qrcode: getQrcode, qrcode: getQrcode,
}; };
@ -558,16 +419,6 @@ export class InstanceController {
enabled: sqsEnabled, enabled: sqsEnabled,
events: getSqsEvents, events: getSqsEvents,
}, },
typebot: {
enabled: typebotUrl ? true : false,
url: typebotUrl,
typebot,
expire: typebotExpire,
keywordFinish: typebotKeywordFinish,
delayMessage: typebotDelayMessage,
unknownMessage: typebotUnknownMessage,
listeningFromMe: typebotListeningFromMe,
},
settings, settings,
chatwoot: { chatwoot: {
enabled: true, enabled: true,

View File

@ -35,13 +35,6 @@ export class InstanceDto {
rabbitmqEvents?: string[]; rabbitmqEvents?: string[];
sqsEnabled?: boolean; sqsEnabled?: boolean;
sqsEvents?: string[]; sqsEvents?: string[];
typebotUrl?: string;
typebot?: string;
typebotExpire?: number;
typebotKeywordFinish?: string;
typebotDelayMessage?: number;
typebotUnknownMessage?: string;
typebotListeningFromMe?: boolean;
proxyHost?: string; proxyHost?: string;
proxyPort?: string; proxyPort?: string;
proxyProtocol?: string; proxyProtocol?: string;

View File

@ -9,6 +9,7 @@ import ChatwootClient, {
} from '@figuro/chatwoot-sdk'; } from '@figuro/chatwoot-sdk';
import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request'; import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';
import { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client'; import { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client';
import { proto } from '@whiskeysockets/baileys';
import axios from 'axios'; import axios from 'axios';
import FormData from 'form-data'; import FormData from 'form-data';
import { createReadStream, unlinkSync, writeFileSync } from 'fs'; import { createReadStream, unlinkSync, writeFileSync } from 'fs';
@ -105,6 +106,7 @@ export class ChatwootService {
await this.waMonitor.waInstances[instance.instanceName].setChatwoot(data); await this.waMonitor.waInstances[instance.instanceName].setChatwoot(data);
if (data.autoCreate) { if (data.autoCreate) {
this.logger.log('Auto create chatwoot instance');
const urlServer = this.configService.get<HttpServer>('SERVER').URL; const urlServer = this.configService.get<HttpServer>('SERVER').URL;
await this.initInstanceChatwoot( await this.initInstanceChatwoot(
@ -175,6 +177,7 @@ export class ChatwootService {
let inboxId: number; let inboxId: number;
this.logger.log('Creating chatwoot inbox');
if (!checkDuplicate) { if (!checkDuplicate) {
const data = { const data = {
type: 'api', type: 'api',
@ -205,7 +208,9 @@ export class ChatwootService {
inboxId = inbox.id; inboxId = inbox.id;
} }
this.logger.log(`Inox created - inboxId: ${inboxId}`);
this.logger.log('Creating chatwoot bot contact');
const contact = const contact =
(await this.findContact(instance, '123456')) || (await this.findContact(instance, '123456')) ||
((await this.createContact( ((await this.createContact(
@ -223,8 +228,10 @@ export class ChatwootService {
} }
const contactId = contact.id || contact.payload.contact.id; const contactId = contact.id || contact.payload.contact.id;
this.logger.log(`Contact created - contactId: ${contactId}`);
if (qrcode) { if (qrcode) {
this.logger.log('QR code enabled');
const data = { const data = {
contact_id: contactId.toString(), contact_id: contactId.toString(),
inbox_id: inboxId.toString(), inbox_id: inboxId.toString(),
@ -259,6 +266,7 @@ export class ChatwootService {
this.logger.warn('conversation not found'); this.logger.warn('conversation not found');
return null; return null;
} }
this.logger.log('Init message sent');
} }
return true; return true;
@ -700,6 +708,7 @@ export class ChatwootService {
}[], }[],
messageBody?: any, messageBody?: any,
sourceId?: string, sourceId?: string,
quotedMsg?: MessageModel,
) { ) {
const client = await this.clientCw(instance); const client = await this.clientCw(instance);
@ -710,6 +719,8 @@ export class ChatwootService {
const replyToIds = await this.getReplyToIds(messageBody, instance); const replyToIds = await this.getReplyToIds(messageBody, instance);
const sourceReplyId = quotedMsg?.chatwootMessageId || null;
const message = await client.messages.create({ const message = await client.messages.create({
accountId: this.provider.accountId, accountId: this.provider.accountId,
conversationId: conversationId, conversationId: conversationId,
@ -722,6 +733,7 @@ export class ChatwootService {
content_attributes: { content_attributes: {
...replyToIds, ...replyToIds,
}, },
source_reply_id: sourceReplyId ? sourceReplyId.toString() : null,
}, },
}); });
@ -1039,7 +1051,6 @@ export class ChatwootService {
return null; return null;
} }
// invalidate the conversation cache if reopenConversation is false and the conversation was resolved
if ( if (
this.provider.reopenConversation === false && this.provider.reopenConversation === false &&
body.event === 'conversation_status_changed' && body.event === 'conversation_status_changed' &&
@ -1081,9 +1092,16 @@ export class ChatwootService {
}); });
if (message) { if (message) {
await waInstance?.client.sendMessage(message[0].key.remoteJid, { delete: message[0].key }); const key = message.key as {
id: string;
remoteJid: string;
fromMe: boolean;
participant: string;
};
this.prismaRepository.message.deleteMany({ await waInstance?.client.sendMessage(key.remoteJid, { delete: key });
await this.prismaRepository.message.deleteMany({
where: { where: {
instanceId: instance.instanceId, instanceId: instance.instanceId,
chatwootMessageId: body.id, chatwootMessageId: body.id,
@ -1206,7 +1224,7 @@ export class ChatwootService {
this.onSendMessageError(instance, body.conversation?.id); this.onSendMessageError(instance, body.conversation?.id);
} }
this.updateChatwootMessageId( await this.updateChatwootMessageId(
{ {
...messageSent, ...messageSent,
owner: instance.instanceName, owner: instance.instanceName,
@ -1239,7 +1257,7 @@ export class ChatwootService {
messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber(); messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();
} }
this.updateChatwootMessageId( await this.updateChatwootMessageId(
{ {
...messageSent, ...messageSent,
instanceId: instance.instanceId, instanceId: instance.instanceId,
@ -1300,32 +1318,10 @@ export class ChatwootService {
await this.prismaRepository.message.updateMany({ await this.prismaRepository.message.updateMany({
where: { where: {
instanceId: instance.instanceId, instanceId: instance.instanceId,
AND: [ key: {
{ path: ['id'],
key: { equals: key.id,
path: ['id'], },
equals: key.id,
},
},
{
key: {
path: ['remoteJid'],
equals: key.remoteJid,
},
},
{
key: {
path: ['fromMe'],
equals: key.fromMe,
},
},
{
key: {
path: ['participant'],
equals: key.participant,
},
},
],
}, },
data: updateMessage, data: updateMessage,
}); });
@ -1351,7 +1347,11 @@ export class ChatwootService {
} }
} }
private updateChatwootMessageId(message: MessageModel, chatwootMessageIds: ChatwootMessage, instance: InstanceDto) { private async updateChatwootMessageId(
message: MessageModel,
chatwootMessageIds: ChatwootMessage,
instance: InstanceDto,
) {
const key = message.key as { const key = message.key as {
id: string; id: string;
fromMe: boolean; fromMe: boolean;
@ -1363,7 +1363,7 @@ export class ChatwootService {
return; return;
} }
this.prismaRepository.message.updateMany({ await this.prismaRepository.message.updateMany({
where: { where: {
key: { key: {
path: ['id'], path: ['id'],
@ -1436,8 +1436,8 @@ export class ChatwootService {
if (message && key?.id) { if (message && key?.id) {
return { return {
key: message[0].key, key: message.key as proto.IMessageKey,
message: message[0].message, message: message.message as proto.IMessage,
}; };
} }
} }
@ -1732,6 +1732,20 @@ export class ChatwootService {
return; return;
} }
const quotedId = body.contextInfo?.stanzaId || body.message?.contextInfo?.stanzaId;
let quotedMsg = null;
if (quotedId)
quotedMsg = await this.prismaRepository.message.findFirst({
where: {
key: {
path: ['id'],
equals: quotedId,
},
},
});
const isMedia = this.isMediaMessage(body.message); const isMedia = this.isMediaMessage(body.message);
const adsMessage = this.getAdsMessage(body.message); const adsMessage = this.getAdsMessage(body.message);
@ -1841,6 +1855,7 @@ export class ChatwootService {
message: { extendedTextMessage: { contextInfo: { stanzaId: reactionMessage.key.id } } }, message: { extendedTextMessage: { contextInfo: { stanzaId: reactionMessage.key.id } } },
}, },
'WAID:' + body.key.id, 'WAID:' + body.key.id,
quotedMsg,
); );
if (!send) { if (!send) {
this.logger.warn('message not sent'); this.logger.warn('message not sent');
@ -1919,6 +1934,7 @@ export class ChatwootService {
[], [],
body, body,
'WAID:' + body.key.id, 'WAID:' + body.key.id,
quotedMsg,
); );
if (!send) { if (!send) {
@ -1937,6 +1953,7 @@ export class ChatwootService {
[], [],
body, body,
'WAID:' + body.key.id, 'WAID:' + body.key.id,
quotedMsg,
); );
if (!send) { if (!send) {
@ -1950,6 +1967,9 @@ export class ChatwootService {
if (event === Events.MESSAGES_DELETE) { if (event === Events.MESSAGES_DELETE) {
const chatwootDelete = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_DELETE; const chatwootDelete = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_DELETE;
console.log('chatwootDelete', chatwootDelete);
if (chatwootDelete === true) { if (chatwootDelete === true) {
if (!body?.key?.id) { if (!body?.key?.id) {
this.logger.warn('message id not found'); this.logger.warn('message id not found');
@ -1957,8 +1977,10 @@ export class ChatwootService {
} }
const message = await this.getMessageByKeyId(instance, body.key.id); const message = await this.getMessageByKeyId(instance, body.key.id);
console.log('message', message);
if (message?.chatwootMessageId && message?.chatwootConversationId) { if (message?.chatwootMessageId && message?.chatwootConversationId) {
this.prismaRepository.message.deleteMany({ await this.prismaRepository.message.deleteMany({
where: { where: {
key: { key: {
path: ['id'], path: ['id'],
@ -2003,6 +2025,7 @@ export class ChatwootService {
message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } }, message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } },
}, },
'WAID:' + body.key.id, 'WAID:' + body.key.id,
null,
); );
if (!send) { if (!send) {
this.logger.warn('edited message not sent'); this.logger.warn('edited message not sent');
@ -2194,12 +2217,16 @@ export class ChatwootService {
limitContacts, limitContacts,
); );
const contactIdentifiers = recentContacts
.map((contact) => contact.identifier)
.filter((identifier) => identifier !== null);
const contactsWithProfilePicture = ( const contactsWithProfilePicture = (
await this.prismaRepository.contact.findMany({ await this.prismaRepository.contact.findMany({
where: { where: {
instanceId: instance.instanceId, instanceId: instance.instanceId,
id: { id: {
in: recentContacts.map((contact) => contact.identifier), in: contactIdentifiers,
}, },
profilePicUrl: { profilePicUrl: {
not: null, not: null,

View File

@ -1,5 +1,6 @@
import { configService, Rabbitmq } from '../../../../config/env.config'; import { configService, Rabbitmq } from '../../../../config/env.config';
import { BadRequestException } from '../../../../exceptions'; import { BadRequestException } from '../../../../exceptions';
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto'; import { InstanceDto } from '../../../dto/instance.dto';
import { RabbitmqDto } from '../dto/rabbitmq.dto'; import { RabbitmqDto } from '../dto/rabbitmq.dto';
import { RabbitmqService } from '../services/rabbitmq.service'; import { RabbitmqService } from '../services/rabbitmq.service';
@ -15,32 +16,7 @@ export class RabbitmqController {
} }
if (data.events.length === 0) { if (data.events.length === 0) {
data.events = [ data.events = Events;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} }
return this.rabbitmqService.create(instance, data); return this.rabbitmqService.create(instance, data);

View File

@ -1,5 +1,6 @@
import { configService, Sqs } from '../../../../config/env.config'; import { configService, Sqs } from '../../../../config/env.config';
import { BadRequestException } from '../../../../exceptions'; import { BadRequestException } from '../../../../exceptions';
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto'; import { InstanceDto } from '../../../dto/instance.dto';
import { SqsDto } from '../dto/sqs.dto'; import { SqsDto } from '../dto/sqs.dto';
import { SqsService } from '../services/sqs.service'; import { SqsService } from '../services/sqs.service';
@ -15,32 +16,7 @@ export class SqsController {
} }
if (data.events.length === 0) { if (data.events.length === 0) {
data.events = [ data.events = Events;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} }
return this.sqsService.create(instance, data); return this.sqsService.create(instance, data);

View File

@ -1,3 +1,4 @@
import { Events } from '../../../../validate/validate.schema';
import { InstanceDto } from '../../../dto/instance.dto'; import { InstanceDto } from '../../../dto/instance.dto';
import { WebsocketDto } from '../dto/websocket.dto'; import { WebsocketDto } from '../dto/websocket.dto';
import { WebsocketService } from '../services/websocket.service'; import { WebsocketService } from '../services/websocket.service';
@ -11,32 +12,7 @@ export class WebsocketController {
} }
if (data.events.length === 0) { if (data.events.length === 0) {
data.events = [ data.events = Events;
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
];
} }
return this.websocketService.create(instance, data); return this.websocketService.create(instance, data);

View File

@ -1,6 +1,8 @@
import { JSONSchema7 } from 'json-schema'; import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { Events } from '../../../../validate/validate.schema';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => { const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {}; const properties = {};
propertyNames.forEach( propertyNames.forEach(
@ -30,32 +32,7 @@ export const websocketSchema: JSONSchema7 = {
minItems: 0, minItems: 0,
items: { items: {
type: 'string', type: 'string',
enum: [ enum: Events,
'APPLICATION_STARTUP',
'QRCODE_UPDATED',
'MESSAGES_SET',
'MESSAGES_UPSERT',
'MESSAGES_UPDATE',
'MESSAGES_DELETE',
'SEND_MESSAGE',
'CONTACTS_SET',
'CONTACTS_UPSERT',
'CONTACTS_UPDATE',
'PRESENCE_UPDATE',
'CHATS_SET',
'CHATS_UPSERT',
'CHATS_UPDATE',
'CHATS_DELETE',
'GROUPS_UPSERT',
'GROUP_UPDATE',
'GROUP_PARTICIPANTS_UPDATE',
'CONNECTION_UPDATE',
'LABELS_EDIT',
'LABELS_ASSOCIATION',
'CALL',
'TYPEBOT_START',
'TYPEBOT_CHANGE_STATUS',
],
}, },
}, },
}, },

View File

@ -90,7 +90,6 @@ export const instanceController = new InstanceController(
websocketService, websocketService,
rabbitmqService, rabbitmqService,
sqsService, sqsService,
typebotService,
proxyController, proxyController,
cache, cache,
chatwootCache, chatwootCache,

View File

@ -1054,15 +1054,18 @@ export class BaileysStartupService extends ChannelStartupService {
) => { ) => {
try { try {
for (const received of messages) { for (const received of messages) {
if ( if (received.message?.protocolMessage?.editedMessage || received.message?.editedMessage?.message) {
this.configService.get<Chatwoot>('CHATWOOT').ENABLED &&
this.localChatwoot.enabled &&
(received.message?.protocolMessage?.editedMessage || received.message?.editedMessage?.message)
) {
const editedMessage = const editedMessage =
received.message?.protocolMessage || received.message?.editedMessage?.message?.protocolMessage; received.message?.protocolMessage || received.message?.editedMessage?.message?.protocolMessage;
if (editedMessage) { if (editedMessage) {
this.chatwootService.eventWhatsapp('messages.edit', { instanceName: this.instance.name }, editedMessage); if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot.enabled)
this.chatwootService.eventWhatsapp(
'messages.edit',
{ instanceName: this.instance.name },
editedMessage,
);
await this.sendDataWebhook(Events.MESSAGES_EDITED, editedMessage);
} }
} }
@ -1169,11 +1172,9 @@ export class BaileysStartupService extends ChannelStartupService {
); );
if (chatwootSentMessage?.id) { if (chatwootSentMessage?.id) {
messageRaw.chatwoot = { messageRaw.chatwootMessageId = chatwootSentMessage.id;
messageId: chatwootSentMessage.id, messageRaw.chatwootInboxId = chatwootSentMessage.inbox_id;
inboxId: chatwootSentMessage.inbox_id, messageRaw.chatwootConversationId = chatwootSentMessage.conversation_id;
conversationId: chatwootSentMessage.conversation_id,
};
} }
} }

View File

@ -11,6 +11,7 @@ export enum Events {
STATUS_INSTANCE = 'status.instance', STATUS_INSTANCE = 'status.instance',
MESSAGES_SET = 'messages.set', MESSAGES_SET = 'messages.set',
MESSAGES_UPSERT = 'messages.upsert', MESSAGES_UPSERT = 'messages.upsert',
MESSAGES_EDITED = 'messages.edited',
MESSAGES_UPDATE = 'messages.update', MESSAGES_UPDATE = 'messages.update',
MESSAGES_DELETE = 'messages.delete', MESSAGES_DELETE = 'messages.delete',
SEND_MESSAGE = 'send.message', SEND_MESSAGE = 'send.message',

View File

@ -78,6 +78,7 @@ export type EventsRabbitmq = {
QRCODE_UPDATED: boolean; QRCODE_UPDATED: boolean;
MESSAGES_SET: boolean; MESSAGES_SET: boolean;
MESSAGES_UPSERT: boolean; MESSAGES_UPSERT: boolean;
MESSAGES_EDITED: boolean;
MESSAGES_UPDATE: boolean; MESSAGES_UPDATE: boolean;
MESSAGES_DELETE: boolean; MESSAGES_DELETE: boolean;
SEND_MESSAGE: boolean; SEND_MESSAGE: boolean;
@ -135,6 +136,7 @@ export type EventsWebhook = {
QRCODE_UPDATED: boolean; QRCODE_UPDATED: boolean;
MESSAGES_SET: boolean; MESSAGES_SET: boolean;
MESSAGES_UPSERT: boolean; MESSAGES_UPSERT: boolean;
MESSAGES_EDITED: boolean;
MESSAGES_UPDATE: boolean; MESSAGES_UPDATE: boolean;
MESSAGES_DELETE: boolean; MESSAGES_DELETE: boolean;
SEND_MESSAGE: boolean; SEND_MESSAGE: boolean;
@ -324,6 +326,7 @@ export class ConfigService {
QRCODE_UPDATED: process.env?.RABBITMQ_EVENTS_QRCODE_UPDATED === 'true', QRCODE_UPDATED: process.env?.RABBITMQ_EVENTS_QRCODE_UPDATED === 'true',
MESSAGES_SET: process.env?.RABBITMQ_EVENTS_MESSAGES_SET === 'true', MESSAGES_SET: process.env?.RABBITMQ_EVENTS_MESSAGES_SET === 'true',
MESSAGES_UPSERT: process.env?.RABBITMQ_EVENTS_MESSAGES_UPSERT === 'true', MESSAGES_UPSERT: process.env?.RABBITMQ_EVENTS_MESSAGES_UPSERT === 'true',
MESSAGES_EDITED: process.env?.RABBITMQ_EVENTS_MESSAGES_EDITED === 'true',
MESSAGES_UPDATE: process.env?.RABBITMQ_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_UPDATE: process.env?.RABBITMQ_EVENTS_MESSAGES_UPDATE === 'true',
MESSAGES_DELETE: process.env?.RABBITMQ_EVENTS_MESSAGES_DELETE === 'true', MESSAGES_DELETE: process.env?.RABBITMQ_EVENTS_MESSAGES_DELETE === 'true',
SEND_MESSAGE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE === 'true', SEND_MESSAGE: process.env?.RABBITMQ_EVENTS_SEND_MESSAGE === 'true',
@ -397,6 +400,7 @@ export class ConfigService {
QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true', QRCODE_UPDATED: process.env?.WEBHOOK_EVENTS_QRCODE_UPDATED === 'true',
MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true', MESSAGES_SET: process.env?.WEBHOOK_EVENTS_MESSAGES_SET === 'true',
MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true', MESSAGES_UPSERT: process.env?.WEBHOOK_EVENTS_MESSAGES_UPSERT === 'true',
MESSAGES_EDITED: process.env?.WEBHOOK_EVENTS_MESSAGES_EDITED === 'true',
MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true', MESSAGES_UPDATE: process.env?.WEBHOOK_EVENTS_MESSAGES_UPDATE === 'true',
MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true', MESSAGES_DELETE: process.env?.WEBHOOK_EVENTS_MESSAGES_DELETE === 'true',
SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true', SEND_MESSAGE: process.env?.WEBHOOK_EVENTS_SEND_MESSAGE === 'true',
@ -436,8 +440,8 @@ export class ConfigService {
}, },
CHATWOOT: { CHATWOOT: {
ENABLED: process.env?.CHATWOOT_ENABLED === 'true', ENABLED: process.env?.CHATWOOT_ENABLED === 'true',
MESSAGE_DELETE: process.env.CHATWOOT_MESSAGE_DELETE === 'false', MESSAGE_DELETE: process.env.CHATWOOT_MESSAGE_DELETE === 'true',
MESSAGE_READ: process.env.CHATWOOT_MESSAGE_READ === 'false', MESSAGE_READ: process.env.CHATWOOT_MESSAGE_READ === 'true',
IMPORT: { IMPORT: {
DATABASE: { DATABASE: {
CONNECTION: { CONNECTION: {

View File

@ -21,6 +21,7 @@ export const Events = [
'QRCODE_UPDATED', 'QRCODE_UPDATED',
'MESSAGES_SET', 'MESSAGES_SET',
'MESSAGES_UPSERT', 'MESSAGES_UPSERT',
'MESSAGES_EDITED',
'MESSAGES_UPDATE', 'MESSAGES_UPDATE',
'MESSAGES_DELETE', 'MESSAGES_DELETE',
'SEND_MESSAGE', 'SEND_MESSAGE',