跳到主要内容

网站小部件

将你的语音代理嵌入任何网站,让访客能够直接从浏览器开始语音对话Widgets 标签页提供嵌入代码、自定义选项和域名安全设置。

在找回拨小部件吗?

回拨小部件的工作方式与本页的小部件截然不同——它不是开始浏览器语音通话,而是收集访客的电话号码并让你的代理回拨给他们。参见专门的回拨小部件页面。

小部件类型

Hanc.AI 提供四种浏览器内小部件类型,外加一个单独的用于电话回拨的回拨小部件

小部件标签名描述最适合
浮动小部件hanc-ai-floating-call悬浮在页面上方的球形按钮始终可见的行动号召
胶囊小部件hanc-ai-pill-call内联放置在内容中的紧凑胶囊形按钮在现有布局中占用极小空间
浮动胶囊小部件hanc-ai-pill-floating-call与胶囊相同的紧凑胶囊形状,但像浮动小部件那样随页面浮动当你想要一个随访客滚动而跟随的胶囊外观时
内联小部件hanc-ai-inline-call嵌入页面内容的全尺寸通话按钮专门的"与我们通话"版块
回拨小部件hanc-ai-callback电话号码表单;代理回拨给访客获客页面、高意向落地页——参见回拨小部件

通用属性

所有小部件类型都支持这些核心属性:

属性是否必需描述默认值
agent-id你的代理的唯一标识符
voice-service-url覆盖语音服务 URL自动检测
api-base-url覆盖 API 基础 URL自动检测

显示属性

属性描述取值默认值
position小部件在页面上的位置bottom-rightbottom-lefttop-righttop-leftstaticbottom-right
size小部件大小(以像素计)数字120
theme颜色主题名称参见颜色主题default

按钮文本属性

属性描述默认值
button-start-text空闲按钮上显示的文本"Call"
button-connecting-text连接时显示的文本"Connecting..."
button-end-text通话进行中显示的文本

条款属性

属性描述默认值
terms-enabled在通话前启用同意对话框false
terms-contentMarkdown 格式的同意文本""
terms-url指向你的条款与条件页面的链接"https://hanc.ai/terms"
privacy-url指向你的隐私政策页面的链接"https://hanc.ai/privacy"
信息

除非 skip-fetch 设置为 true,否则在 HTML 元素上设置的条款属性会被从 API 获取的代理小部件设置覆盖。

声音属性

属性描述默认值
sound-enabled启用通话开始/结束提示音true
sound-volume音效音量0.25
sound-preset声音预设标识符"1"

颜色主题

用 11 种内置颜色主题自定义小部件外观:

主题取值
Defaultdefault
Purplepurple
Blueblue
Cyancyan
Emeraldemerald
Amberamber
Tangerinetangerine
Roserose
Emberember
Blackblack
Whitewhite

每种主题都有深色和浅色两种变体。通过嵌入代码中的 theme 属性设置主题,或在代理的小部件设置中配置。


嵌入示例

浮动小部件

<hanc-ai-floating-call agent-id="YOUR_AGENT_ID"></hanc-ai-floating-call>
<script src="https://unpkg.com/hanc-webrtc-widgets" async type="text/javascript"></script>

带主题和位置的浮动小部件

<hanc-ai-floating-call
agent-id="YOUR_AGENT_ID"
theme="emerald"
position="bottom-left"
size="140"
></hanc-ai-floating-call>
<script src="https://unpkg.com/hanc-webrtc-widgets" async type="text/javascript"></script>

胶囊小部件

<hanc-ai-pill-call agent-id="YOUR_AGENT_ID"></hanc-ai-pill-call>
<script src="https://unpkg.com/hanc-webrtc-widgets" async type="text/javascript"></script>

内联小部件

<hanc-ai-inline-call agent-id="YOUR_AGENT_ID"></hanc-ai-inline-call>
<script src="https://unpkg.com/hanc-webrtc-widgets" async type="text/javascript"></script>
锁定小部件版本

上面的脚本 URL 始终加载最新发布的小部件——你的网站会自动获得改进,未指定版本时 @latest 为默认值。如果你需要锁定到一个固定版本,请通过追加你想要的版本号来明确锁定,例如 https://unpkg.com/hanc-webrtc-widgets@X.Y.Z


小部件事件

小部件会发出你可以在 JavaScript 中监听的事件:

事件描述
status-changed当通话状态改变时触发
connecting通话正在建立
connected通话进行中
idle无进行中的通话
error发生错误
audio-track收到远端音频轨道(用于可视化)
local-audio-track本地麦克风音频轨道(用于可视化)
microphone-enabled麦克风已启用
microphone-disabled麦克风已禁用
call-start当通话成功开始时触发
call-end当通话结束时触发

示例:监听事件

const widget = document.querySelector('hanc-ai-floating-call');

widget.addEventListener('call-start', () => {
console.log('Call started');
});

widget.addEventListener('call-end', () => {
console.log('Call ended');
});

让智能体打开页面

在浏览器通话过程中,智能体可以请求您的网站打开某个页面——「我给您看一下价格」——访客在不中断对话的情况下就能看到。

决定权始终在您的页面。智能体发出请求,由您的代码决定它意味着什么。打开网址、切换标签页、滚动到某个区块、展开折叠面板,都是有效的处理方式。

一共三步,缺一不可。

第 1 步 — 告诉智能体有哪些页面

智能体看不到您的站点地图。它只会请求您给过它的路径,所以请在智能体的提示词或知识库中列出:

我们网站的页面:
/pricing — 套餐与价格
/contact — 联系表单和电话
/product/crm — CRM

跳过这一步,智能体就没有可请求的内容,也就不会尝试。

第 2 步 — 在页面上处理请求

在挂件脚本之后的任意位置添加一次即可。事件会沿页面向上冒泡,因此监听 document 就够了:

<script>
document.addEventListener('agent-command', (event) => {
const { type, payload } = event.detail;

if (type === 'navigate') {
// 单页应用:不刷新地路由——通话继续。
router.push(payload.path);

// 传统站点:另开一个标签页,当前这个(连同通话)得以保留。
// window.open(payload.path, '_blank');

event.preventDefault(); // ← 这一行才是在告诉智能体「已处理」
}
});
</script>
整页刷新会中断通话

通话就活在这个页面里。window.location.href = … 会卸载文档,对话也随之消失——访客会在说到一半时被切断。有路由就在客户端跳转,否则请在新标签页中打开。没有重连机制:刷新之后什么都不会保留。

preventDefault() 不是可选项

这是唯一表示「我处理了」的方式。缺少它,智能体会被告知该网站不支持导航:在本次通话剩余时间里不再尝试,转而口头描述该点哪里。控制台不会有任何提示——页面看上去只是忽略了请求,事实也确实如此。

第 3 步 — 试一试

从网站给您的智能体打电话,按名称索要某个页面。应当发生两件事:页面打开了,并且智能体会说「这是价格」,而不是「您可以在菜单里找到」。


用数据回应智能体

有些指令是提问而非命令。它们以同样的方式到达,但需要用 respond() 回答:

指令智能体在问什么您回什么
navigate「打开这个路径」什么都不用——preventDefault() 即可
page_context「访客正在看什么?」任何有用的信息:路径、标题、商品
cart_state「购物车里有什么?」商品、合计、币种
<script>
document.addEventListener('agent-command', (event) => {
const { type, respond } = event.detail;

if (type === 'page_context') {
event.preventDefault();
respond({ path: location.pathname, title: document.title });
}
});
</script>

preventDefault() 之后约有一秒钟的回应时间:await 没问题,缓慢的 API 调用不行。用手头已有的数据回答即可。


智能体可以请求什么,不可以请求什么

  • 只能是您自己站点内的路径。 路径必须以 / 开头。任何可能离开您域名的写法——//evil.comhttps://…、反斜杠——在到达页面之前就被拒绝。智能体无法把访客带到别处。
  • 仅限浏览器通话。 电话通话中没有页面可开,因此那里不存在这些指令。
  • 一次拒绝就够了。 如果页面没有确认第一次请求,智能体在本次通话剩余时间里不再询问。它不会反复尝试,更重要的是,不会告诉访客自己打开了其实没打开的东西。
什么都没发生?

在过滤之前先把每条指令打印出来:document.addEventListener('agent-command', e => console.log(e.detail))。如果控制台里出现了 navigate,说明智能体这一侧没问题,缺的是 preventDefault() 或您自己的处理逻辑。如果什么都没有,那就是从未告诉过智能体这个路径的存在——回到第 1 步。


技术要求

小部件要求访客的浏览器支持:

  • WebGL 2.0 —— 用于渲染
  • Web Audio API —— 用于音频处理
  • WebRTC —— 用于实时语音通信

所有现代浏览器(Chrome、Firefox、Safari、Edge)都支持这些技术。


域名限制

控制哪些网站可以嵌入你的代理小部件。

始终允许的域名

以下域名无论如何配置都始终被允许:

  • hanc.ai(及其子域名)
  • hanc.me(及其子域名)
  • localhost

允许所有域名

默认情况下,你的小部件可以嵌入到任何网站。在小部件设置中切换 "Allow all domains" 来限制这一点。

限制到特定域名

限制时,添加每个应被允许的域名:

  • 输入域名时不带 https://(例如 example.com
  • 子域名需要单独的条目(例如 www.example.comshop.example.com
  • 可以指定端口(例如 localhost:3000
  • 最多可将 50 个域名加入白名单
安全

对于生产环境的代理,将小部件限制到你自己的域名,以防止未经授权的嵌入。


条款与条件

在来电者能够开始对话之前启用同意对话框。

配置

设置描述
Enable Terms开/关切换条款对话框
Terms Content向用户显示的 Markdown 格式同意文本(最多 5,000 字符)
Terms URL指向你完整条款与条件页面的链接
Privacy URL指向你隐私政策页面的链接

启用时:

  • 用户在开始通话前看到同意对话框
  • 他们必须点击 "Agree" 才能继续
  • 同意信息本地存储在浏览器中
  • Reset Consent 按钮清除已存储的同意信息以便测试

内容格式

条款内容支持 Markdown 格式:

  • 使用 #### 表示标题
  • 使用 **bold** 表示强调
  • 使用换行提高可读性

相关内容