Skip to content

Commit

Permalink
refactor: change webhook reception for all instances
Browse files Browse the repository at this point in the history
This commit refactors the webhook reception to handle all instances at once. Previously, each instance had its own webhook endpoint, but now there is a single endpoint for all instances. This change simplifies the codebase and reduces the potential for errors.

The main changes include:
- Modifying the `InstanceController` to update the webhook URL for all instances.
- Modifying the `WebhookController` to handle the reception of webhooks for all instances.
- Modifying the `IndexRouter` and `WebhookRouter` to add a new route for the webhook reception endpoint.
- Modifying the `ServerModule` to inject the `PrismaRepository` into the `WebhookService`.
- Modifying the `WebhookService` to handle the reception of webhooks for all instances.

These changes improve the maintainability and scalability of the application, as there is no longer a need to manage individual webhook endpoints for each instance.
  • Loading branch information
dgcode-tec committed Jul 12, 2024
1 parent 90e03e6 commit 4737c71
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/api/controllers/instance.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ export class InstanceController {
throw new BadRequestException('number is required');
}
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
webhookWaBusiness = `${urlServer}/webhook/whatsapp/${encodeURIComponent(instance.instanceName)}`;
webhookWaBusiness = `${urlServer}/webhook/meta`;
accessTokenWaBusiness = this.configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK;
}

Expand Down
9 changes: 7 additions & 2 deletions src/api/controllers/webhook.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ export class WebhookController {
return this.webhookService.find(instance);
}

public async receiveWebhook(instance: InstanceDto, data: any) {
return await this.waMonitor.waInstances[instance.instanceName].connectToWhatsapp(data);
public async receiveWebhook(data: any) {
console.log('webhook/meta', data);
this.webhookService.receiveWebhook(data);

return {
message: 'Webhook received',
};
}
}
16 changes: 14 additions & 2 deletions src/api/routes/index.router.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Router } from 'express';
import fs from 'fs';

import { configService } from '../../config/env.config';
import { configService, WaBusiness } from '../../config/env.config';
import { authGuard } from '../guards/auth.guard';
import { instanceExistsGuard, instanceLoggedGuard } from '../guards/instance.guard';
import { ChatwootRouter } from '../integrations/chatwoot/routes/chatwoot.router';
import { RabbitmqRouter } from '../integrations/rabbitmq/routes/rabbitmq.router';
import { SqsRouter } from '../integrations/sqs/routes/sqs.router';
import { TypebotRouter } from '../integrations/typebot/routes/typebot.router';
import { WebsocketRouter } from '../integrations/websocket/routes/websocket.router';
import { webhookController } from '../server.module';
import { ChatRouter } from './chat.router';
import { GroupRouter } from './group.router';
import { InstanceRouter } from './instance.router';
Expand Down Expand Up @@ -59,6 +60,17 @@ router
.use('/sqs', new SqsRouter(...guards).router)
.use('/typebot', new TypebotRouter(...guards).router)
.use('/proxy', new ProxyRouter(...guards).router)
.use('/label', new LabelRouter(...guards).router);
.use('/label', new LabelRouter(...guards).router)
.get('/webhook/meta', 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('/webhook/meta', async (req, res) => {
const { body } = req;
const response = await webhookController.receiveWebhook(body);

return res.status(200).json(response);
});

export { HttpStatus, router };
17 changes: 1 addition & 16 deletions src/api/routes/webhook.router.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RequestHandler, Router } from 'express';

import { ConfigService, WaBusiness } from '../../config/env.config';
import { ConfigService } from '../../config/env.config';
import { instanceSchema, webhookSchema } from '../../validate/validate.schema';
import { RouterBroker } from '../abstract/abstract.router';
import { InstanceDto } from '../dto/instance.dto';
Expand Down Expand Up @@ -31,21 +31,6 @@ export class WebhookRouter extends RouterBroker {
});

res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('whatsapp'), async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance, data) => webhookController.receiveWebhook(instance, data),
});

res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('whatsapp'), async (req, res) => {
if (req.query['hub.verify_token'] === this.configService.get<WaBusiness>('WA_BUSINESS').TOKEN_WEBHOOK)
res.send(req.query['hub.challenge']);
else res.send('Error, wrong validation token');
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/api/server.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const authService = new AuthService(prismaRepository);
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
export const typebotController = new TypebotController(typebotService);

const webhookService = new WebhookService(waMonitor);
const webhookService = new WebhookService(waMonitor, prismaRepository);
export const webhookController = new WebhookController(webhookService, waMonitor);

const websocketService = new WebsocketService(waMonitor);
Expand Down
2 changes: 1 addition & 1 deletion src/api/services/monitor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export class WAMonitoringService {
data: {
id: data.instanceId,
name: data.instanceName,
connectionStatus: 'close',
connectionStatus: data.integration && data.integration === Integration.WHATSAPP_BUSINESS ? 'open' : 'close',
number: data.number,
integration: data.integration || Integration.WHATSAPP_BAILEYS,
token: data.hash,
Expand Down
31 changes: 30 additions & 1 deletion src/api/services/webhook.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { Webhook } from '@prisma/client';
import { Logger } from '../../config/logger.config';
import { InstanceDto } from '../dto/instance.dto';
import { WebhookDto } from '../dto/webhook.dto';
import { PrismaRepository } from '../repository/repository.service';
import { WAMonitoringService } from './monitor.service';

export class WebhookService {
constructor(private readonly waMonitor: WAMonitoringService) {}
constructor(private readonly waMonitor: WAMonitoringService, public readonly prismaRepository: PrismaRepository) {}

private readonly logger = new Logger(WebhookService.name);

Expand All @@ -29,4 +30,32 @@ export class WebhookService {
return null;
}
}

public async receiveWebhook(data: any) {
if (data.object === 'whatsapp_business_account') {
data.entry?.forEach(async (entry: any) => {
const numberId = entry.changes[0].value.metadata.phone_number_id;

if (!numberId) {
this.logger.error('WebhookService -> receiveWebhook -> 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;
});
}

return;
}
}

0 comments on commit 4737c71

Please sign in to comment.