This commit is contained in:
jack ning
2025-10-13 11:53:17 +08:00
parent c4e944287b
commit 0697ad348c
28 changed files with 143 additions and 130 deletions

View File

@@ -1,6 +1,6 @@
{
"/admin/umi.css": "/admin/umi.c10bed78.css",
"/admin/umi.js": "/admin/umi.b232a5b7.js",
"/admin/umi.js": "/admin/umi.15ba68dc.js",
"/admin/4940.76e573c2.async.js": "/admin/4940.76e573c2.async.js",
"/admin/6571.d7d4f92f.async.js": "/admin/6571.d7d4f92f.async.js",
"/admin/9952.56ca2544.async.js": "/admin/9952.56ca2544.async.js",
@@ -132,7 +132,7 @@
"/admin/p__Dashboard__Setting__Server__index.js": "/admin/p__Dashboard__Setting__Server__index.fe37a2f2.async.js",
"/admin/p__Dashboard__Setting__Notification__index.js": "/admin/p__Dashboard__Setting__Notification__index.3285e515.async.js",
"/admin/p__Dashboard__Setting__Webhook__index.js": "/admin/p__Dashboard__Setting__Webhook__index.3ba97cdf.async.js",
"/admin/p__Dashboard__Setting__Token__index.js": "/admin/p__Dashboard__Setting__Token__index.788a009e.async.js",
"/admin/p__Dashboard__Setting__Token__index.js": "/admin/p__Dashboard__Setting__Token__index.aec1044c.async.js",
"/admin/p__Dashboard__Setting__License__index.js": "/admin/p__Dashboard__Setting__License__index.dc8e4c6b.async.js",
"/admin/p__Dashboard__Super__Organization__index.js": "/admin/p__Dashboard__Super__Organization__index.bab3870c.async.js",
"/admin/p__Dashboard__Super__User__index.js": "/admin/p__Dashboard__Super__User__index.b0b0a71c.async.js",

View File

@@ -7,10 +7,10 @@
<link rel="shortcut icon" href="/admin/favicon.ico">
<title>微语</title>
<link rel="stylesheet" href="/admin/umi.c10bed78.css">
<script src="/admin/preload_helper.963beb06.js"></script>
<script src="/admin/preload_helper.f61b1045.js"></script>
</head>
<body>
<div id="root"></div>
<script src="/admin/umi.b232a5b7.js"></script>
<script src="/admin/umi.15ba68dc.js"></script>
</body>
</html>

View File

@@ -1 +1 @@
import{getApiUrl as b}from"./index-CvNVT5L5.js";import{E as l}from"./index-x2o9k_ZH.js";async function f(t,r,i,a){try{const o=new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14),p=r||`${o}_${t.name}`,s=i||t.type||"image/jpeg",e=new FormData;e.append("file",t),e.append("fileName",p),e.append("fileType",s),e.append("isAvatar",(a==null?void 0:a.isAvatar)||"false"),e.append("kbType",(a==null?void 0:a.kbType)||"feedback");const c=(a==null?void 0:a.visitorUid)||localStorage.getItem("bytedesk_uid")||localStorage.getItem("bytedesk_visitor_uid")||"",u=(a==null?void 0:a.visitorNickname)||localStorage.getItem("bytedesk_nickname")||"",g=(a==null?void 0:a.visitorAvatar)||localStorage.getItem("bytedesk_avatar")||"",v=(a==null?void 0:a.orgUid)||"";e.append("visitorUid",c),e.append("visitorNickname",u),e.append("visitorAvatar",g),e.append("orgUid",v),e.append("client",(a==null?void 0:a.client)||"web"),a!=null&&a.isDebug&&l.debug("handleUpload formData",e);const m=`${b()}/visitor/api/upload/file`,n=await fetch(m,{method:"POST",headers:{},body:e});if(!n.ok)throw new Error(`上传失败: ${n.status} ${n.statusText}`);const d=await n.json();return a!=null&&a.isDebug&&l.debug("upload data:",d),d}catch(o){throw l.error("文件上传失败:",o),o}}async function h(t,r){var i;const a=`screenshot_${new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14)}.jpg`;return((i=(await f(t,a,"image/jpeg",{...r,kbType:"feedback"})).data)==null?void 0:i.fileUrl)||""}export{f as handleUpload,h as uploadScreenshot};
import{getApiUrl as b}from"./index-Chq1FiPg.js";import{E as l}from"./index-7uwhsjz9.js";async function f(t,r,i,a){try{const o=new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14),p=r||`${o}_${t.name}`,s=i||t.type||"image/jpeg",e=new FormData;e.append("file",t),e.append("fileName",p),e.append("fileType",s),e.append("isAvatar",(a==null?void 0:a.isAvatar)||"false"),e.append("kbType",(a==null?void 0:a.kbType)||"feedback");const c=(a==null?void 0:a.visitorUid)||localStorage.getItem("bytedesk_uid")||localStorage.getItem("bytedesk_visitor_uid")||"",u=(a==null?void 0:a.visitorNickname)||localStorage.getItem("bytedesk_nickname")||"",g=(a==null?void 0:a.visitorAvatar)||localStorage.getItem("bytedesk_avatar")||"",v=(a==null?void 0:a.orgUid)||"";e.append("visitorUid",c),e.append("visitorNickname",u),e.append("visitorAvatar",g),e.append("orgUid",v),e.append("client",(a==null?void 0:a.client)||"web"),a!=null&&a.isDebug&&l.debug("handleUpload formData",e);const m=`${b()}/visitor/api/upload/file`,n=await fetch(m,{method:"POST",headers:{},body:e});if(!n.ok)throw new Error(`上传失败: ${n.status} ${n.statusText}`);const d=await n.json();return a!=null&&a.isDebug&&l.debug("upload data:",d),d}catch(o){throw l.error("文件上传失败:",o),o}}async function h(t,r){var i;const a=`screenshot_${new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14)}.jpg`;return((i=(await f(t,a,"image/jpeg",{...r,kbType:"feedback"})).data)==null?void 0:i.fileUrl)||""}export{f as handleUpload,h as uploadScreenshot};

View File

@@ -1 +1 @@
import{T as a}from"./index-x2o9k_ZH.js";import r from"./index-CvNVT5L5.js";async function n(e){return r("/visitor/api/v1/message/unread/count",{method:"GET",params:{...e,client:a}})}async function o(e){return r("/visitor/api/v1/message/unread/clear",{method:"POST",data:{...e,client:a}})}export{o as clearUnreadMessages,n as getUnreadMessageCount};
import{T as a}from"./index-7uwhsjz9.js";import r from"./index-Chq1FiPg.js";async function n(e){return r("/visitor/api/v1/message/unread/count",{method:"GET",params:{...e,client:a}})}async function o(e){return r("/visitor/api/v1/message/unread/clear",{method:"POST",data:{...e,client:a}})}export{o as clearUnreadMessages,n as getUnreadMessageCount};

View File

@@ -1 +1 @@
import{T as t}from"./index-x2o9k_ZH.js";import o from"./index-CvNVT5L5.js";async function a(i){return o("/visitor/api/v1/init",{method:"POST",data:{...i,client:t}})}async function e(i){return o("/visitor/api/v1/browse",{method:"POST",data:{...i,client:t}})}export{e as browse,a as initVisitor};
import{T as t}from"./index-7uwhsjz9.js";import o from"./index-Chq1FiPg.js";async function a(i){return o("/visitor/api/v1/init",{method:"POST",data:{...i,client:t}})}async function e(i){return o("/visitor/api/v1/browse",{method:"POST",data:{...i,client:t}})}export{e as browse,a as initVisitor};

View File

@@ -1 +1 @@
import i from"./index-CvNVT5L5.js";import"./index-x2o9k_ZH.js";function e(t){return i({url:"/visitor/api/feedback/submit",method:"post",data:t})}export{e as submitFeedback};
import i from"./index-Chq1FiPg.js";import"./index-7uwhsjz9.js";function e(t){return i({url:"/visitor/api/feedback/submit",method:"post",data:t})}export{e as submitFeedback};

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><link rel="icon" type="image/x-icon" href="/agent/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title></title><script type="module" crossorigin src="/agent/agent/assets/js/index-x2o9k_ZH.js"></script><link rel="stylesheet" crossorigin href="/agent/agent/assets/css/index-DMeNvbmc.css"></head><body><div id="root"></div><script src="https://cdn.weiyuai.cn/agent/assets/js/0.3.5/sdk.js"></script><script src="https://cdn.weiyuai.cn/agent/assets/js/2.0.2/index.js" async></script></body></html>
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><link rel="icon" type="image/x-icon" href="/agent/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title></title><script type="module" crossorigin src="/agent/agent/assets/js/index-7uwhsjz9.js"></script><link rel="stylesheet" crossorigin href="/agent/agent/assets/css/index-DMeNvbmc.css"></head><body><div id="root"></div><script src="https://cdn.weiyuai.cn/agent/assets/js/0.3.5/sdk.js"></script><script src="https://cdn.weiyuai.cn/agent/assets/js/2.0.2/index.js" async></script></body></html>

View File

@@ -14,6 +14,7 @@ import java.util.Objects;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
@@ -30,6 +31,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@ConditionalOnProperty(prefix = "bytedesk.features.ai-bot", name = "enabled", havingValue = "true", matchIfMissing = false)
@RequiredArgsConstructor
public class AiBotHttapiController {
@@ -45,8 +47,8 @@ public class AiBotHttapiController {
@Value("${bytedesk.call.ai.welcome:/usr/local/freeswitch/sounds/en/us/callie/ivr/8000/ivr-welcome.wav}")
private String welcomeFile;
// 录音保存路径模板(放在 FS 本地),支持 ${uuid} 与 ${turn}
@Value("${bytedesk.call.ai.recordPath:/usr/local/freeswitch/recordings/ai-bot-${uuid}-${turn}.wav}")
// 录音保存路径模板(放在 FS 本地),支持 {uuid} 与 {turn}(避免 Spring 解析 ${...} 占位符导致启动失败)
@Value("${bytedesk.call.ai.recordPath:/usr/local/freeswitch/recordings/ai-bot-{uuid}-{turn}.wav}")
private String recordPathTpl;
// 最大录音秒数
@@ -178,7 +180,12 @@ public class AiBotHttapiController {
private String resolveRecordPath(String tpl, String uuid, int turn) {
String path = Objects.requireNonNullElse(tpl, "/usr/local/freeswitch/recordings/ai-bot-" + uuid + "-" + turn + ".wav");
return path.replace("${uuid}", uuid).replace("${turn}", Integer.toString(turn));
// 同时兼容 ${uuid}/${turn} 与 {uuid}/{turn} 两种模板写法
return path
.replace("${uuid}", uuid)
.replace("${turn}", Integer.toString(turn))
.replace("{uuid}", uuid)
.replace("{turn}", Integer.toString(turn));
}
private String safeAsr(String recordPath, String uuid, int turn) {

View File

@@ -23,15 +23,21 @@
## 2. 关键配置
### 2.1 Spring Boot端口、录音与调用
### 2.1 Spring Boot启用开关、端口、录音与调用)
确保以下属性生效(可放在应用的 `application.properties` 或等效配置源中)
默认不开启。要启用对话中枢 HTTAPI 控制器,请显式添加
```
bytedesk.features.ai-bot.enabled=true
```
然后确保以下属性生效(可放在应用的 `application.properties` 或等效配置源中):
- `server.port=9003`(需与 dialplan 中的 HTTAPI URL 对齐)
- modules/call对话编排
- `bytedesk.call.ai.useSpeak=true`(可选:使用 `execute speak` 兜底)
- `bytedesk.call.ai.welcome=/usr/local/freeswitch/sounds/en/us/callie/ivr/ivr-welcome.wav`(可改为自定义欢迎音)
- `bytedesk.call.ai.recordPath=/usr/local/freeswitch/recordings/ai-bot-${uuid}-${turn}.wav`
- `bytedesk.call.ai.recordPath=/usr/local/freeswitch/recordings/ai-bot-{uuid}-{turn}.wav`(支持 {uuid}/{turn},也向后兼容 ${uuid}/${turn}
- `bytedesk.call.ai.recordMaxSec=10`
- `bytedesk.call.ai.silenceSec=2`
- `bytedesk.ai.service.baseUrl=http://127.0.0.1:9003`(指向本机 `modules/ai` 服务)

View File

@@ -1,6 +1,6 @@
{
"/admin/umi.css": "/admin/umi.c10bed78.css",
"/admin/umi.js": "/admin/umi.b232a5b7.js",
"/admin/umi.js": "/admin/umi.15ba68dc.js",
"/admin/4940.76e573c2.async.js": "/admin/4940.76e573c2.async.js",
"/admin/6571.d7d4f92f.async.js": "/admin/6571.d7d4f92f.async.js",
"/admin/9952.56ca2544.async.js": "/admin/9952.56ca2544.async.js",
@@ -132,7 +132,7 @@
"/admin/p__Dashboard__Setting__Server__index.js": "/admin/p__Dashboard__Setting__Server__index.fe37a2f2.async.js",
"/admin/p__Dashboard__Setting__Notification__index.js": "/admin/p__Dashboard__Setting__Notification__index.3285e515.async.js",
"/admin/p__Dashboard__Setting__Webhook__index.js": "/admin/p__Dashboard__Setting__Webhook__index.3ba97cdf.async.js",
"/admin/p__Dashboard__Setting__Token__index.js": "/admin/p__Dashboard__Setting__Token__index.788a009e.async.js",
"/admin/p__Dashboard__Setting__Token__index.js": "/admin/p__Dashboard__Setting__Token__index.aec1044c.async.js",
"/admin/p__Dashboard__Setting__License__index.js": "/admin/p__Dashboard__Setting__License__index.dc8e4c6b.async.js",
"/admin/p__Dashboard__Super__Organization__index.js": "/admin/p__Dashboard__Super__Organization__index.bab3870c.async.js",
"/admin/p__Dashboard__Super__User__index.js": "/admin/p__Dashboard__Super__User__index.b0b0a71c.async.js",

View File

@@ -7,10 +7,10 @@
<link rel="shortcut icon" href="/admin/favicon.ico">
<title>微语</title>
<link rel="stylesheet" href="/admin/umi.c10bed78.css">
<script src="/admin/preload_helper.963beb06.js"></script>
<script src="/admin/preload_helper.f61b1045.js"></script>
</head>
<body>
<div id="root"></div>
<script src="/admin/umi.b232a5b7.js"></script>
<script src="/admin/umi.15ba68dc.js"></script>
</body>
</html>

View File

@@ -1 +1 @@
import{getApiUrl as b}from"./index-CvNVT5L5.js";import{E as l}from"./index-x2o9k_ZH.js";async function f(t,r,i,a){try{const o=new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14),p=r||`${o}_${t.name}`,s=i||t.type||"image/jpeg",e=new FormData;e.append("file",t),e.append("fileName",p),e.append("fileType",s),e.append("isAvatar",(a==null?void 0:a.isAvatar)||"false"),e.append("kbType",(a==null?void 0:a.kbType)||"feedback");const c=(a==null?void 0:a.visitorUid)||localStorage.getItem("bytedesk_uid")||localStorage.getItem("bytedesk_visitor_uid")||"",u=(a==null?void 0:a.visitorNickname)||localStorage.getItem("bytedesk_nickname")||"",g=(a==null?void 0:a.visitorAvatar)||localStorage.getItem("bytedesk_avatar")||"",v=(a==null?void 0:a.orgUid)||"";e.append("visitorUid",c),e.append("visitorNickname",u),e.append("visitorAvatar",g),e.append("orgUid",v),e.append("client",(a==null?void 0:a.client)||"web"),a!=null&&a.isDebug&&l.debug("handleUpload formData",e);const m=`${b()}/visitor/api/upload/file`,n=await fetch(m,{method:"POST",headers:{},body:e});if(!n.ok)throw new Error(`上传失败: ${n.status} ${n.statusText}`);const d=await n.json();return a!=null&&a.isDebug&&l.debug("upload data:",d),d}catch(o){throw l.error("文件上传失败:",o),o}}async function h(t,r){var i;const a=`screenshot_${new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14)}.jpg`;return((i=(await f(t,a,"image/jpeg",{...r,kbType:"feedback"})).data)==null?void 0:i.fileUrl)||""}export{f as handleUpload,h as uploadScreenshot};
import{getApiUrl as b}from"./index-Chq1FiPg.js";import{E as l}from"./index-7uwhsjz9.js";async function f(t,r,i,a){try{const o=new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14),p=r||`${o}_${t.name}`,s=i||t.type||"image/jpeg",e=new FormData;e.append("file",t),e.append("fileName",p),e.append("fileType",s),e.append("isAvatar",(a==null?void 0:a.isAvatar)||"false"),e.append("kbType",(a==null?void 0:a.kbType)||"feedback");const c=(a==null?void 0:a.visitorUid)||localStorage.getItem("bytedesk_uid")||localStorage.getItem("bytedesk_visitor_uid")||"",u=(a==null?void 0:a.visitorNickname)||localStorage.getItem("bytedesk_nickname")||"",g=(a==null?void 0:a.visitorAvatar)||localStorage.getItem("bytedesk_avatar")||"",v=(a==null?void 0:a.orgUid)||"";e.append("visitorUid",c),e.append("visitorNickname",u),e.append("visitorAvatar",g),e.append("orgUid",v),e.append("client",(a==null?void 0:a.client)||"web"),a!=null&&a.isDebug&&l.debug("handleUpload formData",e);const m=`${b()}/visitor/api/upload/file`,n=await fetch(m,{method:"POST",headers:{},body:e});if(!n.ok)throw new Error(`上传失败: ${n.status} ${n.statusText}`);const d=await n.json();return a!=null&&a.isDebug&&l.debug("upload data:",d),d}catch(o){throw l.error("文件上传失败:",o),o}}async function h(t,r){var i;const a=`screenshot_${new Date().toISOString().replace(/[-:T.]/g,"").slice(0,14)}.jpg`;return((i=(await f(t,a,"image/jpeg",{...r,kbType:"feedback"})).data)==null?void 0:i.fileUrl)||""}export{f as handleUpload,h as uploadScreenshot};

View File

@@ -1 +1 @@
import{T as a}from"./index-x2o9k_ZH.js";import r from"./index-CvNVT5L5.js";async function n(e){return r("/visitor/api/v1/message/unread/count",{method:"GET",params:{...e,client:a}})}async function o(e){return r("/visitor/api/v1/message/unread/clear",{method:"POST",data:{...e,client:a}})}export{o as clearUnreadMessages,n as getUnreadMessageCount};
import{T as a}from"./index-7uwhsjz9.js";import r from"./index-Chq1FiPg.js";async function n(e){return r("/visitor/api/v1/message/unread/count",{method:"GET",params:{...e,client:a}})}async function o(e){return r("/visitor/api/v1/message/unread/clear",{method:"POST",data:{...e,client:a}})}export{o as clearUnreadMessages,n as getUnreadMessageCount};

View File

@@ -1 +1 @@
import{T as t}from"./index-x2o9k_ZH.js";import o from"./index-CvNVT5L5.js";async function a(i){return o("/visitor/api/v1/init",{method:"POST",data:{...i,client:t}})}async function e(i){return o("/visitor/api/v1/browse",{method:"POST",data:{...i,client:t}})}export{e as browse,a as initVisitor};
import{T as t}from"./index-7uwhsjz9.js";import o from"./index-Chq1FiPg.js";async function a(i){return o("/visitor/api/v1/init",{method:"POST",data:{...i,client:t}})}async function e(i){return o("/visitor/api/v1/browse",{method:"POST",data:{...i,client:t}})}export{e as browse,a as initVisitor};

View File

@@ -1 +1 @@
import i from"./index-CvNVT5L5.js";import"./index-x2o9k_ZH.js";function e(t){return i({url:"/visitor/api/feedback/submit",method:"post",data:t})}export{e as submitFeedback};
import i from"./index-Chq1FiPg.js";import"./index-7uwhsjz9.js";function e(t){return i({url:"/visitor/api/feedback/submit",method:"post",data:t})}export{e as submitFeedback};

View File

@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><link rel="icon" type="image/x-icon" href="/agent/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title></title><script type="module" crossorigin src="/agent/agent/assets/js/index-x2o9k_ZH.js"></script><link rel="stylesheet" crossorigin href="/agent/agent/assets/css/index-DMeNvbmc.css"></head><body><div id="root"></div><script src="https://cdn.weiyuai.cn/agent/assets/js/0.3.5/sdk.js"></script><script src="https://cdn.weiyuai.cn/agent/assets/js/2.0.2/index.js" async></script></body></html>
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><link rel="icon" type="image/x-icon" href="/agent/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title></title><script type="module" crossorigin src="/agent/agent/assets/js/index-7uwhsjz9.js"></script><link rel="stylesheet" crossorigin href="/agent/agent/assets/css/index-DMeNvbmc.css"></head><body><div id="root"></div><script src="https://cdn.weiyuai.cn/agent/assets/js/0.3.5/sdk.js"></script><script src="https://cdn.weiyuai.cn/agent/assets/js/2.0.2/index.js" async></script></body></html>