feat(chatwoot): read messages from whatsapp in chatwoot

It works only with messages read from whatsapp to chatwoot.
This commit is contained in:
jaison-x 2024-01-15 20:20:02 -03:00
parent 29a48f7914
commit c75dfcd499
3 changed files with 71 additions and 9 deletions

View File

@ -14,6 +14,7 @@ class ChatwootMessage {
messageId?: number;
inboxId?: number;
conversationId?: number;
contactInbox?: { sourceId: string };
}
export class MessageRaw {
@ -51,6 +52,7 @@ const messageSchema = new Schema<MessageRaw>({
messageId: { type: Number },
inboxId: { type: Number },
conversationId: { type: Number },
contactInbox: { type: Object },
},
});

View File

@ -1,4 +1,5 @@
import ChatwootClient, { conversation, inbox } from '@figuro/chatwoot-sdk';
import ChatwootClient, { ChatwootAPIConfig, contact, conversation, inbox } from '@figuro/chatwoot-sdk';
import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';
import axios from 'axios';
import FormData from 'form-data';
import { createReadStream, unlinkSync, writeFileSync } from 'fs';
@ -71,12 +72,7 @@ export class ChatwootService {
this.logger.verbose('create client to instance: ' + instance.instanceName);
const client = new ChatwootClient({
config: {
basePath: provider.url,
with_credentials: true,
credentials: 'include',
token: provider.token,
},
config: this.getClientCwConfig(),
});
this.logger.verbose('client created');
@ -84,6 +80,15 @@ export class ChatwootService {
return client;
}
public getClientCwConfig(): ChatwootAPIConfig {
return {
basePath: this.provider.url,
with_credentials: true,
credentials: 'include',
token: this.provider.token,
};
}
public getCache() {
return this.cache;
}
@ -1200,6 +1205,9 @@ export class ChatwootService {
messageId: body.id,
inboxId: body.inbox?.id,
conversationId: body.conversation?.id,
contactInbox: {
sourceId: body.conversation?.contact_inbox?.source_id,
},
},
instance,
);
@ -1231,6 +1239,9 @@ export class ChatwootService {
messageId: body.id,
inboxId: body.inbox?.id,
conversationId: body.conversation?.id,
contactInbox: {
sourceId: body.conversation?.contact_inbox?.source_id,
},
},
instance,
);
@ -1911,6 +1922,44 @@ export class ChatwootService {
}
}
if (event === 'messages.read') {
this.logger.verbose('read message from instance: ' + instance.instanceName);
if (!body?.key?.id || !body?.key?.remoteJid) {
this.logger.warn('message id not found');
return;
}
const message = await this.getMessageByKeyId(instance, body.key.id);
const { conversationId, contactInbox } = message?.chatwoot || {};
if (conversationId) {
let sourceId = contactInbox?.sourceId;
const inbox = (await this.getInbox(instance)) as inbox & {
inbox_identifier?: string;
};
if (!sourceId && inbox) {
const contact = (await this.findContact(
instance,
this.getNumberFromRemoteJid(body.key.remoteJid),
)) as contact;
const contactInbox = contact?.contact_inboxes?.find((contactInbox) => contactInbox?.inbox?.id === inbox.id);
sourceId = contactInbox?.source_id;
}
if (sourceId && inbox?.inbox_identifier) {
const url =
`/public/api/v1/inboxes/${inbox.inbox_identifier}/contacts/${sourceId}` +
`/conversations/${conversationId}/update_last_seen`;
chatwootRequest(this.getClientCwConfig(), {
method: 'POST',
url: url,
});
}
}
return;
}
if (event === 'status.instance') {
this.logger.verbose('event status.instance');
const data = body;
@ -1981,4 +2030,8 @@ export class ChatwootService {
this.logger.error(error);
}
}
public getNumberFromRemoteJid(remoteJid: string) {
return remoteJid.replace(/:\d+/, '').split('@')[0];
}
}

View File

@ -1932,6 +1932,13 @@ export class WAStartupService {
this.logger.verbose('group ignored');
return;
}
if (status[update.status] === 'READ' && key.fromMe) {
if (this.localChatwoot.enabled) {
this.chatwootService.eventWhatsapp('messages.read', { instanceName: this.instance.name }, { key: key });
}
}
// if (key.remoteJid !== 'status@broadcast' && !key?.remoteJid?.match(/(:\d+)/)) {
if (key.remoteJid !== 'status@broadcast') {
this.logger.verbose('Message update is valid');
@ -2877,8 +2884,8 @@ export class WAStartupService {
this.logger.verbose('Processing audio');
let tempAudioPath: string;
let outputAudio: string;
number = number.replace(/\D/g, "");
number = number.replace(/\D/g, '');
const hash = `${number}-${new Date().getTime()}`;
this.logger.verbose('Hash to audio name: ' + hash);