prima orm: instance controller ok

This commit is contained in:
Davidson Gomes 2024-06-06 16:14:22 -03:00
parent b309d686ec
commit 99c8cc0242
9 changed files with 50 additions and 129 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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 {

View File

@ -7,7 +7,6 @@ export class InstanceDto {
instanceId?: string;
qrcode?: boolean;
number?: string;
mobile?: boolean;
integration?: string;
token?: string;
webhook?: string;

View File

@ -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,
});
});

View File

@ -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: ');

View File

@ -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) {

View File

@ -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);

View File

@ -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 = [];