diff --git a/CHANGELOG.md b/CHANGELOG.md index e5adcb7b..1af5a843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 1.8.2 (2024-07-03 13:50) + +### Fixed + +* Corretion in globall rabbitmq queue name +* Improvement in the use of mongodb database for credentials +* Fixed base64 in webhook for documentWithCaption +* Fixed Generate pairing code + # 1.8.1 (2024-06-08 21:32) ### Feature diff --git a/package.json b/package.json index 8ee94b3e..4d2c17cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.8.1", + "version": "1.8.2", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { @@ -49,7 +49,7 @@ "amqplib": "^0.10.3", "@aws-sdk/client-sqs": "^3.569.0", "axios": "^1.6.5", - "@whiskeysockets/baileys": "6.7.5", + "baileys": "github:EvolutionAPI/Baileys", "class-validator": "^0.14.1", "compression": "^1.7.4", "cors": "^2.8.5", diff --git a/src/api/controllers/instance.controller.ts b/src/api/controllers/instance.controller.ts index bc3ace61..3b2ea0e4 100644 --- a/src/api/controllers/instance.controller.ts +++ b/src/api/controllers/instance.controller.ts @@ -1,4 +1,4 @@ -import { delay } from '@whiskeysockets/baileys'; +import { delay } from 'baileys'; import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; import { v4 } from 'uuid'; diff --git a/src/api/dto/chat.dto.ts b/src/api/dto/chat.dto.ts index 3ed55d52..7952ddc6 100644 --- a/src/api/dto/chat.dto.ts +++ b/src/api/dto/chat.dto.ts @@ -1,4 +1,4 @@ -import { proto, WAPresence, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from '@whiskeysockets/baileys'; +import { proto, WAPresence, WAPrivacyOnlineValue, WAPrivacyValue, WAReadReceiptsValue } from 'baileys'; export class OnWhatsAppDto { constructor( diff --git a/src/api/dto/instance.dto.ts b/src/api/dto/instance.dto.ts index d9a4d87a..1f2ff1c6 100644 --- a/src/api/dto/instance.dto.ts +++ b/src/api/dto/instance.dto.ts @@ -1,4 +1,4 @@ -import { WAPresence } from '@whiskeysockets/baileys'; +import { WAPresence } from 'baileys'; import { ProxyDto } from './proxy.dto'; diff --git a/src/api/dto/sendMessage.dto.ts b/src/api/dto/sendMessage.dto.ts index 7bb33074..5c197d44 100644 --- a/src/api/dto/sendMessage.dto.ts +++ b/src/api/dto/sendMessage.dto.ts @@ -1,4 +1,4 @@ -import { proto, WAPresence } from '@whiskeysockets/baileys'; +import { proto, WAPresence } from 'baileys'; export class Quoted { key: proto.IMessageKey; diff --git a/src/api/integrations/chatwoot/services/chatwoot.service.ts b/src/api/integrations/chatwoot/services/chatwoot.service.ts index 9a30dc12..f209a9f3 100644 --- a/src/api/integrations/chatwoot/services/chatwoot.service.ts +++ b/src/api/integrations/chatwoot/services/chatwoot.service.ts @@ -8,8 +8,8 @@ import ChatwootClient, { inbox, } from '@figuro/chatwoot-sdk'; import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request'; -import { proto } from '@whiskeysockets/baileys'; import axios from 'axios'; +import { proto } from 'baileys'; import FormData from 'form-data'; import { createReadStream, unlinkSync, writeFileSync } from 'fs'; import Jimp from 'jimp'; @@ -444,8 +444,7 @@ export class ChatwootService { const searchableFields = this.getSearchableFields(); // eslint-disable-next-line prettier/prettier - if(contacts.length === 2 && this.getClientCwConfig().merge_brazil_contacts && query.startsWith('+55')){ - + if (contacts.length === 2 && this.getClientCwConfig().merge_brazil_contacts && query.startsWith('+55')) { const contact = this.mergeBrazilianContacts(contacts); if (contact) { return contact; @@ -736,7 +735,12 @@ export class ChatwootService { } this.logger.verbose('find inbox by name'); - const findByName = inbox.payload.find((inbox) => inbox.name === this.getClientCwConfig().name_inbox); + let findByName = inbox.payload.find((inbox) => inbox.name === this.getClientCwConfig().name_inbox); + + if (!findByName) { + findByName = inbox.payload.find((inbox) => inbox.name === this.getClientCwConfig().name_inbox.split('-cwId-')[0]); + } + if (!findByName) { this.logger.warn('inbox not found'); diff --git a/src/api/integrations/chatwoot/utils/chatwoot-import-helper.ts b/src/api/integrations/chatwoot/utils/chatwoot-import-helper.ts index dd0bb23a..e102aa57 100644 --- a/src/api/integrations/chatwoot/utils/chatwoot-import-helper.ts +++ b/src/api/integrations/chatwoot/utils/chatwoot-import-helper.ts @@ -1,5 +1,5 @@ import { inbox } from '@figuro/chatwoot-sdk'; -import { proto } from '@whiskeysockets/baileys'; +import { proto } from 'baileys'; import { InstanceDto } from '../../../../api/dto/instance.dto'; import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../../api/models'; diff --git a/src/api/services/cache.service.ts b/src/api/services/cache.service.ts index caf3dbfa..e03b3eb5 100644 --- a/src/api/services/cache.service.ts +++ b/src/api/services/cache.service.ts @@ -1,4 +1,4 @@ -import { BufferJSON } from '@whiskeysockets/baileys'; +import { BufferJSON } from 'baileys'; import { Logger } from '../../config/logger.config'; import { ICache } from '../abstract/abstract.cache'; diff --git a/src/api/services/channel.service.ts b/src/api/services/channel.service.ts index ac4eae90..ea3a57c1 100644 --- a/src/api/services/channel.service.ts +++ b/src/api/services/channel.service.ts @@ -1,5 +1,5 @@ -import { WASocket } from '@whiskeysockets/baileys'; import axios from 'axios'; +import { WASocket } from 'baileys'; import { execSync } from 'child_process'; import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; @@ -721,7 +721,9 @@ export class ChannelStartupService { autoDelete: false, }); - const queueName = `${this.instanceName}.${event}`; + const eventName = event.replace(/_/g, '.').toLowerCase(); + + const queueName = `${this.instanceName}.${eventName}`; await amqp.assertQueue(queueName, { durable: true, @@ -731,7 +733,7 @@ export class ChannelStartupService { }, }); - await amqp.bindQueue(queueName, exchangeName, event); + await amqp.bindQueue(queueName, exchangeName, eventName); const message = { event, @@ -786,7 +788,7 @@ export class ChannelStartupService { autoDelete: false, }); - const queueName = transformedWe; + const queueName = event; await amqp.assertQueue(queueName, { durable: true, diff --git a/src/api/services/channels/whatsapp.baileys.service.ts b/src/api/services/channels/whatsapp.baileys.service.ts index 210dc72b..d31e0238 100644 --- a/src/api/services/channels/whatsapp.baileys.service.ts +++ b/src/api/services/channels/whatsapp.baileys.service.ts @@ -1,5 +1,6 @@ import ffmpegPath from '@ffmpeg-installer/ffmpeg'; import { Boom } from '@hapi/boom'; +import axios from 'axios'; import makeWASocket, { AnyMessageContent, BufferedEventData, @@ -19,6 +20,7 @@ import makeWASocket, { GroupMetadata, isJidBroadcast, isJidGroup, + isJidNewsletter, isJidUser, makeCacheableSignalKeyStore, MessageUpsertType, @@ -35,10 +37,9 @@ import makeWASocket, { WAMessageUpdate, WAPresence, WASocket, -} from '@whiskeysockets/baileys'; -import { Label } from '@whiskeysockets/baileys/lib/Types/Label'; -import { LabelAssociation } from '@whiskeysockets/baileys/lib/Types/LabelAssociation'; -import axios from 'axios'; +} from 'baileys'; +import { Label } from 'baileys/lib/Types/Label'; +import { LabelAssociation } from 'baileys/lib/Types/LabelAssociation'; import { exec } from 'child_process'; import { isBase64, isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; @@ -253,8 +254,8 @@ export class BaileysStartupService extends ChannelStartupService { this.logger.verbose('Getting profile status'); const status = await this.client.fetchStatus(this.instance.wuid); - this.logger.verbose(`Profile status: ${status.status}`); - return status.status; + this.logger.verbose(`Profile status: ${status[0]?.status}`); + return status[0]?.status; } public get profilePictureUrl() { @@ -517,6 +518,143 @@ export class BaileysStartupService extends ChannelStartupService { return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name)); } + private async createClient(number?: string, mobile?: boolean): Promise { + this.instance.authState = await this.defineAuthState(); + + if (!mobile) { + this.mobile = false; + } else { + this.mobile = mobile; + } + + const session = this.configService.get('CONFIG_SESSION_PHONE'); + + let browserOptions = {}; + + if (number || this.phoneNumber) { + this.phoneNumber = number; + + this.logger.info(`Phone number: ${number}`); + } else { + const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; + browserOptions = { browser }; + + this.logger.info(`Browser: ${browser}`); + } + + let version; + let log; + + if (session.VERSION) { + version = session.VERSION.split(','); + log = `Baileys version env: ${version}`; + } else { + const baileysVersion = await fetchLatestBaileysVersion(); + version = baileysVersion.version; + log = `Baileys version: ${version}`; + } + + this.logger.info(log); + + let options; + + if (this.localProxy.enabled) { + this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host); + + if (this.localProxy?.proxy?.host?.includes('proxyscrape')) { + try { + const response = await axios.get(this.localProxy.proxy?.host); + const text = response.data; + const proxyUrls = text.split('\r\n'); + const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); + const proxyUrl = 'http://' + proxyUrls[rand]; + options = { + agent: makeProxyAgent(proxyUrl), + fetchAgent: makeProxyAgent(proxyUrl), + }; + } catch (error) { + this.localProxy.enabled = false; + } + } else { + options = { + agent: makeProxyAgent(this.localProxy.proxy), + fetchAgent: makeProxyAgent(this.localProxy.proxy), + }; + } + } + + const socketConfig: UserFacingSocketConfig = { + ...options, + auth: { + creds: this.instance.authState.state.creds, + keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any), + }, + logger: P({ level: this.logBaileys }), + printQRInTerminal: false, + mobile, + ...browserOptions, + version, + markOnlineOnConnect: this.localSettings.always_online, + retryRequestDelayMs: 350, + maxMsgRetryCount: 4, + fireInitQueries: true, + connectTimeoutMs: 20_000, + keepAliveIntervalMs: 30_000, + qrTimeout: 45_000, + defaultQueryTimeoutMs: undefined, + emitOwnEvents: false, + shouldIgnoreJid: (jid) => { + const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid); + const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid); + const isNewsletter = isJidNewsletter(jid); + + return isGroupJid || isBroadcast || isNewsletter; + }, + msgRetryCounterCache: this.msgRetryCounterCache, + getMessage: async (key) => (await this.getMessage(key)) as Promise, + generateHighQualityLinkPreview: true, + syncFullHistory: this.localSettings.sync_full_history, + shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => { + return this.historySyncNotification(msg); + }, + userDevicesCache: this.userDevicesCache, + transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 }, + patchMessageBeforeSending(message) { + if ( + message.deviceSentMessage?.message?.listMessage?.listType === proto.Message.ListMessage.ListType.PRODUCT_LIST + ) { + message = JSON.parse(JSON.stringify(message)); + + message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; + } + + if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) { + message = JSON.parse(JSON.stringify(message)); + + message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; + } + + return message; + }, + }; + + this.endSession = false; + + this.logger.verbose('Creating socket'); + + this.client = makeWASocket(socketConfig); + + this.logger.verbose('Socket created'); + + this.eventHandler(); + + this.logger.verbose('Socket event handler initialized'); + + this.phoneNumber = number; + + return this.client; + } + public async connectToWhatsapp(number?: string, mobile?: boolean): Promise { this.logger.verbose('Connecting to whatsapp'); try { @@ -530,129 +668,7 @@ export class BaileysStartupService extends ChannelStartupService { this.loadProxy(); this.loadChamaai(); - this.instance.authState = await this.defineAuthState(); - - if (!mobile) { - this.mobile = false; - } else { - this.mobile = mobile; - } - - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - this.logger.verbose('Browser: ' + JSON.stringify(browser)); - - let version; - let log; - - if (session.VERSION) { - version = session.VERSION.split(','); - log = `Baileys version env: ${version}`; - } else { - const baileysVersion = await fetchLatestBaileysVersion(); - version = baileysVersion.version; - log = `Baileys version: ${version}`; - } - - this.logger.info(log); - - let options; - - if (this.localProxy.enabled) { - this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host); - - if (this.localProxy?.proxy?.host?.includes('proxyscrape')) { - try { - const response = await axios.get(this.localProxy.proxy?.host); - const text = response.data; - const proxyUrls = text.split('\r\n'); - const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); - const proxyUrl = 'http://' + proxyUrls[rand]; - options = { - agent: makeProxyAgent(proxyUrl), - fetchAgent: makeProxyAgent(proxyUrl), - }; - } catch (error) { - this.localProxy.enabled = false; - } - } else { - options = { - agent: makeProxyAgent(this.localProxy.proxy), - fetchAgent: makeProxyAgent(this.localProxy.proxy), - }; - } - } - - const socketConfig: UserFacingSocketConfig = { - ...options, - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any), - }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - mobile, - browser: number ? ['Chrome (Linux)', session.NAME, release()] : browser, - version, - markOnlineOnConnect: this.localSettings.always_online, - retryRequestDelayMs: 350, - maxMsgRetryCount: 4, - fireInitQueries: true, - connectTimeoutMs: 20_000, - keepAliveIntervalMs: 30_000, - qrTimeout: 45_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - shouldIgnoreJid: (jid) => { - const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid); - const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid); - - return isGroupJid || isBroadcast; - }, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: this.localSettings.sync_full_history, - shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => { - return this.historySyncNotification(msg); - }, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 }, - patchMessageBeforeSending(message) { - if ( - message.deviceSentMessage?.message?.listMessage?.listType === - proto.Message.ListMessage.ListType.PRODUCT_LIST - ) { - message = JSON.parse(JSON.stringify(message)); - - message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; - } - - if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) { - message = JSON.parse(JSON.stringify(message)); - - message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; - } - - return message; - }, - }; - - this.endSession = false; - - this.logger.verbose('Creating socket'); - - this.client = makeWASocket(socketConfig); - - this.logger.verbose('Socket created'); - - this.eventHandler(); - - this.logger.verbose('Socket event handler initialized'); - - this.phoneNumber = number; - - return this.client; + return await this.createClient(number, mobile); } catch (error) { this.logger.error(error); throw new InternalServerErrorException(error?.toString()); @@ -719,110 +735,7 @@ export class BaileysStartupService extends ChannelStartupService { public async reloadConnection(): Promise { try { - this.instance.authState = await this.defineAuthState(); - - const session = this.configService.get('CONFIG_SESSION_PHONE'); - const browser: WABrowserDescription = [session.CLIENT, session.NAME, release()]; - - let version; - let log; - - if (session.VERSION) { - version = session.VERSION.split(','); - log = `Baileys version env: ${version}`; - } else { - const baileysVersion = await fetchLatestBaileysVersion(); - version = baileysVersion.version; - log = `Baileys version: ${version}`; - } - - this.logger.info(log); - - let options; - - if (this.localProxy.enabled) { - this.logger.info('Proxy enabled: ' + this.localProxy.proxy?.host); - - if (this.localProxy?.proxy?.host?.includes('proxyscrape')) { - try { - const response = await axios.get(this.localProxy.proxy?.host); - const text = response.data; - const proxyUrls = text.split('\r\n'); - const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length)); - const proxyUrl = 'http://' + proxyUrls[rand]; - options = { - agent: makeProxyAgent(proxyUrl), - fetchAgent: makeProxyAgent(proxyUrl), - }; - } catch (error) { - this.localProxy.enabled = false; - } - } else { - options = { - agent: makeProxyAgent(this.localProxy.proxy), - fetchAgent: makeProxyAgent(this.localProxy.proxy), - }; - } - } - - const socketConfig: UserFacingSocketConfig = { - ...options, - auth: { - creds: this.instance.authState.state.creds, - keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any), - }, - logger: P({ level: this.logBaileys }), - printQRInTerminal: false, - mobile: this.mobile, - browser: this.phoneNumber ? ['Chrome (Linux)', session.NAME, release()] : browser, - version, - markOnlineOnConnect: this.localSettings.always_online, - retryRequestDelayMs: 350, - maxMsgRetryCount: 4, - fireInitQueries: true, - connectTimeoutMs: 20_000, - keepAliveIntervalMs: 30_000, - qrTimeout: 45_000, - defaultQueryTimeoutMs: undefined, - emitOwnEvents: false, - shouldIgnoreJid: (jid) => { - const isGroupJid = this.localSettings.groups_ignore && isJidGroup(jid); - const isBroadcast = !this.localSettings.read_status && isJidBroadcast(jid); - - return isGroupJid || isBroadcast; - }, - msgRetryCounterCache: this.msgRetryCounterCache, - getMessage: async (key) => (await this.getMessage(key)) as Promise, - generateHighQualityLinkPreview: true, - syncFullHistory: this.localSettings.sync_full_history, - shouldSyncHistoryMessage: (msg: proto.Message.IHistorySyncNotification) => { - return this.historySyncNotification(msg); - }, - userDevicesCache: this.userDevicesCache, - transactionOpts: { maxCommitRetries: 5, delayBetweenTriesMs: 2500 }, - patchMessageBeforeSending(message) { - if ( - message.deviceSentMessage?.message?.listMessage?.listType === - proto.Message.ListMessage.ListType.PRODUCT_LIST - ) { - message = JSON.parse(JSON.stringify(message)); - - message.deviceSentMessage.message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; - } - - if (message.listMessage?.listType == proto.Message.ListMessage.ListType.PRODUCT_LIST) { - message = JSON.parse(JSON.stringify(message)); - - message.listMessage.listType = proto.Message.ListMessage.ListType.SINGLE_SELECT; - } - - return message; - }, - }; - - this.client = makeWASocket(socketConfig); - - return this.client; + return await this.createClient(this.phoneNumber, this.mobile); } catch (error) { this.logger.error(error); throw new InternalServerErrorException(error?.toString()); @@ -1060,7 +973,7 @@ export class BaileysStartupService extends ChannelStartupService { m.messageTimestamp = m.messageTimestamp?.toNumber(); } - if (m.messageTimestamp <= timestampLimitToImport) { + if ((m.messageTimestamp as number) <= timestampLimitToImport) { continue; } @@ -1185,6 +1098,7 @@ export class BaileysStartupService extends ChannelStartupService { received?.message?.videoMessage || received?.message?.stickerMessage || received?.message?.documentMessage || + received?.message?.documentWithCaptionMessage || received?.message?.audioMessage; const contentMsg = received?.message[getContentType(received.message)] as any; @@ -1736,7 +1650,7 @@ export class BaileysStartupService extends ChannelStartupService { this.logger.verbose('Getting status'); return { wuid: jid, - status: (await this.client.fetchStatus(jid))?.status, + status: (await this.client.fetchStatus(jid))[0]?.status, }; } catch (error) { this.logger.verbose('Status not found'); @@ -1946,11 +1860,9 @@ export class BaileysStartupService extends ChannelStartupService { } as unknown as AnyMessageContent, { ...option, - cachedGroupMetadata: - !this.configService.get('CACHE').REDIS.ENABLED && - !this.configService.get('CACHE').LOCAL.ENABLED - ? null - : this.getGroupMetadataCache, + useCachedGroupMetadata: + !!this.configService.get('CACHE').REDIS.ENABLED && + !!this.configService.get('CACHE').LOCAL.ENABLED, } as unknown as MiscMessageGenerationOptions, ); } @@ -1966,11 +1878,9 @@ export class BaileysStartupService extends ChannelStartupService { } as unknown as AnyMessageContent, { ...option, - cachedGroupMetadata: - !this.configService.get('CACHE').REDIS.ENABLED && - !this.configService.get('CACHE').LOCAL.ENABLED - ? null - : this.getGroupMetadataCache, + useCachedGroupMetadata: + !!this.configService.get('CACHE').REDIS.ENABLED && + !!this.configService.get('CACHE').LOCAL.ENABLED, } as unknown as MiscMessageGenerationOptions, ); } @@ -1988,11 +1898,9 @@ export class BaileysStartupService extends ChannelStartupService { }, { ...option, - cachedGroupMetadata: - !this.configService.get('CACHE').REDIS.ENABLED && - !this.configService.get('CACHE').LOCAL.ENABLED - ? null - : this.getGroupMetadataCache, + useCachedGroupMetadata: + !!this.configService.get('CACHE').REDIS.ENABLED && + !!this.configService.get('CACHE').LOCAL.ENABLED, } as unknown as MiscMessageGenerationOptions, ); } @@ -2016,11 +1924,9 @@ export class BaileysStartupService extends ChannelStartupService { message as unknown as AnyMessageContent, { ...option, - cachedGroupMetadata: - !this.configService.get('CACHE').REDIS.ENABLED && - !this.configService.get('CACHE').LOCAL.ENABLED - ? null - : this.getGroupMetadataCache, + useCachedGroupMetadata: + !!this.configService.get('CACHE').REDIS.ENABLED && + !!this.configService.get('CACHE').LOCAL.ENABLED, } as unknown as MiscMessageGenerationOptions, ); })(); @@ -3354,6 +3260,10 @@ export class BaileysStartupService extends ChannelStartupService { } public async findGroup(id: GroupJid, reply: 'inner' | 'out' = 'out') { + if (this.localSettings.groups_ignore === true) { + return; + } + this.logger.verbose('Fetching group'); try { const group = await this.client.groupMetadata(id.groupJid); @@ -3384,6 +3294,10 @@ export class BaileysStartupService extends ChannelStartupService { } public async fetchAllGroups(getParticipants: GetParticipant) { + if (this.localSettings.groups_ignore === true) { + return; + } + this.logger.verbose('Fetching all groups'); try { const fetch = Object.values(await this.client.groupFetchAllParticipating()); diff --git a/src/api/types/wa.types.ts b/src/api/types/wa.types.ts index 9c33ac6f..94461964 100644 --- a/src/api/types/wa.types.ts +++ b/src/api/types/wa.types.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-namespace */ -import { AuthenticationState, WAConnectionState } from '@whiskeysockets/baileys'; +import { AuthenticationState, WAConnectionState } from 'baileys'; export enum Events { APPLICATION_STARTUP = 'application.startup', diff --git a/src/cache/rediscache.ts b/src/cache/rediscache.ts index 6e209ef1..c4e98968 100644 --- a/src/cache/rediscache.ts +++ b/src/cache/rediscache.ts @@ -1,4 +1,4 @@ -import { BufferJSON } from '@whiskeysockets/baileys'; +import { BufferJSON } from 'baileys'; import { RedisClientType } from 'redis'; import { ICache } from '../api/abstract/abstract.cache'; diff --git a/src/config/env.config.ts b/src/config/env.config.ts index ddd5ce9f..f1ab0335 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -366,9 +366,9 @@ export class ConfigService { GLOBAL_EVENTS: process.env?.WEBSOCKET_GLOBAL_EVENTS === 'true', }, WA_BUSINESS: { - TOKEN_WEBHOOK: process.env.WA_BUSINESS_TOKEN_WEBHOOK || '', - URL: process.env.WA_BUSINESS_URL || '', - VERSION: process.env.WA_BUSINESS_VERSION || '', + TOKEN_WEBHOOK: process.env.WA_BUSINESS_TOKEN_WEBHOOK || 'evolution', + URL: process.env.WA_BUSINESS_URL || 'https://graph.facebook.com', + VERSION: process.env.WA_BUSINESS_VERSION || 'v19.0', LANGUAGE: process.env.WA_BUSINESS_LANGUAGE || 'en', }, LOG: { diff --git a/src/docs/swagger.yaml b/src/docs/swagger.yaml index 59b252d3..8b73c5d9 100644 --- a/src/docs/swagger.yaml +++ b/src/docs/swagger.yaml @@ -25,7 +25,7 @@ info: [![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/26869335-5546d063-156b-4529-915f-909dd628c090?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D26869335-5546d063-156b-4529-915f-909dd628c090%26entityType%3Dcollection%26workspaceId%3D339a4ee7-378b-45c9-b5b8-fd2c0a9c2442) - version: 1.8.0 + version: 1.8.2 contact: name: DavidsonGomes email: contato@agenciadgcode.com diff --git a/src/utils/use-multi-file-auth-state-db.ts b/src/utils/use-multi-file-auth-state-db.ts index 995ac92a..dd25270e 100644 --- a/src/utils/use-multi-file-auth-state-db.ts +++ b/src/utils/use-multi-file-auth-state-db.ts @@ -1,29 +1,55 @@ -import { - AuthenticationCreds, - AuthenticationState, - BufferJSON, - initAuthCreds, - proto, - SignalDataTypeMap, -} from '@whiskeysockets/baileys'; +import { AuthenticationState, BufferJSON, initAuthCreds, WAProto as proto } from 'baileys'; +import fs from 'fs/promises'; +import path from 'path'; import { configService, Database } from '../config/env.config'; import { Logger } from '../config/logger.config'; +import { INSTANCE_DIR } from '../config/path.config'; import { dbserver } from '../libs/db.connect'; +const fixFileName = (file) => { + if (!file) { + return undefined; + } + const replacedSlash = file.replace(/\//g, '__'); + const replacedColon = replacedSlash.replace(/:/g, '-'); + return replacedColon; +}; + +async function fileExists(file) { + try { + const stat = await fs.stat(file); + if (stat.isFile()) return true; + } catch (error) { + return; + } +} + export async function useMultiFileAuthStateDb( coll: string, ): Promise<{ state: AuthenticationState; saveCreds: () => Promise }> { - const logger = new Logger(useMultiFileAuthStateDb.name); - const client = dbserver.getClient(); + const logger = new Logger(useMultiFileAuthStateDb.name); + const collection = client .db(configService.get('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances') .collection(coll); - const writeData = async (data: any, key: string): Promise => { + const sessionId = coll; + + const localFolder = path.join(INSTANCE_DIR, sessionId); + const localFile = (key: string) => path.join(localFolder, fixFileName(key) + '.json'); + await fs.mkdir(localFolder, { recursive: true }); + + async function writeData(data: any, key: string): Promise { try { + const dataString = JSON.stringify(data, BufferJSON.replacer); + + if (key != 'creds') { + await fs.writeFile(localFile(key), dataString); + return; + } await client.connect(); let msgParsed = JSON.parse(JSON.stringify(data, BufferJSON.replacer)); if (Array.isArray(msgParsed)) { @@ -37,42 +63,59 @@ export async function useMultiFileAuthStateDb( }); } catch (error) { logger.error(error); + return; } - }; + } - const readData = async (key: string): Promise => { + async function readData(key: string): Promise { try { - await client.connect(); - let data = (await collection.findOne({ _id: key })) as any; - if (data?.content_array) { - data = data.content_array; + if (key != 'creds') { + if (!(await fileExists(localFile(key)))) return null; + const rawData = await fs.readFile(localFile(key), { encoding: 'utf-8' }); + + const parsedData = JSON.parse(rawData, BufferJSON.reviver); + return parsedData; + } else { + await client.connect(); + let data = (await collection.findOne({ _id: key })) as any; + if (data?.content_array) { + data = data.content_array; + } + const creds = JSON.stringify(data); + return JSON.parse(creds, BufferJSON.reviver); } - const creds = JSON.stringify(data); - return JSON.parse(creds, BufferJSON.reviver); } catch (error) { logger.error(error); + return null; } - }; + } - const removeData = async (key: string) => { + async function removeData(key: string): Promise { try { - await client.connect(); - return await collection.deleteOne({ _id: key }); + if (key != 'creds') { + await fs.unlink(localFile(key)); + } else { + await client.connect(); + return await collection.deleteOne({ _id: key }); + } } catch (error) { logger.error(error); + return; } - }; + } - const creds: AuthenticationCreds = (await readData('creds')) || initAuthCreds(); + let creds = await readData('creds'); + if (!creds) { + creds = initAuthCreds(); + await writeData(creds, 'creds'); + } return { state: { creds, keys: { - get: async (type, ids: string[]) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const data: { [_: string]: SignalDataTypeMap[type] } = {}; + get: async (type, ids) => { + const data = {}; await Promise.all( ids.map(async (id) => { let value = await readData(`${type}-${id}`); @@ -83,25 +126,24 @@ export async function useMultiFileAuthStateDb( data[id] = value; }), ); - return data; }, - set: async (data: any) => { - const tasks: Promise[] = []; + set: async (data) => { + const tasks = []; for (const category in data) { for (const id in data[category]) { const value = data[category][id]; const key = `${category}-${id}`; + tasks.push(value ? writeData(value, key) : removeData(key)); } } - await Promise.all(tasks); }, }, }, - saveCreds: async () => { - return await writeData(creds, 'creds'); + saveCreds: () => { + return writeData(creds, 'creds'); }, }; } diff --git a/src/utils/use-multi-file-auth-state-provider-files.ts b/src/utils/use-multi-file-auth-state-provider-files.ts index 1051af8f..ec4d7e6c 100644 --- a/src/utils/use-multi-file-auth-state-provider-files.ts +++ b/src/utils/use-multi-file-auth-state-provider-files.ts @@ -34,14 +34,7 @@ * └──────────────────────────────────────────────────────────────────────────────┘ */ -import { - AuthenticationCreds, - AuthenticationState, - BufferJSON, - initAuthCreds, - proto, - SignalDataTypeMap, -} from '@whiskeysockets/baileys'; +import { AuthenticationCreds, AuthenticationState, BufferJSON, initAuthCreds, proto, SignalDataTypeMap } from 'baileys'; import { isNotEmpty } from 'class-validator'; import { ProviderFiles } from '../api/provider/sessions'; diff --git a/src/utils/use-multi-file-auth-state-redis-db.ts b/src/utils/use-multi-file-auth-state-redis-db.ts index 66bb89ea..d077b894 100644 --- a/src/utils/use-multi-file-auth-state-redis-db.ts +++ b/src/utils/use-multi-file-auth-state-redis-db.ts @@ -1,10 +1,4 @@ -import { - AuthenticationCreds, - AuthenticationState, - initAuthCreds, - proto, - SignalDataTypeMap, -} from '@whiskeysockets/baileys'; +import { AuthenticationCreds, AuthenticationState, initAuthCreds, proto, SignalDataTypeMap } from 'baileys'; import { CacheService } from '../api/services/cache.service'; import { Logger } from '../config/logger.config';