CHORE: Release versão 1.0.0

This commit is contained in:
Rafael Alves Lopes 2026-06-09 18:14:55 -03:00
parent 41dc1d78b5
commit 790b9e3a16
4 changed files with 45 additions and 2 deletions

View File

@ -21,7 +21,7 @@ https://chaleiradev.sothistelecom.com/Sothis/omnichannel-deploy
- TypeScript - TypeScript
- PostgreSQL - PostgreSQL
- Socket.IO - Socket.IO
- whatsapp-web.js - whatsapp-web.js, com Puppeteer/Chrome para controlar o WhatsApp Web
- JSON Web Token para autenticacao - JSON Web Token para autenticacao
- LDAP/AD e Microsoft OAuth como provedores de login configuraveis - LDAP/AD e Microsoft OAuth como provedores de login configuraveis
@ -49,6 +49,12 @@ cp .env.example .env.development
Configure as variaveis de banco, JWT, CORS e integracoes no `.env.development`. Configure as variaveis de banco, JWT, CORS e integracoes no `.env.development`.
Para usar o canal WhatsApp, o backend tambem precisa conseguir iniciar Chrome/Chromium.
O `whatsapp-web.js` usa Puppeteer para abrir o WhatsApp Web em modo headless, autenticar por QR Code e manter a sessao local em `whatsapp-session`.
Em ambiente Docker/producao, persista esse diretorio em volume para nao perder a sessao a cada recriacao do container.
Execute em modo desenvolvimento: Execute em modo desenvolvimento:
```bash ```bash

View File

@ -791,6 +791,11 @@ export class AttendanceAssignmentService {
private matchBuilderChild(message: string, children: BotFlowNode[]) { private matchBuilderChild(message: string, children: BotFlowNode[]) {
const normalized = this.normalize(message).trim(); const normalized = this.normalize(message).trim();
const selectedNumber = Number(normalized.match(/^\d+$/)?.[0] || 0);
if (selectedNumber > 0) {
return children.find((child) => Number(child.sort_order) === selectedNumber) || null;
}
return children.find((child) => { return children.find((child) => {
const keywords = String(child.keywords || '') const keywords = String(child.keywords || '')
.split(',') .split(',')

View File

@ -20,6 +20,8 @@ export class AttendanceAssignmentRepository {
reserved_user_id = NULL, reserved_user_id = NULL,
reserved_at = NULL, reserved_at = NULL,
pause_released_at = NULL, pause_released_at = NULL,
conversation_started_at = CURRENT_TIMESTAMP,
expires_at = CURRENT_TIMESTAMP + INTERVAL '24 hours',
triage_flow_id = NULL, triage_flow_id = NULL,
triage_audience_id = NULL, triage_audience_id = NULL,
triage_intent_id = NULL, triage_intent_id = NULL,
@ -85,6 +87,8 @@ export class AttendanceAssignmentRepository {
reserved_user_id = NULL, reserved_user_id = NULL,
reserved_at = NULL, reserved_at = NULL,
pause_released_at = NULL, pause_released_at = NULL,
conversation_started_at = CURRENT_TIMESTAMP,
expires_at = CURRENT_TIMESTAMP + INTERVAL '24 hours',
triage_flow_id = NULL, triage_flow_id = NULL,
triage_audience_id = NULL, triage_audience_id = NULL,
triage_intent_id = NULL, triage_intent_id = NULL,

View File

@ -1,4 +1,4 @@
import { Controller, Get, Post, Body, Delete, Param } from '@nestjs/common'; import { Controller, Get, Post, Body, Delete, Param, ForbiddenException, Query, RawBody } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { WhatsappService } from './whatsapp.service'; import { WhatsappService } from './whatsapp.service';
import { AttendanceAssignmentService } from '../attendance/attendance-assignment.service'; import { AttendanceAssignmentService } from '../attendance/attendance-assignment.service';
@ -12,6 +12,9 @@ import {
UpdateWhatsappTemplateDto, UpdateWhatsappTemplateDto,
} from './dto/whatsapp.dto'; } from './dto/whatsapp.dto';
import { WhatsappTemplateService } from './whatsapp-template.service'; import { WhatsappTemplateService } from './whatsapp-template.service';
import { Public } from '../auth/decorators/public.decorator';
@ApiTags('WhatsApp') @ApiTags('WhatsApp')
@Controller('whatsapp') @Controller('whatsapp')
@ -268,4 +271,29 @@ export class WhatsappController {
async deleteTemplate(@Param('id') id: string) { async deleteTemplate(@Param('id') id: string) {
return this.whatsappTemplateService.deleteTemplate(Number(id)); return this.whatsappTemplateService.deleteTemplate(Number(id));
} }
@Public()
@ApiOperation({ summary: 'Verificação do webhook Meta' })
@Get('webhook')
verifyWebhook(
@Query('hub.mode') mode: string,
@Query('hub.verify_token') token: string,
@Query('hub.challenge') challenge: string,
) {
if (mode === 'subscribe' && token === process.env.META_WEBHOOK_TOKEN) {
return challenge;
}
throw new ForbiddenException('Token inválido');
}
@Public()
@ApiOperation({ summary: 'Recebe eventos do webhook Meta' })
@Post('webhook')
async receiveWebhook(@Body() body: any) {
console.log('Webhook Meta:', JSON.stringify(body, null, 2));
return { status: 'ok' };
}
} }