From 2a028f007e6353390d616b7d56a53d71ada98ae0 Mon Sep 17 00:00:00 2001 From: adriano Date: Thu, 11 Jul 2024 15:50:35 -0300 Subject: [PATCH] feat: add route for audio transcription using OpenAI API and update Swagger documentation --- controllers/naturalLanguageController.js | 46 +++- package-lock.json | 228 +++++++++++++++++++- package.json | 1 + routes/naturalLanguageRoute.js | 3 +- swagger.yaml | 60 ++++-- swagger_production.yaml => swagger_dev.yaml | 2 +- utils/index.js | 5 +- utils/speechToTextOpenai.js | 26 +++ 8 files changed, 342 insertions(+), 29 deletions(-) rename swagger_production.yaml => swagger_dev.yaml (98%) create mode 100644 utils/speechToTextOpenai.js diff --git a/controllers/naturalLanguageController.js b/controllers/naturalLanguageController.js index ada6b74..cb6f88d 100644 --- a/controllers/naturalLanguageController.js +++ b/controllers/naturalLanguageController.js @@ -7,7 +7,7 @@ const languageCodes = require('../mockData/languageCodes.json') const path = require('path') const fs = require('fs') const speech = require('@google-cloud/speech') -const { speechToText, speechToTextJob } = require('../utils') +const { speechToText, speechToTextJob, speechToTextOpenai } = require('../utils') const client = new speech.SpeechClient() const protobuf = require('protobufjs') @@ -203,11 +203,53 @@ const getVoiceConfig = async (req, res) => { res.status(StatusCodes.OK).json({ configs }) } + +const getTextFromAudioOpenai = async (req, res) => { + + // const { languageCode } = req.body + + const audio = req.file + + if (!audio) + throw new CustomError.BadRequestError(`Missing the audio file`) + + // if (languageCode) { + // const existLanguageCode = languageCodes.find(l => l.languageCode == languageCode) + + // if (!existLanguageCode) { + // fs.unlinkSync(audio.path) + // throw new CustomError.BadRequestError(`Invalid language code`) + // } + + // } + const inputFile = path.resolve(audio.path) + + const fileName = path.basename(inputFile, path.extname(inputFile)) + + // const outputFile = path.join(__dirname, '..', 'public', 'uploads', `${fileName}.wav`) + + // const filePath = await convertAudioToLinear16(inputFile, outputFile) + + // fs.unlinkSync(inputFile) + + const obj = await speechToTextOpenai(inputFile) + + // fs.unlinkSync(filePath) + fs.unlinkSync(inputFile) + + + if (obj?.transcription) return res.status(StatusCodes.OK).json({ transcription: obj.transcription }) + + res.status(obj.status).json({ msg: obj.msg }) + +} + module.exports = { getSentiment, getAudioFromText, getTextFromAudio, getVoiceConfig, getJobStatus, - uploadAudioToTranscript + uploadAudioToTranscript, + getTextFromAudioOpenai } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bb3490b..a41e959 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "mongoose": "^7.3.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", + "openai": "^4.52.7", "protobufjs": "^7.2.5", "swagger-ui-express": "^4.1.6", "validator": "^13.6.0", @@ -915,6 +916,28 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" }, + "node_modules/@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/node-fetch/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/normalize-package-data": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", @@ -1042,6 +1065,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -2286,6 +2320,31 @@ "node": ">= 0.12" } }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/formdata-node/node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "engines": { + "node": ">= 14" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2696,6 +2755,14 @@ "node": ">=10.17.0" } }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dependencies": { + "ms": "^2.0.0" + } + }, "node_modules/husky": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", @@ -3652,6 +3719,24 @@ "node": ">= 0.6" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -3867,6 +3952,32 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openai": { + "version": "4.52.7", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.7.tgz", + "integrity": "sha512-dgxA6UZHary6NXUHEDj5TWt8ogv0+ibH+b4pT5RrWMjiRZVylNwLcw/2ubDrX5n0oUmHX/ZgudMJeemxzOvz7A==", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7", + "web-streams-polyfill": "^3.2.1" + }, + "bin": { + "openai": "bin/cli" + } + }, + "node_modules/openai/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -5112,6 +5223,11 @@ "debug": "^2.2.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -5254,6 +5370,14 @@ "node": ">=6.0.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -6153,6 +6277,27 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.1.tgz", "integrity": "sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==" }, + "@types/node-fetch": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", + "requires": { + "@types/node": "*", + "form-data": "^4.0.0" + }, + "dependencies": { + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "@types/normalize-package-data": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", @@ -6256,6 +6401,14 @@ } } }, + "agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "requires": { + "humanize-ms": "^1.2.1" + } + }, "ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -6819,7 +6972,8 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.4.0.tgz", "integrity": "sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==", - "dev": true + "dev": true, + "requires": {} }, "create-require": { "version": "1.1.1", @@ -7105,7 +7259,8 @@ "express-async-errors": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", - "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==" + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "requires": {} }, "express-fileupload": { "version": "1.2.1", @@ -7206,6 +7361,27 @@ "mime-types": "^2.1.12" } }, + "form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" + }, + "formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "requires": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "dependencies": { + "web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==" + } + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -7514,6 +7690,14 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "requires": { + "ms": "^2.0.0" + } + }, "husky": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", @@ -8239,6 +8423,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, "node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8396,6 +8585,31 @@ "mimic-fn": "^2.1.0" } }, + "openai": { + "version": "4.52.7", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.52.7.tgz", + "integrity": "sha512-dgxA6UZHary6NXUHEDj5TWt8ogv0+ibH+b4pT5RrWMjiRZVylNwLcw/2ubDrX5n0oUmHX/ZgudMJeemxzOvz7A==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7", + "web-streams-polyfill": "^3.2.1" + }, + "dependencies": { + "@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -9333,6 +9547,11 @@ "debug": "^2.2.0" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", @@ -9438,6 +9657,11 @@ "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" }, + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" + }, "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index 32c6139..574a991 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "mongoose": "^7.3.1", "morgan": "^1.10.0", "multer": "^1.4.5-lts.1", + "openai": "^4.52.7", "protobufjs": "^7.2.5", "swagger-ui-express": "^4.1.6", "validator": "^13.6.0", diff --git a/routes/naturalLanguageRoute.js b/routes/naturalLanguageRoute.js index 39f3fed..71b2656 100644 --- a/routes/naturalLanguageRoute.js +++ b/routes/naturalLanguageRoute.js @@ -2,11 +2,12 @@ const express = require('express') const router = express.Router() const { authorization, } = require('../middleware/authentication') const { audioUpload } = require("../utils") -const { getSentiment, getAudioFromText, getTextFromAudio, getVoiceConfig, uploadAudioToTranscript, getJobStatus } = require('../controllers/naturalLanguageController') +const { getSentiment, getAudioFromText, getTextFromAudioOpenai, getTextFromAudio, getVoiceConfig, uploadAudioToTranscript, getJobStatus } = require('../controllers/naturalLanguageController') router.route('/sentiment').post(authorization, getSentiment) router.route('/text-to-speech').get(authorization, getAudioFromText) router.route('/speech-to-text').post(audioUpload.single('audio'), authorization, getTextFromAudio) +router.route('/openai/speech-to-text').post(audioUpload.single('audio'), authorization, getTextFromAudioOpenai) router.route('/upload-audio-to-transcript').post(audioUpload.single('audio'), authorization, uploadAudioToTranscript) router.route('/query-job-status').get(getJobStatus) router.route('/voice-config').get(getVoiceConfig) diff --git a/swagger.yaml b/swagger.yaml index 8e47865..e5b659b 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -5,7 +5,7 @@ info: contact: {} version: '1.0' servers: -- url: http://localhost:6001/api/v1/nl +- url: https://hit-nl.omnihit.app.br/api/v1/nl variables: {} paths: /upload-audio-to-transcript: @@ -94,6 +94,33 @@ paths: deprecated: false security: - bearer: [] + /openai/speech-to-text: + post: + tags: + - Speech to text openai + summary: Speech to text + operationId: Speechtotext + parameters: [] + requestBody: + content: + multipart/form-data: + encoding: {} + schema: + required: + - audio + type: object + properties: + audio: + type: string + format: binary + required: false + responses: + '200': + description: '' + headers: {} + deprecated: false + security: + - bearer: [] /sentiment: post: tags: @@ -106,8 +133,7 @@ paths: content: application/json: schema: - allOf: - - $ref: '#/components/schemas/GetsentimentRequest' + allOf: - example: text: Toda vez a mesma coisa ja to cansado de ficar ligando pra resolver esses problemas de conexão! example: @@ -138,31 +164,31 @@ paths: example: Vela branca na enxurrada la vou eu de léo em léo, se o navio é pequeno do tamanho de um chapeu, não importa a volta ao mundo, é viagem de brinquedo em um barquinho de papel. - name: voice_name in: query - description: '' + description: 'Ex: pt-BR-Wavenet-C' required: false style: form explode: true schema: - type: string - example: pt-BR-Wavenet-C + type: string + example: - name: voice_gender in: query - description: '' + description: 'Ex: FEMALE' required: false style: form explode: true schema: type: string - example: FEMALE + example: - name: languageCode in: query - description: '' + description: 'Ex: pt-BR' required: false style: form explode: true schema: type: string - example: pt-BR + example: responses: '200': description: '' @@ -193,17 +219,6 @@ paths: deprecated: false security: [] components: - schemas: - GetsentimentRequest: - title: GetsentimentRequest - required: - - text - type: object - properties: - text: - type: string - example: - text: Toda vez a mesma coisa ja to cansado de ficar ligando pra resolver esses problemas de conexão! securitySchemes: bearer: type: http @@ -212,5 +227,6 @@ security: [] tags: - name: Speech to text async - name: Speech to text sync +- name: Speech to text openai +- name: Text to speech - name: Sentiment -- name: Text to speech \ No newline at end of file diff --git a/swagger_production.yaml b/swagger_dev.yaml similarity index 98% rename from swagger_production.yaml rename to swagger_dev.yaml index 93e639a..8e47865 100644 --- a/swagger_production.yaml +++ b/swagger_dev.yaml @@ -5,7 +5,7 @@ info: contact: {} version: '1.0' servers: -- url: https://hit-nl.omnihit.app.br/api/v1/nl +- url: http://localhost:6001/api/v1/nl variables: {} paths: /upload-audio-to-transcript: diff --git a/utils/index.js b/utils/index.js index 2bbec66..770b1e2 100644 --- a/utils/index.js +++ b/utils/index.js @@ -11,6 +11,8 @@ const audioUploadToBucket = require('./audioUploadToBucket') const audioUpload = require('./audioUpload') const speechToText = require('./speechToText') const speechToTextJob = require('./speechToTextJob') +const speechToTextOpenai = require('./speechToTextOpenai') + module.exports = { sentiment, @@ -21,5 +23,6 @@ module.exports = { audioUploadToBucket, audioUpload, speechToText, - speechToTextJob + speechToTextJob, + speechToTextOpenai } diff --git a/utils/speechToTextOpenai.js b/utils/speechToTextOpenai.js new file mode 100644 index 0000000..9a9cf66 --- /dev/null +++ b/utils/speechToTextOpenai.js @@ -0,0 +1,26 @@ +const fs = require('fs') +const OpenAI = require('openai') +const { StatusCodes } = require("http-status-codes") + +const openai = new OpenAI({ apiKey: process.env.TOKEN_OPENAI }) + +async function speechToTextOpenai(audioPath) { + + try { + + const transcription = await openai.audio.transcriptions.create({ + file: fs.createReadStream(audioPath), + model: "whisper-1", + // language: "de", // this is optional but helps the model + }) + + return { msg: `Transcript success`, status: StatusCodes.OK, transcription } + + } catch (error) { + console.log('ERROR ON TRY TRANSCRIPT FROM OPENAI: ', error) + return { msg: `Error on try transcript the file`, status: StatusCodes.INTERNAL_SERVER_ERROR } + } + +} + +module.exports = speechToTextOpenai