mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-14 01:41:24 -06:00
prima orm: instance controller ok
This commit is contained in:
parent
b309d686ec
commit
99c8cc0242
@ -12,6 +12,8 @@
|
||||
* Connection to mongodb removed
|
||||
* Standardized all request bodies to use camelCase
|
||||
* Change in webhook information from owner to instanceId
|
||||
* Changed the .env file configuration, removed the yml version and added .env to the repository root
|
||||
* Removed the mobile type connection with Baileys
|
||||
|
||||
# 1.8.0 (2024-05-27 16:10)
|
||||
|
||||
|
@ -56,6 +56,8 @@ model Instance {
|
||||
Websocket Websocket?
|
||||
Typebot Typebot?
|
||||
Session Session?
|
||||
MessageUpdate MessageUpdate[]
|
||||
TypebotSession TypebotSession[]
|
||||
}
|
||||
|
||||
model Session {
|
||||
@ -130,6 +132,8 @@ model MessageUpdate {
|
||||
status String @db.VarChar(30)
|
||||
Message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
||||
messageId Int
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String
|
||||
}
|
||||
|
||||
model Webhook {
|
||||
@ -277,4 +281,6 @@ model TypebotSession {
|
||||
Typebot Typebot @relation(fields: [typebotId], references: [id], onDelete: Cascade)
|
||||
typebotId Int
|
||||
Message Message[]
|
||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||
instanceId String
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ export class InstanceController {
|
||||
webhookEvents,
|
||||
qrcode,
|
||||
number,
|
||||
mobile,
|
||||
integration,
|
||||
token,
|
||||
chatwootAccountId,
|
||||
@ -130,7 +129,7 @@ export class InstanceController {
|
||||
|
||||
const instanceId = v4();
|
||||
|
||||
await this.waMonitor.saveInstance({ instanceId, integration, instanceName, token, number, mobile });
|
||||
await this.waMonitor.saveInstance({ instanceId, integration, instanceName, token, number });
|
||||
|
||||
instance.instanceName = instanceName;
|
||||
instance.instanceId = instanceId;
|
||||
@ -442,7 +441,7 @@ export class InstanceController {
|
||||
|
||||
if (qrcode) {
|
||||
this.logger.verbose('creating qrcode');
|
||||
await instance.connectToWhatsapp(number, mobile);
|
||||
await instance.connectToWhatsapp(number);
|
||||
await delay(5000);
|
||||
getQrcode = instance.qrCode;
|
||||
}
|
||||
@ -608,7 +607,7 @@ export class InstanceController {
|
||||
}
|
||||
}
|
||||
|
||||
public async connectToWhatsapp({ instanceName, number = null, mobile = null }: InstanceDto) {
|
||||
public async connectToWhatsapp({ instanceName, number = null }: InstanceDto) {
|
||||
try {
|
||||
this.logger.verbose('requested connectToWhatsapp from ' + instanceName + ' instance');
|
||||
|
||||
@ -631,7 +630,7 @@ export class InstanceController {
|
||||
|
||||
if (state == 'close') {
|
||||
this.logger.verbose('connecting');
|
||||
await instance.connectToWhatsapp(number, mobile);
|
||||
await instance.connectToWhatsapp(number);
|
||||
|
||||
await delay(5000);
|
||||
return instance.qrCode;
|
||||
@ -672,20 +671,6 @@ export class InstanceController {
|
||||
}
|
||||
}
|
||||
|
||||
public async registerMobileCode({ instanceName }: InstanceDto, { mobileCode }: any) {
|
||||
try {
|
||||
this.logger.verbose('requested registerMobileCode from ' + instanceName + ' instance');
|
||||
|
||||
const instance = this.waMonitor.waInstances[instanceName];
|
||||
|
||||
console.log('mobileCode', mobileCode);
|
||||
await instance.receiveMobileCode(mobileCode);
|
||||
return { status: 'SUCCESS', error: false, response: { message: 'Mobile code registered' } };
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async connectionState({ instanceName }: InstanceDto) {
|
||||
this.logger.verbose('requested connectionState from ' + instanceName + ' instance');
|
||||
return {
|
||||
|
@ -7,7 +7,6 @@ export class InstanceDto {
|
||||
instanceId?: string;
|
||||
qrcode?: boolean;
|
||||
number?: string;
|
||||
mobile?: boolean;
|
||||
integration?: string;
|
||||
token?: string;
|
||||
webhook?: string;
|
||||
|
@ -165,10 +165,10 @@ class ChatwootImport {
|
||||
remoteJid: string;
|
||||
};
|
||||
|
||||
return (
|
||||
parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) ||
|
||||
(a.messageTimestamp as number) - (b.messageTimestamp as number)
|
||||
);
|
||||
const aMessageTimestamp = a.messageTimestamp as any as number;
|
||||
const bMessageTimestamp = b.messageTimestamp as any as number;
|
||||
|
||||
return parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) || aMessageTimestamp - bMessageTimestamp;
|
||||
});
|
||||
|
||||
const allMessagesMappedByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesOrdered);
|
||||
@ -176,8 +176,8 @@ class ChatwootImport {
|
||||
const phoneNumbersWithTimestamp = new Map<string, firstLastTimestamp>();
|
||||
allMessagesMappedByPhoneNumber.forEach((messages: Message[], phoneNumber: string) => {
|
||||
phoneNumbersWithTimestamp.set(phoneNumber, {
|
||||
first: messages[0]?.messageTimestamp as number,
|
||||
last: messages[messages.length - 1]?.messageTimestamp as number,
|
||||
first: messages[0]?.messageTimestamp as any as number,
|
||||
last: messages[messages.length - 1]?.messageTimestamp as any as number,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -47,22 +47,6 @@ export class InstanceRouter extends RouterBroker {
|
||||
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.post(this.routerPath('registerMobileCode'), ...guards, async (req, res) => {
|
||||
logger.verbose('request received in registerMobileCode');
|
||||
logger.verbose('request body: ');
|
||||
logger.verbose(req.body);
|
||||
|
||||
logger.verbose('request query: ');
|
||||
logger.verbose(req.query);
|
||||
const response = await this.dataValidate<null>({
|
||||
request: req,
|
||||
schema: instanceNameSchema,
|
||||
ClassRef: SetPresenceDto,
|
||||
execute: (instance, data) => instanceController.registerMobileCode(instance, data),
|
||||
});
|
||||
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
})
|
||||
.get(this.routerPath('connect'), ...guards, async (req, res) => {
|
||||
logger.verbose('request received in connectInstance');
|
||||
logger.verbose('request body: ');
|
||||
|
@ -24,7 +24,6 @@ import makeWASocket, {
|
||||
MessageUpsertType,
|
||||
MiscMessageGenerationOptions,
|
||||
ParticipantAction,
|
||||
PHONENUMBER_MCC,
|
||||
prepareWAMessageMedia,
|
||||
proto,
|
||||
useMultiFileAuthState,
|
||||
@ -44,7 +43,6 @@ import { isBase64, isURL } from 'class-validator';
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
// import ffmpeg from 'fluent-ffmpeg';
|
||||
import fs, { existsSync, readFileSync } from 'fs';
|
||||
import { parsePhoneNumber } from 'libphonenumber-js';
|
||||
import Long from 'long';
|
||||
import NodeCache from 'node-cache';
|
||||
import { getMIMEType } from 'node-mime-types';
|
||||
@ -143,7 +141,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
this.logger.verbose('BaileysStartupService initialized');
|
||||
this.cleanStore();
|
||||
this.instance.qrcode = { count: 0 };
|
||||
this.mobile = false;
|
||||
this.recoveringMessages();
|
||||
this.cronForceUpdateGroupMetadataCache();
|
||||
|
||||
@ -159,7 +156,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
public stateConnection: wa.StateConnection = { state: 'close' };
|
||||
|
||||
public phoneNumber: string;
|
||||
public mobile: boolean;
|
||||
|
||||
private async recoveringMessages() {
|
||||
this.logger.info('Recovering messages lost');
|
||||
@ -452,13 +448,8 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (connection === 'connecting') {
|
||||
if (this.mobile) this.sendMobileCode();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Refactor this method for prisma
|
||||
private async getMessage(key: proto.IMessageKey, full = false) {
|
||||
this.logger.verbose('Getting message with key: ' + JSON.stringify(key));
|
||||
try {
|
||||
@ -525,7 +516,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
return await useMultiFileAuthState(join(INSTANCE_DIR, this.instance.name));
|
||||
}
|
||||
|
||||
public async connectToWhatsapp(number?: string, mobile?: boolean): Promise<WASocket> {
|
||||
public async connectToWhatsapp(number?: string): Promise<WASocket> {
|
||||
this.logger.verbose('Connecting to whatsapp');
|
||||
try {
|
||||
this.loadWebhook();
|
||||
@ -539,12 +530,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
|
||||
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));
|
||||
@ -598,7 +583,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
},
|
||||
logger: P({ level: this.logBaileys }),
|
||||
printQRInTerminal: false,
|
||||
mobile,
|
||||
browser: number ? ['Chrome (Linux)', session.NAME, release()] : browser,
|
||||
version,
|
||||
markOnlineOnConnect: this.localSettings.alwaysOnline,
|
||||
@ -663,64 +647,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
}
|
||||
}
|
||||
|
||||
private async sendMobileCode() {
|
||||
const { registration } = this.client.authState.creds || null;
|
||||
|
||||
let phoneNumber = registration.phoneNumber || this.phoneNumber;
|
||||
|
||||
if (!phoneNumber.startsWith('+')) {
|
||||
phoneNumber = '+' + phoneNumber;
|
||||
}
|
||||
|
||||
if (!phoneNumber) {
|
||||
this.logger.error('Phone number not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const parsedPhoneNumber = parsePhoneNumber(phoneNumber);
|
||||
|
||||
if (!parsedPhoneNumber?.isValid()) {
|
||||
this.logger.error('Phone number invalid');
|
||||
return;
|
||||
}
|
||||
|
||||
registration.phoneNumber = parsedPhoneNumber.format('E.164');
|
||||
registration.phoneNumberCountryCode = parsedPhoneNumber.countryCallingCode;
|
||||
registration.phoneNumberNationalNumber = parsedPhoneNumber.nationalNumber;
|
||||
|
||||
const mcc = await PHONENUMBER_MCC[parsedPhoneNumber.countryCallingCode];
|
||||
if (!mcc) {
|
||||
this.logger.error('MCC not found');
|
||||
return;
|
||||
}
|
||||
|
||||
registration.phoneNumberMobileCountryCode = mcc;
|
||||
registration.method = 'sms';
|
||||
|
||||
try {
|
||||
const response = await this.client.requestRegistrationCode(registration);
|
||||
|
||||
if (['ok', 'sent'].includes(response?.status)) {
|
||||
this.logger.verbose('Registration code sent successfully');
|
||||
|
||||
return response;
|
||||
}
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async receiveMobileCode(code: string) {
|
||||
await this.client
|
||||
.register(code.replace(/["']/g, '').trim().toLowerCase())
|
||||
.then(async () => {
|
||||
this.logger.verbose('Registration code received successfully');
|
||||
})
|
||||
.catch((error) => {
|
||||
this.logger.error(error);
|
||||
});
|
||||
}
|
||||
|
||||
public async reloadConnection(): Promise<WASocket> {
|
||||
try {
|
||||
this.instance.authState = await this.defineAuthState();
|
||||
@ -1429,6 +1355,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
participant: key?.remoteJid,
|
||||
status: 'DELETED',
|
||||
dateTime: Date.now(),
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
@ -1458,6 +1385,7 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
status: status[update.status],
|
||||
dateTime: Date.now(),
|
||||
pollUpdates,
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
@ -3289,7 +3217,6 @@ export class BaileysStartupService extends ChannelStartupService {
|
||||
if (!isJidGroup(groupJid)) return null;
|
||||
|
||||
if (await groupMetadataCache.has(groupJid)) {
|
||||
console.log('Has cache for group: ' + groupJid);
|
||||
const meta = await groupMetadataCache.get(groupJid);
|
||||
|
||||
if (Date.now() - meta.timestamp > 3600000) {
|
||||
|
@ -541,6 +541,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
participant: key?.remoteJid,
|
||||
status: 'DELETED',
|
||||
dateTime: Date.now(),
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
@ -569,6 +570,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
participant: key?.remoteJid,
|
||||
status: item.status.toUpperCase(),
|
||||
dateTime: Date.now(),
|
||||
instanceId: this.instanceId,
|
||||
};
|
||||
|
||||
this.logger.verbose(message);
|
||||
|
@ -209,7 +209,12 @@ export class WAMonitoringService {
|
||||
|
||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
this.logger.verbose('cleaning up instance in database: ' + instanceName);
|
||||
// TODO: deleta instancia
|
||||
await this.prismaRepository.instance.update({
|
||||
where: { name: instanceName },
|
||||
data: { connectionStatus: 'close' },
|
||||
});
|
||||
|
||||
await this.prismaRepository.session.deleteMany({ where: { sessionId: instanceName } });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -254,7 +259,27 @@ export class WAMonitoringService {
|
||||
|
||||
this.logger.verbose('cleaning store database instance: ' + instanceName);
|
||||
|
||||
// TODO: deleta dados da instancia
|
||||
await this.prismaRepository.session.deleteMany({ where: { sessionId: instanceName } });
|
||||
|
||||
await this.prismaRepository.chat.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.contact.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.messageUpdate.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.message.deleteMany({ where: { instanceId: instanceName } });
|
||||
|
||||
await this.prismaRepository.integration.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.auth.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.webhook.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.chatwoot.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.proxy.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.rabbitmq.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.sqs.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.typebotSession.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.typebot.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.websocket.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.setting.deleteMany({ where: { instanceId: instanceName } });
|
||||
await this.prismaRepository.label.deleteMany({ where: { instanceId: instanceName } });
|
||||
|
||||
await this.prismaRepository.instance.delete({ where: { name: instanceName } });
|
||||
}
|
||||
|
||||
public async loadInstance() {
|
||||
@ -276,8 +301,6 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
public async saveInstance(data: any) {
|
||||
this.logger.verbose('Save instance');
|
||||
|
||||
try {
|
||||
const msgParsed = JSON.parse(JSON.stringify(data));
|
||||
if (this.db.ENABLED && this.db.SAVE_DATA.INSTANCE) {
|
||||
@ -289,7 +312,6 @@ export class WAMonitoringService {
|
||||
},
|
||||
});
|
||||
|
||||
console.log('saveInstance');
|
||||
await this.prismaRepository.integration.create({
|
||||
data: {
|
||||
instanceId: data.instanceId,
|
||||
@ -309,7 +331,6 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async setInstance(id: string, name: string) {
|
||||
console.log('setInstance', name);
|
||||
const integration = await this.prismaRepository.integration.findUnique({
|
||||
where: { instanceId: id },
|
||||
});
|
||||
@ -355,7 +376,6 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async loadInstancesFromRedis() {
|
||||
console.log('loadInstancesFromRedis');
|
||||
this.logger.verbose('Redis enabled');
|
||||
const keys = await this.cache.keys();
|
||||
|
||||
@ -368,11 +388,9 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async loadInstancesFromDatabasePostgres() {
|
||||
console.log('loadInstancesFromDatabasePostgres');
|
||||
this.logger.verbose('Database enabled');
|
||||
const instances = await this.prismaRepository.instance.findMany();
|
||||
|
||||
console.log('instances', instances);
|
||||
if (instances.length === 0) {
|
||||
this.logger.verbose('No instances found');
|
||||
return;
|
||||
@ -382,7 +400,6 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async loadInstancesFromProvider() {
|
||||
console.log('loadInstancesFromProvider');
|
||||
this.logger.verbose('Provider in files enabled');
|
||||
const [instances] = await this.providerFiles.allInstances();
|
||||
|
||||
@ -395,7 +412,6 @@ export class WAMonitoringService {
|
||||
}
|
||||
|
||||
private async loadInstancesFromFiles() {
|
||||
console.log('loadInstancesFromFiles');
|
||||
this.logger.verbose('Store in files enabled');
|
||||
const dir = opendirSync(INSTANCE_DIR, { encoding: 'utf-8' });
|
||||
const instanceDirs = [];
|
||||
|
Loading…
Reference in New Issue
Block a user