CTICloud AgentSDK 集成到 OpenClaw
本文档说明如何借助 OpenClaw AI 助手,快速完成 CTICloud AgentSDK 的集成工作。
概述
关于 AgentSDK
CTICloud AgentSDK 是一个企业级无界面通话 SDK,提供以下能力:
- Operations:基于 Promise 风格的操作 API
- Events:通过 WebSocket 实时推送事件
- Softphone:基于 WebRTC 的语音通话能力
关于 OpenClaw
OpenClaw 是一个 AI 驱动的开发助手,可以:
- 快速理解技术文档
- 生成高质量业务代码
- 协助调试与排障
前置准备
环境要求
| 项目 | 要求 |
|---|---|
| 浏览器 | Chrome 80+ / Edge 80+ / Firefox 75+ |
| 协议 | HTTPS(软电话场景必需) |
| OpenClaw | 已部署并可访问 |
参数清单
请提前准备以下参数:
| 参数 | 说明 |
|---|---|
| Base URL | Agent Gateway 服务地址 |
| Tenant ID | 租户标识 |
| Agent No | 座席工号 |
| SessionKey | 登录凭证(由你的后端生成) |
| Endpoint Type | 终端类型:1=PSTN,2=分机,3=软电话 |
| Endpoint | 终端号码 |
集成步骤
步骤 1:提供 SDK 文档
将 AgentSDK 官方文档链接发送给 OpenClaw:
请阅读并记住以下文档:
https://docs.cticloud.cn/docs/product-integration-overview
https://docs.cticloud.cn/docs/quick-start
https://docs.cticloud.cn/docs/core-concepts-lifecycle
https://docs.cticloud.cn/docs/api-operations
https://docs.cticloud.cn/docs/types
https://docs.cticloud.cn/docs/error-handling
OpenClaw 会自动解析文档内容,并理解 SDK 的 API 结构与使用方式。
步骤 2:描述业务需求
2.1 需求描述方式
建议使用结构化描述,包含以下要素:
| 要素 | 说明 | 示例 |
|---|---|---|
| 功能清单 | 需要实现的核心能力 | 登录、外呼、转接 |
| 业务场景 | 使用场景描述 | 预览外呼 + 软电话 |
| 参数配置 | 已知配置参数 | tenantId、agentNo |
| 特殊要求 | 额外约束或偏好 | 深色主题、移动端适配 |
2.2 需求描述示例
基础描述:
请实现一个座席工作台页面,包含以下功能:
1. 登录/登出
2. 座席状态展示与切换
3. 预览外呼
4. 软电话接听/挂断
详细描述:
请实现一个座席工作台页面:
[功能需求]
- 登录:接收 sessionKey 参数
- 状态:展示当前座席状态,支持忙碌/空闲切换
- 外呼:预览外呼,支持输入客户号码
- 通话:软电话模式,支持接听、挂断、保持
- 转接:咨询转接、盲转、转 IVR
- 班长:监听、耳语、强插、代接
[UI 要求]
- 现代简洁风格
- 按 Tab 组织功能
- 通话面板居中展示
[参数配置]
- baseURL: https://agent-gateway.xxx.cn
- tenantId: 6000001
- endpointType: 3(软电话)
按模块描述:
请按模块实现座席工作台:
模块 1:登录模块
- 输入参数:tenantId、agentNo、sessionKey
- 展示当前状态
- 提供忙碌/空闲按钮
模块 2:外呼模块
- 输入框:客户号码
- 发起/取消外呼
- 展示外呼状态(拨号中/振铃中/已接通)
模块 3:通话模块
- 通话面板:展示号码、时长
- 操作按钮:接听、挂断、保持、静音
模块 4:班长模块
- 输入框:目标座席工号
- 操作:监听、耳语、强插、代接
2.3 描述技巧
| 技巧 | 说明 |
|---|---|
| 分层描述 | 先描述整体框架,再细化各模块 |
| 提供示例 | 给出参考界面或交互流程 |
| 明确约束 | 说明必须满足的业务规则 |
| 提供参数 | 给出明确配置值,减少来回沟通 |
步骤 3:审阅并调整代码
3.1 检查生成结果
OpenClaw 生成代码后,建议重点关注:
| 检查项 | 说明 |
|---|---|
| 功能完整性 | 是否覆盖了所有需求 |
| 参数正确性 | 配置参数是否正确 |
| 逻辑正确性 | 业务流程是否合理 |
| 代码规范 | 是否符合团队规范 |
3.2 提出调整要求
如果发现问题,可以直接向 OpenClaw 描述调整需求:
增加功能:
请增加以下功能:
- 增加满意度调查按钮
- 增加外呼客户振铃状态展示
修复 Bug:
客户挂断后,通话面板没有隐藏。请修复这个问题。
样式调整:
请调整 UI 样式:
- 使用深色主题
- 将通话按钮改为圆形
- 默认折叠日志面板
术语修正:
请修正术语:
- 将 "set busy" 改为 "mark busy"
- 将 "pickup" 改为 "intercept"
3.3 迭代优化
建议采用迭代方式逐步完善:
第 1 轮:生成基础框架
↓
第 2 轮:补充业务功能
↓
第 3 轮:优化 UI 样式
↓
第 4 轮:修复问题,打磨细节
3.4 验证与测试
代码完成后,建议验证:
| 验证项 | 方法 |
|---|---|
| 登录流程 | 使用有效的 sessionKey 测试 |
| 外呼流程 | 发起外呼,检查状态变化 |
| 事件接收 | 检查日志面板是否正常记录 |
| 异常处理 | 模拟网络断开等异常场景 |
核心代码示例
SDK 初始化
// 引入 SDK
<script src="https://your-cdn/agent-sdk.umd.js"></script>
// 获取 SDK 对象
const AgentSDK = window.AgentSDK.default || window.AgentSDK;
// 初始化配置
AgentSDK.setup({
baseURL: 'https://agent-gateway.example.com',
debug: false,
webrtc: true,
webrtcStats: false
});登录
async function login(sessionKey) {
const res = await AgentSDK.login({
tenantId: 'your-tenant-id',
agentNo: 'your-agent-no',
sessionKey: sessionKey,
bindEndpoint: {
endpointType: 3, // 3 = 软电话
endpoint: '1883'
},
initialStatus: 1 // 1 = 空闲
});
return res.code === 0;
}事件订阅
const { EventType } = AgentSDK;
// 座席状态
AgentSDK.on(EventType.AGENT_STATUS, (e) => {
console.log('状态:', e.status.state, e.status.stateAction);
});
// 外呼事件
AgentSDK.on(EventType.PREVIEW_OBCALL_RINGING, (e) => {
console.log('客户振铃中:', e.customerNumber);
});
AgentSDK.on(EventType.PREVIEW_OBCALL_BRIDGE, (e) => {
console.log('已接通');
});
// 重连通知
AgentSDK.on(EventType.RECONNECT_ATTEMPT, (e) => {
console.log('重连中:', e.attempt, '/', e.maxAttempts);
});外呼与通话控制
// 发起外呼
await AgentSDK.previewObCall({
customerNumber: '13800138000',
agentAnswerTimeout: 30,
customerAnswerTimeout: 45
});
// 接听(软电话)
await AgentSDK.sipLink();
// 挂断
await AgentSDK.sipUnlink();
// 保持
await AgentSDK.hold();状态控制
// 置忙
await AgentSDK.pause({
pauseType: 1,
pauseDescription: 'MEETING'
});
// 置闲
await AgentSDK.unpause();API 参考
核心操作
| 操作 | 说明 |
|---|---|
setup(config) | SDK 初始化 |
login(params) | 登录 |
logout(params) | 登出 |
pause(params) | 置忙 |
unpause() | 置闲 |
外呼相关
| 操作 | 说明 |
|---|---|
previewObCall(params) | 预览外呼 |
cancelPreviewObCall() | 取消外呼 |
通话控制
| 操作 | 说明 |
|---|---|
sipLink() | 软电话接听 |
sipUnlink() | 软电话挂断 |
hold() | 保持 |
unhold() | 取消保持 |
mute(params) | 静音 |
unmute(params) | 取消静音 |
咨询与转接
| 操作 | 说明 |
|---|---|
startAtxfer(params) | 发起咨询 |
cancelAtxfer() | 取消咨询 |
completeAtxfer() | 完成转接 |
threewayAtxfer() | 发起三方 |
blxfer(params) | 盲转 |
班长操作
| 操作 | 说明 |
|---|---|
spy(params) | 监听 |
unspy() | 结束监听 |
whisper(params) | 耳语 |
unWhisper() | 结束耳语 |
barge(params) | 强插 |
最佳实践
错误处理
try {
const res = await AgentSDK.previewObCall(params);
// 服务端业务失败
if (res.code !== 0) {
console.error('操作失败:', res.message, res.errorCode);
return;
}
// 成功
console.log('操作成功');
} catch (err) {
// SDK 本地错误
if (err?.name === 'AgentSdkError') {
console.error('SDK 错误:', err.code, err.message);
}
}状态管理
使用 state 和 stateAction 驱动 UI:
AgentSDK.on(EventType.AGENT_STATUS, (e) => {
const { state, stateAction } = e.status;
// 更新 UI
updateStatusBadge(state);
updateStatusText(stateAction);
updateButtonState(state);
});重连处理
AgentSDK.on(EventType.RECONNECT_ATTEMPT, (e) => {
if (e.attempt >= e.maxAttempts) {
// 超过最大重连次数
alert('连接已断开,请重新登录');
logout();
}
});参数配置
建议将配置参数统一提取:
const CONFIG = {
baseURL: 'https://agent-gateway.example.com',
tenantId: '6000001',
agentNo: '1865',
endpointType: 3,
endpoint: '1883'
};附录
座席状态
| 状态 | 说明 |
|---|---|
| offline | 离线 |
| idle | 空闲 |
| busy | 忙碌 |
| ringing | 振铃 |
| talking | 通话中 |
| wrapup | 整理态 |
终端类型
| 类型值 | 说明 |
|---|---|
| 1 | PSTN 电话 |
| 2 | 分机 |
| 3 | 软电话(WebRTC) |
相关资源
文档版本:1.0 | 最后更新:2026-03-17