如何在Watson Assistant网页聊天中使用控制IBM Carbon组件及对接iframe
Watson Assistant 开发问题实现方案
1. 对话回复中使用IBM Carbon组件并实现控制
首先你需要使用Watson Assistant的自定义Web Chat集成,默认托管的聊天界面不支持自定义组件渲染,必须自行实现前端壳层嵌入WA的web chat实例。
具体实现流程:
- 在WA对话节点配置
user_defined类型的自定义响应,按照你的业务需求传入组件标识、配置参数、绑定的动作ID,示例响应结构如下:{ "response_type": "user_defined", "component_type": "carbon-select", "component_config": { "label": "请选择选项", "options": ["选项A", "选项B", "选项C"] }, "bind_action": "select_option_submit" } - 前端初始化WA实例后,监听
pre:receive事件,拦截到user_defined类型的响应时阻止默认渲染逻辑,拿到当前对话气泡的DOM容器,将对应Carbon组件渲染到容器内 - 组件的状态控制逻辑直接在前端实现,你可以自行绑定Carbon组件的交互事件,比如选择、点击、输入事件触发时,调用WA实例的
send()方法将用户操作数据回传给对话流,也可以直接在前端修改组件的显隐、禁用等状态,不需要依赖WA后端响应
代码示例:
const waInstance = await window.watsonAssistantChatClient.init({ integrationID: "你的集成ID", region: "你的服务区域", serviceInstanceID: "你的服务实例ID" }); waInstance.on({ type: 'pre:receive', handler: (event) => { const response = event.data.message.output.generic?.[0]; if (!response || response.response_type !== 'user_defined') return; // 阻止默认渲染 event.preventDefault(); const messageContainer = event.data.element; // 渲染对应Carbon组件 if (response.component_type === 'carbon-select') { // 初始化Carbon Select组件,这里以原生Carbon Web Components为例 const select = document.createElement('cds-select'); select.labelText = response.component_config.label; response.component_config.options.forEach(opt => { const selectItem = document.createElement('cds-select-item'); selectItem.value = opt; selectItem.textContent = opt; select.appendChild(selectItem); }); // 绑定选择事件,回传数据到WA select.addEventListener('change', (e) => { waInstance.send({ input: { text: e.target.value }, context: { trigger_action: response.bind_action } }); }); messageContainer.appendChild(select); } } }); await waInstance.render();
2. 内嵌iframe对接,交互触发对话流指定动作
核心通过父子页面的postMessage通信实现,具体流程:
- 首先确认你的iframe与WA所在的父页面满足跨域通信要求:如果是跨域部署,需要在iframe的服务端配置
X-Frame-Options允许父页域名嵌入,同时配置Content-Security-Policy放开父页域名的通信权限 - iframe侧在用户完成指定交互时,调用
postMessage方法将交互事件通知到父页,示例代码:// iframe内代码 const triggerWAAction = (actionId, payload) => { window.parent.postMessage({ type: 'WA_TRIGGER_ACTION', action_id: actionId, payload: payload }, '你的父页部署域名'); } // 比如用户点击iframe内的提交按钮时触发 document.querySelector('#submit-btn').addEventListener('click', () => { triggerWAAction('submit_form_success', { formData: { name: '张三', phone: '13xxxxxxxxx' } }); }); - 父页侧注册消息监听事件,校验消息来源安全后,调用WA实例的方法触发对应对话动作:
// 父页内代码 window.addEventListener('message', (event) => { // 校验消息来源,避免恶意请求 if (event.origin !== '你的iframe部署域名') return; if (event.data.type !== 'WA_TRIGGER_ACTION') return; // 调用WA接口触发指定动作 waInstance.send({ input: { // 可以传空文本,直接通过上下文匹配对话节点 text: '', context: { trigger_action: event.data.action_id, action_payload: event.data.payload } } }); });
注意:需要提前在WA的对话技能里配置对应动作的触发条件,比如当上下文变量
trigger_action等于你设置的动作ID时,直接进入指定对话节点返回对应响应即可。
内容的提问来源于stack exchange,提问作者Nourhan Hassan
相关产品推荐
相关产品推荐

