Agentspace 聊天组件
一、AgentSpace 聊天组件概述
简介:
AgentSpace 聊天组件 是一个基于 React 开发的智能助手聊天组件,提供完整的对话交互能力。通过 OpenSDK 体系对外开放,第三方可以快速集成到自己的业务系统中。
核心特性
- ✅ 完整对话能力:支持文本对话、流式输出、打字机效果
- ✅ 会话管理:新建对话、历史会话、会话切换
- ✅ 知识库上传:支持对话携带知识库
- ✅ 富文本渲染:Markdown、代码高亮、数学公式、Mermaid 图表
- ✅ 主题切换:支持明暗主题(light/dark)
- ✅ 国际化:支持中文简体、繁体、英文
- ✅ 事件监听:完整的生命周期事件通知
- ✅ 自定义扩展:支持自定义按钮、样式等
效果演示:


二、开发必读
前置准备
准备好 AgentSpace 的
agentId(应用AK)去 AgentSpace 创建一个应用

完成 365API权限相关配置
详见 鉴权流程说明
在agentspace平台申请相关聊天对话组件需要的scope
1.agentspace_chat需要申请的权限:
功能名称 scope 业务域: Agentspace智能问答组件 kso.component.agentspace_chat 开放组件 智能体会话管理 kso.devhub_session.readwrite 智能体管理 智能体对话管理 kso.devhub_chat.readwrite 智能体管理 智能体应用管理 kso.devhub_app.readwrite 智能体管理 查询和管理知识库 kso.wiki.readwrite 知识库 

2、配置您的可信域名

去开放平台获取该应用的AK 和Sk
访问 https://365.kdocs.cn/3rd/open/developer/manager/{your-agentId}}/app-info

授权回调地址
需要
用户授权的开放组件,需要配置OAuth2回调地址- 对接用户授权对接流程: 鉴权流程说明

发布版本
返回agentspace 你创建的应用 发布一个版本

三、快速开始
如果想要更加便捷的配置 直接查看 完整示例
3.1 引入 OpenSDK
3.1.1引入SDK介绍
您可以直接下载opensdK到您自己的项目 或者直接引入在线CDN
OpenSDK地址:https://qn.cache.wpscdn.cn/open_static/libs/open-sdk/0.0.1/open-sdk.0.0.1.umd.js
agent_chat地址:https://qn.cache.wpscdn.cn/open_static/libs/widgets/agentspace_chat/1.0.2/kso.component.agentspace_chat.1.0.2.umd.js
3.1.2在 HTML 页面中引入 OpenSDK以及agentspace聊天组件:
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AgentSpace Chat SDK Demo</title>
<style>
body {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #f7f8f9 !important;
}
#agentspace-container {
height: 100vh;
width: 100vw;
}
</style>
</head>
<body>
<div id="root" class="height-100vh width-100vw">
<div id="agentspace-container" class="height-100vh width-100vw"></div>
</div>
//引入opensdk以及 agentspace_chat
<script src="https://qn.cache.wpscdn.cn/open_static/libs/open-sdk/0.0.1/open-sdk.0.0.1.umd.js"></script>
<script src="https://qn.cache.wpscdn.cn/open_static/libs/widgets/agentspace_chat/1.0.2/kso.component.agentspace_chat.1.0.2.umd.js"></script>
<script>
// 业务方逻辑
</script>
</body>
</html>3.2 鉴权配置
在创建组件实例前,需要先完成 授权配置:
javascript
// 定义所需的权限范围
const defaultScopes = [
'kso.devhub_app.readwrite', //智能体应用查询和创建
'kso.wiki.readwrite', //知识库获取权限
'kso.component.agentspace_chat', // AgentSpace 聊天组件权限(必需)
'kso.devhub_chat.readwrite', // DevHub 聊天读写权限
'kso.devhub_session.readwrite' // DevHub 会话读写权限
];
// 从 localStorage 获取已保存的权限,或使用默认值
const savedScopes = localStorage.getItem('merged_scopes');
let scopes = savedScopes ? JSON.parse(savedScopes) : defaultScopes;
// OAuth2 授权函数
async function authorize(scopes) {
OpenSDK.OAuth2.authorize({
appId: 'YOUR_APP_ID', // 必填:您的应用 ID
redirect_uri: 'https://agentspace.wps.cn/sdk-callback', // 必填:回调地址(需要在应用配置中设置)
scope: scopes.join(','), // 必填:权限范围,用逗号分隔
mode: OpenSDK.OAuth2.Mode.POPUP, // 必填:授权模式(POPUP 或 REDIRECT)
state: 'agent-space-chat', // 可选:自定义状态参数
});
}3.3 完整的初始化流程
javascript
let hasRender = false;
const host = 'http://127.0.0.1:3000'; // 您的后端服务地址
async function startApp() {
if (hasRender) return;
OpenSDK.setDebug(true); // 开启调试模式(生产环境请关闭)
// 检查缓存的配置是否过期(2小时有效期)
const app_config = localStorage.getItem('app_config');
if (app_config) {
const {
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token,
app_config_timestamp
} = JSON.parse(app_config);
// 检查是否在有效期内(2小时 = 7200000 毫秒)
if (Date.now() - app_config_timestamp < 7200000) {
// 使用缓存的配置
await OpenSDK.config({
scopes,
signature,
appId: app_id,
timestamp,
nonceStr: noncestr,
tag,
url,
});
// 等待组件加载完成后渲染
const timer = setInterval(() => {
renderWidget(app_access_token);
if (hasRender) {
clearInterval(timer);
}
}, 1000);
return;
} else {
// 配置已过期,清除缓存
localStorage.removeItem('app_config');
}
}
// 无缓存或缓存过期,开始 OAuth2 授权流程
console.log('[授权流程] 开始授权');
authorize(scopes);
// 监听 OAuth2 授权回调消息
OpenSDK.addEventListener(OpenSDK.Events.OAuth2Message, async (event) => {
// 安全检查:验证消息来源
if (event.origin !== 'https://agentspace.wps.cn') return;
const code = event.data.code;
console.log('OAuth2Message code', code);
if (!code) {
authorize(scopes);
return;
}
// 步骤一:使用 auth_code 从您的后端获取 app_access_token 和签名信息
const {
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token
} = await fetch(`${host}/api/get_app_config?code=${code}`)
.then(async (res) => {
const resp = await res.json();
if (resp?.code === 0) {
return resp.data || {};
} else {
throw new Error('获取signature失败');
}
});
// 步骤二:缓存配置信息(2小时有效期)
localStorage.setItem('app_config', JSON.stringify({
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token,
app_config_timestamp: Date.now()
}));
// 步骤三:配置 OpenSDK
await OpenSDK.config({
scopes,
signature, // 签名(来自您的后端)
appId: app_id, // 应用 ID
timestamp, // 时间戳(秒)
nonceStr: noncestr, // 随机字符串
tag, // ticket 标签
url, // 当前页面 URL(不含 query 和 hash)
});
// 步骤四:等待组件注册完成后渲染
function tryRenderWidget() {
if (hasRender) {
console.log('[渲染组件] 组件已渲染,停止尝试');
return;
}
if (OpenSDK && OpenSDK.components && OpenSDK.components.size > 0) {
console.log('[渲染组件] OpenSDK 组件已加载,开始渲染');
renderWidget(app_access_token);
} else {
console.log('[渲染组件] 等待 OpenSDK 组件加载...');
setTimeout(tryRenderWidget, 100); // 100ms 后重试
}
}
tryRenderWidget();
});
}
// 页面加载完成后初始化
startApp();3.4 创建组件实例
javascript
async function renderWidget(app_access_token) {
// 检查组件是否已注册
if (OpenSDK.components.size === 0) return;
// 创建 AgentSpace 聊天组件实例
const agentspaceChat = OpenSDK.create('kso-agentspace-chat', {
agentId: 'YOUR_AGENT_ID', // 必填:智能助手 ID
scopes: scopes, // 必填:权限范围数组
theme: 'light', // 可选:主题(light/dark)
locale: 'zh-CN', // 可选:语言(zh-CN/zh-TW/en)
welcomeMessage: '您好!我是您的智能助手,有什么可以帮助您的吗?',
placeholder: '请输入您的问题...',
});
// 将组件挂载到 DOM 节点
agentspaceChat.mount(document.getElementById('agentspace-container'));
hasRender = true;
// 设置事件监听(见下一节)
setupEventListeners(agentspaceChat);
}3.5 监听事件
javascript
function setupEventListeners(agentspaceChat) {
// 监听权限不足,需要二次授权的事件(重要)
agentspaceChat.addEventListener(agentspaceChat.Events.OnAuthRequest, async (e) => {
console.log('[第三方监听] OnAuthRequest: 需要额外权限', e);
// 合并新的权限范围
const missingScopes = e.scopes || [];
const mergedScopes = [...new Set([...scopes, ...missingScopes])];
scopes = mergedScopes;
// 保存合并后的权限
localStorage.setItem('merged_scopes', JSON.stringify(mergedScopes));
// 清除缓存的配置,强制重新授权
localStorage.removeItem('app_config');
// 显示授权提示 UI(自定义实现)
showAuthPrompt(missingScopes, mergedScopes);
});
}3.6 自定义授权提示ui
js
// 显示授权提示 UI(不使用 window.confirm,避免被浏览器拦截)
function showAuthPrompt(missingScopes, mergedScopes) {
// 创建提示框
const promptBox = document.createElement('div');
promptBox.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
z-index: 99999;
min-width: 300px;
`;
// 设置内容
promptBox.innerHTML = `
<div style="margin-bottom: 15px;">
<strong>需要新增权限</strong>
</div>
<div style="margin-bottom: 15px; font-size: 14px; color: #666;">
缺失权限:${missingScopes.join(', ')}
</div>
<div style="text-align: right;">
<button id="auth-cancel-btn" style="margin-right: 10px; padding: 6px 15px; cursor: pointer;">取消</button>
<button id="auth-confirm-btn" style="padding: 6px 15px; background: #1890ff; color: white; border: none; cursor: pointer;">授权</button>
</div>
`;
document.body.appendChild(promptBox);
// 确认按钮事件
document.getElementById('auth-confirm-btn').onclick = () => {
console.log('[授权提示] 用户点击授权');
document.body.removeChild(promptBox);
authorize(mergedScopes); // 重新发起授权
};
// 取消按钮事件
document.getElementById('auth-cancel-btn').onclick = () => {
console.log('[授权提示] 用户取消');
document.body.removeChild(promptBox);
};
}3.7 动态更新配置
javascript
agentspaceChat.update({
theme: 'dark',
welcomeMessage: '配置已更新!我是您的智能助手,有什么可以帮助您的吗?',
locale: 'en',
placeholder: 'Please enter your question...',
});3.8 卸载组件
javascript
agentspaceChat.unmount();3.9后端api 接口示例
js
export async function getAccessToken(data: {
code: string;
agent_ak: string;
agent_sk: string;
}): Promise<IResponse<any>> {
if (!data.code) {
return {
code: 1,
message: 'code is required',
data: {},
};
}
const userResp = await openApi.post<any, any>(
'/oauth2/token',
{
grant_type: 'authorization_code',
client_id: data.agent_ak,
client_secret: data.agent_sk,
code: data.code,
redirect_uri: 'https://agentspace.wps.cn/sdk-callback',
},
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
}
);
console.log('用户授权结果:', userResp);
if (userResp?.access_token) {
return {
code: 0,
data: {
user_token: userResp.access_token,
user_auth: userResp,
},
};
}
return {
code: 1,
message: 'user authorization failed',
data: {},
};
}
export async function getJSAPITicket(
access_token: string
): Promise<IResponse<any>> {
const resp = await openApi.get('/oauth2/jsapi_ticket', {
headers: {
Authorization: `bearer ${access_token}`,
},
});
return {
code: 0,
data: {
...(resp || {}),
},
};
}js
const index: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
// 步骤1:用户授权,code 换 access_token, access_token 禁止返回前端保存
// 开发者自行实现OAuth2授权,获取并维护access_token
// 开发文档:https://365.kdocs.cn/3rd/open/documents/app-integration-dev/wps365/server/certification-authorization/user-authorization/flow.html
// 步骤2:业务方接口,获取用户信息,app,signature等
fastify.get('/get_app_config', async function (request, reply) {
// 此处简化获取access_token,js_ticket逻辑
const { code = '' } = (request.query as { code: string }) || {};
let user_access_token = '';
const resp = await getAccessToken({
code,
agent_ak: config.agent_ak,
agent_sk: config.agent_sk,
});
if (resp?.code === 0) {
user_access_token = resp?.data?.user_token || '';
if (!user_access_token) {
return reply
.status(400)
.send({ code: 400, message: '获取access_token失败' });
}
} else {
return reply
.status(400)
.send({ code: 400, message: '获取access_token失败' });
}
console.log('授权信息', {
user_access_token,
full_response: resp,
});
let jsapi_ticket = {
ticket: '',
tag: '',
};
if (!jsapi_ticket.ticket) {
const ticketResp: any = await getJSAPITicket(user_access_token);
console.log('js_ticket', ticketResp);
if (ticketResp?.code === 0) {
jsapi_ticket = ticketResp.data;
} else {
return reply
.status(400)
.send({ code: 400, message: '获取jsapi_ticket失败' });
}
}
// 请求页面的url,不包含query,search
const url = `http://${request.headers.host}`;
console.log('url', url);
const noncestr = Math.random().toString(36).substring(2, 15);
const timestamp = (Date.now() / 1e3) | 0;
console.log('timestamp', timestamp);
const signature = genSignature(
jsapi_ticket.ticket,
noncestr,
timestamp,
url
);
return MakeSuccess({
app_id: config.agent_ak,
signature,
noncestr,
timestamp,
tag: jsapi_ticket?.tag,
url,
});
});
};四、事件监听
4.1 支持的事件类型
| 事件名称 | 说明 | 事件数据 | 回调参数 |
|---|---|---|---|
| Updated | 组件配置更新时触发 | info: 更新信息描述,如 "AgentSpace组件刷新完成" | |
| OnChatStart | 对话开始时触发 | message: 用户发送的消息对象(包含 id、text、sender、timestamp 等字段) | |
| OnChatEnd | 对话结束时触发 | {} | 无参数(空对象) |
| OnError | 发生错误时触发 | { error: Error | any } | error: 错误对象或错误信息 |
| OnMessageSend | 用户发送消息时触发 | message: 发送的消息对象(包含消息内容、发送者等信息) | |
| OnMessageReceive | 接收到 AI 回复时触发 | message: 接收的消息对象(可能包含 content_blocks、wps_tools 等富内容) | |
| OnSelected | 用户进行选择操作时触发 | any | 选择的内容(根据具体场景而定) |
| OnAuthRequest | 需要额外权限时触发(用于二次授权) | AuthRequestEvent | scopes: 缺失的权限数组 allRequiredScopes: 所有必需权限数组 mergedScopes: 合并后的权限数组 missingScopes: 明确缺失的权限数组 |
4.2 事件监听示例
javascript
// 1. Updated 事件
agentspaceChat.addEventListener(agentspaceChat.Events.Updated, (e) => {
console.log('[Updated]', e.info); // "AgentSpace组件刷新完成"
});
// 2. OnChatStart 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnChatStart, (e) => {
console.log('[OnChatStart]', e.message.text);
});
// 3. OnChatEnd 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnChatEnd, (e) => {
console.log('[OnChatEnd] 对话结束');
});
// 4. OnError 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnError, (e) => {
console.error('[OnError]', e.error);
});
// 5. OnMessageSend 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnMessageSend, (e) => {
console.log('[OnMessageSend]', e.message.text, e.message.sender);
});
// 6. OnMessageReceive 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnMessageReceive, (e) => {
console.log('[OnMessageReceive]', e.message.text);
// 处理富内容
if (e.message.content_blocks) {
e.message.content_blocks.forEach(block => {
console.log('内容块:', block.title);
});
}
});
// 7. OnSelected 事件
agentspaceChat.addEventListener(agentspaceChat.Events.OnSelected, (e) => {
console.log('[OnSelected]', e);
});
// 8. OnAuthRequest 事件(重要)
agentspaceChat.addEventListener(agentspaceChat.Events.OnAuthRequest, (e) => {
console.log('[OnAuthRequest] 缺失权限:', e.missingScopes);
console.log('[OnAuthRequest] 所有必需权限:', e.allRequiredScopes);
console.log('[OnAuthRequest] 合并后权限:', e.mergedScopes);
// 保存合并后的权限
localStorage.setItem('merged_scopes', JSON.stringify(e.mergedScopes));
localStorage.removeItem('app_config');
// 显示授权提示并重新授权
showAuthPrompt(e.missingScopes, e.mergedScopes);
});4.3 移除事件监听
javascript
// 定义事件处理函数
const handleChatStart = (event) => {
console.log('对话开始:', event);
};
// 添加监听
agentspaceChat.addEventListener(agentspaceChat.Events.OnChatStart, handleChatStart);
// 移除监听
agentspaceChat.removeEventListener(agentspaceChat.Events.OnChatStart, handleChatStart);五、完整使用示例
1.index.html
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AgentSpace Chat SDK Demo</title>
<style>
body {
width: 100vw;
height: 100vh;
overflow: hidden;
background-color: #f7f8f9 !important;
}
#agentspace-container{
height: 100vh;
width: 100vw;
}
</style>
</head>
<body>
<div id="root" class="height-100vh width-100vw">
<div id="agentspace-container" class="height-100vh width-100vw"></div>
</div>
<script src="https://qn.cache.wpscdn.cn/open_static/libs/open-sdk/0.0.1/open-sdk.0.0.1.umd.js"></script>
<script src="https://qn.cache.wpscdn.cn/open_static/libs/widgets/agentspace_chat/1.0.2/kso.component.agentspace_chat.1.0.2.umd.js"></script>
<!-- 授权弹框辅助函数【此处模拟业务方的实现】 -->
<script src="./demo/chat-demo/auth-popup-helpers.js"></script>
<script>
// 初始化弹窗检测器
initPopupBlockDetector();
</script>
<!-- 配置文件 -->
<script src="./demo/chat-demo/config.js"></script>
<!-- 授权逻辑 -->
<script src="./demo/chat-demo/auth.js"></script>
<!-- 主应用逻辑 -->
<script src="./demo/chat-demo/app.js"></script>
<!-- 启动应用 -->
<script>
startApp()
</script>
</body>
</html>2.config.js
js
/**
* 配置文件
*/
// biz-server 第三方服务地址 ,您需要替换为您的服务地址
const host = 'http://127.0.0.1:3000';
// 默认权限范围,您需要配置您需要的权限
const defaultScopes = [
// 'kso.file.readwrite',
// 'kso.file_search.readwrite',
// 'kso.file_permission.readwrite',
'kso.component.agentspace_chat',
'kso.devhub_chat.readwrite',
'kso.devhub_session.readwrite',
'kso.devhub_app.readwrite',
'kso.wiki.readwrite',
];
// OAuth2 配置,您需要配置您的appid 以及state
const oauthConfig = {
appId: 'AK20251111RJYVZA',
redirect_uri: 'https://agentspace.wps.cn/sdk-callback',
state: 'agent-space-chat',
};
// Agent 配置,您需要配置您的agentspace的agentid
const agentConfig = {
agentId: 'AK20251110EGNSHO',
};3.auth.js
js
/**
* 授权相关函数
*/
// 发起授权
async function authorize(scopes) {
// 用户授权演示
// 以下信息,建议从业务服务端返回给前端
OpenSDK.OAuth2.authorize({
appId: oauthConfig.appId,
redirect_uri: oauthConfig.redirect_uri,
scope: scopes.join(','),
mode: OpenSDK.OAuth2.Mode.POPUP,
state: oauthConfig.state,
});
}
// 暴露给全局
window.authorize = authorize;4.app.js
js
/**
* 主应用逻辑
*/
let hasRender = false;
// localStorage.scopes || 使用默认值
const savedScopes = localStorage.getItem('merged_scopes');
let scopes = savedScopes ? JSON.parse(savedScopes) : defaultScopes;
async function startApp() {
if (hasRender) return;
OpenSDK.setDebug(true);
// 检查app_config是否过期
const app_config = localStorage.getItem('app_config');
if (app_config) {
const {
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token,
app_config_timestamp,
} = JSON.parse(app_config);
console.log('app_config_timestamp', Date.now() - app_config_timestamp);
if (Date.now() - app_config_timestamp < 7200000) {
OpenSDK.config({
scopes,
signature,
appId: app_id,
timestamp,
nonceStr: noncestr,
tag,
url,
});
// 创建定时器不断尝试加载组件
const timer = setInterval(() => {
renderWidget(app_access_token);
if (hasRender) {
clearInterval(timer);
}
}, 1000);
return;
} else {
localStorage.removeItem('app_config');
// 缓存过期,重新开始授权流程
// console.log('[授权流程] app_config 缓存已过期,重新授权')
window.location.reload();
}
}
// 无缓存或缓存过期,开始授权
console.log('[授权流程] 开始授权');
authorize(scopes);
OpenSDK.addEventListener(OpenSDK.Events.OAuth2Message, async (event) => {
// 安全起见,判断来源
if (event.origin !== 'https://agentspace.wps.cn') return;
const code = event.data.code;
console.log('OAuth2Message code', code);
// 步骤一:拿到临时授权码code,提交给服务端申请access_token
// 应用授权,无需走OAuth授权流程,直接申请access_token
// 用户授权,走OAuth授权流程,获取auth_code,然后申请access_token
if (!code) {
authorize(scopes);
return;
}
// 步骤二:获取biz-server 申请的js_ticket相关签名信息
const {
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token,
} = await fetch(`${host}/api/get_app_config?code=${code}`).then(
async (res) => {
const resp = await res.json();
if (resp?.code === 0) {
return resp.data || {};
} else {
throw new Error('获取signature失败');
}
}
);
// 将获取的信息缓存存储,两个小时后过期
localStorage.setItem(
'app_config',
JSON.stringify({
app_id,
signature,
noncestr,
timestamp,
tag,
url,
app_access_token,
app_config_timestamp: Date.now(),
})
);
// 步骤三:OpenSDK设置签名信息
await OpenSDK.config({
scopes,
signature, // 签名
appId: app_id, // 应用 appId
timestamp, // 时间戳(毫秒)
nonceStr: noncestr, // 随机字符串
tag,
url,
});
// 步骤四:渲染组件
// 使用递归 setTimeout 代替 setInterval
function tryRenderWidget() {
if (hasRender) {
console.log('[渲染组件] 组件已渲染,停止尝试');
return;
}
if (OpenSDK && OpenSDK.components && OpenSDK.components.size > 0) {
console.log('[渲染组件] OpenSDK 组件已加载,开始渲染');
renderWidget(app_access_token);
} else {
console.log('[渲染组件] 等待 OpenSDK 组件加载...');
setTimeout(tryRenderWidget, 100); // 100ms 后重试
}
}
tryRenderWidget();
});
}
async function renderWidget(app_access_token) {
if (OpenSDK.components.size === 0) return;
const agentspaceChat = OpenSDK.create('kso-agentspace-chat', {
agentId: agentConfig.agentId,
appAccessToken: app_access_token,
});
agentspaceChat.mount(document.getElementById('agentspace-container'));
hasRender = true;
// 第三方开发者监听事件
agentspaceChat.addEventListener(agentspaceChat.Events.Updated, (e) => {
console.log('[3rd] Updated:', e);
});
agentspaceChat.addEventListener(agentspaceChat.Events.OnSelected, (e) => {
console.log('[3rd] OnSelected:', e);
});
// 监听scopes范围不够,二次授权
agentspaceChat.addEventListener(
agentspaceChat.Events.OnAuthRequest,
async (e) => {
const detailScopeUser = e.detailScopeUser || []; // detail接口返回的所有required scopes
console.log(
'[业务方 addEventListener] detailScopeUser:',
detailScopeUser
);
// 使用本地配置的scopes进行对比,判断缺失的scopes
const missingScopes = detailScopeUser.filter(
(scope) => !scopes.includes(scope)
);
// 如果没有缺失的权限,无需重新授权
if (missingScopes.length === 0) {
console.log('[业务方 addEventListener] 权限验证通过,无需重新授权');
return;
}
// 合并 scopes
const mergedScopes = [...new Set([...scopes, ...missingScopes])];
scopes = mergedScopes;
// 保存合并后的scopes
localStorage.setItem('merged_scopes', JSON.stringify(mergedScopes));
// 清除缓存的 app_config,强制重新获取新的授权信息
localStorage.removeItem('app_config');
console.log('[业务方 addEventListener] 合并后的scopes:', mergedScopes);
// 显示自定义授权提示 UI(不使用 window.confirm)
showAuthPrompt(
missingScopes,
mergedScopes,
// 确认授权回调
(mergedScopes) => authorize(mergedScopes),
// 取消授权回调
() => {
console.log('[业务方 addEventListener] 用户取消授权');
}
);
}
);
}