iframe 嵌入(或者url跳转)
基本说明
本系统的所有页面均可通过 iframe 方式接入。接入的逻辑如下:
假设系统起在http://ip:port上面,需要iframe接入的地址是http://ip:port/chat,这里称之为目标页面。
- 首先,iframe嵌入或者跳转的时候,是要在链接地址上带上用户信息的。 用户信息以一个jwt token的形式传递。 jwt token的具体生成方式见下文。
- 要带上token的话,页面必须是
http://ip:port/user/login?token=xxx。 - 接下来需要告诉浏览器,token登陆成功后,跳转到目标页面(
http://ip:port/chat)。 这个方法的参数是redirect=xxxx。这个xxxx就是/chat(相对路径即可) - 但是因为
/chat是redirect的参数,所以/chat要进行url编码,编码为:%2Fchat。 - 最后合成的链接地址就是:
http://ip:port/user/login?token=xxx&redirect=%2Fchat
如果目标页面有参数,例如,需要跳转的地址是:http://ip:port/chat?ask=今年销售额,那么redirect参数的值就是/chat?ask=今年销售额。经过url编码后:%2Fchat%3Fask%3D%E4%BB%8A%E5%B9%B4%E9%94%80%E5%94%AE%E9%A2%9D。所以最后合成地址就是: http://ip:port/user/login?token=xxx&redirect=%2Fchat%3Fask%3D%E4%BB%8A%E5%B9%B4%E9%94%80%E5%94%AE%E9%A2%9D
一些比较通用的页面的参数如下:
智能搜索页
http://ip:port/user/login?token=xxx&redirect=%2Fnlq
系统配置页
http://ip:port/user/login?token=xxx&redirect=%2Fsettings
系统配置页有多个子页面。本系统也支持子页面拆开配置,详见下面的系统配置页参数一览
数据处理页
http://ip:port/user/login?token=xxx&redirect=%2Fsourcedata
数据看板页
http://ip:port/user/login?token=xxx&redirect=%2Fdashboard
报表页
http://ip:port/user/login?token=xxx&redirect=%2Freport
数据下载页
http://ip:port/user/login?token=xxx&redirect=%2Faccount%2Fdataexports
其中,token 为用户加密 ID,如果不传,则会弹出用户名/密码输入窗口。token 生成方式见下文:权限对接。
隐藏导航栏
隐藏导航栏的需求可以分为两种:
- 无论是直接访问还是iframe访问,全局都隐藏导航栏。
- 只在iframe的时候隐藏导航栏。
1. 全局隐藏
系统设置 -> 系统管理与配置 -> 系统参数配置 -> 专家模式 -> frontend字段中加入"headerRender": false。刷新页面即可。
2. iframe隐藏
iframe 参数
使用<iframe>标签,建议开启一些权限:<iframe allow="clipboard-write" sandbox="allow-scripts allow-top-navigation allow-same-origin allow-downloads" id="xxx" src="xxx" width="xxx" height="xxx" />
其中allow参数允许 iframe 使用粘贴板。sandbox参数允许 iframe 让主页面进行页面跳转(主要是跳转到登录页)
权限对接
当外部系统使用 iframe 或者 url 跳转的方式对接本系统时,有时候会需要将当前用户的 ID 传给本系统,以达到免登录的效果。免登录的方式非常简单,将用户 token url 中进行登录即可,url 如下:
http://ip:port/user/login?token=xxx
token 生成方式
本系统采用 JWT(JSON Web Tokens)生成 token. 首先您需要在 config.json 文件中,加入"jwtsecret":"xxxx"一行,来指定系统 jwtsecret。
然后构造如下 JSON:
{
"_id": "xxxxx",
"iat": 1689831524,
"exp": 1690436324
}
其中_id填入需要登录的用户 id。iat是 token 创建时间戳(精确到秒)。 exp是过期时间戳(精确到秒),可以根据自己系统的需要设定 token 过期时间。
使用 JWT 算法将上述 json 用 jwtsecret 生成 token 即可。
一个正确的 jwttoken 形如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
所有页面通用参数一览
| 参数名 | 作用 | 示例 |
|---|---|---|
| token | 用户权限 token | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ... |
| redirect | 登录完成后跳转的页面。页面路径 需要经过 encodeURIComponent 处理 | %2Fchat |
| headerRender | 0 | 隐藏导航栏 |
智能搜索页参数一览
| 参数名 | 作用 | 示例 |
|---|---|---|
| ask | 将问题传给系统。问题需要经过 encodeURIComponent 处理 | %E9%94%80%E5%94%AE%E9%A2%9D |
| hideSearchBar | 隐藏搜索栏 | 2:隐藏全平台搜索栏。 1:仅隐藏 PC 端搜索栏 |
| hideRecordingButton | 单独隐藏右下角的浮动录音按钮 | 1 |
| hideAnchor | 隐藏问答左侧历史记录列表 | 1 |
| hideVisualizer | 隐藏问答解释栏 | 1 |
| dashboard | 修改某一个数据看板,传入数据看板 id 号。如果传入_new,则代表新建一个数据看板 | _new/GAPwv2SCD2Gpf1is_hqyx |
| askMoreHandleByTop | 用户点击【您可能还想问】的链接的时候,是由本系统自动解决,还是由外部系统解决 | 1 |
| cardOnly | 只显示卡片部分,外部的margin、padding等都不要,关闭卡片按钮也不要 | 1 |
| analyzer | 填0则不显示智能归因 | 0 |
| llm | 填0则不显示大语言模型归纳功能 | 0 |
| hideCardFooter | 填1隐藏点赞部分 | 1 |
| actions | 卡片上角三个点菜单开启项,逗号分隔 | actions=sql,chart,detail,title,dashboard,llm,share |
| download | 0 | 隐藏下载、导出按钮 |
| mobile | 1 | 采用移动端的布局方式显示页面 |
| questionEncrypted | 对问题文本加密后再传给系统,其余同ask参数相同 | 5LuK5bm06ZSA5ZSu6aKd |
在不刷新页面情况下传递 ask 参数
每次用户问一个新的问题的时候,iframe 会刷新,会把老问题给刷新掉。如果不想要这样的效果,可以通过通信的方式将问题传给系统。方法如下:
第一步:给 iframe 设定一个 id,例如<iframe id='chatbi' />
第二步:在自己的程序中,调用document.getElementById("chatbi").contentWindow.postMessage({"ask":"今年销售额"}, '*');。其中,{"ask":"今年销售额"}是个 js object。
系统配置页参数一览
| 参数名 | 作用 | 示例 |
|---|---|---|
| page | 方便自定义集成页面。所有页面的对应参数如下文所示。 | page=measurements |
| hideSidebar | 设置 hideSidebar=1 参数后,能让页面不渲染二级导航菜单。 | hideSidebar=1 |
page 参数对应页面
- modeling: 数据建模页
- measurements: 指标编辑页
- storyline: 故事线编辑页
- customNode: 自定义词汇编辑页
- syno: 全局同义词编辑页
- alisa: 关键词优先级配置页
- prompt: 关键词优先级配置页
- hot: 系统热搜编辑页
- bulletin: 公告栏页
- config: 系统参数配置页
- auth: 权限编辑页
- logs: 问答使用记录页
- feedback: 用户反馈页
- etl: ETL设置页
- llm: 配置大语言模型页
- sql: SQL测试器页
- testcase: 测试用例页
- messageSender: 消息推送页
- alarm: 数据预警页
- licence: 许可证管理页
- serverLogViewer: 后台日志页
- operationLogViewer: 操作记录页
数据看板页参数一览
显示某一个数据看板
| 参数名 | 作用 | 示例 |
|---|---|---|
| i | 某一个数据看板的 id 号,让页面只显示某一个数据看板。 | GAPwv2SCD2Gpf1is_hqyx |
案例:
https://xx.com/dashboard?i=xxx
新建一个数据看板
注:新建一个数据看板,主页面是 nlq,加入 dashboard 参数。详见上文智能搜索页参数一览
修改某一个数据看板
注:修改某一个数据看板,主页面是 nlq,加入 dashboard 参数。详见上文智能搜索页参数一览
分享
本系统中,有些行为需要跳转页面或者是复制一个分享链接到剪贴板中。在 iframe 的情况下,需要父系统来决定链接地址。所以当本系统被 iframe 嵌入之后,所有的跳转按钮、分享按钮将不会触发行为,而是会发一条消息给父 window。本系统通过window.top.postMessage函数来发送。父系统需要监听该事件,通过 js 代码:
window.onmessage = function (e) {
if (e.data) {
try {
// 这里可以写处理逻辑
} catch (error) {}
}
};
本系统发送的 data 里面,会是一个 js object。共支持一下几个参数:
e.data = {
app: 'chatbi',
action: '', // 分为share、jump、ask。share为复制分享链接,jump为打开新窗口,ask为点击一些提问推荐的链接时候会触发的。
params: {
type: '', // 分为dashboard,ask,detail。此参数在action=share或jump时必定会存在。在action=ask时用不到。
id: '', // type = dashboard,detail的时候有。
value: '', // action=share and type = ask,或者action = ask的时候有。给的是encodeURIComponent之前的。
schema: '', // type = detail的时候有
redirect: '', // 我们内部的跳转链接。如果不想有自己特殊的逻辑,可以按照这个跳转。此参数必定会存在。
},
};
本系统根据上述参数,对应的地址为:
params.type = dashboard
/dashboard?i=${params.id}
redirect 参数和上述地址保持一致。
params.type = ask
/nlq?ask=${encodeURIComponent(params.value)}
redirect 参数和上述地址保持一致。
params.type = detail
/data/${params.schema}/${params.id}
redirect 参数和上述地址保持一致。
获取卡片高度
如果需要知道卡片高度,可以通过监听action:card/sizechange来判断,本系统每次卡片被改变大小的时候,会对外post一条message,格式如下:
{
app: "chatbi",
action: "card/sizechange",
size: {width: 1299, height: 242},
}
获取系统对外的 LLM Prompt
本系统通过大语言模型对数据结果进行归纳总结和建议,相关prompt也会通过post message的形式告知外部系统,以方便进一步处理。message格式如下:
{
app: "chatbi",
action: "card/llm/prompt",,
messages: [{role: 'user/assistant', content: 'xxxx'}],
}
获取卡片错误信息
有时候,问答会因为某些原因(如没有权限)产生错误。本系统会将错误通过post message的形式告知外部系统。格式为
{
app: "chatbi",
action: "card/data",
error: "错误信息",
}
- 没有权限:
error = "noauth"
关于iframe中的语音功能
因为浏览器会禁止iframe中的语音功能,所以在iframe的情况下,外部系统需要自行实现一个录音按钮(可以是在右下角悬浮)。这个录音功能要能够接受一段语音 -> 转成文字 -> 通过postMessage的方式告诉chatbi系统。postMessage的格式见此
邮件对接教程
你需要准备的东西
| 项目 | 说明 | 示例 |
|---|---|---|
| 发件邮箱账号 | 用来发送邮件的邮箱 | example@gmail.com |
| 发件邮箱授权码 | 用来登录 SMTP,而不是你平时登录邮箱的密码 | Gmail/QQ/163 都需要“授权码” |
| SMTP 服务器地址 | 邮件服务商提供 | smtp.gmail.com / smtp.qq.com / smtp.163.com |
| SMTP 端口 | 通常为 465 或 587 | SSL: 465,非 SSL: 587 |
去系统参数配置如下内容:
{
"thirdParty": {
"email": {
"auth": {
"user": "发件邮箱账号",
"pass": "发件邮箱授权码"
},
"host": "SMTP 服务器地址",
"port": "SMTP 端口",
"subject": "邮件主题"
}
}
}