diff --git a/package.json b/package.json index 6612414..4870d24 100644 --- a/package.json +++ b/package.json @@ -12,25 +12,25 @@ "dependencies": { "@dckj/react-better-modal": "^0.1.2", "@lexical/react": "^0.20.0", - "@vonage/client-sdk": "^1.7.2", + "@vonage/client-sdk": "^2.0.0", "antd": "^5.22.2", "dayjs": "^1.11.13", "dingtalk-jsapi": "^3.0.41", "emoji-picker-react": "^4.12.0", "lexical": "^0.20.0", "react": "^18.3.1", + "react-chat-elements": "^12.0.17", "react-dom": "^18.3.1", "react-router-dom": "^6.28.0", - "zustand": "^4.5.5", - "react-chat-elements": "^12.0.17", "rxjs": "^7.8.1", - "uuid": "^9.0.1" + "uuid": "^9.0.1", + "zustand": "^4.5.5" }, "devDependencies": { "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@vitejs/plugin-react": "^4.3.3", - "@vonage/client-sdk": "^1.7.2", + "@vonage/client-sdk": "^2.0.0", "autoprefixer": "^10.4.20", "eslint": "^8.45.0", "eslint-plugin-react": "^7.37.2", diff --git a/src/stores/CallCenterStore.js b/src/stores/CallCenterStore.js index 19a33e1..67cf00b 100644 --- a/src/stores/CallCenterStore.js +++ b/src/stores/CallCenterStore.js @@ -6,7 +6,10 @@ import { VONAGE_URL, DATETIME_FORMAT } from "@/config"; import dayjs from "dayjs"; const callCenterStore = create((set, get) => ({ - client: new VonageClient({ apiUrl: "https://api-ap-3.vonage.com", websocketUrl: "wss://ws-ap-3.vonage.com" }), + client: new VonageClient({ + // region: "AP", + // apiUrl: "https://api-ap-3.vonage.com", websocketUrl: "wss://ws-ap-3.vonage.com" + }), call_id: 0, loading: false, logs: "", @@ -18,8 +21,9 @@ const callCenterStore = create((set, get) => ({ const fetchUrl = prepareUrl(VONAGE_URL + "/jwt") .append("user_id", user_id) .build(); - return fetchJSON(fetchUrl).then(json => { - if (json.status === 200) { + return fetchJSON(fetchUrl).then(res => { + const json = res.result; + if (json?.status === 200) { let jwt = json.token; client diff --git a/vonage-server/README.md b/vonage-server/README.md index bcded1a..d014125 100644 --- a/vonage-server/README.md +++ b/vonage-server/README.md @@ -1 +1,25 @@ -vonage的服务端,用于生成jwt和应答语音视频请求 \ No newline at end of file +vonage的服务端,用于生成jwt和应答语音视频请求 + +```sh +> vonage users create --display-name Highlights +✅ Creating User + +User ID: USR-a778518f-6d94-43b8-ab3c-413e6af8f10a +Name: NAM-3f97db93-da89-4937-b457-14be72b7b62b +Display Name: Highlights +Image URL: Not Set +Time to Live: Not Set + +Channels: + None Set +> vonage users list +✅ Fetching users + +User ID Name Display Name +---------------------------------------- ---------------------------------------- ------------ +USR-4476dbcc-8e2a-4048-ac8a-8ab49345167a HighlightsTravel +USR-a778518f-6d94-43b8-ab3c-413e6af8f10a NAM-3f97db93-da89-4937-b457-14be72b7b62b +USR-9f60dff4-78c3-40c8-9aad-f762df371728 NAM-c54db270-643a-43a6-883e-b8c28d292dbe + +Done Listing users +``` diff --git a/vonage-server/index.js b/vonage-server/index.js index f254987..c456fc6 100644 --- a/vonage-server/index.js +++ b/vonage-server/index.js @@ -3,7 +3,7 @@ const express = require("express"); const fs = require("fs"); const { tokenGenerate } = require("@vonage/jwt"); -const privateKey = fs.readFileSync("gh-private.key"); +const privateKey = fs.readFileSync("private20250417.key"); const aclPaths = { paths: { "/*/rtc/**": {}, @@ -21,7 +21,19 @@ const aclPaths = { const app = express(); app.use(express.json()); -const vonageNumber = "12052553394"; //用于通话的号码,今后根据前端提交来做号码切换 +const app_id = '503c548f-cb61-4a3a-8599-cd815680b390'; +const api_key = '197c68c9'; +const api_secret = 'Aa11be17f298dfd4118bdf23'; +const vonageNumber = "12019751815"; //用于通话的号码,今后根据前端提交来做号码切换 +const vonageUser = "HighlightsTravel"; // user name + +const response = (data) => { + return { + errcode: 0, + errmsg: '', + result: data, + } +} //设置跨域访问 app.all("*", function (req, res, next) { @@ -36,7 +48,7 @@ app.get("/voice/answer", (req, res) => { console.log("NCCO request:"); console.log(` - callee: ${req.query.to}`); console.log("---"); - res.json([ + const result = [ { action: "talk", text: "Please wait while we connect you.", @@ -50,24 +62,23 @@ app.get("/voice/answer", (req, res) => { from: vonageNumber, endpoint: [{ type: "phone", number: req.query.to }], }, - ]); + ]; + res.json(result); }); app.get("/jwt", (req, res) => { console.log("jwt Generate:"); const exp_time = new Date(Date.now() + 3 * 24 * 3600 * 1000); - const token = tokenGenerate("39f32a2a-e343-4ca0-9d92-5946573af5ea", privateKey, { + const token = tokenGenerate(app_id, privateKey, { exp: Math.round(exp_time.getTime() / 1000), - sub: "hainatravel", + sub: vonageUser, acl: aclPaths, }); console.log(Math.round(exp_time.getTime() / 1000)); - console.log(token); + console.log(token.substring(0, 5)); console.log("---"); - res.json({ - token: token, - status: 200, - }); + const result = response({ token, status: 200}); + res.json(result); }); app.all("/voice/event", (req, res) => { diff --git a/vonage-server/private20250417.key b/vonage-server/private20250417.key new file mode 100644 index 0000000..1e1af70 --- /dev/null +++ b/vonage-server/private20250417.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCXaDD9rLbsAWpr +r0Nz3vc04Q/w9WgSsmLW8fg08+4V604QQUwbyXYPQACIzNguEB5ggbvbyxL7j5Bf ++bXW6HCu5Gxw0+ciMyhaymR7aGrbzIWOP8abTQnb6+ljZWeCvD+R8Ow6xJrhTACJ +X48IrLPDN3kqFQWVjm0vV9GiviPF4ifDCmNW+78oPrEo5YHKwyoYrGBkr6pKMiER +m9pSu++owv8XUV/hQVTkq20khlvRy35bwx2qmbGbE9BgQsS4KNri9jHOIB413sFg +p8zcvdKTxtje99M5iPHUKgF8WrzRHFqvKFRyg90p22twNAUnvgc3eiUoW2Qv+A78 +X9ZaaEQTAgMBAAECggEACEwzKyPfs9gcBKIf+JCxTETtV7pLUC2rPGEZxjp8GNgY +I3dApuEynCwDcNExI80fAmZPF6uYcxBEzE27c8yx/ZO9Ma3F+VouYv4ROwYs8mDS +DPVdJWkNGkVijrT2/Z44KapiIpJgc+pzY76d8Hluh0tZ/j7ABe3pTp0/JZkgDW8o +Q92TObC/cN5ZguIpNWlW2lQhKiJkwkcLFpxzm5QhStiQaahjWJBye6tvc9M3CSxm +69e9pPW0ZBTW6wyIU6OQHzfnT6+bwo3kbmV2Svx3OHL1yiJV1p4rbuH3XJKQ6d2O +zh2mew7zqXOuMggLotevDJXmRcrgmo4kxoxW6BKMuQKBgQDHkxlapdGuH1rZwPZj +KcQvy29Z0xRP5wbUlTRkthHPXUeUonZTeKfw/oSfz81rHV2z046Bp7tE5qshzLiS +RMl9U68t36t+i3vNiUFNtNT4Uu9w4KL2dwi0onBauc9m2xNSR0YHJlWTHkgauQaq +XoV/rQca6nBagXxQ9qeoJr4m1wKBgQDCNsuhm53503i74HYoVEOM3noAuqVW3usl +4QHsQsGuItFC5/sTLudvJv6wTZItDEf15eLqge3j6tjxG8+2RoYiCTSKdW848fLi +PUkIyCfMYmA3L7eIwJmDwPxG80E4tQWKPyENvXSKNmNS+Cnu7fPl9mOJIqHncC6r +UowBID6xJQKBgQCe59sqOBmqQMD/3QrRjjHttFem99CWhmcD4QFkpyurJqSWDn2U +nN9rndxPuw/el/VB99LiHYGYrOnZ8b2MiUS9i2JSbmOIUNt0njLnAnMIflC0Wcin +4cOGwEghlQ004n6R5ro1eypsB5J15JkQEk7NiCG+JqjrB2rKtHpuAtso5QKBgDLs +azhUtXdsG5wnntO0RIILU7IdPn0otj+YYAiy+FXQi04fxZWiFszuTJmtvUZSkgvH +21fh+Z5pVbjisfP5SfJit4QWhrNHvYfUyfGjicvtf4z41gbleVsynvN7lP5peKpn +IyOXKZeT6zc2GsirW+hQUokCq7EjmRkS6+LfsZCBAoGBAMAfhVcSz73yDqTR6YR3 ++kzpm8+bEOBhUERxtidyvEdaF1255BoeDigFVgSophdk+tWdcIMFLmg8VkVD9FCa +3mVbmD6lNm1eJfUtsMQYja0x338PpSFmd6whBbWRb/8CUbyFJSP5wFlPe9G9qxN8 +6HrZzqr1ydp2MWMoKFYCiiQR +-----END PRIVATE KEY-----