diff --git a/kotlin/deepgram-audio-summary/README.md b/kotlin/deepgram-audio-summary/README.md new file mode 100644 index 00000000..36682b71 --- /dev/null +++ b/kotlin/deepgram-audio-summary/README.md @@ -0,0 +1,79 @@ +# 🔉📃 Summarize Audio with Deepgram + +A Kotlin Cloud Function for summarizing audio number using [Deepgram API](https://deepgram.com/). + +_Example input:_ + +```json +{ + "fileUrl": "https://static.deepgram.com/examples/interview_speech-analytics.wav" +} +``` + +_Example output:_ + +```json +{ + "success": true, + + "deepgramData": [ + { + "summary": "another big problem in the speech analytics space. When customers first bring the software on is that they they are blown away by the fact that an engine can monitor hundreds of Kpis.", + + "start_word": 0, + + "end_word": 228 + } + ] +} +``` + +_Example error output:_ + +```json +{ + "success": false, + + "message": "Error Message" +} +``` + +## 📝 Environment Variables + +List of environment variables used by this cloud function: + +- **DEEPGRAM_API_KEY** - Deepgram API Key + +â„šī¸ _Create your Deepgram API key at console.deepgram.com_ + +## 🚀 Deployment + +1. Clone this repository, and enter this function folder: + +```bash + +git clone https://github.com/open-runtimes/examples.git && cd examples + +cd kotlin/deepgram-audio-summary + +``` + +2. Build the code: + +```bash + +docker run -e INTERNAL_RUNTIME_ENTRYPOINT=src/Index.kt --rm --interactive --tty --volume ${PWD}:/usr/code openruntimes/kotlin:v2-1.6 sh /usr/local/src/build.sh +``` + +3. Spin-up open-runtime: + +```bash + +docker run -p 3000:3000 -e INTERNAL_RUNTIME_KEY=secret-key --rm --interactive --tty --volume ${PWD}/code.tar.gz:/tmp/code.tar.gz:ro openruntimes/kotlin:v2-1.6 sh /usr/local/src/start.sh +``` + +Your function is now listening on port `3000`, and you can execute it by sending `POST` request with appropriate authorization headers. To learn more about runtime, you can visit Kotlin runtime [README](https://github.com/open-runtimes/open-runtimes/tree/main/runtimes/kotlin-1.6). + +## 📝 Notes + +- This function is designed for use with Appwrite Cloud Functions. You can learn more about it in [Appwrite docs](https://appwrite.io/docs/functions). diff --git a/kotlin/deepgram-audio-summary/deps.gradle b/kotlin/deepgram-audio-summary/deps.gradle new file mode 100644 index 00000000..a2e7f58b --- /dev/null +++ b/kotlin/deepgram-audio-summary/deps.gradle @@ -0,0 +1,3 @@ +dependencies { + implementation 'com.google.code.gson:gson:2.9.0' +} \ No newline at end of file diff --git a/kotlin/deepgram-audio-summary/src/Index.kt b/kotlin/deepgram-audio-summary/src/Index.kt new file mode 100644 index 00000000..d6c2eba2 --- /dev/null +++ b/kotlin/deepgram-audio-summary/src/Index.kt @@ -0,0 +1,87 @@ +import com.google.gson.Gson +import com.google.gson.JsonSyntaxException +import io.openruntimes.kotlin.RuntimeRequest +import io.openruntimes.kotlin.RuntimeResponse +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader +import java.io.OutputStream +import java.net.HttpURLConnection +import java.net.URL + + +val HTTP_BAD_REQEST = 400 +val DEEPGRAM_AUDIO_SUMMARY_API_END_POINT = "https://api.deepgram.com/v1/listen?summarize=true&punctuate=true" +val gson = Gson() + +fun getErrorResponseWithMessage(res: RuntimeResponse, message: String? = "Some error occurred"): RuntimeResponse { + return res.json( + data = mapOf( + "success" to false, + "message" to message + ), + statusCode = HTTP_BAD_REQEST + ) +} + +@Throws(Exception::class) +suspend fun main(req: RuntimeRequest, res: RuntimeResponse): RuntimeResponse { + + val deepgramApiKey = req.variables["DEEPGRAM_API_KEY"] + + if (deepgramApiKey == null || deepgramApiKey.trim().isEmpty()) { + return getErrorResponseWithMessage(res, "Deepgram API key must be set to use this function.") + } + + val payloadMap = Gson().fromJson>( + req.payload.ifBlank { "{}" }, + Map::class.java + ) + val fileUrl = payloadMap["fileUrl"] ?: "" + + if (fileUrl.isEmpty() || fileUrl.trim().isEmpty()) { + return getErrorResponseWithMessage(res, "Payload doesn't contain 'fileUrl'") + } + + val url = URL(DEEPGRAM_AUDIO_SUMMARY_API_END_POINT) + val conn: HttpURLConnection = url.openConnection() as HttpURLConnection + + conn.requestMethod = "POST" + conn.addRequestProperty("Content-Type", "application/json") + conn.addRequestProperty("Authorization", "Token $deepgramApiKey") + + conn.doOutput = true + + //prepare request body + val requestBody ="{\"url\":\""+fileUrl+"\"}" + + val response = StringBuilder() + + try { + val os: OutputStream = conn.getOutputStream() + val input: ByteArray = requestBody.toByteArray(Charsets.UTF_8) + os.write(input, 0, input.size) + + val br = BufferedReader(InputStreamReader(conn.getInputStream(), "utf-8")) + var responseLine: String? = null + while (br.readLine().also { responseLine = it } != null) { + response.append(responseLine!!.trim { it <= ' ' }) + } + + br.close() + conn.disconnect() + } + catch (e: Exception){ + return getErrorResponseWithMessage(res, e.message) + } + + + val deepgramResponse = response.toString() + return res.json( + data = mapOf( + "success" to true, + "deepgramData" to deepgramResponse + ), + statusCode = 200 + ) +} \ No newline at end of file