import { SessionState } from "indite-js/schemas"; import { CreateSpeechOpenAIOptions, OpenAICredentials, } from "indite-js/schemas/features/blocks/integrations/openai"; import { isNotEmpty } from "indite-js/lib"; import { decrypt } from "indite-js/lib/api/encryption/decrypt"; import prisma from "indite-js/lib/prisma"; import { defaultOpenAIOptions } from "indite-js/schemas/features/blocks/integrations/openai/constants"; import { ExecuteIntegrationResponse } from "../../../../../types"; import OpenAI, { ClientOptions } from "openai"; import { uploadFileToBucket } from "indite-js/lib/s3/uploadFileToBucket"; import { updateVariablesInSession } from "indite-js/variables/updateVariablesInSession"; import { createId } from "@paralleldrive/cuid2"; import { parseVariables } from "indite-js/variables/parseVariables"; export const createSpeechOpenAI = async ( state: SessionState, { outgoingEdgeId, options, }: { outgoingEdgeId?: string; options: CreateSpeechOpenAIOptions; } ): Promise => { let newSessionState = state; const noCredentialsError = { status: "error", description: "Make sure to select an OpenAI account", }; if (!options.input || !options.voice || !options.saveUrlInVariableId) { return { outgoingEdgeId, logs: [ { status: "error", description: "Make sure to enter an input, select a voice and select a variable to save the URL in", }, ], }; } if (!options.credentialsId) { return { outgoingEdgeId, logs: [noCredentialsError], }; } const credentials = await prisma.credentials.findUnique({ where: { id: options.credentialsId, }, }); if (!credentials) { console.error("Could not find credentials in database"); return { outgoingEdgeId, logs: [noCredentialsError] }; } const { apiKey } = (await decrypt( credentials.data, credentials.iv )) as OpenAICredentials["data"]; const config = { apiKey, baseURL: options.baseUrl ?? defaultOpenAIOptions.baseUrl, defaultHeaders: { "api-key": apiKey, }, defaultQuery: isNotEmpty(options.apiVersion) ? { "api-version": options.apiVersion, } : undefined, } satisfies ClientOptions; const openai = new OpenAI(config); const variables = newSessionState.botsQueue[0].bot.variables; const saveUrlInVariable = variables.find( (v) => v.id === options.saveUrlInVariableId ); if (!saveUrlInVariable) { return { outgoingEdgeId, logs: [ { status: "error", description: "Could not find variable to save URL in", }, ], }; } const rawAudio = (await openai.audio.speech.create({ input: parseVariables(variables)(options.input), voice: options.voice, model: options.model as "tts-1" | "tts-1-hd", })) as any; const url = await uploadFileToBucket({ file: Buffer.from((await rawAudio.arrayBuffer()) as ArrayBuffer), key: `tmp/openai/audio/${createId() + createId()}.mp3`, mimeType: "audio/mpeg", }); newSessionState = updateVariablesInSession({ newVariables: [ { ...saveUrlInVariable, value: url, }, ], state: newSessionState, currentBlockId: undefined, }).updatedState; return { startTimeShouldBeUpdated: true, outgoingEdgeId, newSessionState, }; };