Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"deepgramTranscribeAudio" function added #140

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions java/deepgramTranscribeAudio/Index.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.*;
import java.util.stream.*;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;

import com.google.gson.Gson;
import org.apache.commons.validator.routines.UrlValidator;
final Gson gson=new Gson();

public RuntimeResponse main(RuntimeRequest req,RuntimeResponse res)throws Exception{
// Validate that values present in the request are not empty (payload, variables)
RuntimeResponse errorResponse=checkEmptyPayloadAndVariables(req,res);
if(errorResponse!=null){
return errorResponse;
}

// Validate the requested payload (URL)
String payloadString=req.getPayload().toString();
Map<String, Object> payload=gson.fromJson(payloadString,Map.class);

errorResponse=validatePayload(payload,res);
if(errorResponse!=null){
return errorResponse;
}

// Get file url from payload
String fileurl=payload.get("fileUrl").toString();

// Name API key is not empty
String apiKeyVariable="DEEPGRAM_SECRET_KEY";

errorResponse=checkEmptyAPIKey(req,res,apiKeyVariable);
if(errorResponse!=null){
return errorResponse;
}

String apiKey=req.getVariables().get(apiKeyVariable).toString();

String deepgramData="";
Map<String, Object> responseData=new HashMap<>();

try{
deepgramData=transcribeAudio(fileurl,apiKey);
}catch(Exception e){
responseData.put("success",false);
responseData.put("message","Something went wrong while generating the summary, please check with the developers. Error: "+e.getMessage());//TODO
return res.json(responseData);
}
responseData.put("success",true);
responseData.put("deepgramData",deepgramData);

return res.json(responseData);
}


/**
* This method will send a POST request to the specified endpoint and return the Deepgram's response
*
* @param requestBody is the Request Body for the POST request containing the URL to the wav file to Summarize
* @param apiKey is the access token used by Deepgram to summarize
* @return the Deepgram's response to the POST request
* @throws Exception in case of malformed URL, I/O exception, etc.
*/
private String transcribeAudio(String requestBody,String apiKey)throws Exception{

String endpointUrl="https://api.deepgram.com/v1/listen";
URL url=new URL(endpointUrl);
HttpURLConnection con=(HttpURLConnection)url.openConnection();

con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","application/json");
con.setRequestProperty("Authorization","Token "+apiKey);

con.setDoOutput(true);

//prepare request body
requestBody="{\"url\":\""+requestBody+"\"}";

OutputStream os=con.getOutputStream();
byte[] input=requestBody.getBytes("utf-8");
os.write(input,0,input.length);

StringBuilder response=new StringBuilder();

BufferedReader br=new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8"));
String responseLine=null;
while((responseLine=br.readLine())!=null){
response.append(responseLine.trim());
}

br.close();
con.disconnect();

return response.toString();
}

/**
* This method validates that a non-empty API key is present in variables
*
* @param req is the received POST request
* @return null if non-empty API key is present, otherwise an error response
*/
private RuntimeResponse checkEmptyAPIKey(RuntimeRequest req,RuntimeResponse res,String apiKeyVariable){
Map<String, String> variables=req.getVariables();

if(!variables.containsKey(apiKeyVariable)){
Map<String, Object> responseData=new HashMap<>();
responseData.put("success",false);
responseData.put("message","Please pass a non-empty API Key "+apiKeyVariable+" for Deepgram");

return res.json(responseData);
}

return null;
}
/**
* This method validates that non-empty URL is present in the payload
*
* @param payload is the object that contains the URL
* @return null if payload is valid, otherwise an error response
*/
private RuntimeResponse validatePayload(Map<String, Object> payload,RuntimeResponse res){
Map<String, Object> responseData=new HashMap<>();

// Validate that payload has fileUrl
if(!payload.containsKey("fileUrl")){
responseData.put("success",false);
responseData.put("message","Please provide a valid file URL");
return res.json(responseData);
}

String fileUrl=payload.get("fileUrl").toString();

// Validate the URL
UrlValidator urlValidator=new UrlValidator();
if(!urlValidator.isValid(fileUrl)){
responseData.put("success",false);
responseData.put("message","Provided URL: "+fileUrl+" is not valid, please provide a valid, correctly formed URL");
return res.json(responseData);
}

return null;
}
/**
* This function will validate that the payload and variables are non-empty in the request
*
* @param req is the received POST request
* @return null is nothing is empty, otherwise an error response
*/
private RuntimeResponse checkEmptyPayloadAndVariables(RuntimeRequest req,RuntimeResponse res){
Map<String, Object> responseData=new HashMap<>();

if(req.getPayload().isEmpty()||req.getPayload().trim().equals("{}")){
responseData.put("message","Payload is empty, expected a payload with provider and URL");
return res.json(responseData);
}

if(req.getVariables()==null){
responseData.put("success",false);
responseData.put("message","Empty function variables found. You need to pass an API key for the provider");
return res.json(responseData);
}
return null;
}
72 changes: 72 additions & 0 deletions java/deepgramTranscribeAudio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 🧹Deepgram Transcribe Audio

A Cloud Function for Transcribing Audio using [Deepgram](https://deepgram.com/)

_Example input:_

```json
{
"fileUrl": "https://static.deepgram.com/examples/interview_speech-analytics.wav"
}
```

_Example output:_

```json
{
"success": true,
"deepgramData": {}
}
```

_Example error output:_

```json
{
"success": false,
"message": "Please provide a valid file URL."
}
```

## 📝 Environment Variables

**DEEPGRAM_API_KEY** - Your Deepgram secret API key.
Details are under link: [Deepgram_getting_started](https://developers.deepgram.com/documentation/getting-started/)

## 🚀 Deployment

1. Clone this repository, and enter this function folder:

```bash
git clone https://github.com/open-runtimes/examples.git && cd examples
cd java/deepgramTranscribeAudio
```

2. Build the code:

```bash
docker run -e INTERNAL_RUNTIME_ENTRYPOINT=Index.java --rm --interactive --tty --volume $PWD:/usr/code openruntimes/java:v2-11.0 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/java:v2-11.0 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 Java runtime [README](https://github.com/open-runtimes/open-runtimes/tree/main/runtimes/java-11.0).

4. Run the curl function to send request.

```bash
curl --location --request POST 'http://localhost:3000/' \
--header 'X-Internal-Challenge: secret-key' \
--header 'Content-Type: application/json' \
--data-raw '{"payload": "{\"fileUrl\": \"https://static.deepgram.com/examples/interview_speech-analytics.wav\"}",
"variables": {"DEEPGRAM_SECRET_KEY":"<YOUR_API_KEY>"}}
'
```

## 📝 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).
4 changes: 4 additions & 0 deletions java/deepgramTranscribeAudio/deps.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies {
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'commons-validator:commons-validator:1.7'
}