mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-14 01:41:24 -06:00
320 lines
9.5 KiB
TypeScript
320 lines
9.5 KiB
TypeScript
import { delay } from '@whiskeysockets/baileys';
|
|
import EventEmitter2 from 'eventemitter2';
|
|
import { Auth, ConfigService } from '../../config/env.config';
|
|
import { BadRequestException, InternalServerErrorException } from '../../exceptions';
|
|
import { InstanceDto } from '../dto/instance.dto';
|
|
import { RepositoryBroker } from '../repository/repository.manager';
|
|
import { AuthService, OldToken } from '../services/auth.service';
|
|
import { WAMonitoringService } from '../services/monitor.service';
|
|
import { WAStartupService } from '../services/whatsapp.service';
|
|
import { WebhookService } from '../services/webhook.service';
|
|
import { Logger } from '../../config/logger.config';
|
|
import { wa } from '../types/wa.types';
|
|
import { RedisCache } from '../../db/redis.client';
|
|
|
|
export class InstanceController {
|
|
constructor(
|
|
private readonly waMonitor: WAMonitoringService,
|
|
private readonly configService: ConfigService,
|
|
private readonly repository: RepositoryBroker,
|
|
private readonly eventEmitter: EventEmitter2,
|
|
private readonly authService: AuthService,
|
|
private readonly webhookService: WebhookService,
|
|
private readonly cache: RedisCache,
|
|
) {}
|
|
|
|
private readonly logger = new Logger(InstanceController.name);
|
|
|
|
public async createInstance({
|
|
instanceName,
|
|
webhook,
|
|
webhook_by_events,
|
|
events,
|
|
qrcode,
|
|
token,
|
|
}: InstanceDto) {
|
|
this.logger.verbose('requested createInstance from ' + instanceName + ' instance');
|
|
|
|
const mode = this.configService.get<Auth>('AUTHENTICATION').INSTANCE.MODE;
|
|
|
|
if (mode === 'container') {
|
|
this.logger.verbose('container mode');
|
|
|
|
if (Object.keys(this.waMonitor.waInstances).length > 0) {
|
|
throw new BadRequestException([
|
|
'Instance already created',
|
|
'Only one instance can be created',
|
|
]);
|
|
}
|
|
|
|
this.logger.verbose('checking duplicate token');
|
|
await this.authService.checkDuplicateToken(token);
|
|
|
|
this.logger.verbose('creating instance');
|
|
const instance = new WAStartupService(
|
|
this.configService,
|
|
this.eventEmitter,
|
|
this.repository,
|
|
this.cache,
|
|
);
|
|
instance.instanceName = instanceName;
|
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
|
|
|
this.waMonitor.waInstances[instance.instanceName] = instance;
|
|
this.waMonitor.delInstanceTime(instance.instanceName);
|
|
|
|
this.logger.verbose('generating hash');
|
|
const hash = await this.authService.generateHash(
|
|
{
|
|
instanceName: instance.instanceName,
|
|
},
|
|
token,
|
|
);
|
|
|
|
this.logger.verbose('hash: ' + hash + ' generated');
|
|
|
|
let getEvents: string[];
|
|
|
|
if (webhook) {
|
|
this.logger.verbose('creating webhook');
|
|
try {
|
|
this.webhookService.create(instance, {
|
|
enabled: true,
|
|
url: webhook,
|
|
events,
|
|
webhook_by_events,
|
|
});
|
|
|
|
getEvents = (await this.webhookService.find(instance)).events;
|
|
} catch (error) {
|
|
this.logger.log(error);
|
|
}
|
|
}
|
|
|
|
this.logger.verbose('instance created');
|
|
this.logger.verbose({
|
|
instance: {
|
|
instanceName: instance.instanceName,
|
|
status: 'created',
|
|
},
|
|
hash,
|
|
webhook,
|
|
events: getEvents,
|
|
});
|
|
|
|
return {
|
|
instance: {
|
|
instanceName: instance.instanceName,
|
|
status: 'created',
|
|
},
|
|
hash,
|
|
webhook,
|
|
events: getEvents,
|
|
};
|
|
} else {
|
|
this.logger.verbose('server mode');
|
|
|
|
this.logger.verbose('checking duplicate token');
|
|
await this.authService.checkDuplicateToken(token);
|
|
|
|
this.logger.verbose('creating instance');
|
|
const instance = new WAStartupService(
|
|
this.configService,
|
|
this.eventEmitter,
|
|
this.repository,
|
|
this.cache,
|
|
);
|
|
instance.instanceName = instanceName;
|
|
|
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
|
|
|
this.waMonitor.waInstances[instance.instanceName] = instance;
|
|
this.waMonitor.delInstanceTime(instance.instanceName);
|
|
|
|
this.logger.verbose('generating hash');
|
|
const hash = await this.authService.generateHash(
|
|
{
|
|
instanceName: instance.instanceName,
|
|
},
|
|
token,
|
|
);
|
|
|
|
this.logger.verbose('hash: ' + hash + ' generated');
|
|
|
|
let getEvents: string[];
|
|
|
|
if (webhook) {
|
|
this.logger.verbose('creating webhook');
|
|
try {
|
|
this.webhookService.create(instance, {
|
|
enabled: true,
|
|
url: webhook,
|
|
events,
|
|
webhook_by_events,
|
|
});
|
|
|
|
getEvents = (await this.webhookService.find(instance)).events;
|
|
} catch (error) {
|
|
this.logger.log(error);
|
|
}
|
|
}
|
|
|
|
let getQrcode: wa.QrCode;
|
|
|
|
if (qrcode) {
|
|
this.logger.verbose('creating qrcode');
|
|
await instance.connectToWhatsapp();
|
|
await delay(2000);
|
|
getQrcode = instance.qrCode;
|
|
}
|
|
|
|
this.logger.verbose('instance created');
|
|
this.logger.verbose({
|
|
instance: {
|
|
instanceName: instance.instanceName,
|
|
status: 'created',
|
|
},
|
|
hash,
|
|
webhook,
|
|
webhook_by_events,
|
|
events: getEvents,
|
|
qrcode: getQrcode,
|
|
});
|
|
|
|
return {
|
|
instance: {
|
|
instanceName: instance.instanceName,
|
|
status: 'created',
|
|
},
|
|
hash,
|
|
webhook,
|
|
webhook_by_events,
|
|
events: getEvents,
|
|
qrcode: getQrcode,
|
|
};
|
|
}
|
|
}
|
|
|
|
public async connectToWhatsapp({ instanceName }: InstanceDto) {
|
|
try {
|
|
this.logger.verbose(
|
|
'requested connectToWhatsapp from ' + instanceName + ' instance',
|
|
);
|
|
|
|
const instance = this.waMonitor.waInstances[instanceName];
|
|
const state = instance?.connectionStatus?.state;
|
|
|
|
this.logger.verbose('state: ' + state);
|
|
|
|
switch (state) {
|
|
case 'close':
|
|
this.logger.verbose('connecting');
|
|
await instance.connectToWhatsapp();
|
|
await delay(2000);
|
|
return instance.qrCode;
|
|
case 'connecting':
|
|
return instance.qrCode;
|
|
default:
|
|
return await this.connectionState({ instanceName });
|
|
}
|
|
} catch (error) {
|
|
this.logger.error(error);
|
|
}
|
|
}
|
|
|
|
public async restartInstance({ instanceName }: InstanceDto) {
|
|
try {
|
|
this.logger.verbose('requested restartInstance from ' + instanceName + ' instance');
|
|
|
|
this.logger.verbose('deleting instance: ' + instanceName);
|
|
delete this.waMonitor.waInstances[instanceName];
|
|
|
|
this.logger.verbose('creating instance: ' + instanceName);
|
|
const instance = new WAStartupService(
|
|
this.configService,
|
|
this.eventEmitter,
|
|
this.repository,
|
|
this.cache,
|
|
);
|
|
|
|
instance.instanceName = instanceName;
|
|
|
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
|
|
|
this.logger.verbose('connecting instance: ' + instanceName);
|
|
await instance.connectToWhatsapp();
|
|
this.waMonitor.waInstances[instance.instanceName] = instance;
|
|
|
|
return { error: false, message: 'Instance restarted' };
|
|
} catch (error) {
|
|
this.logger.error(error);
|
|
}
|
|
}
|
|
|
|
public async connectionState({ instanceName }: InstanceDto) {
|
|
this.logger.verbose('requested connectionState from ' + instanceName + ' instance');
|
|
return this.waMonitor.waInstances[instanceName]?.connectionStatus;
|
|
}
|
|
|
|
public async fetchInstances({ instanceName }: InstanceDto) {
|
|
this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance');
|
|
if (instanceName) {
|
|
this.logger.verbose('instanceName: ' + instanceName);
|
|
return this.waMonitor.instanceInfo(instanceName);
|
|
}
|
|
|
|
return this.waMonitor.instanceInfo();
|
|
}
|
|
|
|
public async logout({ instanceName }: InstanceDto) {
|
|
this.logger.verbose('requested logout from ' + instanceName + ' instance');
|
|
try {
|
|
this.logger.verbose('logging out instance: ' + instanceName);
|
|
await this.waMonitor.waInstances[instanceName]?.client?.logout(
|
|
'Log out instance: ' + instanceName,
|
|
);
|
|
|
|
this.logger.verbose('close connection instance: ' + instanceName);
|
|
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
|
|
|
return { error: false, message: 'Instance logged out' };
|
|
} catch (error) {
|
|
throw new InternalServerErrorException(error.toString());
|
|
}
|
|
}
|
|
|
|
public async deleteInstance({ instanceName }: InstanceDto) {
|
|
this.logger.verbose('requested deleteInstance from ' + instanceName + ' instance');
|
|
const stateConn = await this.connectionState({ instanceName });
|
|
|
|
if (stateConn.state === 'open') {
|
|
throw new BadRequestException([
|
|
'Deletion failed',
|
|
'The instance needs to be disconnected',
|
|
]);
|
|
}
|
|
try {
|
|
if (stateConn.state === 'connecting') {
|
|
this.logger.verbose('logging out instance: ' + instanceName);
|
|
|
|
await this.logout({ instanceName });
|
|
delete this.waMonitor.waInstances[instanceName];
|
|
return { error: false, message: 'Instance deleted' };
|
|
} else {
|
|
this.logger.verbose('deleting instance: ' + instanceName);
|
|
|
|
delete this.waMonitor.waInstances[instanceName];
|
|
this.eventEmitter.emit('remove.instance', instanceName, 'inner');
|
|
return { error: false, message: 'Instance deleted' };
|
|
}
|
|
} catch (error) {
|
|
throw new BadRequestException(error.toString());
|
|
}
|
|
}
|
|
|
|
public async refreshToken(_: InstanceDto, oldToken: OldToken) {
|
|
this.logger.verbose('requested refreshToken');
|
|
return await this.authService.refreshToken(oldToken);
|
|
}
|
|
}
|