diff --git a/build.gradle.kts b/build.gradle.kts index 351990b..0063328 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,21 +13,22 @@ repositories { dependencies { implementation("com.annimon:tgbots-module:6.5.1") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.0-Beta") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2") implementation("com.github.kittinunf.fuel:fuel:2.3.1") implementation("com.google.code.gson:gson:2.10.1") implementation("org.imgscalr:imgscalr-lib:4.2") implementation("org.json:json:20230227") + implementation("org.slf4j:slf4j-api:2.0.6") + implementation("ch.qos.logback:logback-classic:1.4.7") - implementation("org.xerial:sqlite-jdbc:3.40.1.0") implementation("org.jetbrains.exposed:exposed-core:0.41.1") - implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1") implementation("org.jetbrains.exposed:exposed-java-time:0.41.1") + implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.0-Beta") + implementation("org.xerial:sqlite-jdbc:3.40.1.0") - implementation("org.slf4j:slf4j-api:2.0.6") - implementation("ch.qos.logback:logback-classic:1.4.7") + implementation("com.google.cloud:google-cloud-translate:2.23.0") + implementation("com.google.cloud:google-cloud-texttospeech:2.24.0") } application { diff --git a/src/main/kotlin/com/helltar/artific_intellig_bot/BotConfig.kt b/src/main/kotlin/com/helltar/artific_intellig_bot/BotConfig.kt index 12e36e2..7961ef3 100644 --- a/src/main/kotlin/com/helltar/artific_intellig_bot/BotConfig.kt +++ b/src/main/kotlin/com/helltar/artific_intellig_bot/BotConfig.kt @@ -28,7 +28,6 @@ data class BotMainConfig( open class BotConfig { - val googleCloudKey: String val openaiKey: String val stableDiffusionKey: String @@ -38,7 +37,6 @@ open class BotConfig { try { Properties().run { load(FileReader(filename)) - googleCloudKey = getProperty("google_cloud_key") openaiKey = getProperty("openai_key") stableDiffusionKey = getProperty("stable_diffusion_key") } diff --git a/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTCommand.kt b/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTCommand.kt index fabf296..574c084 100644 --- a/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTCommand.kt +++ b/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTCommand.kt @@ -4,6 +4,9 @@ import com.annimon.tgbotsmodule.commands.context.MessageContext import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.core.isSuccessful import com.github.kittinunf.fuel.httpPost +import com.google.api.gax.rpc.ApiException +import com.google.cloud.texttospeech.v1.* +import com.google.cloud.translate.TranslateOptions import com.google.gson.Gson import com.helltar.artific_intellig_bot.Commands.cmdChatAsVoice import com.helltar.artific_intellig_bot.DIR_FILES @@ -16,13 +19,8 @@ import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.CHAT_ROLE import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.CHAT_ROLE_USER import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.ChatData import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.ChatMessageData -import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.TextToSpeechJsonData -import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.TtsAudioConfigData -import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.TtsInputData -import com.helltar.artific_intellig_bot.commands.user.chat.ChatGPTData.TtsVoiceData import com.helltar.artific_intellig_bot.dao.DatabaseFactory import com.helltar.artific_intellig_bot.localizedString -import com.helltar.artific_intellig_bot.utils.Utils.detectLangCode import org.json.JSONException import org.json.JSONObject import org.slf4j.LoggerFactory @@ -130,17 +128,15 @@ open class ChatGPTCommand(ctx: MessageContext) : BotCommand(ctx) { userUsageTokens[userId] = userUsageTokens[userId]!! + usageTotalTokens userContextMap[userId]?.add(ChatMessageData(CHAT_ROLE_ASSISTANT, answer)) - deleteMessage(waitMessageId) - - if (isVoiceOut) { + if (isVoiceOut) sendVoice(answer, messageId) - return - } - - if (isCommandDisabled(cmdChatAsVoice)) - replyToMessage(answer, messageId, markdown = true) else - sendVoice(answer, messageId) + if (isCommandDisabled(cmdChatAsVoice)) + replyToMessage(answer, messageId, markdown = true) + else + sendVoice(answer, messageId) + + deleteMessage(waitMessageId) } catch (e: JSONException) { log.error(e.message) @@ -149,7 +145,7 @@ open class ChatGPTCommand(ctx: MessageContext) : BotCommand(ctx) { } private fun sendVoice(text: String, messageId: Int) { - textToSpeech(text, detectLangCode(text))?.let { oggBytes -> + textToSpeech(text, detectLanguage(text))?.let { oggBytes -> // todo: tempFile val voice = File.createTempFile("tmp", ".ogg").apply { writeBytes(oggBytes) } sendVoice(voice, messageId) @@ -167,31 +163,32 @@ open class ChatGPTCommand(ctx: MessageContext) : BotCommand(ctx) { .responseString() private fun textToSpeech(text: String, languageCode: String): ByteArray? { - var json = Gson().toJson(TextToSpeechJsonData(TtsInputData(text), TtsVoiceData(languageCode), TtsAudioConfigData())) - - "https://texttospeech.googleapis.com/v1/text:synthesize?fields=audioContent&key=$googleCloudKey".httpPost() - .header("Content-Type", "application/json; charset=utf-8") - .timeout(FUEL_TIMEOUT) - .timeoutRead(FUEL_TIMEOUT) - .jsonBody(json) - .responseString().run { - json = - if (second.isSuccessful) - third.get() - else { - log.error(this.third.component2()?.message) - return null - } + TextToSpeechClient.create().use { textToSpeechClient -> + val input = SynthesisInput.newBuilder().setText(text).build() + + val voice = + VoiceSelectionParams.newBuilder() + .setLanguageCode(languageCode) + .setSsmlGender(SsmlVoiceGender.NEUTRAL) + .build() + + val audioConfig = AudioConfig.newBuilder().setAudioEncoding(AudioEncoding.OGG_OPUS).build() + + return try { + val response = textToSpeechClient.synthesizeSpeech(input, voice, audioConfig) + response.audioContent.toByteArray() + } catch (e: ApiException) { + log.error(e.message) + null } - - return try { - Base64.getDecoder().decode(JSONObject(json).getString("audioContent")) - } catch (e: JSONException) { - log.error(e.message) - null } } + private fun detectLanguage(text: String): String { + val translate = TranslateOptions.getDefaultInstance().getService() + return translate.detect(text).language + } + private fun getLoadingGifFileId(): String { if (DatabaseFactory.filesIds.exists(FILE_NAME_LOADING_GIF)) return DatabaseFactory.filesIds.getFileId(FILE_NAME_LOADING_GIF) diff --git a/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTData.kt b/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTData.kt index ddb77fd..457cc0c 100644 --- a/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTData.kt +++ b/src/main/kotlin/com/helltar/artific_intellig_bot/commands/user/chat/ChatGPTData.kt @@ -16,26 +16,4 @@ object ChatGPTData { val role: String, val content: String ) - - /* https://cloud.google.com/text-to-speech/docs/reference/rest/v1/text/synthesize */ - - data class TtsInputData( - val text: String - ) - - data class TtsVoiceData( - val languageCode: String, - val ssmlGender: String = "FEMALE" - ) - - data class TtsAudioConfigData( - val audioEncoding: String = "OGG_OPUS", - val speakingRate: Float = 1.0f - ) - - data class TextToSpeechJsonData( - val input: TtsInputData, - val voice: TtsVoiceData, - val audioConfig: TtsAudioConfigData - ) } \ No newline at end of file