fix: when deleting a message in whatsapp, delete the message in chatwoot too

The message model schema was changed. Old format in message model was field chatwootMessageId. Now we have a document chatwoot with new properties.

I cant find a simple way to create a migration function up then the old field was no migrate to new format.
This commit is contained in:
jaison-x 2023-12-20 17:53:37 -03:00
parent 060a945aea
commit 07e8449379
4 changed files with 100 additions and 26 deletions

View File

@ -10,6 +10,12 @@ class Key {
participant?: string; participant?: string;
} }
class ChatwootMessage {
messageId?: number;
inboxId?: number;
conversationId?: number;
}
export class MessageRaw { export class MessageRaw {
_id?: string; _id?: string;
key?: Key; key?: Key;
@ -22,7 +28,7 @@ export class MessageRaw {
source?: 'android' | 'web' | 'ios'; source?: 'android' | 'web' | 'ios';
source_id?: string; source_id?: string;
source_reply_id?: string; source_reply_id?: string;
chatwootMessageId?: string; chatwoot?: ChatwootMessage;
} }
const messageSchema = new Schema<MessageRaw>({ const messageSchema = new Schema<MessageRaw>({
@ -40,10 +46,14 @@ const messageSchema = new Schema<MessageRaw>({
source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] }, source: { type: String, minlength: 3, enum: ['android', 'web', 'ios'] },
messageTimestamp: { type: Number, required: true }, messageTimestamp: { type: Number, required: true },
owner: { type: String, required: true, minlength: 1 }, owner: { type: String, required: true, minlength: 1 },
chatwootMessageId: { type: String, required: false }, chatwoot: {
messageId: { type: Number },
inboxId: { type: Number },
conversationId: { type: Number },
},
}); });
messageSchema.index({ chatwootMessageId: 1, owner: 1 }); messageSchema.index({ 'chatwoot.messageId': 1, owner: 1 });
messageSchema.index({ 'key.id': 1 }); messageSchema.index({ 'key.id': 1 });
messageSchema.index({ 'key.id': 1, owner: 1 }); messageSchema.index({ 'key.id': 1, owner: 1 });
messageSchema.index({ owner: 1 }); messageSchema.index({ owner: 1 });

View File

@ -91,11 +91,13 @@ export class MessageRepository extends Repository {
this.logger.verbose('finding messages'); this.logger.verbose('finding messages');
if (this.dbSettings.ENABLED) { if (this.dbSettings.ENABLED) {
this.logger.verbose('finding messages in db'); this.logger.verbose('finding messages in db');
if (query?.where?.key) { for (const [o, p] of Object.entries(query?.where)) {
for (const [k, v] of Object.entries(query.where.key)) { if (typeof p === 'object' && p !== null && !Array.isArray(p)) {
query.where['key.' + k] = v; for (const [k, v] of Object.entries(p)) {
query.where[`${o}.${k}`] = v;
}
delete query.where[o];
} }
delete query?.where?.key;
} }
return await this.messageModel return await this.messageModel

View File

@ -14,6 +14,7 @@ import { InstanceDto } from '../dto/instance.dto';
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto'; import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../dto/sendMessage.dto';
import { MessageRaw } from '../models'; import { MessageRaw } from '../models';
import { RepositoryBroker } from '../repository/repository.manager'; import { RepositoryBroker } from '../repository/repository.manager';
import { Events } from '../types/wa.types';
import { WAMonitoringService } from './monitor.service'; import { WAMonitoringService } from './monitor.service';
export class ChatwootService { export class ChatwootService {
@ -1036,7 +1037,9 @@ export class ChatwootService {
const message = await this.repository.message.find({ const message = await this.repository.message.find({
where: { where: {
owner: instance.instanceName, owner: instance.instanceName,
chatwootMessageId: body.id, chatwoot: {
messageId: body.id,
},
}, },
limit: 1, limit: 1,
}); });
@ -1160,7 +1163,11 @@ export class ChatwootService {
...messageSent, ...messageSent,
owner: instance.instanceName, owner: instance.instanceName,
}, },
body.id, {
messageId: body.id,
inboxId: body.inbox?.id,
conversationId: body.conversation?.id,
},
instance, instance,
); );
} }
@ -1187,7 +1194,11 @@ export class ChatwootService {
...messageSent, ...messageSent,
owner: instance.instanceName, owner: instance.instanceName,
}, },
body.id, {
messageId: body.id,
inboxId: body.inbox?.id,
conversationId: body.conversation?.id,
},
instance, instance,
); );
} }
@ -1221,15 +1232,33 @@ export class ChatwootService {
} }
} }
private updateChatwootMessageId(message: MessageRaw, chatwootMessageId: string, instance: InstanceDto) { private updateChatwootMessageId(
if (!chatwootMessageId || !message?.key?.id) { message: MessageRaw,
chatwootMessageIds: MessageRaw['chatwoot'],
instance: InstanceDto,
) {
if (!chatwootMessageIds.messageId || !message?.key?.id) {
return; return;
} }
message.chatwootMessageId = chatwootMessageId; message.chatwoot = chatwootMessageIds;
this.repository.message.update([message], instance.instanceName, true); this.repository.message.update([message], instance.instanceName, true);
} }
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageRaw> {
const messages = await this.repository.message.find({
where: {
key: {
id: keyId,
},
owner: instance.instanceName,
},
limit: 1,
});
return messages.length ? messages[0] : null;
}
private async getReplyToIds( private async getReplyToIds(
msg: any, msg: any,
instance: InstanceDto, instance: InstanceDto,
@ -1240,17 +1269,9 @@ export class ChatwootService {
if (msg) { if (msg) {
inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId; inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId;
if (inReplyToExternalId) { if (inReplyToExternalId) {
const message = await this.repository.message.find({ const message = await this.getMessageByKeyId(instance, inReplyToExternalId);
where: { if (message?.chatwoot?.messageId) {
key: { inReplyTo = message.chatwoot.messageId;
id: inReplyToExternalId,
},
owner: instance.instanceName,
},
limit: 1,
});
if (message.length && message[0]?.chatwootMessageId) {
inReplyTo = message[0].chatwootMessageId;
} }
} }
} }
@ -1265,7 +1286,9 @@ export class ChatwootService {
if (msg?.content_attributes?.in_reply_to) { if (msg?.content_attributes?.in_reply_to) {
const message = await this.repository.message.find({ const message = await this.repository.message.find({
where: { where: {
chatwootMessageId: msg?.content_attributes?.in_reply_to, chatwoot: {
messageId: msg?.content_attributes?.in_reply_to,
},
owner: instance.instanceName, owner: instance.instanceName,
}, },
limit: 1, limit: 1,
@ -1757,6 +1780,25 @@ export class ChatwootService {
} }
} }
if (event === Events.MESSAGES_DELETE) {
this.logger.verbose('deleting message from instance: ' + instance.instanceName);
if (!body?.key?.id) {
this.logger.warn('message id not found');
return;
}
const message = await this.getMessageByKeyId(instance, body.key.id);
if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) {
this.logger.verbose('deleting message in chatwoot. Message id: ' + body.key.id);
return await client.messages.delete({
accountId: this.provider.account_id,
conversationId: message.chatwoot.conversationId,
messageId: message.chatwoot.messageId,
});
}
}
if (event === 'status.instance') { if (event === 'status.instance') {
this.logger.verbose('event status.instance'); this.logger.verbose('event status.instance');
const data = body; const data = body;

View File

@ -1798,7 +1798,11 @@ export class WAStartupService {
); );
if (chatwootSentMessage?.id) { if (chatwootSentMessage?.id) {
messageRaw.chatwootMessageId = chatwootSentMessage.id; messageRaw.chatwoot = {
messageId: chatwootSentMessage.id,
inboxId: chatwootSentMessage.inbox_id,
conversationId: chatwootSentMessage.conversation_id,
};
} }
} }
@ -1941,6 +1945,22 @@ export class WAStartupService {
this.instance.name, this.instance.name,
database.SAVE_DATA.MESSAGE_UPDATE, database.SAVE_DATA.MESSAGE_UPDATE,
); );
if (this.localChatwoot.enabled) {
this.chatwootService.eventWhatsapp(
Events.MESSAGES_DELETE,
{ instanceName: this.instance.name },
{
key: {
remoteJid: key.remoteJid,
fromMe: key.fromMe,
id: key.id,
participant: key.participant,
},
},
);
}
return; return;
} }