This commit is contained in:
parent
41dc1d78b5
commit
c681814cca
@ -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
|
||||||
|
|||||||
@ -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(',')
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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' };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user