Skip to content

Commit e429c5d

Browse files
authored
feat: Support websocket (#60)
- support normal transcriptions api - support coze websocket api
1 parent 0f47f6c commit e429c5d

128 files changed

Lines changed: 5431 additions & 168 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,47 @@ jobs:
1616
strategy:
1717
fail-fast: false
1818
matrix:
19-
java-version: [ "8", "11", "17" ]
20-
os: [ "ubuntu-latest" ]
21-
os-label: [ "Ubuntu" ]
19+
java-version: [ "11", "17" ]
20+
os: [ "ubuntu-latest", "windows-latest", "macos-latest" ]
21+
os-label: [ "Ubuntu", "Windows", "macOS" ]
2222
include:
23-
- { java-version: "11", os: "windows-latest", os-label: "Windows" }
24-
- { java-version: "11", os: "macos-latest", os-label: "macOS" }
23+
- { java-version: "8", os: "macos-latest", os-label: "macOS", distribution: "zulu" }
24+
exclude:
25+
- os: "windows-latest"
26+
os-label: "Ubuntu"
27+
- os: "windows-latest"
28+
os-label: "macOS"
29+
- os: "macos-latest"
30+
os-label: "Ubuntu"
31+
- os: "macos-latest"
32+
os-label: "Windows"
33+
- os: "ubuntu-latest"
34+
os-label: "Windows"
35+
- os: "ubuntu-latest"
36+
os-label: "macOS"
2537
steps:
2638
- uses: actions/checkout@v4
2739
- name: Set up JDK ${{ matrix.java-version }}
2840
uses: actions/setup-java@v4
2941
with:
30-
distribution: 'adopt'
42+
distribution: ${{ matrix.java-version == '8' && matrix.os == 'macos-latest' && 'zulu' || 'temurin' }}
3143
java-version: ${{ matrix.java-version }}
3244
cache: 'maven'
45+
java-package: 'jdk'
46+
- name: Set JAVA_HOME (Windows)
47+
if: runner.os == 'Windows'
48+
run: |
49+
echo "JAVA_HOME=${{ env.JAVA_HOME }}" >> $GITHUB_ENV
50+
echo "${{ env.JAVA_HOME }}/bin" >> $GITHUB_PATH
51+
shell: bash
3352
- name: Code style check
34-
run: mvn spotless:check
53+
run: |
54+
echo "Java version:"
55+
java -version
56+
echo "Javac version:"
57+
javac -version
58+
mvn -v
59+
mvn spotless:check
3560
- name: Build and Test with Coverage
3661
run: |
3762
mvn -pl api clean test-compile

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
**/bin/*
88
**/obj/*
99
.mvn
10+
*.wav
1011

1112
# Compiled class file
1213
*.class

README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ dependencies {
7171
| how to handle exception | [HandlerExceptionExample.java](example/src/main/java/example/service/HandlerExceptionExample.java) |
7272
| get request log id | [GetLogExample.java](example/src/main/java/example/service/GetLogExample.java) |
7373
| set timeout | [SetRequestTimeoutExample.java](example/src/main/java/example/service/SetRequestTimeoutExample.java) |
74+
| websocket chat | [ChatExample.java](example/src/main/java/example/websocket/chat/ChatExample.java) |
75+
| websocket speech synthesis | [WebsocketAudioSpeechExample.java](example/src/main/java/example/websocket/audio/speech/WebsocketAudioSpeechExample.java) |
76+
| websocket transcription | [WebsocketTranscriptionsExample.java](example/src/main/java/example/websocket/audio/transcriptions/WebsocketTranscriptionsExample.java) |
7477

7578
### Initialize the Coze Client
7679

@@ -984,4 +987,123 @@ while (iterator.hasNext()) {
984987

985988
```
986989

990+
### WebSocket
991+
992+
The SDK provides WebSocket interfaces for real-time chat, speech synthesis and speech transcription.
993+
994+
You can check the official documentation for more information:
995+
https://www.coze.cn/open/docs/guides/websocket_openapi
996+
997+
#### WebSocket Chat
998+
999+
WebSocket chat allows real-time communication with bots, including text and audio interactions:
1000+
1001+
```java
1002+
WebsocketChatClient client = coze.websocket()
1003+
.chat()
1004+
.create(new WebsocketChatCreateReq(botID, new CallbackHandler()));
1005+
1006+
// Send audio data
1007+
String audioData = "..."; // Base64 encoded audio data
1008+
client.inputAudioBufferAppend(audioData);
1009+
client.inputAudioBufferComplete();
1010+
1011+
// Handle responses in callback
1012+
class CallbackHandler extends WebsocketChatCallbackHandler {
1013+
// Handle text responses
1014+
@Override
1015+
public void onConversationMessageDelta(WebsocketChatClient client, ConversationMessageDeltaEvent event) {
1016+
System.out.printf("Received: %s\n", event.getData().getContent());
1017+
}
1018+
1019+
// Handle audio responses
1020+
@Override
1021+
public void onConversationAudioDelta(WebsocketChatClient client, ConversationAudioDeltaEvent event) {
1022+
byte[] audioData = event.getData().getAudio();
1023+
// Process audio data...
1024+
}
1025+
}
1026+
```
1027+
1028+
#### Speech Synthesis
1029+
1030+
WebSocket speech synthesis allows real-time text-to-speech conversion:
1031+
1032+
```java
1033+
WebsocketAudioSpeechClient client = coze.websocket()
1034+
.audio()
1035+
.speech()
1036+
.create(new WebsocketAudioSpeechCreateReq(new CallbackHandler()));
1037+
1038+
// Configure audio output
1039+
OutputAudio outputAudio = OutputAudio.builder()
1040+
.voiceId(voiceID)
1041+
.codec("pcm")
1042+
.speechRate(50)
1043+
.pcmConfig(PCMConfig.builder().sampleRate(24000).build())
1044+
.build();
1045+
client.speechUpdate(new SpeechUpdateEventData(outputAudio));
1046+
1047+
// Send text for synthesis
1048+
client.inputTextBufferAppend("Hello world!");
1049+
client.inputTextBufferComplete();
1050+
1051+
// Handle synthesized audio in callback
1052+
class CallbackHandler extends WebsocketAudioSpeechCallbackHandler {
1053+
@Override
1054+
public void onSpeechAudioUpdate(WebsocketAudioSpeechClient client, SpeechAudioUpdateEvent event) {
1055+
byte[] audioData = event.getDelta();
1056+
// Process audio data...
1057+
}
1058+
}
1059+
```
1060+
1061+
#### Speech Transcription
1062+
1063+
WebSocket speech transcription provides real-time speech-to-text conversion:
1064+
1065+
```java
1066+
WebsocketAudioTranscriptionsClient client = coze.websocket()
1067+
.audio()
1068+
.transcriptions()
1069+
.create(new WebsocketAudioTranscriptionsCreateReq(new CallbackHandler()));
1070+
1071+
// Configure audio input
1072+
InputAudio inputAudio = InputAudio.builder()
1073+
.sampleRate(24000)
1074+
.codec("pcm")
1075+
.format("wav")
1076+
.channel(2)
1077+
.build();
1078+
client.transcriptionsUpdate(new TranscriptionsUpdateEventData(inputAudio));
1079+
1080+
// Send audio for transcription
1081+
String audioData = "..."; // Base64 encoded audio data
1082+
client.inputAudioBufferAppend(audioData);
1083+
client.inputAudioBufferComplete();
1084+
1085+
// Handle transcription results in callback
1086+
class CallbackHandler extends WebsocketAudioTranscriptionsCallbackHandler {
1087+
@Override
1088+
public void onTranscriptionsMessageUpdate(
1089+
WebsocketAudioTranscriptionsClient client,
1090+
TranscriptionsMessageUpdateEvent event) {
1091+
System.out.println(event.getData().getContent());
1092+
}
1093+
}
1094+
```
1095+
1096+
All WebSocket clients support proper resource cleanup:
1097+
1098+
```java
1099+
try {
1100+
// Use the client...
1101+
} finally {
1102+
if (client != null) {
1103+
client.close();
1104+
}
1105+
coze.shutdownExecutor();
1106+
}
1107+
```
1108+
9871109

api/pom.xml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
</parent>
4444

4545
<artifactId>coze-api</artifactId>
46-
<version>0.2.8</version>
46+
<version>0.2.9</version>
4747

4848
<scm>
4949
<connection>scm:git:git://github.com/coze-dev/coze-java.git</connection>
@@ -68,7 +68,7 @@
6868
<jackson.version>2.14.2</jackson.version>
6969
<jwt.version>0.11.5</jwt.version>
7070
<junit.version>5.10.2</junit.version>
71-
<okhttp.version>4.8.1</okhttp.version>
71+
<okhttp.version>3.14.9</okhttp.version>
7272
</properties>
7373

7474
<dependencies>
@@ -280,17 +280,20 @@
280280
<plugin>
281281
<groupId>org.apache.maven.plugins</groupId>
282282
<artifactId>maven-surefire-plugin</artifactId>
283-
<version>2.22.2</version>
283+
<version>3.2.5</version>
284284
<configuration>
285285
<includes>
286286
<include>**/*Test.java</include>
287287
</includes>
288288
<useSystemClassLoader>false</useSystemClassLoader>
289289
<forkCount>1</forkCount>
290290
<reuseForks>true</reuseForks>
291-
<argLine>@{argLine} -Djava.security.egd=file:/dev/./urandom</argLine>
291+
<argLine>@{argLine}</argLine>
292292
<systemPropertyVariables>
293-
<okhttp.platform>jdk</okhttp.platform>
293+
<okhttp.platform>jdk-8</okhttp.platform>
294+
<java.security.egd>file:/dev/urandom</java.security.egd>
295+
<javax.net.ssl.trustStore>${java.home}/lib/security/cacerts</javax.net.ssl.trustStore>
296+
<javax.net.ssl.trustStorePassword>changeit</javax.net.ssl.trustStorePassword>
294297
</systemPropertyVariables>
295298
</configuration>
296299
</plugin>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.coze.openapi.api;
2+
3+
import com.coze.openapi.client.audio.transcriptions.CreateTranscriptionsResp;
4+
import com.coze.openapi.client.common.BaseReq;
5+
import com.coze.openapi.client.common.BaseResponse;
6+
7+
import okhttp3.MultipartBody;
8+
import retrofit2.Call;
9+
import retrofit2.http.Multipart;
10+
import retrofit2.http.POST;
11+
import retrofit2.http.Part;
12+
import retrofit2.http.Tag;
13+
14+
public interface AudioTranscriptionAPI {
15+
@Multipart
16+
@POST("/v1/audio/transcriptions")
17+
Call<BaseResponse<CreateTranscriptionsResp>> create(
18+
@Part MultipartBody.Part file, @Tag BaseReq baseReq);
19+
}

api/src/main/java/com/coze/openapi/client/audio/speech/CreateSpeechReq.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,7 @@ public class CreateSpeechReq extends BaseReq {
2828
@JsonProperty("speed")
2929
@Builder.Default
3030
private float speed = 1.0f;
31+
32+
@JsonProperty("sample_rate")
33+
private int sampleRate;
3134
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.coze.openapi.client.audio.transcriptions;
2+
3+
import java.io.File;
4+
5+
import com.coze.openapi.client.common.BaseReq;
6+
7+
import lombok.EqualsAndHashCode;
8+
import lombok.Getter;
9+
import lombok.NoArgsConstructor;
10+
import lombok.experimental.SuperBuilder;
11+
12+
@Getter
13+
@SuperBuilder
14+
@NoArgsConstructor
15+
@EqualsAndHashCode(callSuper = true)
16+
public class CreateTranscriptionsReq extends BaseReq {
17+
/** local file path */
18+
private String filePath;
19+
20+
/*
21+
* file byte array
22+
*/
23+
private byte[] fileBytes;
24+
25+
/** file name */
26+
private String fileName;
27+
28+
/** file object */
29+
private File file;
30+
31+
public static CreateTranscriptionsReq of(String fileName, byte[] fileBytes) {
32+
return CreateTranscriptionsReq.builder().fileName(fileName).fileBytes(fileBytes).build();
33+
}
34+
35+
public static CreateTranscriptionsReq of(File file) {
36+
return CreateTranscriptionsReq.builder().file(file).build();
37+
}
38+
39+
public static CreateTranscriptionsReq of(String filePath) {
40+
return CreateTranscriptionsReq.builder().filePath(filePath).build();
41+
}
42+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.coze.openapi.client.audio.transcriptions;
2+
3+
import com.coze.openapi.client.common.BaseResp;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
import lombok.*;
7+
8+
@Data
9+
@Builder
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
@EqualsAndHashCode(callSuper = true)
13+
@ToString(callSuper = true)
14+
public class CreateTranscriptionsResp extends BaseResp {
15+
@JsonProperty("text")
16+
private String text;
17+
}

api/src/main/java/com/coze/openapi/client/bots/CreateBotReq.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.coze.openapi.client.bots;
22

3-
import org.jetbrains.annotations.NotNull;
4-
53
import com.coze.openapi.client.bots.model.BotOnboardingInfo;
64
import com.coze.openapi.client.bots.model.BotPromptInfo;
75
import com.coze.openapi.client.common.BaseReq;
@@ -11,6 +9,7 @@
119
import lombok.Data;
1210
import lombok.EqualsAndHashCode;
1311
import lombok.NoArgsConstructor;
12+
import lombok.NonNull;
1413
import lombok.experimental.SuperBuilder;
1514

1615
@Data
@@ -19,11 +18,11 @@
1918
@AllArgsConstructor
2019
@EqualsAndHashCode(callSuper = true)
2120
public class CreateBotReq extends BaseReq {
22-
@NotNull
21+
@NonNull
2322
@JsonProperty("space_id")
2423
String spaceID;
2524

26-
@NotNull
25+
@NonNull
2726
@JsonProperty("name")
2827
String name;
2928

api/src/main/java/com/coze/openapi/client/bots/UpdateBotReq.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
package com.coze.openapi.client.bots;
22

3-
import org.jetbrains.annotations.NotNull;
4-
53
import com.coze.openapi.client.bots.model.BotKnowledge;
64
import com.coze.openapi.client.bots.model.BotOnboardingInfo;
75
import com.coze.openapi.client.bots.model.BotPromptInfo;
86
import com.coze.openapi.client.common.BaseReq;
97
import com.fasterxml.jackson.annotation.JsonProperty;
108

11-
import lombok.AllArgsConstructor;
12-
import lombok.Data;
13-
import lombok.EqualsAndHashCode;
14-
import lombok.NoArgsConstructor;
9+
import lombok.*;
1510
import lombok.experimental.SuperBuilder;
1611

1712
@Data
@@ -21,7 +16,7 @@
2116
@EqualsAndHashCode(callSuper = true)
2217
public class UpdateBotReq extends BaseReq {
2318

24-
@NotNull
19+
@NonNull
2520
@JsonProperty("bot_id")
2621
private String botID;
2722

0 commit comments

Comments
 (0)