mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-22 20:12:02 -06:00
Merge branch 'release/1.8.2'
This commit is contained in:
commit
28c517a3d5
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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';
|
||||
|
@ -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(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { WAPresence } from '@whiskeysockets/baileys';
|
||||
import { WAPresence } from 'baileys';
|
||||
|
||||
import { ProxyDto } from './proxy.dto';
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { proto, WAPresence } from '@whiskeysockets/baileys';
|
||||
import { proto, WAPresence } from 'baileys';
|
||||
|
||||
export class Quoted {
|
||||
key: proto.IMessageKey;
|
||||
|
@ -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');
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
@ -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,
|
||||
|
@ -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<WASocket> {
|
||||
this.instance.authState = await this.defineAuthState();
|
||||
|
||||
if (!mobile) {
|
||||
this.mobile = false;
|
||||
} else {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
const session = this.configService.get<ConfigSessionPhone>('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<proto.IMessage>,
|
||||
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<WASocket> {
|
||||
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<ConfigSessionPhone>('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<proto.IMessage>,
|
||||
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<WASocket> {
|
||||
try {
|
||||
this.instance.authState = await this.defineAuthState();
|
||||
|
||||
const session = this.configService.get<ConfigSessionPhone>('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<proto.IMessage>,
|
||||
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<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!this.configService.get<CacheConf>('CACHE').LOCAL.ENABLED
|
||||
? null
|
||||
: this.getGroupMetadataCache,
|
||||
useCachedGroupMetadata:
|
||||
!!this.configService.get<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!!this.configService.get<CacheConf>('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<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!this.configService.get<CacheConf>('CACHE').LOCAL.ENABLED
|
||||
? null
|
||||
: this.getGroupMetadataCache,
|
||||
useCachedGroupMetadata:
|
||||
!!this.configService.get<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!!this.configService.get<CacheConf>('CACHE').LOCAL.ENABLED,
|
||||
} as unknown as MiscMessageGenerationOptions,
|
||||
);
|
||||
}
|
||||
@ -1988,11 +1898,9 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
},
|
||||
{
|
||||
...option,
|
||||
cachedGroupMetadata:
|
||||
!this.configService.get<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!this.configService.get<CacheConf>('CACHE').LOCAL.ENABLED
|
||||
? null
|
||||
: this.getGroupMetadataCache,
|
||||
useCachedGroupMetadata:
|
||||
!!this.configService.get<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!!this.configService.get<CacheConf>('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<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!this.configService.get<CacheConf>('CACHE').LOCAL.ENABLED
|
||||
? null
|
||||
: this.getGroupMetadataCache,
|
||||
useCachedGroupMetadata:
|
||||
!!this.configService.get<CacheConf>('CACHE').REDIS.ENABLED &&
|
||||
!!this.configService.get<CacheConf>('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());
|
||||
|
@ -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',
|
||||
|
2
src/cache/rediscache.ts
vendored
2
src/cache/rediscache.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { BufferJSON } from '@whiskeysockets/baileys';
|
||||
import { BufferJSON } from 'baileys';
|
||||
import { RedisClientType } from 'redis';
|
||||
|
||||
import { ICache } from '../api/abstract/abstract.cache';
|
||||
|
@ -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: {
|
||||
|
@ -25,7 +25,7 @@ info:
|
||||
</font>
|
||||
|
||||
[](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
|
||||
|
@ -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<void> }> {
|
||||
const logger = new Logger(useMultiFileAuthStateDb.name);
|
||||
|
||||
const client = dbserver.getClient();
|
||||
|
||||
const logger = new Logger(useMultiFileAuthStateDb.name);
|
||||
|
||||
const collection = client
|
||||
.db(configService.get<Database>('DATABASE').CONNECTION.DB_PREFIX_NAME + '-instances')
|
||||
.collection(coll);
|
||||
|
||||
const writeData = async (data: any, key: string): Promise<any> => {
|
||||
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<any> {
|
||||
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<any> => {
|
||||
async function readData(key: string): Promise<any> {
|
||||
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<any> {
|
||||
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<void>[] = [];
|
||||
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');
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -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';
|
||||
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user