Askport / 开发者文档

开发者接入

官网只需嵌入脚本;已登录的产品额外提供一个签发短期 JWT 的后端接口。不需要实现聊天、历史或实时消息接口。

1. 准备接入点

在控制台 接入点 中为官网或产品创建入口,点击 复制“接入代码”。同一产品的不同页面共用一个入口,页面位置由组件自动传递。适用产品在入口中固定,客户端不能覆盖。

以下示例将客服服务地址写为 https://support.example.com,入口标识 替换为控制台生成的实际值。

2. 匿名接入

在页面 </body> 前加入:

<script src="https://support.example.com/widget.js"
        data-entry="入口标识" async></script>

也可将 https://support.example.com/chat/?entry=入口标识 用作页面按钮、二维码或微信公众号菜单的链接。公众号菜单打开的是聊天网页,暂不接收公众号原生消息。

匿名身份由组件管理。同一浏览器的同一接入点可继续未结束的会话;不同浏览器、无痕窗口和接入点分别隔离。无需自行生成访客 ID。

3. 接入产品登录用户

在入口高级设置中开启“需要产品登录身份”并保存,系统自动生成密钥。在“接入代码”中点击“获取签名密钥”,将其配置到产品后端。已有部署的 WIDGET_IDENTITY_KEYS 配置优先于自动生成密钥,由部署管理员维护。

签名密钥只能放在产品后端,不能写进前端代码或提交到仓库。

产品后端:验证登录后签发 JWT

下面是产品使用 Django 时的最小示例,依赖 PyJWT。ASKPORT_ENTRY 与 ASKPORT_SIGNING_KEY 是示例所需的产品后端 settings,分别从产品的部署配置读取入口标识和签名密钥。

import time

import jwt
from django.conf import settings
from django.http import JsonResponse
from django.views.decorators.http import require_GET


@require_GET
def support_token(request):
    if not request.user.is_authenticated:
        response = JsonResponse({"error": "请先登录"}, status=401)
    else:
        now = int(time.time())
        token = jwt.encode({
            "sub": str(request.user.pk),
            "aud": f"askport:{settings.ASKPORT_ENTRY}",
            "iat": now,
            "exp": now + 300,
        }, settings.ASKPORT_SIGNING_KEY, algorithm="HS256")
        response = JsonResponse({"token": token})
    response["Cache-Control"] = "no-store"
    return response

在产品后端将此视图注册为 /api/support-token。该路径是接入示例,Askport 不提供此接口。其他后端框架按相同规则实现即可。

字段规则
sub从已验证的产品登录会话取稳定用户 ID;非空字符串,最多 255 字符
aud固定为 askport:入口标识
iat / exp整数秒时间戳;有效期大于 0 且不超过 300 秒
name可选显示名称,字符串,最多 100 字符

算法固定为 HS256。不要接受前端提交的用户 ID 来签发令牌;用户 ID 应长期稳定且不重新分配。同一入口接入多个租户时,sub 应在这些租户间唯一,例如 tenant_id:user_id。服务端时钟需保持同步。

产品前端:先配置回调,再加载脚本

<script>
window.AskportSettings = {
  async getIdentityToken() {
    const response = await fetch('/api/support-token', {
      credentials: 'same-origin',
      cache: 'no-store'
    });
    if (!response.ok) throw new Error('请先登录产品');
    return (await response.json()).token;
  }
};
</script>
<script src="https://support.example.com/widget.js"
        data-entry="入口标识" async></script>

令牌回调应每次请求后端取得新令牌,组件会在需要验证或重连时调用。

不要把令牌写进 URL、页面背景或 localStorage。

产品退出登录时调用 window.Askport.logout();重新登录或切换账号后调用 window.Askport.login(getIdentityToken),传入返回新令牌的函数。这些调用须在脚本加载完成后执行。logout() 清除旧聊天界面并保持登录验证模式,不转为匿名;产品后端也必须停止为已退出的登录会话签发令牌。已经签发的令牌最多仍有效 5 分钟。

已验证用户按“接入点 + 用户 ID + 产品”恢复未结束的会话,可跨浏览器;匿名历史不会自动合并。身份验证失败时不加载历史、不发送消息,也不降级为匿名。强制登录入口的独立聊天链接无法直接继承产品登录,请在已登录产品页面的嵌入组件中使用。

4. 可选:传递页面背景

组件自动读取当前页面 URL 和标题。URL 只保留域名、端口与路径,移除账号、密码、查询参数和片段;不会自动抓取网页。

在加载脚本前可设置初始背景:

<script>
window.AskportContext = {
  version: '2.3.1',
  platform: 'Web',
  page_note: '项目文件上传页面,用户正在选择文件。'
};
</script>

脚本加载后,单页应用在路由和页面标题更新完成时调用:

window.Askport.setContext({
  version: '2.3.1',
  platform: 'Web',
  page_note: '项目设置页面,用户正在配置通知。'
});

setContext 替换全部客户端补充背景,需要保留的字段须一并传入;URL 和标题自动重新读取。浏览器前进、后退和片段变化自动同步;使用 pushState 的路由需主动调用。页面变化不新建会话,下一条消息携带最新背景。

字段长度上限说明
product100入口未固定产品时可指定
version100产品版本,自由文本
platform100平台
page_note1000当前页面业务背景
page500嵌入组件自动读取的 HTTP(S) URL
page_title200嵌入组件自动读取的页面标题

所有字段均为字符串。背景仅帮助理解问题,不代表用户身份或业务授权;不要放入密钥或敏感业务数据。

5. 前端 API

加载前通过全局变量配置;加载后通过 window.Askport 调用。

名称用途
AskportSettings.getIdentityToken加载前设置;返回产品后端签发的新令牌
AskportContext加载前设置;初始页面背景
Askport.open() / close()打开或隐藏聊天窗口,便于自定义客服按钮;关闭不结束会话、不退出登录
Askport.login(getToken)重新登录或切换账号后传入令牌回调
Askport.logout()产品退出登录时清除聊天界面,保持登录验证模式
Askport.setContext(context)替换客户端补充背景

6. 本地验证与排查

  1. 启动本地 Askport 服务,打开 http://localhost:8000 管理接入点。
  2. 在本地产品页面使用 http://localhost:8000/widget.js,替换入口标识。页面通过 HTTP 服务打开,不使用 file://。若配置了嵌入来源,加入产品实际来源,例如 http://localhost:5173,端口必须一致;留空时检查全局 WIDGET_ALLOWED_ORIGINS。
  3. 匿名入口发送消息并刷新,确认能继续会话;用无痕窗口确认不会看到原窗口历史。在客服工作台确认接收到消息。AI 回复还需要可用的模型配置与 worker。
  4. 登录入口分别验证未登录、用户 A、用户 B、退出登录,确认未登录被阻断、账号历史隔离、退出后旧界面清除。令牌接口使用产品自身的登录会话。
  5. 切换产品页面后发送一条消息,在客服工作台确认页面标题、地址与背景已更新。
现象检查
登录后仍提示身份失败入口标识与 aud、两端密钥、用户 ID 类型、令牌有效期和服务器时间
/api/support-token 返回 404 / 401产品是否实现此接口,当前产品登录会话是否有效
组件被浏览器拒绝嵌入入口及全局允许来源;填写完整来源如 https://app.example.com,不含路径
直接打开聊天链接要求登录在已配置令牌回调的产品嵌入页面测试
AI 不回复或消息不更新web / worker / Redis 是否正常;检查服务日志与部署配置

生产环境使用 HTTPS。