diff --git a/README.md b/README.md index 11e65320..a4f1a61a 100644 --- a/README.md +++ b/README.md @@ -154,4 +154,17 @@ This code was produced based on the baileys library and it is still under develo

CHAVE PIX (Telefone): (74)99987-9409

-
\ No newline at end of file +
+ +# Content Creator Partners + +We are proud to collaborate with the following content creators who have contributed valuable insights and tutorials about Evolution API: + +- [Promovaweb](https://www.youtube.com/@promovaweb) +- [Comunidade ZDG](https://www.youtube.com/@ComunidadeZDG) +- [Francis MNO](https://www.youtube.com/@FrancisMNO) +- [Pablo Cabral](https://youtube.com/@pablocabral) +- [XPop Digital](https://www.youtube.com/@xpopdigital) +- [Costar Wagner Dev](https://www.youtube.com/@costarwagnerdev) +- [Dante Testa](https://youtube.com/@dantetesta_) +- [Rubén Salazar](https://youtube.com/channel/UCnYGZIE2riiLqaN9sI6riig) \ No newline at end of file diff --git a/instances/.gitkeep b/instances/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/api/controllers/instance.controller.ts b/src/api/controllers/instance.controller.ts index e5a72128..9955b3db 100644 --- a/src/api/controllers/instance.controller.ts +++ b/src/api/controllers/instance.controller.ts @@ -1,6 +1,6 @@ import { JsonValue } from '@prisma/client/runtime/library'; import { delay } from '@whiskeysockets/baileys'; -import { isURL } from 'class-validator'; +import { isArray, isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; import { v4 } from 'uuid'; @@ -215,8 +215,6 @@ export class InstanceController { const rabbitmqEventsJson: JsonValue = (await this.rabbitmqService.find(instance)).events; getRabbitmqEvents = Array.isArray(rabbitmqEventsJson) ? rabbitmqEventsJson.map((event) => String(event)) : []; - - // rabbitmqEvents = (await this.rabbitmqService.find(instance)).events; } catch (error) { this.logger.log(error); } @@ -279,7 +277,7 @@ export class InstanceController { syncFullHistory: syncFullHistory ?? false, }; - this.settingsService.create(instance, settings); + await this.settingsService.create(instance, settings); let webhookWaBusiness = null, accessTokenWaBusiness = ''; @@ -296,7 +294,7 @@ export class InstanceController { if (!chatwootAccountId || !chatwootToken || !chatwootUrl) { let getQrcode: wa.QrCode; - if (qrcode) { + if (qrcode && integration === Integration.WHATSAPP_BAILEYS) { await instance.connectToWhatsapp(number); await delay(5000); getQrcode = instance.qrCode; @@ -334,6 +332,8 @@ export class InstanceController { qrcode: getQrcode, }; + console.log('log13', result); + return result; } @@ -438,8 +438,8 @@ export class InstanceController { }, }; } catch (error) { - this.logger.error(error.message[0]); - throw new BadRequestException(error.message[0]); + this.logger.error(isArray(error.message) ? error.message[0] : error.message); + throw new BadRequestException(isArray(error.message) ? error.message[0] : error.message); } } diff --git a/src/api/integrations/chatwoot/services/chatwoot.service.ts b/src/api/integrations/chatwoot/services/chatwoot.service.ts index f37edc40..bed0a211 100644 --- a/src/api/integrations/chatwoot/services/chatwoot.service.ts +++ b/src/api/integrations/chatwoot/services/chatwoot.service.ts @@ -721,6 +721,8 @@ export class ChatwootService { const sourceReplyId = quotedMsg?.chatwootMessageId || null; + console.log('sourceReplyId', sourceReplyId); + const message = await client.messages.create({ accountId: this.provider.accountId, conversationId: conversationId, @@ -1734,6 +1736,8 @@ export class ChatwootService { const quotedId = body.contextInfo?.stanzaId || body.message?.contextInfo?.stanzaId; + console.log('quotedId', quotedId); + let quotedMsg = null; if (quotedId) @@ -1746,6 +1750,8 @@ export class ChatwootService { }, }); + console.log('quotedMsg', quotedMsg); + const isMedia = this.isMediaMessage(body.message); const adsMessage = this.getAdsMessage(body.message); @@ -1968,8 +1974,6 @@ export class ChatwootService { if (event === Events.MESSAGES_DELETE) { const chatwootDelete = this.configService.get('CHATWOOT').MESSAGE_DELETE; - console.log('chatwootDelete', chatwootDelete); - if (chatwootDelete === true) { if (!body?.key?.id) { this.logger.warn('message id not found'); @@ -1977,7 +1981,6 @@ export class ChatwootService { } const message = await this.getMessageByKeyId(instance, body.key.id); - console.log('message', message); if (message?.chatwootMessageId && message?.chatwootConversationId) { await this.prismaRepository.message.deleteMany({ diff --git a/src/api/integrations/typebot/services/typebot.service.ts b/src/api/integrations/typebot/services/typebot.service.ts index 53a5624a..03b51eca 100644 --- a/src/api/integrations/typebot/services/typebot.service.ts +++ b/src/api/integrations/typebot/services/typebot.service.ts @@ -935,7 +935,7 @@ export class TypebotService { formattedText = formattedText.replace(/\n$/, ''); - await instance.textMessage( + await instance.textMessage( { number: remoteJid.split('@')[0], delay: settings?.delayMessage || 1000, diff --git a/src/api/services/channels/whatsapp.baileys.service.ts b/src/api/services/channels/whatsapp.baileys.service.ts index b03d6e48..3352d1c1 100644 --- a/src/api/services/channels/whatsapp.baileys.service.ts +++ b/src/api/services/channels/whatsapp.baileys.service.ts @@ -268,7 +268,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { message: 'QR code limit reached, please login again', statusCode: DisconnectReason.badSession, @@ -326,7 +326,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.QRCODE_UPDATED, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { qrcode: { instance: this.instance.name, @@ -381,7 +381,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.STATUS_INSTANCE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { instance: this.instance.name, status: 'closed', @@ -427,7 +427,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.CONNECTION_UPDATE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { instance: this.instance.name, status: 'open', @@ -835,8 +835,14 @@ export class BaileysStartupService extends ChannelStartupService { this.localChatwoot.importContacts && contactsRaw.length ) { - this.chatwootService.addHistoryContacts({ instanceName: this.instance.name }, contactsRaw); - chatwootImport.importHistoryContacts({ instanceName: this.instance.name }, this.localChatwoot); + this.chatwootService.addHistoryContacts( + { instanceName: this.instance.name, instanceId: this.instance.id }, + contactsRaw, + ); + chatwootImport.importHistoryContacts( + { instanceName: this.instance.name, instanceId: this.instance.id }, + this.localChatwoot, + ); } const updatedContacts = await Promise.all( @@ -1061,7 +1067,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) this.chatwootService.eventWhatsapp( 'messages.edit', - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instance.id }, editedMessage, ); @@ -1167,7 +1173,7 @@ export class BaileysStartupService extends ChannelStartupService { ) { const chatwootSentMessage = await this.chatwootService.eventWhatsapp( Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instance.id }, messageRaw, ); @@ -1221,7 +1227,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { await this.chatwootService.eventWhatsapp( Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, contactRaw, ); } @@ -1260,7 +1266,11 @@ export class BaileysStartupService extends ChannelStartupService { if (status[update.status] === 'READ' && key.fromMe) { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { - this.chatwootService.eventWhatsapp('messages.read', { instanceName: this.instance.name }, { key: key }); + this.chatwootService.eventWhatsapp( + 'messages.read', + { instanceName: this.instance.name, instanceId: this.instanceId }, + { key: key }, + ); } } @@ -1313,7 +1323,7 @@ export class BaileysStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.MESSAGES_DELETE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { key: key }, ); } @@ -1680,7 +1690,11 @@ export class BaileysStartupService extends ChannelStartupService { key: { remoteJid: isWA.jid }, }; - this.chatwootService.eventWhatsapp('contact.is_not_in_wpp', { instanceName: this.instance.name }, body); + this.chatwootService.eventWhatsapp( + 'contact.is_not_in_wpp', + { instanceName: this.instance.name, instanceId: this.instance.id }, + body, + ); } throw new BadRequestException(isWA); } @@ -1889,7 +1903,11 @@ export class BaileysStartupService extends ChannelStartupService { this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled && !isIntegration) { - this.chatwootService.eventWhatsapp(Events.SEND_MESSAGE, { instanceName: this.instance.name }, messageRaw); + this.chatwootService.eventWhatsapp( + Events.SEND_MESSAGE, + { instanceName: this.instance.name, instanceId: this.instanceId }, + messageRaw, + ); } if (this.configService.get('TYPEBOT').ENABLED && !isIntegration) { diff --git a/src/api/services/channels/whatsapp.business.service.ts b/src/api/services/channels/whatsapp.business.service.ts index ce442696..d170aee9 100644 --- a/src/api/services/channels/whatsapp.business.service.ts +++ b/src/api/services/channels/whatsapp.business.service.ts @@ -126,6 +126,7 @@ export class BusinessStartupService extends ChannelStartupService { public async connectToWhatsapp(data?: any): Promise { if (!data) return; + const content = data.entry[0].changes[0].value; try { this.loadWebhook(); @@ -316,10 +317,11 @@ export class BusinessStartupService extends ChannelStartupService { ...this.messageMediaJson(received), base64: buffer ? buffer.toString('base64') : undefined, }, + contextInfo: this.messageTextJson(received)?.contextInfo, messageType: this.renderMessageType(received.messages[0].type), - messageTimestamp: received.messages[0].timestamp as number, - owner: this.instance.name, - // source: getDevice(received.key.id), + messageTimestamp: parseInt(received.messages[0].timestamp) as number, + source: 'unknown', + instanceId: this.instanceId, }; } else if (received?.messages[0].interactive) { messageRaw = { @@ -328,10 +330,11 @@ export class BusinessStartupService extends ChannelStartupService { message: { ...this.messageInteractiveJson(received), }, + contextInfo: this.messageTextJson(received)?.contextInfo, messageType: 'conversation', - messageTimestamp: received.messages[0].timestamp as number, - owner: this.instance.name, - // source: getDevice(received.key.id), + messageTimestamp: parseInt(received.messages[0].timestamp) as number, + source: 'unknown', + instanceId: this.instanceId, }; } else if (received?.messages[0].reaction) { messageRaw = { @@ -340,10 +343,11 @@ export class BusinessStartupService extends ChannelStartupService { message: { ...this.messageReactionJson(received), }, + contextInfo: this.messageTextJson(received)?.contextInfo, messageType: 'reactionMessage', - messageTimestamp: received.messages[0].timestamp as number, - owner: this.instance.name, - // source: getDevice(received.key.id), + messageTimestamp: parseInt(received.messages[0].timestamp) as number, + source: 'unknown', + instanceId: this.instanceId, }; } else if (received?.messages[0].contacts) { messageRaw = { @@ -352,20 +356,22 @@ export class BusinessStartupService extends ChannelStartupService { message: { ...this.messageContactsJson(received), }, + contextInfo: this.messageTextJson(received)?.contextInfo, messageType: 'conversation', - messageTimestamp: received.messages[0].timestamp as number, - owner: this.instance.name, - // source: getDevice(received.key.id), + messageTimestamp: parseInt(received.messages[0].timestamp) as number, + source: 'unknown', + instanceId: this.instanceId, }; } else { messageRaw = { key, pushName, message: this.messageTextJson(received), + contextInfo: this.messageTextJson(received)?.contextInfo, messageType: this.renderMessageType(received.messages[0].type), - messageTimestamp: received.messages[0].timestamp as number, - owner: this.instance.name, - //source: getDevice(received.key.id), + messageTimestamp: parseInt(received.messages[0].timestamp) as number, + source: 'unknown', + instanceId: this.instanceId, }; } @@ -384,23 +390,21 @@ export class BusinessStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { const chatwootSentMessage = await this.chatwootService.eventWhatsapp( Events.MESSAGES_UPSERT, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, messageRaw, ); if (chatwootSentMessage?.id) { - messageRaw.chatwoot = { - messageId: chatwootSentMessage.id, - inboxId: chatwootSentMessage.inbox_id, - conversationId: chatwootSentMessage.conversation_id, - }; + messageRaw.chatwootMessageId = chatwootSentMessage.id; + messageRaw.chatwootInboxId = chatwootSentMessage.id; + messageRaw.chatwootConversationId = chatwootSentMessage.id; } } if (this.configService.get('TYPEBOT').ENABLED) { if (messageRaw.messageType !== 'reactionMessage') await this.typebotService.sendTypebot( - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, messageRaw.key.remoteJid, messageRaw, ); @@ -438,7 +442,7 @@ export class BusinessStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { await this.chatwootService.eventWhatsapp( Events.CONTACTS_UPDATE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, contactRaw, ); } @@ -479,6 +483,10 @@ export class BusinessStartupService extends ChannelStartupService { }, }); + if (!findMessage) { + return; + } + if (item.message === null && item.status === undefined) { this.sendDataWebhook(Events.MESSAGES_DELETE, key); @@ -489,7 +497,6 @@ export class BusinessStartupService extends ChannelStartupService { fromMe: key.fromMe, participant: key?.remoteJid, status: 'DELETED', - dateTime: Date.now(), instanceId: this.instanceId, }; @@ -500,7 +507,7 @@ export class BusinessStartupService extends ChannelStartupService { if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled) { this.chatwootService.eventWhatsapp( Events.MESSAGES_DELETE, - { instanceName: this.instance.name }, + { instanceName: this.instance.name, instanceId: this.instanceId }, { key: key }, ); } @@ -515,7 +522,6 @@ export class BusinessStartupService extends ChannelStartupService { fromMe: key.fromMe, participant: key?.remoteJid, status: item.status.toUpperCase(), - dateTime: Date.now(), instanceId: this.instanceId, }; @@ -607,7 +613,7 @@ export class BusinessStartupService extends ChannelStartupService { this.messageHandle(content, database, settings); } - protected async sendMessageWithTyping(number: string, message: any, options?: Options, isChatwoot = false) { + protected async sendMessageWithTyping(number: string, message: any, options?: Options, isIntegration = false) { try { let quoted: any; const linkPreview = options?.linkPreview != false ? undefined : false; @@ -793,8 +799,6 @@ export class BusinessStartupService extends ChannelStartupService { throw messageSent.error.message.toString(); } - console.log(content); - const messageRaw: any = { key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) }, //pushName: messageSent.pushName, @@ -802,15 +806,28 @@ export class BusinessStartupService extends ChannelStartupService { messageType: this.renderMessageType(content.type), messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000), instanceId: this.instanceId, - //ource: getDevice(messageSent.key.id), + source: 'unknown', }; this.logger.log(messageRaw); this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw); - if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled && !isChatwoot) { - this.chatwootService.eventWhatsapp(Events.SEND_MESSAGE, { instanceName: this.instance.name }, messageRaw); + if (this.configService.get('CHATWOOT').ENABLED && this.localChatwoot.enabled && !isIntegration) { + this.chatwootService.eventWhatsapp( + Events.SEND_MESSAGE, + { instanceName: this.instance.name, instanceId: this.instanceId }, + messageRaw, + ); + } + + if (this.configService.get('TYPEBOT').ENABLED && !isIntegration) { + if (messageRaw.messageType !== 'reactionMessage') + await this.typebotService.sendTypebot( + { instanceName: this.instance.name, instanceId: this.instanceId }, + messageRaw.key.remoteJid, + messageRaw, + ); } await this.prismaRepository.message.create({ @@ -819,13 +836,14 @@ export class BusinessStartupService extends ChannelStartupService { return messageRaw; } catch (error) { + console.log(error.response.data); this.logger.error(error); throw new BadRequestException(error.toString()); } } // Send Message Controller - public async textMessage(data: SendTextDto, isChatwoot = false) { + public async textMessage(data: SendTextDto, isIntegration = false) { const res = await this.sendMessageWithTyping( data.number, { @@ -841,7 +859,7 @@ export class BusinessStartupService extends ChannelStartupService { mentioned: data?.mentioned, }, }, - isChatwoot, + isIntegration, ); return res; } @@ -890,19 +908,15 @@ export class BusinessStartupService extends ChannelStartupService { gifPlayback: false, }; - if (mediaMessage.mimetype) { - mimetype = mediaMessage.mimetype; + if (isURL(mediaMessage.media)) { + mimetype = getMIMEType(mediaMessage.media); + prepareMedia.id = mediaMessage.media; + prepareMedia.type = 'link'; } else { - if (isURL(mediaMessage.media)) { - mimetype = getMIMEType(mediaMessage.media); - prepareMedia.id = mediaMessage.media; - prepareMedia.type = 'link'; - } else { - mimetype = getMIMEType(mediaMessage.fileName); - const id = await this.getIdMedia(prepareMedia); - prepareMedia.id = id; - prepareMedia.type = 'id'; - } + mimetype = getMIMEType(mediaMessage.fileName); + const id = await this.getIdMedia(prepareMedia); + prepareMedia.id = id; + prepareMedia.type = 'id'; } prepareMedia.mimetype = mimetype; @@ -914,7 +928,7 @@ export class BusinessStartupService extends ChannelStartupService { } } - public async mediaMessage(data: SendMediaDto, isChatwoot = false) { + public async mediaMessage(data: SendMediaDto, isIntegration = false) { const message = await this.prepareMediaMessage(data); return await this.sendMessageWithTyping( @@ -930,7 +944,7 @@ export class BusinessStartupService extends ChannelStartupService { mentioned: data?.mentioned, }, }, - isChatwoot, + isIntegration, ); } @@ -962,7 +976,7 @@ export class BusinessStartupService extends ChannelStartupService { return prepareMedia; } - public async audioWhatsapp(data: SendAudioDto, isChatwoot = false) { + public async audioWhatsapp(data: SendAudioDto, isIntegration = false) { const message = await this.processAudio(data.audio, data.number); return await this.sendMessageWithTyping( @@ -978,7 +992,7 @@ export class BusinessStartupService extends ChannelStartupService { mentioned: data?.mentioned, }, }, - isChatwoot, + isIntegration, ); } @@ -1088,7 +1102,7 @@ export class BusinessStartupService extends ChannelStartupService { ); } - public async templateMessage(data: SendTemplateDto, isChatwoot = false) { + public async templateMessage(data: SendTemplateDto, isIntegration = false) { const res = await this.sendMessageWithTyping( data.number, { @@ -1108,7 +1122,7 @@ export class BusinessStartupService extends ChannelStartupService { mentioned: data?.mentioned, }, }, - isChatwoot, + isIntegration, ); return res; } diff --git a/src/api/services/settings.service.ts b/src/api/services/settings.service.ts index 20ba41f8..565962bd 100644 --- a/src/api/services/settings.service.ts +++ b/src/api/services/settings.service.ts @@ -8,8 +8,8 @@ export class SettingsService { private readonly logger = new Logger(SettingsService.name); - public create(instance: InstanceDto, data: SettingsDto) { - this.waMonitor.waInstances[instance.instanceName].setSettings(data); + public async create(instance: InstanceDto, data: SettingsDto) { + await this.waMonitor.waInstances[instance.instanceName].setSettings(data); return { settings: { ...instance, settings: data } }; }