diff --git a/vetti-admin/src/main/java/com/vetti/socket/MyWebSocketClient.java b/vetti-admin/src/main/java/com/vetti/socket/MyWebSocketClient.java index f2b78de..750ea0d 100644 --- a/vetti-admin/src/main/java/com/vetti/socket/MyWebSocketClient.java +++ b/vetti-admin/src/main/java/com/vetti/socket/MyWebSocketClient.java @@ -29,8 +29,8 @@ public class MyWebSocketClient { try { // 发送消息到服务端 Map map = new HashMap<>(); - map.put("type", "contextual_update"); - map.put("user_id", session.getId()); + map.put("type", "transcript"); + map.put("role", "user"); map.put("text", "你好,只回复一句话"); String s = JSONUtil.toJsonStr(map); session.getBasicRemote().sendText(s); @@ -44,8 +44,8 @@ public class MyWebSocketClient { Thread.sleep(2000); // 发送消息到服务端 Map map = new HashMap<>(); - map.put("type", "contextual_update"); - map.put("user_id", session.getId()); + map.put("type", "transcript"); + map.put("role", "user"); map.put("text", "你能回答我其他的嘛"); String s = JSONUtil.toJsonStr(map); session.getBasicRemote().sendText(s); @@ -78,7 +78,7 @@ public class MyWebSocketClient { // WebSocket服务端地址(示例) String serverUri = "ws://vetti.hotake.cn/prod-api/voice-websocket/elevenLabsAgent/104"; try { - // 获取WebSocket容器 + // 获取WebSocket容器c WebSocketContainer container = ContainerProvider.getWebSocketContainer(); // 连接服务端(传入客户端端点实例和服务端URI) container.connectToServer(new MyWebSocketClient(), new URI(serverUri)); diff --git a/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeElevenLabsConvAiTokenClientController.java b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeElevenLabsConvAiTokenClientController.java new file mode 100644 index 0000000..9f3fe70 --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/controller/ai/HotakeElevenLabsConvAiTokenClientController.java @@ -0,0 +1,42 @@ +package com.vetti.web.controller.ai; + +import com.vetti.common.core.controller.BaseController; +import com.vetti.common.core.domain.R; +import com.vetti.hotake.domain.dto.HotakeJobDescriptionGeneratorDto; +import com.vetti.hotake.domain.vo.HotakeJobDescriptionGeneratorVo; +import com.vetti.hotake.service.IHotakeAiCommonToolsService; +import com.vetti.web.entity.dto.ConvAiTokenDto; +import com.vetti.web.service.IElevenLabsConvAiTokenClientService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * AI ElevemLabs Agent 信息Controller + * + * @author wangxiangshun + * @date 2025-12-14 + */ +@Api(tags ="AI ElevemLabs Agent") +@RestController +@RequestMapping("/hotake/elevenLabsConvAi") +public class HotakeElevenLabsConvAiTokenClientController extends BaseController { + + @Autowired + private IElevenLabsConvAiTokenClientService convAiTokenClientService; + + + /** + * 获取ElevemLabs Agent令牌 + */ + @ApiOperation("获取ElevemLabs Agent令牌") + @PostMapping(value = "/getToken") + public R handleElevemLabsAgentToken() + { + return R.ok(convAiTokenClientService.getConvAiToken()); + } + +} diff --git a/vetti-admin/src/main/java/com/vetti/web/entity/dto/ConvAiTokenDto.java b/vetti-admin/src/main/java/com/vetti/web/entity/dto/ConvAiTokenDto.java new file mode 100644 index 0000000..5c0726c --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/entity/dto/ConvAiTokenDto.java @@ -0,0 +1,26 @@ +package com.vetti.web.entity.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 获取ElevenLabs Agent token 信息对象 + * + * @author wangxiangshun + * @date 2025-11-02 + */ +@Data +@Accessors(chain = true) +public class ConvAiTokenDto { + + @ApiModelProperty("核心对话Token") + private String token; + + @ApiModelProperty("会话ID") + private String conversation_id; + + @ApiModelProperty("Token过期时间(时间戳,秒)") + private long expires_at; + +} diff --git a/vetti-admin/src/main/java/com/vetti/web/entity/vo/ConvAiTokenRequestVo.java b/vetti-admin/src/main/java/com/vetti/web/entity/vo/ConvAiTokenRequestVo.java new file mode 100644 index 0000000..19a5093 --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/entity/vo/ConvAiTokenRequestVo.java @@ -0,0 +1,25 @@ +package com.vetti.web.entity.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 获取ElevenLabs Agent token 请求体 信息对象 + * + * @author wangxiangshun + * @date 2025-11-02 + */ +@Data +@Accessors(chain = true) +public class ConvAiTokenRequestVo { + + @ApiModelProperty("Agent ID(必填)") + private String agent_id; + + @ApiModelProperty("会话ID(可选)") + private String conversation_id; + + @ApiModelProperty("用户ID(可选)") + private String user_id; +} diff --git a/vetti-admin/src/main/java/com/vetti/web/service/ElevenLabsConvAiTokenClientService.java b/vetti-admin/src/main/java/com/vetti/web/service/ElevenLabsConvAiTokenClientService.java deleted file mode 100644 index 3f58edf..0000000 --- a/vetti-admin/src/main/java/com/vetti/web/service/ElevenLabsConvAiTokenClientService.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.vetti.web.service; - -public interface ElevenLabsConvAiTokenClientService { -} diff --git a/vetti-admin/src/main/java/com/vetti/web/service/IElevenLabsConvAiTokenClientService.java b/vetti-admin/src/main/java/com/vetti/web/service/IElevenLabsConvAiTokenClientService.java new file mode 100644 index 0000000..8258901 --- /dev/null +++ b/vetti-admin/src/main/java/com/vetti/web/service/IElevenLabsConvAiTokenClientService.java @@ -0,0 +1,17 @@ +package com.vetti.web.service; + +import com.vetti.web.entity.dto.ConvAiTokenDto; +/** + * ElevenLabs Agent 信息 服务类 + * + * @author WangXiangShun + * @since 2025-08-27 + */ +public interface IElevenLabsConvAiTokenClientService { + + /** + * 获取ConvAI对话Token + * @return + */ + public ConvAiTokenDto getConvAiToken(); +} diff --git a/vetti-admin/src/main/java/com/vetti/web/service/impl/ElevenLabsConvAiTokenClientServiceImpl.java b/vetti-admin/src/main/java/com/vetti/web/service/impl/ElevenLabsConvAiTokenClientServiceImpl.java index 689c40b..c17a88a 100644 --- a/vetti-admin/src/main/java/com/vetti/web/service/impl/ElevenLabsConvAiTokenClientServiceImpl.java +++ b/vetti-admin/src/main/java/com/vetti/web/service/impl/ElevenLabsConvAiTokenClientServiceImpl.java @@ -1,111 +1,93 @@ package com.vetti.web.service.impl; -import com.google.gson.Gson; +import cn.hutool.json.JSONUtil; +import com.vetti.common.exception.ServiceException; +import com.vetti.common.utils.SecurityUtils; +import com.vetti.web.entity.dto.ConvAiTokenDto; +import com.vetti.web.entity.vo.ConvAiTokenRequestVo; +import com.vetti.web.service.IElevenLabsConvAiTokenClientService; +import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import org.springframework.stereotype.Service; + import java.io.IOException; import java.util.UUID; import java.util.concurrent.TimeUnit; -public class ElevenLabsConvAiTokenClientServiceImpl { +/** + * ElevenLabs Agent 信息 服务实现类 + * + * @author WangXiangShun + * @since 2025-08-27 + */ +@Slf4j +@Service +public class ElevenLabsConvAiTokenClientServiceImpl implements IElevenLabsConvAiTokenClientService { // ========== 配置项(替换为你的实际值) ========== - private static final String XI_API_KEY = "sk_dfe2b45e19bf8ad93a71d3a0faa61619a91e817df549d116"; // 从ElevenLabs控制台获取 - private static final String AGENT_ID = "agent_9401kd09yfjnes2vddz1n29wev2t"; // 如:agent_9401kd09yfjnes2vddz1n29wev2t - private static final String TOKEN_API_URL = "https://api.elevenlabs.io/v1/convai/conversation/token"; - + // 从ElevenLabs控制台获取 + private static final String XI_API_KEY = "sk_dfe2b45e19bf8ad93a71d3a0faa61619a91e817df549d116"; + // 如:agent_9401kd09yfjnes2vddz1n29wev2t + private static final String AGENT_ID = "agent_9401kd09yfjnes2vddz1n29wev2t"; + //请求地址 + private static final String TOKEN_API_URL = "https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=agent_9401kd09yfjnes2vddz1n29wev2t"; // JSON媒体类型 private static final MediaType JSON_MEDIA_TYPE = MediaType.get("application/json; charset=utf-8"); - private final OkHttpClient client; - private final Gson gson; - - // 构造方法:初始化客户端 - public ElevenLabsConvAiTokenClientServiceImpl() { - // 初始化OkHttp客户端(设置超时) - this.client = new OkHttpClient.Builder() - .connectTimeout(10, TimeUnit.SECONDS) - .readTimeout(10, TimeUnit.SECONDS) - .writeTimeout(10, TimeUnit.SECONDS) - .build(); - this.gson = new Gson(); - } // ===================== 核心:获取ConvAI Token ===================== /** * 获取ConvAI对话Token - * @param conversationId 会话ID(可选,不传则自动生成) - * @param userId 用户ID(可选,用于区分用户) * @return Token响应对象 * @throws IOException 网络/接口异常 */ - public ConvAiTokenResponse getConvAiToken(String conversationId, String userId) throws IOException { - // 1. 构造请求体 - ConvAiTokenRequest requestBody = new ConvAiTokenRequest(); - requestBody.setAgent_id(AGENT_ID); - // 会话ID:不传则生成随机ID - requestBody.setConversation_id(conversationId == null ? UUID.randomUUID().toString() : conversationId); - requestBody.setUser_id(userId); // 用户ID(可选) - - // 2. 构建HTTP请求 - Request request = new Request.Builder() - .url(TOKEN_API_URL) - // 核心鉴权:添加XI-API-KEY头 - .addHeader("xi-api-key", XI_API_KEY) - .addHeader("Content-Type", "application/json") - // 发送JSON请求体 - .post(RequestBody.create(gson.toJson(requestBody), JSON_MEDIA_TYPE)) - .build(); - - // 3. 执行请求并解析响应 - try (Response response = client.newCall(request).execute()) { - // 检查响应状态 - if (!response.isSuccessful()) { - String errorBody = response.body() != null ? response.body().string() : "无错误信息"; - throw new IOException("获取Token失败:HTTP码=" + response.code() + ",错误信息=" + errorBody); + public ConvAiTokenDto getConvAiToken() { + try { + // 用户ID(可选,用于区分用户) + Long userId = SecurityUtils.getUserId(); + // 1. 构造请求体 + ConvAiTokenRequestVo requestBody = new ConvAiTokenRequestVo(); + requestBody.setAgent_id(AGENT_ID); + // 会话ID:不传则生成随机ID + requestBody.setConversation_id(UUID.randomUUID().toString()); + // 用户ID(可选) + requestBody.setUser_id(userId.toString()); + // 2. 构建HTTP请求 + Request request = new Request.Builder() + .url(TOKEN_API_URL) + // 核心鉴权:添加XI-API-KEY头 + .addHeader("xi-api-key", XI_API_KEY) + .addHeader("Content-Type", "application/json") + .build(); + // 初始化OkHttp客户端(设置超时) + OkHttpClient client = new OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .readTimeout(10, TimeUnit.SECONDS) + .writeTimeout(10, TimeUnit.SECONDS) + .build(); + // 3. 执行请求并解析响应 + try (Response response = client.newCall(request).execute()) { + log.info("1-错误信息为:{}",JSONUtil.toJsonStr(response)); + // 检查响应状态 + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "无错误信息"; + log.info("2-错误信息为:{}",errorBody); + throw new IOException("Failed to obtain Token"); + } + // 解析JSON响应为实体类 + String responseBody = response.body().string(); + log.info("3-获取令牌数据:{}", responseBody); + return JSONUtil.toBean(responseBody, ConvAiTokenDto.class); } - - // 解析JSON响应为实体类 - String responseBody = response.body().string(); - return gson.fromJson(responseBody, ConvAiTokenResponse.class); + } catch (Exception e) { + e.printStackTrace(); + throw new ServiceException("Failed to obtain Token"); } + } - // ===================== 数据模型(匹配接口格式) ===================== - /** - * Token请求体(对应接口入参) - */ - static class ConvAiTokenRequest { - private String agent_id; // Agent ID(必填) - private String conversation_id; // 会话ID(可选) - private String user_id; // 用户ID(可选) - - // Getter & Setter - public String getAgent_id() { return agent_id; } - public void setAgent_id(String agent_id) { this.agent_id = agent_id; } - public String getConversation_id() { return conversation_id; } - public void setConversation_id(String conversation_id) { this.conversation_id = conversation_id; } - public String getUser_id() { return user_id; } - public void setUser_id(String user_id) { this.user_id = user_id; } - } - - /** - * Token响应体(对应接口返回) - */ - static class ConvAiTokenResponse { - private String token; // 核心对话Token - private String conversation_id; // 会话ID - private long expires_at; // Token过期时间(时间戳,秒) - - // Getter & Setter - public String getToken() { return token; } - public void setToken(String token) { this.token = token; } - public String getConversation_id() { return conversation_id; } - public void setConversation_id(String conversation_id) { this.conversation_id = conversation_id; } - public long getExpires_at() { return expires_at; } - public void setExpires_at(long expires_at) { this.expires_at = expires_at; } - } // ===================== 测试主方法 ===================== // public static void main(String[] args) { @@ -120,10 +102,10 @@ public class ElevenLabsConvAiTokenClientServiceImpl { // System.out.println("会话ID:" + response.getConversation_id()); // System.out.println("过期时间(时间戳):" + response.getExpires_at()); // +// // // 后续使用:拼接WebSocket地址 // String wsUrl = "wss://api.elevenlabs.io/v1/convai/ws?token=" + response.getToken(); // System.out.println("WebSocket连接地址:" + wsUrl); -// // } catch (IOException e) { // System.err.println("❌ 获取Token失败:" + e.getMessage()); // e.printStackTrace();