mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-19 03:42:23 -06:00
Add support for managing WhatsApp templates via official API
This commit introduces changes to support managing WhatsApp templates using the official WhatsApp Business API. The following modifications have been made: - Implemented a new Template model in the Prisma schema, including fields for template ID, name, language, and associated Instance (business ID, instance ID, and created/updated timestamps). - Modified the Instance model in the Prisma schema to include a Template relationship. - Updated InstanceController to include a new `businessId` property in the InstanceDto. - Added a new TemplateRouter, TemplateController, and TemplateService to handle template-related requests and services. - Updated the WebhookService to utilize the new TemplateService. - Added new TypebotController, WebhookController, and WAMonitoringService methods to handle template-related events. - Updated the validate schema to include a new template schema. The main goal of this commit is to enable managing WhatsApp templates, including creating, updating, and deleting templates, as well as associating them with specific instances.
This commit is contained in:
@@ -69,12 +69,14 @@ export class ChannelStartupService {
|
||||
public typebotService = new TypebotService(waMonitor, this.configService, this.prismaRepository);
|
||||
|
||||
public setInstance(instance: InstanceDto) {
|
||||
this.instance.name = instance.instanceName;
|
||||
this.logger.setInstance(instance.instanceName);
|
||||
|
||||
this.instance.name = instance.instanceName;
|
||||
this.instance.id = instance.instanceId;
|
||||
this.instance.integration = instance.integration;
|
||||
this.instance.number = instance.number;
|
||||
this.instance.token = instance.token;
|
||||
this.instance.businessId = instance.businessId;
|
||||
|
||||
this.sendDataWebhook(Events.STATUS_INSTANCE, {
|
||||
instance: this.instance.name,
|
||||
|
||||
@@ -76,8 +76,7 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
const result = await axios.post(urlServer, message, { headers });
|
||||
return result.data;
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
return e.response.data;
|
||||
return e.response?.data?.error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -793,9 +792,9 @@ export class BusinessStartupService extends ChannelStartupService {
|
||||
}
|
||||
})();
|
||||
|
||||
if (messageSent?.error?.message) {
|
||||
this.logger.error(messageSent.error.message);
|
||||
throw messageSent.error.message.toString();
|
||||
if (messageSent?.error_data) {
|
||||
this.logger.error(messageSent);
|
||||
return messageSent;
|
||||
}
|
||||
|
||||
const messageRaw: any = {
|
||||
|
||||
@@ -221,6 +221,7 @@ export class WAMonitoringService {
|
||||
integration: instanceData.integration,
|
||||
token: instanceData.token,
|
||||
number: instanceData.number,
|
||||
businessId: instanceData.businessId,
|
||||
});
|
||||
} else {
|
||||
instance = new BaileysStartupService(
|
||||
@@ -239,6 +240,7 @@ export class WAMonitoringService {
|
||||
integration: instanceData.integration,
|
||||
token: instanceData.token,
|
||||
number: instanceData.number,
|
||||
businessId: instanceData.businessId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -267,6 +269,7 @@ export class WAMonitoringService {
|
||||
integration: instanceData.integration,
|
||||
token: instanceData.token,
|
||||
number: instanceData.number,
|
||||
businessId: instanceData.businessId,
|
||||
};
|
||||
|
||||
this.setInstance(instance);
|
||||
@@ -294,6 +297,7 @@ export class WAMonitoringService {
|
||||
integration: instance.integration,
|
||||
token: instance.token,
|
||||
number: instance.number,
|
||||
businessId: instance.businessId,
|
||||
});
|
||||
}),
|
||||
);
|
||||
@@ -317,6 +321,7 @@ export class WAMonitoringService {
|
||||
instanceName: instance.name,
|
||||
integration: instance.integration,
|
||||
token: instance.token,
|
||||
businessId: instance.businessId,
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
105
src/api/services/template.service.ts
Normal file
105
src/api/services/template.service.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { Template } from '@prisma/client';
|
||||
import axios from 'axios';
|
||||
|
||||
import { ConfigService, WaBusiness } from '../../config/env.config';
|
||||
import { Logger } from '../../config/logger.config';
|
||||
import { InstanceDto } from '../dto/instance.dto';
|
||||
import { TemplateDto } from '../dto/template.dto';
|
||||
import { PrismaRepository } from '../repository/repository.service';
|
||||
import { WAMonitoringService } from './monitor.service';
|
||||
|
||||
export class TemplateService {
|
||||
constructor(
|
||||
private readonly waMonitor: WAMonitoringService,
|
||||
public readonly prismaRepository: PrismaRepository,
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
private readonly logger = new Logger(TemplateService.name);
|
||||
|
||||
private businessId: string;
|
||||
private token: string;
|
||||
|
||||
public async find(instance: InstanceDto) {
|
||||
const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;
|
||||
|
||||
if (!getInstance) {
|
||||
throw new Error('Instance not found');
|
||||
}
|
||||
|
||||
this.businessId = getInstance.businessId;
|
||||
this.token = getInstance.token;
|
||||
|
||||
const response = await this.requestTemplate({}, 'GET');
|
||||
|
||||
if (!response) {
|
||||
throw new Error('Error to create template');
|
||||
}
|
||||
|
||||
console.log(response);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async create(instance: InstanceDto, data: TemplateDto): Promise<Template> {
|
||||
try {
|
||||
const getInstance = await this.waMonitor.waInstances[instance.instanceName].instance;
|
||||
|
||||
if (!getInstance) {
|
||||
throw new Error('Instance not found');
|
||||
}
|
||||
|
||||
this.businessId = getInstance.businessId;
|
||||
this.token = getInstance.token;
|
||||
|
||||
const postData = {
|
||||
name: data.name,
|
||||
category: data.category,
|
||||
allow_category_change: data.allowCategoryChange,
|
||||
language: data.language,
|
||||
components: data.components,
|
||||
};
|
||||
|
||||
const response = await this.requestTemplate(postData, 'POST');
|
||||
|
||||
if (!response) {
|
||||
throw new Error('Error to create template');
|
||||
}
|
||||
|
||||
console.log(response);
|
||||
|
||||
const template = await this.prismaRepository.template.create({
|
||||
data: {
|
||||
instanceId: getInstance.id,
|
||||
templateId: response.id,
|
||||
name: data.name,
|
||||
language: data.language,
|
||||
},
|
||||
});
|
||||
|
||||
return template;
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
throw new Error('Error to create template');
|
||||
}
|
||||
}
|
||||
|
||||
private async requestTemplate(data: any, method: string) {
|
||||
try {
|
||||
let urlServer = this.configService.get<WaBusiness>('WA_BUSINESS').URL;
|
||||
const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;
|
||||
urlServer = `${urlServer}/${version}/${this.businessId}/message_templates`;
|
||||
const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };
|
||||
if (method === 'GET') {
|
||||
const result = await axios.get(urlServer, { headers });
|
||||
return result.data;
|
||||
} else if (method === 'POST') {
|
||||
const result = await axios.post(urlServer, data, { headers });
|
||||
return result.data;
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.error(e.response.data);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user