mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-16 12:12:55 -06:00
feat: Sending template approval status webhook
This commit is contained in:
parent
31cb83a40c
commit
0bb2b92853
@ -3,6 +3,7 @@
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* Webhook url by submitted template to send status updates
|
* Webhook url by submitted template to send status updates
|
||||||
|
* Sending template approval status webhook
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "Template" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"templateId" VARCHAR(255) NOT NULL,
|
||||||
|
"name" VARCHAR(255) NOT NULL,
|
||||||
|
"template" JSONB NOT NULL,
|
||||||
|
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" TIMESTAMP NOT NULL,
|
||||||
|
"instanceId" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "Template_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "Template_templateId_key" ON "Template"("templateId");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "Template_name_key" ON "Template"("name");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "Template" ADD CONSTRAINT "Template_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Template" ADD COLUMN "webhookUrl" VARCHAR(500);
|
@ -0,0 +1,2 @@
|
|||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "Instance_token_key";
|
@ -56,7 +56,7 @@ model Instance {
|
|||||||
integration String? @db.VarChar(100)
|
integration String? @db.VarChar(100)
|
||||||
number String? @db.VarChar(100)
|
number String? @db.VarChar(100)
|
||||||
businessId String? @db.VarChar(100)
|
businessId String? @db.VarChar(100)
|
||||||
token String? @unique @db.VarChar(255)
|
token String? @db.VarChar(255)
|
||||||
clientName String? @db.VarChar(100)
|
clientName String? @db.VarChar(100)
|
||||||
createdAt DateTime? @default(now()) @db.Timestamp
|
createdAt DateTime? @default(now()) @db.Timestamp
|
||||||
updatedAt DateTime? @updatedAt @db.Timestamp
|
updatedAt DateTime? @updatedAt @db.Timestamp
|
||||||
@ -81,6 +81,7 @@ model Instance {
|
|||||||
OpenaiBot OpenaiBot[]
|
OpenaiBot OpenaiBot[]
|
||||||
OpenaiSession OpenaiSession[]
|
OpenaiSession OpenaiSession[]
|
||||||
OpenaiSetting OpenaiSetting?
|
OpenaiSetting OpenaiSetting?
|
||||||
|
Template Template[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model Session {
|
model Session {
|
||||||
@ -412,3 +413,15 @@ model OpenaiSetting {
|
|||||||
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
instanceId String @unique
|
instanceId String @unique
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model Template {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
templateId String @unique @db.VarChar(255)
|
||||||
|
name String @unique @db.VarChar(255)
|
||||||
|
template Json @db.JsonB
|
||||||
|
webhookUrl String? @db.VarChar(500)
|
||||||
|
createdAt DateTime? @default(now()) @db.Timestamp
|
||||||
|
updatedAt DateTime @updatedAt @db.Timestamp
|
||||||
|
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
|
||||||
|
instanceId String
|
||||||
|
}
|
||||||
|
@ -90,7 +90,7 @@ export class InstanceController {
|
|||||||
businessId,
|
businessId,
|
||||||
}: InstanceDto) {
|
}: InstanceDto) {
|
||||||
try {
|
try {
|
||||||
if (token) await this.authService.checkDuplicateToken(token);
|
// if (token) await this.authService.checkDuplicateToken(token);
|
||||||
|
|
||||||
if (!token && integration === Integration.WHATSAPP_BUSINESS) {
|
if (!token && integration === Integration.WHATSAPP_BUSINESS) {
|
||||||
throw new BadRequestException('token is required');
|
throw new BadRequestException('token is required');
|
||||||
@ -623,14 +623,14 @@ export class InstanceController {
|
|||||||
// let arrayReturn = false;
|
// let arrayReturn = false;
|
||||||
|
|
||||||
if (env.KEY !== key) {
|
if (env.KEY !== key) {
|
||||||
const instanceByKey = await this.prismaRepository.instance.findUnique({
|
const instanceByKey = await this.prismaRepository.instance.findMany({
|
||||||
where: {
|
where: {
|
||||||
token: key,
|
token: key,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (instanceByKey) {
|
if (instanceByKey) {
|
||||||
name = instanceByKey.name;
|
name = instanceByKey[0].name;
|
||||||
// arrayReturn = true;
|
// arrayReturn = true;
|
||||||
} else {
|
} else {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
|
@ -4,4 +4,5 @@ export class TemplateDto {
|
|||||||
allowCategoryChange: boolean;
|
allowCategoryChange: boolean;
|
||||||
language: string;
|
language: string;
|
||||||
components: any;
|
components: any;
|
||||||
|
webhookUrl?: string;
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
const content = data.entry[0].changes[0].value;
|
const content = data.entry[0].changes[0].value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.loadWebhook();
|
this.loadWebhook();
|
||||||
this.loadChatwoot();
|
this.loadChatwoot();
|
||||||
@ -297,6 +298,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
|||||||
|
|
||||||
protected async messageHandle(received: any, database: Database, settings: any) {
|
protected async messageHandle(received: any, database: Database, settings: any) {
|
||||||
try {
|
try {
|
||||||
|
console.log(received);
|
||||||
let messageRaw: any;
|
let messageRaw: any;
|
||||||
let pushName: any;
|
let pushName: any;
|
||||||
|
|
||||||
|
@ -59,11 +59,21 @@ export class TemplateService {
|
|||||||
|
|
||||||
const response = await this.requestTemplate(postData, 'POST');
|
const response = await this.requestTemplate(postData, 'POST');
|
||||||
|
|
||||||
if (!response) {
|
if (!response || response.error) {
|
||||||
return response;
|
throw new Error('Error to create template');
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
const template = await this.prismaRepository.template.create({
|
||||||
|
data: {
|
||||||
|
templateId: response.id,
|
||||||
|
name: data.name,
|
||||||
|
template: response,
|
||||||
|
webhookUrl: data.webhookUrl,
|
||||||
|
instanceId: getInstance.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return template;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(error);
|
this.logger.error(error);
|
||||||
throw new Error('Error to create template');
|
throw new Error('Error to create template');
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Webhook } from '@prisma/client';
|
import { Webhook } from '@prisma/client';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
import { Logger } from '../../config/logger.config';
|
import { Logger } from '../../config/logger.config';
|
||||||
import { InstanceDto } from '../dto/instance.dto';
|
import { InstanceDto } from '../dto/instance.dto';
|
||||||
@ -33,6 +34,26 @@ export class WebhookService {
|
|||||||
|
|
||||||
public async receiveWebhook(data: any) {
|
public async receiveWebhook(data: any) {
|
||||||
if (data.object === 'whatsapp_business_account') {
|
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) => {
|
data.entry?.forEach(async (entry: any) => {
|
||||||
const numberId = entry.changes[0].value.metadata.phone_number_id;
|
const numberId = entry.changes[0].value.metadata.phone_number_id;
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ export const templateSchema: JSONSchema7 = {
|
|||||||
allowCategoryChange: { type: 'boolean' },
|
allowCategoryChange: { type: 'boolean' },
|
||||||
language: { type: 'string' },
|
language: { type: 'string' },
|
||||||
components: { type: 'array' },
|
components: { type: 'array' },
|
||||||
|
webhookUrl: { type: 'string' },
|
||||||
},
|
},
|
||||||
required: ['name', 'category', 'language', 'components'],
|
required: ['name', 'category', 'language', 'components'],
|
||||||
...isNotEmpty('name', 'category', 'language', 'components'),
|
...isNotEmpty('name', 'category', 'language', 'components'),
|
||||||
|
Loading…
Reference in New Issue
Block a user