chore: Crud openai complete

This commit is contained in:
Davidson Gomes 2024-07-18 10:14:53 -03:00
parent 5b13de377b
commit 29b9e688a8
12 changed files with 2417 additions and 135 deletions

View File

@ -119,6 +119,9 @@ CHATWOOT_MESSAGE_READ=false
CHATWOOT_IMPORT_DATABASE_CONNECTION_URI=postgresql://user:pass@host:5432/dbname
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=false
OPENAI_ENABLED=false
OPENAI_API_KEY_GLOBAL=
CACHE_REDIS_ENABLED=true
CACHE_REDIS_URI=redis://localhost:6379/6
CACHE_REDIS_PREFIX_KEY=evolution

View File

@ -0,0 +1,118 @@
-- AlterTable
ALTER TABLE "Message" ADD COLUMN "openaiSessionId" TEXT;
-- CreateTable
CREATE TABLE "OpenaiCreds" (
"id" TEXT NOT NULL,
"apiKey" VARCHAR(255) NOT NULL,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "OpenaiCreds_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "OpenaiBot" (
"id" TEXT NOT NULL,
"botType" VARCHAR(100) NOT NULL,
"assistantId" VARCHAR(255),
"model" VARCHAR(100),
"systemMessages" JSONB,
"assistantMessages" JSONB,
"userMessages" JSONB,
"maxTokens" INTEGER,
"expire" INTEGER DEFAULT 0,
"keywordFinish" VARCHAR(100),
"delayMessage" INTEGER,
"unknownMessage" VARCHAR(100),
"listeningFromMe" BOOLEAN DEFAULT false,
"stopBotFromMe" BOOLEAN DEFAULT false,
"keepOpen" BOOLEAN DEFAULT false,
"debounceTime" INTEGER,
"ignoreJids" JSONB,
"triggerType" "TriggerType",
"triggerOperator" "TriggerOperator",
"triggerValue" TEXT,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"openaiCredsId" TEXT NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "OpenaiBot_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "OpenaiSession" (
"id" TEXT NOT NULL,
"sessionId" VARCHAR(255) NOT NULL,
"remoteJid" VARCHAR(100) NOT NULL,
"status" "TypebotSessionStatus" NOT NULL,
"awaitUser" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"openaiBotId" TEXT NOT NULL,
"instanceId" TEXT NOT NULL,
CONSTRAINT "OpenaiSession_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "OpenaiSetting" (
"id" TEXT NOT NULL,
"expire" INTEGER DEFAULT 0,
"keywordFinish" VARCHAR(100),
"delayMessage" INTEGER,
"unknownMessage" VARCHAR(100),
"listeningFromMe" BOOLEAN DEFAULT false,
"stopBotFromMe" BOOLEAN DEFAULT false,
"keepOpen" BOOLEAN DEFAULT false,
"debounceTime" INTEGER,
"ignoreJids" JSONB,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP NOT NULL,
"openaiCredsId" TEXT NOT NULL,
"openaiIdFallback" VARCHAR(100),
"instanceId" TEXT NOT NULL,
CONSTRAINT "OpenaiSetting_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "OpenaiCreds_apiKey_key" ON "OpenaiCreds"("apiKey");
-- CreateIndex
CREATE UNIQUE INDEX "OpenaiCreds_instanceId_key" ON "OpenaiCreds"("instanceId");
-- CreateIndex
CREATE UNIQUE INDEX "OpenaiBot_assistantId_key" ON "OpenaiBot"("assistantId");
-- CreateIndex
CREATE UNIQUE INDEX "OpenaiSetting_instanceId_key" ON "OpenaiSetting"("instanceId");
-- AddForeignKey
ALTER TABLE "Message" ADD CONSTRAINT "Message_openaiSessionId_fkey" FOREIGN KEY ("openaiSessionId") REFERENCES "OpenaiSession"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiCreds" ADD CONSTRAINT "OpenaiCreds_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiBot" ADD CONSTRAINT "OpenaiBot_openaiCredsId_fkey" FOREIGN KEY ("openaiCredsId") REFERENCES "OpenaiCreds"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiBot" ADD CONSTRAINT "OpenaiBot_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiSession" ADD CONSTRAINT "OpenaiSession_openaiBotId_fkey" FOREIGN KEY ("openaiBotId") REFERENCES "OpenaiBot"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiSession" ADD CONSTRAINT "OpenaiSession_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiSetting" ADD CONSTRAINT "OpenaiSetting_openaiCredsId_fkey" FOREIGN KEY ("openaiCredsId") REFERENCES "OpenaiCreds"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiSetting" ADD CONSTRAINT "OpenaiSetting_openaiIdFallback_fkey" FOREIGN KEY ("openaiIdFallback") REFERENCES "OpenaiBot"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "OpenaiSetting" ADD CONSTRAINT "OpenaiSetting_instanceId_fkey" FOREIGN KEY ("instanceId") REFERENCES "Instance"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "OpenaiBot" ADD COLUMN "enabled" BOOLEAN NOT NULL DEFAULT true;

View File

@ -78,10 +78,9 @@ model Instance {
TypebotSetting TypebotSetting?
Media Media[]
OpenaiCreds OpenaiCreds?
OpenaiAssistant OpenaiAssistant[]
OpenaiAssistantThread OpenaiAssistantThread[]
OpenaiChatCompletion OpenaiChatCompletion[]
OpenaiChatCompletionSession OpenaiChatCompletionSession[]
OpenaiBot OpenaiBot[]
OpenaiSession OpenaiSession[]
OpenaiSetting OpenaiSetting?
}
model Session {
@ -134,10 +133,8 @@ model Message {
MessageUpdate MessageUpdate[]
TypebotSession TypebotSession? @relation(fields: [typebotSessionId], references: [id])
Media Media?
OpenaiAssistantThread OpenaiAssistantThread? @relation(fields: [openaiAssistantThreadId], references: [id])
openaiAssistantThreadId String?
OpenaiChatCompletionSession OpenaiChatCompletionSession? @relation(fields: [openaiChatCompletionSessionId], references: [id])
openaiChatCompletionSessionId String?
OpenaiSession OpenaiSession? @relation(fields: [openaiSessionId], references: [id])
openaiSessionId String?
}
model MessageUpdate {
@ -342,48 +339,16 @@ model OpenaiCreds {
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
OpenaiAssistant OpenaiBot[]
OpenaiSetting OpenaiSetting[]
}
model OpenaiAssistant {
model OpenaiBot {
id String @id @default(cuid())
assistantId String @unique @db.VarChar(255)
expire Int? @default(0) @db.Integer
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Integer
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false) @db.Boolean
stopBotFromMe Boolean? @default(false) @db.Boolean
keepOpen Boolean? @default(false) @db.Boolean
debounceTime Int? @db.Integer
ignoreJids Json?
triggerType TriggerType?
triggerOperator TriggerOperator?
triggerValue String?
createdAt DateTime? @default(now()) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
OpenaiAssistantThread OpenaiAssistantThread[]
}
model OpenaiAssistantThread {
id String @id @default(cuid())
threadId String @db.VarChar(255)
remoteJid String @db.VarChar(100)
status TypebotSessionStatus
awaitUser Boolean @default(false) @db.Boolean
createdAt DateTime? @default(now()) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiAssistant OpenaiAssistant @relation(fields: [openaiAssistantId], references: [id], onDelete: Cascade)
openaiAssistantId String
Message Message[]
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
}
model OpenaiChatCompletion {
id String @id @default(cuid())
model String @db.VarChar(100)
enabled Boolean @default(true) @db.Boolean
botType String @db.VarChar(100)
assistantId String? @unique @db.VarChar(255)
model String? @db.VarChar(100)
systemMessages Json? @db.JsonB
assistantMessages Json? @db.JsonB
userMessages Json? @db.JsonB
@ -402,21 +367,46 @@ model OpenaiChatCompletion {
triggerValue String?
createdAt DateTime? @default(now()) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiCreds OpenaiCreds @relation(fields: [openaiCredsId], references: [id], onDelete: Cascade)
openaiCredsId String
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
OpenaiChatCompletionSession OpenaiChatCompletionSession[]
OpenaiSession OpenaiSession[]
OpenaiSetting OpenaiSetting[]
}
model OpenaiChatCompletionSession {
model OpenaiSession {
id String @id @default(cuid())
sessionId String @db.VarChar(255)
remoteJid String @db.VarChar(100)
sessionId String @db.VarChar(100)
status TypebotSessionStatus
awaitUser Boolean @default(false) @db.Boolean
createdAt DateTime? @default(now()) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiChatCompletion OpenaiChatCompletion @relation(fields: [openaiChatCompletionId], references: [id], onDelete: Cascade)
openaiChatCompletionId String
OpenaiBot OpenaiBot @relation(fields: [openaiBotId], references: [id], onDelete: Cascade)
openaiBotId String
Message Message[]
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String
}
model OpenaiSetting {
id String @id @default(cuid())
expire Int? @default(0) @db.Integer
keywordFinish String? @db.VarChar(100)
delayMessage Int? @db.Integer
unknownMessage String? @db.VarChar(100)
listeningFromMe Boolean? @default(false) @db.Boolean
stopBotFromMe Boolean? @default(false) @db.Boolean
keepOpen Boolean? @default(false) @db.Boolean
debounceTime Int? @db.Integer
ignoreJids Json?
createdAt DateTime? @default(now()) @db.Timestamp
updatedAt DateTime @updatedAt @db.Timestamp
OpenaiCreds OpenaiCreds? @relation(fields: [openaiCredsId], references: [id])
openaiCredsId String
Fallback OpenaiBot? @relation(fields: [openaiIdFallback], references: [id])
openaiIdFallback String? @db.VarChar(100)
Instance Instance @relation(fields: [instanceId], references: [id], onDelete: Cascade)
instanceId String @unique
}

View File

@ -0,0 +1,81 @@
import { configService, Openai } from '../../../../config/env.config';
import { BadRequestException } from '../../../../exceptions';
import { InstanceDto } from '../../../dto/instance.dto';
import { OpenaiCredsDto, OpenaiDto, OpenaiIgnoreJidDto } from '../dto/openai.dto';
import { OpenaiService } from '../services/openai.service';
export class OpenaiController {
constructor(private readonly openaiService: OpenaiService) {}
public async createOpenaiCreds(instance: InstanceDto, data: OpenaiCredsDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.createCreds(instance, data);
}
public async findOpenaiCreds(instance: InstanceDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.findCreds(instance);
}
public async createOpenai(instance: InstanceDto, data: OpenaiDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.create(instance, data);
}
public async findOpenai(instance: InstanceDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.find(instance);
}
public async fetchOpenai(instance: InstanceDto, openaiBotId: string) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.fetch(instance, openaiBotId);
}
public async updateOpenai(instance: InstanceDto, openaiBotId: string, data: OpenaiDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.update(instance, openaiBotId, data);
}
public async deleteOpenai(instance: InstanceDto, openaiBotId: string) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.delete(instance, openaiBotId);
}
public async settings(instance: InstanceDto, data: any) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.setDefaultSettings(instance, data);
}
public async fetchSettings(instance: InstanceDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.fetchDefaultSettings(instance);
}
public async changeStatus(instance: InstanceDto, data: any) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.changeStatus(instance, data);
}
public async fetchSessions(instance: InstanceDto, openaiBotId: string) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.fetchSessions(instance, openaiBotId);
}
public async ignoreJid(instance: InstanceDto, data: OpenaiIgnoreJidDto) {
if (!configService.get<Openai>('OPENAI').ENABLED) throw new BadRequestException('Openai is disabled');
return this.openaiService.ignoreJid(instance, data);
}
}

View File

@ -0,0 +1,56 @@
import { TriggerOperator, TriggerType } from '@prisma/client';
export class Session {
remoteJid?: string;
sessionId?: string;
status?: string;
createdAt?: number;
updateAt?: number;
}
export class OpenaiCredsDto {
apiKey: string;
}
export class OpenaiDto {
enabled?: boolean;
openaiCredsId: string;
botType?: string;
assistantId?: string;
model?: string;
systemMessages?: string[];
assistantMessages?: string[];
userMessages?: string[];
maxTokens?: number;
expire?: number;
keywordFinish?: string;
delayMessage?: number;
unknownMessage?: string;
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
triggerType?: TriggerType;
triggerOperator?: TriggerOperator;
triggerValue?: string;
ignoreJids?: any;
}
export class OpenaiSettingDto {
openaiCredsId?: string;
expire?: number;
keywordFinish?: string;
delayMessage?: number;
unknownMessage?: string;
listeningFromMe?: boolean;
stopBotFromMe?: boolean;
keepOpen?: boolean;
debounceTime?: number;
openaiIdFallback?: string;
ignoreJids?: any;
}
export class OpenaiIgnoreJidDto {
remoteJid?: string;
action?: string;
}

View File

@ -0,0 +1,144 @@
import { RequestHandler, Router } from 'express';
import {
instanceSchema,
openaiCredsSchema,
openaiIgnoreJidSchema,
openaiSchema,
openaiSettingSchema,
openaiStatusSchema,
} from '../../../../validate/validate.schema';
import { RouterBroker } from '../../../abstract/abstract.router';
import { InstanceDto } from '../../../dto/instance.dto';
import { HttpStatus } from '../../../routes/index.router';
import { openaiController } from '../../../server.module';
import { OpenaiCredsDto, OpenaiDto, OpenaiIgnoreJidDto, OpenaiSettingDto } from '../dto/openai.dto';
export class OpenaiRouter extends RouterBroker {
constructor(...guards: RequestHandler[]) {
super();
this.router
.post(this.routerPath('creds'), ...guards, async (req, res) => {
const response = await this.dataValidate<OpenaiCredsDto>({
request: req,
schema: openaiCredsSchema,
ClassRef: OpenaiCredsDto,
execute: (instance, data) => openaiController.createOpenaiCreds(instance, data),
});
res.status(HttpStatus.CREATED).json(response);
})
.get(this.routerPath('creds'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.findOpenaiCreds(instance),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('create'), ...guards, async (req, res) => {
const response = await this.dataValidate<OpenaiDto>({
request: req,
schema: openaiSchema,
ClassRef: OpenaiDto,
execute: (instance, data) => openaiController.createOpenai(instance, data),
});
res.status(HttpStatus.CREATED).json(response);
})
.get(this.routerPath('find'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.findOpenai(instance),
});
res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('fetch/:openaiBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.fetchOpenai(instance, req.params.openaiBotId),
});
res.status(HttpStatus.OK).json(response);
})
.put(this.routerPath('update/:openaiBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<OpenaiDto>({
request: req,
schema: openaiSchema,
ClassRef: OpenaiDto,
execute: (instance, data) => openaiController.updateOpenai(instance, req.params.openaiBotId, data),
});
res.status(HttpStatus.OK).json(response);
})
.delete(this.routerPath('delete/:openaiBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.deleteOpenai(instance, req.params.openaiBotId),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('settings'), ...guards, async (req, res) => {
const response = await this.dataValidate<OpenaiSettingDto>({
request: req,
schema: openaiSettingSchema,
ClassRef: OpenaiSettingDto,
execute: (instance, data) => openaiController.settings(instance, data),
});
res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('fetchSettings'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.fetchSettings(instance),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('changeStatus'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: openaiStatusSchema,
ClassRef: InstanceDto,
execute: (instance, data) => openaiController.changeStatus(instance, data),
});
res.status(HttpStatus.OK).json(response);
})
.get(this.routerPath('fetchSessions/:openaiBotId'), ...guards, async (req, res) => {
const response = await this.dataValidate<InstanceDto>({
request: req,
schema: instanceSchema,
ClassRef: InstanceDto,
execute: (instance) => openaiController.fetchSessions(instance, req.params.openaiBotId),
});
res.status(HttpStatus.OK).json(response);
})
.post(this.routerPath('ignoreJid'), ...guards, async (req, res) => {
const response = await this.dataValidate<OpenaiIgnoreJidDto>({
request: req,
schema: openaiIgnoreJidSchema,
ClassRef: OpenaiIgnoreJidDto,
execute: (instance, data) => openaiController.ignoreJid(instance, data),
});
res.status(HttpStatus.OK).json(response);
});
}
public readonly router = Router();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,125 @@
import { JSONSchema7 } from 'json-schema';
import { v4 } from 'uuid';
const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
const properties = {};
propertyNames.forEach(
(property) =>
(properties[property] = {
minLength: 1,
description: `The "${property}" cannot be empty`,
}),
);
return {
if: {
propertyNames: {
enum: [...propertyNames],
},
},
then: { properties },
};
};
export const openaiSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
enabled: { type: 'boolean' },
openaiCredsId: { type: 'string' },
botType: { type: 'string', enum: ['assistant', 'chatCompletion'] },
assistantId: { type: 'string' },
model: { type: 'string' },
systemMessages: { type: 'array', items: { type: 'string' } },
assistantMessages: { type: 'array', items: { type: 'string' } },
userMessages: { type: 'array', items: { type: 'string' } },
maxTokens: { type: 'integer' },
triggerType: { type: 'string', enum: ['all', 'keyword'] },
triggerOperator: { type: 'string', enum: ['equals', 'contains', 'startsWith', 'endsWith', 'regex', 'none'] },
triggerValue: { type: 'string' },
expire: { type: 'integer' },
keywordFinish: { type: 'string' },
delayMessage: { type: 'integer' },
unknownMessage: { type: 'string' },
listeningFromMe: { type: 'boolean' },
stopBotFromMe: { type: 'boolean' },
keepOpen: { type: 'boolean' },
debounceTime: { type: 'integer' },
ignoreJids: { type: 'array', items: { type: 'string' } },
},
required: ['enabled', 'openaiCredsId', 'botType', 'triggerType'],
...isNotEmpty('enabled', 'openaiCredsId', 'botType', 'triggerType'),
};
export const openaiCredsSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
apiKey: { type: 'string' },
},
required: ['enabled', 'apiKey'],
...isNotEmpty('enabled', 'apiKey'),
};
export const openaiStatusSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
remoteJid: { type: 'string' },
status: { type: 'string', enum: ['opened', 'closed', 'paused'] },
},
required: ['remoteJid', 'status'],
...isNotEmpty('remoteJid', 'status'),
};
export const openaiSettingSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
openaiCredsId: { type: 'string' },
expire: { type: 'integer' },
keywordFinish: { type: 'string' },
delayMessage: { type: 'integer' },
unknownMessage: { type: 'string' },
listeningFromMe: { type: 'boolean' },
stopBotFromMe: { type: 'boolean' },
keepOpen: { type: 'boolean' },
debounceTime: { type: 'integer' },
ignoreJids: { type: 'array', items: { type: 'string' } },
openaiIdFallback: { type: 'string' },
},
required: [
'openaiCredsId',
'expire',
'keywordFinish',
'delayMessage',
'unknownMessage',
'listeningFromMe',
'stopBotFromMe',
'keepOpen',
'debounceTime',
'ignoreJids',
],
...isNotEmpty(
'openaiCredsId',
'expire',
'keywordFinish',
'delayMessage',
'unknownMessage',
'listeningFromMe',
'stopBotFromMe',
'keepOpen',
'debounceTime',
'ignoreJids',
),
};
export const openaiIgnoreJidSchema: JSONSchema7 = {
$id: v4(),
type: 'object',
properties: {
remoteJid: { type: 'string' },
action: { type: 'string', enum: ['add', 'remove'] },
},
required: ['remoteJid', 'action'],
...isNotEmpty('remoteJid', 'action'),
};

View File

@ -13,6 +13,8 @@ import { TemplateController } from './controllers/template.controller';
import { WebhookController } from './controllers/webhook.controller';
import { ChatwootController } from './integrations/chatwoot/controllers/chatwoot.controller';
import { ChatwootService } from './integrations/chatwoot/services/chatwoot.service';
import { OpenaiController } from './integrations/openai/controllers/openai.controller';
import { OpenaiService } from './integrations/openai/services/openai.service';
import { RabbitmqController } from './integrations/rabbitmq/controllers/rabbitmq.controller';
import { RabbitmqService } from './integrations/rabbitmq/services/rabbitmq.service';
import { S3Controller } from './integrations/s3/controllers/s3.controller';
@ -65,6 +67,9 @@ const authService = new AuthService(prismaRepository);
const typebotService = new TypebotService(waMonitor, configService, prismaRepository);
export const typebotController = new TypebotController(typebotService);
const openaiService = new OpenaiService(waMonitor, configService, prismaRepository);
export const openaiController = new OpenaiController(openaiService);
const s3Service = new S3Service(prismaRepository);
export const s3Controller = new S3Controller(s3Service);

View File

@ -191,6 +191,7 @@ export type Chatwoot = {
PLACEHOLDER_MEDIA_MESSAGE: boolean;
};
};
export type Openai = { ENABLED: boolean; API_KEY_GLOBAL?: string };
export type S3 = {
ACCESS_KEY: string;
@ -224,6 +225,7 @@ export interface Env {
QRCODE: QrCode;
TYPEBOT: Typebot;
CHATWOOT: Chatwoot;
OPENAI: Openai;
CACHE: CacheConf;
S3?: S3;
AUTHENTICATION: Auth;
@ -431,6 +433,10 @@ export class ConfigService {
PLACEHOLDER_MEDIA_MESSAGE: process.env?.CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE === 'true',
},
},
OPENAI: {
ENABLED: process.env?.OPENAI_ENABLED === 'true',
API_KEY_GLOBAL: process.env?.OPENAI_API_KEY_GLOBAL || null,
},
CACHE: {
REDIS: {
ENABLED: process.env?.CACHE_REDIS_ENABLED === 'true',

View File

@ -1,5 +1,6 @@
// Integrations Schema
export * from '../api/integrations/chatwoot/validate/chatwoot.schema';
export * from '../api/integrations/openai/validate/openai.schema';
export * from '../api/integrations/rabbitmq/validate/rabbitmq.schema';
export * from '../api/integrations/sqs/validate/sqs.schema';
export * from '../api/integrations/typebot/validate/typebot.schema';