mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-24 17:38:40 -06:00
refactor: channel integration folders
This commit is contained in:
parent
fff11ea452
commit
a83a358620
@ -2,14 +2,15 @@ import { InstanceDto } from '@api/dto/instance.dto';
|
|||||||
import { ProviderFiles } from '@api/provider/sessions';
|
import { ProviderFiles } from '@api/provider/sessions';
|
||||||
import { PrismaRepository } from '@api/repository/repository.service';
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
import { CacheService } from '@api/services/cache.service';
|
import { CacheService } from '@api/services/cache.service';
|
||||||
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
import { Integration } from '@api/types/wa.types';
|
import { Integration } from '@api/types/wa.types';
|
||||||
import { ConfigService } from '@config/env.config';
|
import { ConfigService } from '@config/env.config';
|
||||||
import { BadRequestException } from '@exceptions';
|
import { BadRequestException } from '@exceptions';
|
||||||
import EventEmitter2 from 'eventemitter2';
|
import EventEmitter2 from 'eventemitter2';
|
||||||
|
|
||||||
import { EvolutionStartupService } from './evolution/evolution.channel.service';
|
import { EvolutionStartupService } from './evolution/evolution.channel.service';
|
||||||
import { BaileysStartupService } from './whatsapp/baileys/whatsapp.baileys.service';
|
import { BusinessStartupService } from './meta/whatsapp.business.service';
|
||||||
import { BusinessStartupService } from './whatsapp/business/whatsapp.business.service';
|
import { BaileysStartupService } from './whatsapp/whatsapp.baileys.service';
|
||||||
|
|
||||||
type ChannelDataType = {
|
type ChannelDataType = {
|
||||||
configService: ConfigService;
|
configService: ConfigService;
|
||||||
@ -21,7 +22,35 @@ type ChannelDataType = {
|
|||||||
providerFiles: ProviderFiles;
|
providerFiles: ProviderFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface ChannelControllerInterface {
|
||||||
|
receiveWebhook(data: any): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
export class ChannelController {
|
export class ChannelController {
|
||||||
|
public prismaRepository: PrismaRepository;
|
||||||
|
public waMonitor: WAMonitoringService;
|
||||||
|
|
||||||
|
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
||||||
|
this.prisma = prismaRepository;
|
||||||
|
this.monitor = waMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set prisma(prisma: PrismaRepository) {
|
||||||
|
this.prismaRepository = prisma;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get prisma() {
|
||||||
|
return this.prismaRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set monitor(waMonitor: WAMonitoringService) {
|
||||||
|
this.waMonitor = waMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get monitor() {
|
||||||
|
return this.waMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
public init(instanceData: InstanceDto, data: ChannelDataType) {
|
public init(instanceData: InstanceDto, data: ChannelDataType) {
|
||||||
if (!instanceData.token && instanceData.integration === Integration.WHATSAPP_BUSINESS) {
|
if (!instanceData.token && instanceData.integration === Integration.WHATSAPP_BUSINESS) {
|
||||||
throw new BadRequestException('token is required');
|
throw new BadRequestException('token is required');
|
||||||
|
15
src/api/integrations/channel/channel.router.ts
Normal file
15
src/api/integrations/channel/channel.router.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Router } from 'express';
|
||||||
|
|
||||||
|
import { EvolutionRouter } from './evolution/evolution.router';
|
||||||
|
import { MetaRouter } from './meta/meta.router';
|
||||||
|
|
||||||
|
export class ChannelRouter {
|
||||||
|
public readonly router: Router;
|
||||||
|
|
||||||
|
constructor(configService: any) {
|
||||||
|
this.router = Router();
|
||||||
|
|
||||||
|
this.router.use('/', new EvolutionRouter(configService).router);
|
||||||
|
this.router.use('/', new MetaRouter(configService).router);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
|
import { Logger } from '@config/logger.config';
|
||||||
|
|
||||||
|
import { ChannelController, ChannelControllerInterface } from '../channel.controller';
|
||||||
|
|
||||||
|
export class EvolutionController extends ChannelController implements ChannelControllerInterface {
|
||||||
|
private readonly logger = new Logger(EvolutionController.name);
|
||||||
|
|
||||||
|
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
||||||
|
super(prismaRepository, waMonitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
integrationEnabled: boolean;
|
||||||
|
|
||||||
|
public async receiveWebhook(data: any) {
|
||||||
|
const numberId = data.numberId;
|
||||||
|
|
||||||
|
if (!numberId) {
|
||||||
|
this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = await this.prismaRepository.instance.findFirst({
|
||||||
|
where: { number: numberId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
this.logger.error('WebhookService -> receiveWebhook -> instance not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
18
src/api/integrations/channel/evolution/evolution.router.ts
Normal file
18
src/api/integrations/channel/evolution/evolution.router.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { RouterBroker } from '@api/abstract/abstract.router';
|
||||||
|
import { evolutionController } from '@api/server.module';
|
||||||
|
import { ConfigService } from '@config/env.config';
|
||||||
|
import { Router } from 'express';
|
||||||
|
|
||||||
|
export class EvolutionRouter extends RouterBroker {
|
||||||
|
constructor(readonly configService: ConfigService) {
|
||||||
|
super();
|
||||||
|
this.router.post(this.routerPath('webhook/evolution', false), async (req, res) => {
|
||||||
|
const { body } = req;
|
||||||
|
const response = await evolutionController.receiveWebhook(body);
|
||||||
|
|
||||||
|
return res.status(200).json(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly router: Router = Router();
|
||||||
|
}
|
72
src/api/integrations/channel/meta/meta.controller.ts
Normal file
72
src/api/integrations/channel/meta/meta.controller.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { PrismaRepository } from '@api/repository/repository.service';
|
||||||
|
import { WAMonitoringService } from '@api/services/monitor.service';
|
||||||
|
import { Logger } from '@config/logger.config';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import { ChannelController, ChannelControllerInterface } from '../channel.controller';
|
||||||
|
|
||||||
|
export class MetaController extends ChannelController implements ChannelControllerInterface {
|
||||||
|
private readonly logger = new Logger(MetaController.name);
|
||||||
|
|
||||||
|
constructor(prismaRepository: PrismaRepository, waMonitor: WAMonitoringService) {
|
||||||
|
super(prismaRepository, waMonitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
integrationEnabled: boolean;
|
||||||
|
|
||||||
|
public async receiveWebhook(data: any) {
|
||||||
|
if (data.object === 'whatsapp_business_account') {
|
||||||
|
if (data.entry[0]?.changes[0]?.field === 'message_template_status_update') {
|
||||||
|
const template = await this.prismaRepository.template.findFirst({
|
||||||
|
where: { templateId: `${data.entry[0].changes[0].value.message_template_id}` },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!template) {
|
||||||
|
console.log('template not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { webhookUrl } = template;
|
||||||
|
|
||||||
|
await axios.post(webhookUrl, data.entry[0].changes[0].value, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.entry?.forEach(async (entry: any) => {
|
||||||
|
const numberId = entry.changes[0].value.metadata.phone_number_id;
|
||||||
|
|
||||||
|
if (!numberId) {
|
||||||
|
this.logger.error('WebhookService -> receiveWebhookMeta -> numberId not found');
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = await this.prismaRepository.instance.findFirst({
|
||||||
|
where: { number: numberId },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
this.logger.error('WebhookService -> receiveWebhookMeta -> instance not found');
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 'success',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
24
src/api/integrations/channel/meta/meta.router.ts
Normal file
24
src/api/integrations/channel/meta/meta.router.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { RouterBroker } from '@api/abstract/abstract.router';
|
||||||
|
import { metaController } from '@api/server.module';
|
||||||
|
import { ConfigService, WaBusiness } from '@config/env.config';
|
||||||
|
import { Router } from 'express';
|
||||||
|
|
||||||
|
export class MetaRouter extends RouterBroker {
|
||||||
|
constructor(readonly configService: ConfigService) {
|
||||||
|
super();
|
||||||
|
this.router
|
||||||
|
.get(this.routerPath('webhook/meta', false), async (req, res) => {
|
||||||
|
if (req.query['hub.verify_token'] === configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK)
|
||||||
|
res.send(req.query['hub.challenge']);
|
||||||
|
else res.send('Error, wrong validation token');
|
||||||
|
})
|
||||||
|
.post(this.routerPath('webhook/meta', false), async (req, res) => {
|
||||||
|
const { body } = req;
|
||||||
|
const response = await metaController.receiveWebhook(body);
|
||||||
|
|
||||||
|
return res.status(200).json(response);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly router: Router = Router();
|
||||||
|
}
|
@ -186,76 +186,4 @@ export class WebhookController extends EventController implements EventControlle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async receiveWebhookMeta(data: any) {
|
|
||||||
if (data.object === 'whatsapp_business_account') {
|
|
||||||
if (data.entry[0]?.changes[0]?.field === 'message_template_status_update') {
|
|
||||||
const template = await this.prismaRepository.template.findFirst({
|
|
||||||
where: { templateId: `${data.entry[0].changes[0].value.message_template_id}` },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!template) {
|
|
||||||
console.log('template not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { webhookUrl } = template;
|
|
||||||
|
|
||||||
await axios.post(webhookUrl, data.entry[0].changes[0].value, {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.entry?.forEach(async (entry: any) => {
|
|
||||||
const numberId = entry.changes[0].value.metadata.phone_number_id;
|
|
||||||
|
|
||||||
if (!numberId) {
|
|
||||||
this.logger.error('WebhookService -> receiveWebhookMeta -> numberId not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const instance = await this.prismaRepository.instance.findFirst({
|
|
||||||
where: { number: numberId },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
this.logger.error('WebhookService -> receiveWebhookMeta -> instance not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
|
|
||||||
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async receiveWebhookEvolution(data: any) {
|
|
||||||
const numberId = data.numberId;
|
|
||||||
|
|
||||||
if (!numberId) {
|
|
||||||
this.logger.error('WebhookService -> receiveWebhookEvolution -> numberId not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const instance = await this.prismaRepository.instance.findFirst({
|
|
||||||
where: { number: numberId },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
this.logger.error('WebhookService -> receiveWebhook -> instance not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.waMonitor.waInstances[instance.name].connectToWhatsapp(data);
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'success',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { RouterBroker } from '@api/abstract/abstract.router';
|
|||||||
import { InstanceDto } from '@api/dto/instance.dto';
|
import { InstanceDto } from '@api/dto/instance.dto';
|
||||||
import { HttpStatus } from '@api/routes/index.router';
|
import { HttpStatus } from '@api/routes/index.router';
|
||||||
import { webhookController } from '@api/server.module';
|
import { webhookController } from '@api/server.module';
|
||||||
import { ConfigService, WaBusiness } from '@config/env.config';
|
import { ConfigService } from '@config/env.config';
|
||||||
import { instanceSchema, webhookSchema } from '@validate/validate.schema';
|
import { instanceSchema, webhookSchema } from '@validate/validate.schema';
|
||||||
import { RequestHandler, Router } from 'express';
|
import { RequestHandler, Router } from 'express';
|
||||||
|
|
||||||
@ -31,23 +31,6 @@ export class WebhookRouter extends RouterBroker {
|
|||||||
});
|
});
|
||||||
|
|
||||||
res.status(HttpStatus.OK).json(response);
|
res.status(HttpStatus.OK).json(response);
|
||||||
})
|
|
||||||
.get(this.routerPath('meta', false), async (req, res) => {
|
|
||||||
if (req.query['hub.verify_token'] === configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK)
|
|
||||||
res.send(req.query['hub.challenge']);
|
|
||||||
else res.send('Error, wrong validation token');
|
|
||||||
})
|
|
||||||
.post(this.routerPath('meta', false), async (req, res) => {
|
|
||||||
const { body } = req;
|
|
||||||
const response = await webhookController.receiveWebhookMeta(body);
|
|
||||||
|
|
||||||
return res.status(200).json(response);
|
|
||||||
})
|
|
||||||
.post(this.routerPath('evolution', false), async (req, res) => {
|
|
||||||
const { body } = req;
|
|
||||||
const response = await webhookController.receiveWebhookEvolution(body);
|
|
||||||
|
|
||||||
return res.status(200).json(response);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { authGuard } from '@api/guards/auth.guard';
|
import { authGuard } from '@api/guards/auth.guard';
|
||||||
import { instanceExistsGuard, instanceLoggedGuard } from '@api/guards/instance.guard';
|
import { instanceExistsGuard, instanceLoggedGuard } from '@api/guards/instance.guard';
|
||||||
import Telemetry from '@api/guards/telemetry.guard';
|
import Telemetry from '@api/guards/telemetry.guard';
|
||||||
|
import { ChannelRouter } from '@api/integrations/channel/channel.router';
|
||||||
import { ChatbotRouter } from '@api/integrations/chatbot/chatbot.router';
|
import { ChatbotRouter } from '@api/integrations/chatbot/chatbot.router';
|
||||||
import { EventRouter } from '@api/integrations/event/event.router';
|
import { EventRouter } from '@api/integrations/event/event.router';
|
||||||
import { StorageRouter } from '@api/integrations/storage/storage.router';
|
import { StorageRouter } from '@api/integrations/storage/storage.router';
|
||||||
@ -84,6 +85,7 @@ router
|
|||||||
.use('/settings', new SettingsRouter(...guards).router)
|
.use('/settings', new SettingsRouter(...guards).router)
|
||||||
.use('/proxy', new ProxyRouter(...guards).router)
|
.use('/proxy', new ProxyRouter(...guards).router)
|
||||||
.use('/label', new LabelRouter(...guards).router)
|
.use('/label', new LabelRouter(...guards).router)
|
||||||
|
.use('', new ChannelRouter(configService).router)
|
||||||
.use('', new EventRouter(configService, ...guards).router)
|
.use('', new EventRouter(configService, ...guards).router)
|
||||||
.use('', new ChatbotRouter(...guards).router)
|
.use('', new ChatbotRouter(...guards).router)
|
||||||
.use('', new StorageRouter(...guards).router);
|
.use('', new StorageRouter(...guards).router);
|
||||||
|
@ -12,6 +12,8 @@ import { SendMessageController } from './controllers/sendMessage.controller';
|
|||||||
import { SettingsController } from './controllers/settings.controller';
|
import { SettingsController } from './controllers/settings.controller';
|
||||||
import { TemplateController } from './controllers/template.controller';
|
import { TemplateController } from './controllers/template.controller';
|
||||||
import { ChannelController } from './integrations/channel/channel.controller';
|
import { ChannelController } from './integrations/channel/channel.controller';
|
||||||
|
import { EvolutionController } from './integrations/channel/evolution/evolution.controller';
|
||||||
|
import { MetaController } from './integrations/channel/meta/meta.controller';
|
||||||
import { ChatbotController } from './integrations/chatbot/chatbot.controller';
|
import { ChatbotController } from './integrations/chatbot/chatbot.controller';
|
||||||
import { ChatwootController } from './integrations/chatbot/chatwoot/controllers/chatwoot.controller';
|
import { ChatwootController } from './integrations/chatbot/chatwoot/controllers/chatwoot.controller';
|
||||||
import { ChatwootService } from './integrations/chatbot/chatwoot/services/chatwoot.service';
|
import { ChatwootService } from './integrations/chatbot/chatwoot/services/chatwoot.service';
|
||||||
@ -102,7 +104,11 @@ export const labelController = new LabelController(waMonitor);
|
|||||||
|
|
||||||
export const eventController = new EventController(prismaRepository, waMonitor);
|
export const eventController = new EventController(prismaRepository, waMonitor);
|
||||||
export const chatbotController = new ChatbotController(prismaRepository, waMonitor);
|
export const chatbotController = new ChatbotController(prismaRepository, waMonitor);
|
||||||
export const channelController = new ChannelController();
|
export const channelController = new ChannelController(prismaRepository, waMonitor);
|
||||||
|
|
||||||
|
// channels
|
||||||
|
export const evolutionController = new EvolutionController(prismaRepository, waMonitor);
|
||||||
|
export const metaController = new MetaController(prismaRepository, waMonitor);
|
||||||
|
|
||||||
// events
|
// events
|
||||||
export const websocketController = new WebsocketController(prismaRepository, waMonitor);
|
export const websocketController = new WebsocketController(prismaRepository, waMonitor);
|
||||||
|
Loading…
Reference in New Issue
Block a user