FlowHunt JS API 让你完全掌控聊天机器人与网站的集成方式。借助 v2 集成代码,你可以嵌入聊天机器人、订阅生命周期与交互事件、通过流程变量传递动态数据、在对话中使用 sendHook() 触发 Chat Hook、用 URL 参数跟踪交互,并以编程方式控制聊天窗口。
本指南涵盖 JS API 的方方面面,并附有可直接复制并适配到你项目中的代码示例。
集成代码(v2)
将下方代码片段复制并粘贴到 HTML 中 </body> 关闭标签之前。把 YOUR_CHATBOT_ID 和 YOUR_WORKSPACE_ID 替换为 FlowHunt 聊天机器人设置中的对应值。
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// The chatbot is ready — use chatbotManager here
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
全局变量名(window.FHChatbot_YOUR_CHATBOT_ID)中的聊天机器人 ID 使用下划线替代连字符。
使用 setConfig() 覆盖配置
在调用 init() 之前,可以使用 setConfig() 覆盖默认的聊天机器人设置:
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
headerTitle: 'Support Assistant',
maxWindowWidth: '700px',
showChatButton: false,
flowVariables: {
userId: '12345',
plan: 'enterprise',
},
urlSuffix: '?utm_source=chatbot',
});
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// Chatbot initialised with custom config
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
可用配置选项
| 选项 | 类型 | 描述 |
|---|---|---|
headerTitle | string | 自定义顶部标题文本 |
maxWindowWidth | string | 聊天窗口最大宽度(例如 "700px") |
maxWindowHeight | string | 聊天窗口最大高度 |
inputPlaceholder | string | 消息输入框的占位符文本 |
showChatButton | boolean | 显示或隐藏默认的悬浮聊天按钮 |
openChatPanel | boolean | 页面加载时自动打开聊天面板 |
flowVariables | object | 传给流程的自定义键值对数据。值可以是任意可序列化为 JSON 的类型(字符串、数字、布尔、对象、数组)。 |
urlSuffix | string | 附加到聊天机器人生成的所有 URL 后的查询字符串 |
cookieConsent | boolean | 启用基于 Cookie 的会话持久化 |
embedded | string | 启用嵌入模式(无关闭按钮) |
theme | string | 主题模式 |
流程变量:传递动态数据
flowVariables 会被合并到聊天机器人创建的每个会话中。它们通常作为静态上下文使用(页面加载时即已知):用户 ID、套餐、当前区域设置等。
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
flowVariables: {
userId: getCurrentUserId(),
userEmail: getCurrentUserEmail(),
currentPage: window.location.pathname,
plan: 'enterprise',
},
});
如果用户在聊天打开后又进行了导航,这里传入的值就会过期。要在对话中更新它们,请调用
chatbotManager.sendHook()并传入options.flowVariables——参见下文的 对话中宿主 → 流程通信。
URL 后缀:跟踪聊天机器人交互
urlSuffix 参数会在聊天机器人生成的每个 URL 后追加一个查询字符串。这对在分析工具中跟踪由聊天机器人带来的流量非常有用:
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
urlSuffix: '?utm_source=chatbot&utm_medium=widget',
});
使用场景:
- 跟踪转化 —— 在 Google Analytics 中跟踪聊天机器人交互带来的转化。
- 分析用户行为 —— 分析与聊天机器人互动后的用户行为。
- 归因营销活动 —— 归因推动聊天机器人参与的营销活动。
对话中宿主 → 流程通信
2026 年 4 月作为 FlowHunt Chat Hook 功能的一部分新增。
在单页应用(SPA)中,用户在不同界面间切换时,聊天窗口通常会保持打开。一旦聊天已经在运行,通过 setConfig() 传入的 flowVariables 就会过期,而且也没有办法把宿主页面上发生的事告知流程。一个统一的管理器方法——sendHook(name, payload, options?)——可同时覆盖"触发触发器"与"仅更新上下文"两类用法:
- 传入
name和(可选的)payload,用以触发流程的 Chat Hook 触发器。流程作者只需在画布上放置一个 Chat Hook 节点,然后基于{ChatHook.hook_name}进行分支以决定后续行为。 - 同时传入
options.flowVariables,可在触发的同时合并会话变量——这些值会先持久化,然后触发器才会触发,并在此后整个会话中可用。 - 如果流程没有 Chat Hook 触发器,本次调用就是一次静默的 200 空操作:
options.flowVariables仍会被合并,但不会有触发器运行,也不会扣除积分。这意味着宿主页面可以放心地乐观调用sendHook(),不必关心流程作者是否已经接入触发器。
sendHook() 在会话尚未建立前调用是安全的(内部会缓冲,待会话建立后自动刷新),并且永远不会对宿主页面抛出异常——网络错误仅通过 console.warn 记录。
输入限制
适用于 sendHook() 的服务端与客户端边界。违反这些限制不会导致崩溃——后端会返回 HTTP 422,管理器会通过 console.warn 记录日志,不会抛错。
| 约束 | 限制 | 强制位置 | 违反时的行为 |
|---|---|---|---|
sendHook 的 name 长度 | 1–256 字符 | 后端(Pydantic) | HTTP 422,触发器不会触发 |
options.flowVariables 中的键数量 | ≤ 64 | 后端(Pydantic) | HTTP 422,不持久化任何内容 |
options.flowVariables 中每个键的长度 | ≤ 128 字符 | 后端(Pydantic) | HTTP 422,不持久化任何内容 |
| 管理器在会话建立前缓冲的调用数 | 50 | 小部件(浏览器内) | 最早入队的调用会被丢弃,并通过 console.warn 记录 |
会话建立前的缓冲上限只有在会话长时间无法建立的页面(例如永久性网络故障)上才会触发。在正常情况下,一旦 onFHChatbotSessionCreated 触发,队列就会被立即刷新。
1. 添加 Chat Hook 触发器(流程作者侧)
- 在 FlowHunt 编辑器中打开与你的聊天机器人关联的流程。
- 将一个 Chat Hook 触发器节点拖到画布上。编辑器强制每个流程只能有一个触发器——不允许多个。
- (可选)开启 Validate Payload Schema 并定义传入 payload 必须匹配的 JSON Schema。校验在步骤内部执行——不匹配会作为流程错误事件呈现(端点仍返回 200;该错误可通过
onFHError观察到)。 - 将触发器的输出(
hook_name、payload、flow_variables)连接到你想触发的下游步骤(Generator、Chat Output、Tool Calls、基于hook_name的条件分支等)。 - 发布流程。
2. 在流程内部基于不同的 hook 名称分支
宿主页面传给 sendHook() 的 name 是供你的流程进行分支的标签,并不是路由键——后端不会根据名称去匹配节点。流程中那一个 Chat Hook 触发器会一律触发,并把名称作为 {ChatHook.hook_name} 暴露出来,你在流程逻辑中引用它来决定要做什么。
系统提示示例:
If {ChatHook.hook_name} is "screen_changed", briefly summarise the page at
{ChatHook.payload.url}. If it is "user_action", acknowledge the action and
update memory. Otherwise, continue the conversation normally.
如需更复杂的路由,可在 {ChatHook.hook_name} 上接一个条件步骤,并分支到多条下游路径。
3. chatbotManager.sendHook(name, payload, options?)
chatbotManager.sendHook(
name: string,
payload?: Record<string, unknown>,
options?: { flowVariables?: Record<string, unknown> }
): Promise<void>;
参数
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | 是 | 作为 {ChatHook.hook_name} 转发给流程的标签。无论值是什么触发器都会触发;分支由你的流程逻辑根据它判断。 |
payload | object | 否 | 作为 {ChatHook.payload} 传给触发器的 JSON 数据。如启用了节点的 schema 校验,会据此校验。默认 {}。 |
options.flowVariables | object | 否 | 在触发器触发之前合并的会话变量。下游步骤以及之后的用户消息均可访问。 |
行为
- 在
onFHChatbotSessionCreated之前调用是安全的;调用会被缓冲,待会话存在后再刷新。缓冲区有上限——参见上文 输入限制。 - 如果流程没有 Chat Hook 触发器,请求是一次静默的 200 空操作——因此宿主页面可以乐观地调用
sendHook(),无需等待流程作者接入触发器。即便如此,options.flowVariables仍会被持久化,所以这一次调用同时也是一次"仅更新上下文"的调用。 - 如果 Chat Hook 触发器启用了 schema 校验,且 payload 校验失败,校验会在步骤内部执行——端点返回 200,但流程会发出步骤错误事件(可通过
onFHError观察到)。 name与options.flowVariables都有上限——参见上文 输入限制。违反时返回 HTTP 422,且不持久化任何内容。- 如果传入了
options.flowVariables,调用成功后会发出一个onFHChatbotFlowVariablesUpdate事件(参见 Event Reference)。 - 永不抛出。网络故障与非 2xx 响应仅通过
console.warn记录。
示例 —— SPA 导航时的主动建议
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('screen_changed', {
url: window.location.href,
screen_name: getScreenName(),
}, {
flowVariables: { current_page_url: window.location.href },
});
});
});
示例 —— 仅更新上下文(未接入 Chat Hook)
如果流程没有 Chat Hook 触发器,调用就是一次静默的 200——因此同一个 API 也可以在不触发任何东西的情况下保持 flow_variables 同步:
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('navigate', {}, {
flowVariables: {
current_page_url: window.location.href,
screen_name: getScreenName(),
},
});
});
});
4. 流程作者如何使用这些值
{ChatHook.hook_name}与{ChatHook.payload.foo}—— 通过sendHook('x', { foo: 1 })传入的值会暴露在 Chat Hook 触发器的执行路径上。仅在由该次 hook 触发启动的路径上可用。{flow_variables.foo}—— 通过options.flowVariables传入的值会在触发器触发之前合并到会话的变量集中。每条执行路径(包括由 Chat Input 触发的普通用户消息)都能读取它们。
如果你希望下一条用户消息能看到新值,请把它放进 options.flowVariables——单独的 payload 只会影响由那次 hook 启动的执行运行。
事件参考
FlowHunt JS API 在 window 对象上分派 11 个自定义事件。所有事件都使用 CustomEvent
API,并设置 bubbles: true 与 composed: true。
onFHChatbotReady
当聊天机器人小部件完全渲染并可用时触发。
- 事件数据:无。
- 触发时机:小部件 DOM 挂载完成且聊天按钮可见之后。
onFHChatbotSessionCreated
当服务器上创建了新的聊天会话时触发。
- 事件数据:
event.detail.sessionId—— 新建会话的 ID。 - 触发时机:会话创建 API 调用成功之后。
onFHChatbotWindowOpened
当用户打开聊天窗口时触发。嵌入模式下不触发。
onFHChatbotWindowClosed
当用户关闭聊天窗口时触发。嵌入模式下不触发。
onFHMessageSent
当用户发送消息时触发。
event.detail.metadata = {
content: 'Hello, I need help with...',
createdAt: '2026-02-19T10:30:00.000Z',
};
onFHMessageReceived
当聊天机器人接收并显示响应时触发。
event.detail.metadata = {
flow_id: 'abc123',
message_id: 'msg_456',
message: 'Sure, I can help you with that!',
sender: {
sender_name: 'Support Agent',
sender_avatar: 'https://example.com/avatar.png',
},
};
sender 是可选字段,仅在有人工客服参与时存在。
onFHFormDataSent
当用户通过聊天机器人提交表单数据时触发。
event.detail.metadata = {
objectData: { name: 'John', email: 'john@example.com' },
createdAt: '2026-02-19T10:31:00.000Z',
};
onFHFeedback
当用户对聊天机器人消息给出点赞 / 点踩反馈时触发。
event.detail.metadata = {
message_id: 'msg_456',
content: 'Optional feedback text',
feedback: 'P', // 'P' = positive, 'N' = negative
};
onFHToolCall
在流程处理过程中执行工具或操作时触发。仅在 flowAssistant 与 flowAssistantV3 模式下触发。
event.detail.metadata = {
metadata: {
flow_id: 'abc123',
message_id: 'msg_789',
message: 'Calling search API...',
},
createdAt: '2026-02-19T10:32:00.000Z',
};
onFHError
聊天机器人运行过程中发生错误时触发。
event.detail.metadata = {
metadata: {
flow_id: 'abc123',
message_id: 'msg_err',
message: 'Flow execution failed',
},
createdAt: '2026-02-19T10:33:00.000Z',
};
onFHChatbotFlowVariablesUpdate
2026 年 4 月新增。
在一次成功且传入了 options.flowVariables 的 chatbotManager.sendHook(...) 调用之后触发。对未传 flowVariables 的 sendHook() 调用不会触发。
event.detail = {
variables: {
current_page_url: 'https://example.com/products',
screen_name: 'products',
},
};
可用它来观察被合并进来的变量(例如同步你自己的宿主端状态、用于调试,或重新渲染依赖同一份数据的 UI 元素)。
订阅事件
订阅聊天机器人事件有两种方式。
方法 1:窗口事件监听器
在页面任何位置使用 window.addEventListener。即便聊天机器人尚未加载也可使用:
<script>
document.addEventListener('DOMContentLoaded', function () {
window.addEventListener('onFHChatbotReady', function () {
console.log('Chatbot is ready');
});
window.addEventListener('onFHChatbotSessionCreated', function (event) {
console.log('Session created:', event.detail.sessionId);
});
window.addEventListener('onFHChatbotWindowOpened', function () {
console.log('Chat window opened');
});
window.addEventListener('onFHChatbotWindowClosed', function () {
console.log('Chat window closed');
});
window.addEventListener('onFHMessageSent', function (event) {
console.log('User sent:', event.detail.metadata.content);
});
window.addEventListener('onFHMessageReceived', function (event) {
console.log('Bot replied:', event.detail.metadata.message);
});
window.addEventListener('onFHFormDataSent', function (event) {
console.log('Form submitted:', event.detail.metadata.objectData);
});
window.addEventListener('onFHFeedback', function (event) {
var fb = event.detail.metadata;
console.log('Feedback on message', fb.message_id, ':', fb.feedback);
});
window.addEventListener('onFHToolCall', function (event) {
console.log('Tool called:', event.detail.metadata);
});
window.addEventListener('onFHError', function (event) {
console.error('Chatbot error:', event.detail.metadata);
});
window.addEventListener('onFHChatbotFlowVariablesUpdate', function (event) {
console.log('Variables merged:', event.detail.variables);
});
});
</script>
要移除监听器,需要保留处理器引用:
var handleMessage = function (event) {
console.log(event.detail.metadata);
};
window.addEventListener('onFHMessageReceived', handleMessage);
// Later …
window.removeEventListener('onFHMessageReceived', handleMessage);
方法 2:管理器回调方法
在 init() 回调内部,使用聊天机器人管理器的内置方法:
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
chatbotManager.onSessionCreated(function () {
console.log('Session created');
});
chatbotManager.onWindowOpened(function () {
console.log('Window opened');
});
chatbotManager.onWindowClosed(function () {
console.log('Window closed');
});
chatbotManager.onMessageSent(function (event) {
console.log('User sent:', event.metadata);
});
chatbotManager.onMessageReceived(function (event) {
console.log('Bot replied:', event.metadata);
});
chatbotManager.onFormDataSent(function (event) {
console.log('Form data:', event.metadata);
});
chatbotManager.onFeedback(function (event) {
console.log('Feedback:', event.metadata);
});
chatbotManager.onToolCall(function (event) {
console.log('Tool call:', event.metadata);
});
chatbotManager.onError(function (event) {
console.error('Error:', event.metadata);
});
});
管理器方法参考
| 方法 | 参数 | 描述 |
|---|---|---|
onSessionCreated(fn) | fn: () => void | 监听会话创建 |
onWindowOpened(fn) | fn: () => void | 监听窗口打开 |
onWindowClosed(fn) | fn: () => void | 监听窗口关闭 |
onMessageSent(fn) | fn: (event) => void | 监听用户消息 |
onMessageReceived(fn) | fn: (event) => void | 监听机器人响应 |
onFormDataSent(fn) | fn: (event) => void | 监听表单提交 |
onFeedback(fn) | fn: (event) => void | 监听用户反馈 |
onToolCall(fn) | fn: (event) => void | 监听工具执行 |
onError(fn) | fn: (event) => void | 监听错误 |
openChat() | — | 打开聊天面板 |
closeChat() | — | 关闭聊天面板 |
sendHook(name, payload?, options?) (新增) | name: string、payload?: object、options?: { flowVariables?: object } | 在运行中的流程里触发 Chat Hook 触发器(若未接入触发器,则静默地合并 options.flowVariables) |
自定义聊天激活:隐藏按钮并按需打开
要完全掌控聊天机器人的出现时机,请隐藏默认的悬浮按钮,并以编程方式打开聊天——例如通过你自己的自定义按钮。
<button id="my-chat-button">Chat with us</button>
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({ showChatButton: false });
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
document.getElementById('my-chat-button')
.addEventListener('click', function () {
chatbotManager.openChat();
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
仅在聊天机器人就绪时显示自定义按钮
可将隐藏激活方式与事件监听器结合,构建更高级的交互:
<button id="open-chat" style="display:none;">Need help?</button>
<script>
window.addEventListener('onFHChatbotReady', function () {
document.getElementById('open-chat').style.display = 'block';
});
</script>
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({ showChatButton: false });
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
document.getElementById('open-chat')
.addEventListener('click', function () {
chatbotManager.openChat();
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
完整集成示例
下面是一个综合演示配置覆盖、事件跟踪、自定义聊天激活以及全新 sendHook() 方法的完整可运行示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FlowHunt Chatbot Integration</title>
</head>
<body>
<h1>My Website</h1>
<button id="open-chat-btn">Talk to our AI assistant</button>
<button id="close-chat-btn">Close chat</button>
<!-- Subscribe to events before the chatbot loads -->
<script>
document.addEventListener('DOMContentLoaded', function () {
window.addEventListener('onFHChatbotReady', function () {
console.log('Chatbot widget is ready');
});
window.addEventListener('onFHChatbotSessionCreated', function (event) {
console.log('New chat session started:', event.detail.sessionId);
});
window.addEventListener('onFHMessageSent', function (event) {
console.log('User message:', event.detail.metadata.content);
});
window.addEventListener('onFHMessageReceived', function (event) {
console.log('Bot response:', event.detail.metadata.message);
});
window.addEventListener('onFHChatbotFlowVariablesUpdate', function (event) {
console.log('Context updated:', event.detail.variables);
});
window.addEventListener('onFHError', function (event) {
console.error('Chatbot error:', event.detail.metadata);
});
});
</script>
<!-- FlowHunt integration -->
<script id="fh-chatbot-script-YOUR_CHATBOT_ID">
var currentScript = document.currentScript
|| document.getElementById('fh-chatbot-script-YOUR_CHATBOT_ID');
var script = document.createElement('script');
script.async = true;
script.src = 'https://app.flowhunt.io/api/chatbot/YOUR_CHATBOT_ID'
+ '?workspace_id=YOUR_WORKSPACE_ID&v=2';
script.onload = function () {
window.FHChatbot_YOUR_CHATBOT_ID.setConfig({
showChatButton: false,
headerTitle: 'AI Assistant',
maxWindowWidth: '600px',
flowVariables: {
source: 'website',
current_page_url: window.location.href,
},
urlSuffix: '?utm_source=chatbot',
});
window.FHChatbot_YOUR_CHATBOT_ID.init(function (chatbotManager) {
// Open / close from custom buttons
document.getElementById('open-chat-btn')
.addEventListener('click', function () {
chatbotManager.openChat();
});
document.getElementById('close-chat-btn')
.addEventListener('click', function () {
chatbotManager.closeChat();
});
// Keep the flow's context in sync with SPA navigation and
// optionally fire the Chat Hook trigger (if the flow has one wired).
// If the flow has no Chat Hook, the call is a silent 200 — the
// flow_variables still get merged, so the same line covers both
// "notify the flow" and "just update context".
window.addEventListener('hashchange', function () {
chatbotManager.sendHook('screen_changed', {
url: window.location.href,
}, {
flowVariables: { current_page_url: window.location.href },
});
});
});
};
if (currentScript && currentScript.parentNode) {
currentScript.parentNode.insertBefore(script, currentScript.nextSibling);
} else {
document.head.appendChild(script);
}
</script>
</body>
</html>
