npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

icsoc-visitor-sdk

v1.0.2

Published

ICSOC 访客侧聊天 JSSDK,用于在访客页面中建立会话、收发消息和接收状态变化

Readme

访客侧 JSSDK 接入文档

Visitor SDK 用于在你的访客页面中建立会话、收发消息和接收状态变化。页面的聊天样式、消息气泡、路由和弹窗由你的项目实现。

版本:v1.0.2 | 更新日期:2026-8-12

1. 接入说明

1.1 安装

npm install icsoc-visitor-sdk
# 或
pnpm add icsoc-visitor-sdk

包名为 icsoc-visitor-sdk

1.2 初始化

在聊天页面加载时创建 SDK 实例,并完成初始化与连接:

import {
  createVisitorClient,
  loadBrowserDependencies
} from "icsoc-visitor-sdk";

loadBrowserDependencies().then(({ signer, protocolAdapter }) => {
  createVisitorClient({
    channel: {
      key: "你的 channelKey",
      type: 0
    },
    signer,
    protocolAdapter,
    identity: {
      thirdId: "当前登录用户的稳定 ID",
      username: "张三",
      avatar: "https://example.com/avatar.png"
    },
    context: {
      language: "zh_CN",
      init: "1",
      matchType: "1",
      matchObject: "10001"
    }
  }).then((client) => {
    client.initialize().then(() => client.connect());
  });
});

loadBrowserDependencies() 会自动准备请求签名、WebSocket 通信和消息编解码组件,不需要单独引入脚本。

1.2.1 参数说明

createVisitorClient(options) 的常用参数如下:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | channel.key | string | 是 | 平台为渠道分配的 channelKey。 | | channel.type | number | 是 | 渠道类型,标准网页访客侧填写 0。 | | signer | VisitorSigner | 是 | 由 loadBrowserDependencies() 返回。 | | protocolAdapter | VisitorProtocolAdapter | 是 | 由 loadBrowserDependencies() 返回。 | | identity.thirdId | string | 否 | 你的业务系统中的稳定用户标识。登录用户建议传入同一值,以关联该用户的历史记录。不要传手机号、身份证号、邮箱等敏感信息。 | | identity.anonymousId | string | 否 | 未登录访客的匿名标识。可以保存 SDK 初始化后返回的匿名标识,在同一浏览器再次进入时传回。 | | identity.username | string | 否 | 访客用户名。不提供则由服务端默认生成"匿名用户+数字"。 | | identity.avatar | string | 否 | 访客头像 URL。不提供则使用服务端默认头像。 | | context.language | string | 否 | 语言,简体中文填写 zh_CN。 | | context.init | string | 否 | 首次进入渠道时填写 "1"。 | | context.matchType | string | 否 | 指定转人工匹配类型:"1"坐席ID、"2"坐席工号、"3"技能组ID。需配合 matchObject 使用。 | | context.matchObject | string | 否 | 指定匹配的人工对象(坐席ID、工号或技能组ID),配合 matchType 使用。 | | apiBase | string | 否 | 服务地址。省略时自动使用生产服务地址。仅内部联调测试环境时配置。 | | websocketBase | string | 否 | WebSocket 服务地址。通常与 apiBase 配套,仅内部联调时配置。 |

1.3 监听事件

initialize() 前注册监听。页面收到事件后,读取 SDK 当前状态并刷新自己的界面即可。

client.on("connection.changed", ({ state }) => {
  // 更新页面连接状态
});

client.on("message.received", () => {
  // 通过 client.getMessages() 获取当前消息列表并渲染
});

client.on("error", ({ error }) => {
  // 展示错误提示或记录日志
});

发送结果说明

SDK 不单独派发 ACK 事件。发送消息后,通过 sendText()sendImage()sendFile() 等方法返回的 Promise 处理结果:then() 表示服务端确认成功,catch() 表示超时或发送失败。

1.4 图片与文件发送

sendImage()sendFile() 只负责发送一条携带 URL 的聊天消息,本身不会上传文件。文件来源可以有两种:

1.4.1 使用平台对象存储

调用 uploadFile() 后,SDK 向平台申请上传凭证并上传到平台对象存储,返回正式 URL;再把 URL 传给发送方法。

void client.uploadFile({
  file,
  fileName: file.name,
  category: "image",
  contentType: file.type
})
  .then((uploaded) => client.sendImage({
    url: uploaded.url,
    thumbnailUrl: uploaded.thumbnailUrl
  }))
  .then(({ clientMessageId, messageId }) => {
    markMessageSent(clientMessageId, messageId);
  })
  .catch(showUploadOrSendError);

1.4.2 使用你的图片或文件服务

如果你的系统已经管理图片、文件或 OSS,可以先由你的服务完成上传,再把可访问的 HTTPS URL 传给 SDK。此时不需要调用 uploadFile()

void uploadToYourStorage(file)
  .then((url) => client.sendImage({
    url,
    previewUrl: url
  }))
  .then(({ clientMessageId, messageId }) => {
    markMessageSent(clientMessageId, messageId);
  })
  .catch(showUploadOrSendError);

你的 URL 应能被访客和座席浏览器访问;图片、文件的访问权限、有效期、下载鉴权与内容安全由你的存储服务负责。

1.5 验证

交付包中的 sample/ 是 SDK 验证页。部署后访问:

https://你的静态站点/visitor-sdk/sample/?channelKey=你的渠道标识&init=1

建议依次验证:初始化、建立会话、发送文本、消息确认、加载历史消息、图片或文件发送。


2. API 与事件

2.1 创建与连接

2.1.1 加载浏览器运行组件

描述:自动准备请求签名、WebSocket 通信和消息编解码所需组件。生产环境无需传入参数。

loadBrowserDependencies().then(({ signer, protocolAdapter }) => {
  // 使用 signer、protocolAdapter 创建 SDK 实例
});

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | options.apiBase | string | 否 | 服务地址。省略时使用生产服务地址;仅内部联调测试环境时配置。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | signer | VisitorSigner | 请求签名器,创建 SDK 实例时必填。 | | protocolAdapter | VisitorProtocolAdapter | 协议适配器,创建 SDK 实例时必填。 |

2.1.2 创建访客 SDK 实例

描述:创建一个访客 SDK 实例。一个聊天页面通常只创建一个实例。

createVisitorClient({
  channel: { key: "你的 channelKey", type: 0 },
  signer,
  protocolAdapter
}).then((client) => {
  // 使用 client 调用后续方法
});

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | channel.key | string | 是 | 平台分配的 channelKey。 | | channel.type | number | 是 | 渠道类型,网页访客侧填写 0。 | | signer | VisitorSigner | 是 | loadBrowserDependencies() 返回的签名器。 | | protocolAdapter | VisitorProtocolAdapter | 是 | loadBrowserDependencies() 返回的协议适配器。 | | identity.thirdId | string | 否 | 业务系统稳定用户标识。登录用户推荐传入相同值以关联历史记录;不要传手机号、身份证号、邮箱等敏感信息。 | | identity.anonymousId | string | 否 | 匿名访客标识。同一浏览器再次进入时可传回,以便平台识别匿名访客。 | | context.language | string | 否 | 页面语言,例如 zh_CN。 | | context.init | string | 否 | 首次进入渠道时填写 "1"。 | | apiBase | string | 否 | HTTP 服务地址。省略时使用生产服务。 | | websocketBase | string | 否 | WebSocket 服务地址。通常仅内部联调时配置。 | | ackTimeout | number | 否 | 默认等待消息确认的超时时间,单位毫秒。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | client | VisitorClient | 后续会话、消息、上传和监听均通过此实例调用。 |

2.1.3 初始化 SDK

描述:初始化访客身份与渠道配置。必须在 connect() 前调用。

client.initialize().then(() => {
  // 初始化完成,可调用 connect()
});

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 成功结果 | Promise<void> | 初始化完成后可调用 connect()。 |

2.1.4 建立连接

描述:建立 WebSocket 连接。连接状态通过 connection.changed 事件获取。

client.connect().then(() => {
  // WebSocket 连接建立完成
});

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 成功结果 | Promise<void> | 连接建立完成。 |

2.1.5 断开连接

描述:主动断开当前 WebSocket 连接;需要恢复时再次调用 connect()

client.disconnect();

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 无 | void | 方法立即返回。 |

2.1.6 销毁 SDK 实例

描述:销毁 SDK 实例,释放连接与内部资源。聊天页面或组件卸载时调用。

client.destroy();

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 无 | void | 实例销毁后不可继续使用。 |

2.1.7 获取 SDK 状态

描述:获取 SDK 当前生命周期状态。

const state = client.getState();

if (state === "connected") {
  // 可以发送消息
}

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | state | ChatClientState | 可能为 idleinitializinginitializedconnectingconnected。 |

2.2 会话与历史消息

2.2.1 创建会话

描述:创建会话。返回对象中的 sId 是后续查询历史消息时使用的会话 ID。

client.startConversation().then((conversation) => {
  console.log(conversation.sId); // 会话 ID
  console.log(conversation.status); // "active"
});

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | input.conversationId | string | 否 | 指定会话 ID 的预留参数。通常不传,由平台创建会话。 | | input.metadata | Record<string, unknown> | 否 | 可附带的扩展元数据。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | sId | string | 会话 ID。 | | status | activeendedpending | 会话状态。 |

2.2.2 获取当前会话

描述:读取当前 SDK 实例保存的会话;没有会话时返回 undefined

const conversation = client.getCurrentConversation();

if (conversation) {
  console.log(conversation.sId);
}

参数说明:

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | conversation | Sessionundefined | 当前会话对象或空。 |

2.2.3 结束会话

描述:结束当前会话。结束后页面应停止发送消息,并根据业务决定是否保留历史展示。

client.endConversation().then(() => {
  // 会话已结束
});

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | reason | string | 否 | 结束原因,例如 visitor_end。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 成功结果 | Promise<void> | 结束请求完成。 |

2.2.4 加载历史消息

描述:加载历史消息。查询结果会自动合并到 getMessages() 返回的消息列表,不需要手动重复追加。

client.listMessages().then((page) => {
  console.log(page.items); // 本次加载的消息
  console.log(page.nextCursor); // 下一页游标
  console.log(page.hasMore); // 是否还有历史消息
});

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | conversationId | string | 否 | 会话 ID。省略时使用当前会话。 | | cursor | string | 否 | 上一次返回的 nextCursor,用于继续分页。 | | direction | beforeafter | 否 | 查询方向。加载更早消息使用 before。 | | limit | number | 否 | 单次加载条数。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | items | ChatMessage[] | 本次查询的消息。 | | nextCursor | stringundefined | 下一页游标。 | | hasMore | boolean | 是否还有更多历史消息。 |

2.2.5 获取消息列表

描述:获取 SDK 当前保存的标准消息列表。收到新消息、ACK 或历史消息后重新调用此方法即可。

const messages = client.getMessages();

console.log(messages.length);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | conversationId | string | 否 | 指定会话 ID。省略时使用当前会话。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | messages | ChatMessage[] | 标准消息数组。 |

2.2.6 获取历史分页状态

描述:获取当前会话历史分页状态,用于决定是否展示“加载更多”。

const history = client.getHistoryState();

if (history?.hasMore) {
  client.listMessages({ cursor: history.nextCursor }).then(() => {
    // 更早消息加载完成
  });
}

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | conversationId | string | 否 | 指定会话 ID。省略时使用当前会话。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | hasMore | boolean | 是否还有更多历史消息。 | | nextCursor | stringundefined | 加载下一页时传给 listMessages() 的游标。 |

2.3 发送消息

2.3.1 发送文本消息

描述:发送文本消息。方法返回 Promise,不会阻塞页面;使用 then()catch() 分别处理服务端确认和发送失败。

const clientMessageId = crypto.randomUUID();

// 1. 立即展示“发送中”
renderSendingMessage({ clientMessageId, text: "你好" });

// 2. 发起发送后,页面可继续执行其他逻辑
const sendTask = client.sendText({
  text: "你好",
  clientMessageId,
  waitForAck: true,
  ackTimeout: 10_000
});

continueOtherWork();

// 3. ACK 成功后进入 then;超时或发送失败进入 catch
void sendTask
  .then(({ messageId, status, message }) => {
    markMessageSent(clientMessageId, messageId);
    console.log(status); // "sent"
    console.log(message); // 标准消息对象
  })
  .catch((error) => {
    markMessageFailed(clientMessageId, error);
  });

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | text | string | 是 | 文本内容。 | | conversationId | string | 否 | 指定会话 ID。省略时使用当前会话。 | | clientMessageId | string | 否 | 客户自定义的本地消息 ID。 | | waitForAck | boolean | 否 | 是否等待服务端确认;客户接入建议保持 true。 | | ackTimeout | number | 否 | 服务端确认超时时间,单位毫秒。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | clientMessageId | string | 本地消息 ID。 | | messageId | stringundefined | 服务端消息 ID。 | | status | acceptedsent | 发送结果状态。 | | message | ChatMessage | 标准消息对象。 |

2.3.2 上传文件

描述:使用平台对象存储上传文件,返回可发送的 URL。若你已使用自己的 OSS 或文件服务,则自行上传后直接调用对应发送方法,不需要调用此方法。

void client.uploadFile({
  file,
  fileName: file.name,
  category: "image",
  contentType: file.type
}).then((uploaded) => {
  console.log(uploaded.url); // 用于 sendImage()、sendFile() 等发送方法
}).catch(showUploadError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | file | Blob | 是 | 浏览器选择的文件对象。 | | fileName | string | 是 | 文件名称。 | | category | imagefileaudiovideo | 是 | 上传文件类别。 | | contentType | string | 否 | MIME 类型,例如 image/png。 | | width / height | number | 否 | 图片宽高。 | | durationSeconds | number | 否 | 音视频时长,单位秒。 | | onProgress | (progress) => void | 否 | 上传进度回调,范围为 01。 |

返回字段:

| 返回字段 | 类型 | 说明 | |---|---|---| | url | string | 正式资源地址。 | | thumbnailUrl | stringundefined | 缩略图地址。 | | fileName | string | 文件名称。 | | sizeBytes | number | 文件大小,单位字节。 |

2.3.3 发送图片消息

描述:发送图片 URL,不执行上传。URL 可以来自 uploadFile(),也可以来自你的 OSS 或图片服务。

void client.sendImage({
  url: uploaded.url,
  thumbnailUrl: uploaded.thumbnailUrl
}).then(({ clientMessageId, messageId, status }) => {
  markMessageSent(clientMessageId, messageId);
  console.log(status);
}).catch(showSendError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | url | string | 是 | 访客和座席浏览器可访问的图片 HTTPS URL。 | | thumbnailUrl | string | 否 | 缩略图 URL。 | | previewUrl | string | 否 | 本地预览或大图 URL。 | | width / height | number | 否 | 图片宽高。 | | conversationIdclientMessageIdwaitForAckackTimeout | 对应类型 | 否 | 与 sendText() 同名参数含义一致。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 发送结果 | SendMessageResult | 字段与 sendText() 返回值一致。 |

2.3.4 发送文件消息

描述:发送普通文件 URL,不执行上传。

void client.sendFile({
  url: uploaded.url,
  fileName: uploaded.fileName,
  fileSizeBytes: uploaded.sizeBytes
}).then(({ clientMessageId, messageId, status }) => {
  markMessageSent(clientMessageId, messageId);
  console.log(status);
}).catch(showSendError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | url | string | 是 | 文件下载地址。 | | fileName | string | 是 | 文件名称。 | | downloadUrl | string | 否 | 单独的下载地址。 | | fileType | string | 否 | 文件类型。 | | fileSizeBytes | number | 否 | 文件大小,单位字节。 | | fileSizeLabel | string | 否 | 展示用文件大小,例如 2.3 MB。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 发送结果 | SendMessageResult | 字段与 sendText() 返回值一致。 |

2.3.5 发送音频消息

描述:发送音频消息。

void client.sendAudio({
  url,
  durationSeconds: 12
}).then(({ clientMessageId, messageId, status }) => {
  markMessageSent(clientMessageId, messageId);
  console.log(status);
}).catch(showSendError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | url | string | 是 | 音频资源地址。 | | durationSeconds | number | 否 | 音频时长,单位秒。 | | transcript | string | 否 | 音频转写文本。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 发送结果 | SendMessageResult | 字段与 sendText() 返回值一致。 |

2.3.6 发送视频消息

描述:发送视频消息。

void client.sendVideo({
  url,
  previewUrl
}).then(({ clientMessageId, messageId, status }) => {
  markMessageSent(clientMessageId, messageId);
  console.log(status);
}).catch(showSendError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | url | string | 是 | 视频资源地址。 | | previewUrl | string | 否 | 本地预览或封面地址。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 发送结果 | SendMessageResult | 字段与 sendText() 返回值一致。 |

2.3.7 重试失败消息

描述:重试已发送失败的消息,不会重新创建一条文本消息。

void client.retryMessage(clientMessageId)
  .then(({ messageId, status }) => {
    markMessageSent(clientMessageId, messageId);
    console.log(status);
  })
  .catch(showSendError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | clientMessageId | string | 是 | 失败消息的本地消息 ID。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | 发送结果 | SendMessageResult | 字段与 sendText() 返回值一致。 |

2.3.8 撤回消息

描述:撤回可撤回消息。

void client.recallMessage({ messageId })
  .then((message) => {
    removeMessageBubble(message.msgId);
  })
  .catch(showRecallError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | messageId | string | 是 | 要撤回的服务端消息 ID。 | | conversationId | string | 否 | 指定会话 ID。省略时使用当前会话。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | message | ChatMessage | 撤回后的标准消息对象。 |

2.3.9 标记消息已读

描述:标记收到的消息为已读。

void client.markMessageRead({ messageId })
  .then((marked) => {
    if (marked) markMessageRead(messageId);
  })
  .catch(showReadError);

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | messageId | string | 是 | 要标记的服务端消息 ID。 | | conversationId | string | 否 | 指定会话 ID。省略时使用当前会话。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | marked | boolean | 是否成功标记。 |

2.4 事件监听

2.4.1 注册事件监听

描述:注册 SDK 事件。返回的函数用于取消当前监听。

const dispose = client.on("message.received", (event) => {
  console.log(event.conversationId, event.message);
});

// 页面卸载或不再监听时调用
dispose();

参数说明:

| 参数 | 类型 | 必填 | 说明 | |---|---|---|---| | eventName | ChatSdkEventName | 是 | 需要监听的事件名称。 | | listener | (event) => void | 是 | 事件回调函数。 |

返回值:

| 返回值 | 类型 | 说明 | |---|---|---| | dispose | () => void | 取消本次监听。 |

2.4.2 接收消息字段

message.received 回调字段:

| 字段 | 类型 | 说明 | |---|---|---| | conversationId | string | 消息所在会话 ID。 | | message | ChatMessage | 接收的标准消息对象。 |

message 字段:

| 字段 | 类型 | 说明 | |---|---|---| | msgId | stringundefined | 服务端消息 ID。 | | cMsgId | stringundefined | 本地消息 ID,用于关联发送中的消息。 | | sId | string | 会话 ID。 | | subId | stringundefined | 子渠道或子会话标识。 | | msgType | number | 底层消息类型编号,主要用于排障。 | | msgTypeDes | textsystemrevoke 等 | SDK 归一化后的消息大类。 | | content | object | 消息原始内容,字段随消息大类变化。 | | sender | visitoragentrobotsystemother | 消息发送方。 | | direction | inboundoutbound | 消息方向。 | | createdAt | number | 消息创建时间,Unix 毫秒时间戳。 | | sendStatus | pendingsendingsentfailedrevoked | 本地发送状态。 | | errorMessage | stringundefined | 发送失败原因。 |

页面展示模型

resolveMessagePresentation(message) 返回以下公共字段:

| 字段 | 类型 | 说明 | |---|---|---| | id | string | 展示模型唯一 ID。 | | conversationId | string | 会话 ID。 | | messageId | stringundefined | 服务端消息 ID。 | | clientMessageId | stringundefined | 本地消息 ID。 | | direction | sendreceivecenter | 展示方向。 | | sender | visitoragentrobotsystemotherundefined | 发送方。 | | text | string | 通用文本内容;卡片类型可能为空。 | | createdAt | number | 创建时间,Unix 毫秒时间戳。 | | status | { type: string; label: string }undefined | 展示状态,例如发送中、已发送、失败。 | | actions | MessageIntent[] | 当前消息可执行的操作。 |

kind 与专有字段:

| kind | 消息类型 | 专有字段 | |---|---|---| | textrich_text | 文本 | htmlaiGeneratedTextfeedback | | image | 图片 | urlpreviewUrlwidthheightvariant | | audio | 语音 | urldurationSecondstranscript | | video | 视频 | url | | file | 文件 | urldownloadUrlfileNamefileTypefileSizeLabeluploadProgressuploadState | | reply_quote | 引用回复 | htmlquote | | article_listcrosswise_cardorder_cardself_card | 列表或卡片 | items | | option_card | 选项卡片 | modetitlefooterimageUrlpageSizedisableBatchitemsgroups | | html_card | HTML 卡片 | html | | info_gather_card | 信息收集 | themetitlesubtitleimageUrlimageAlignfieldsbuttons | | wait_notice | 等待提示 | waitType | | evaluate_card | 满意度评价 | titleevaluationStatusevaluationTypeexpiresAttimeoutcanUpdate | | work_order_noticework_order_info | 工单消息 | titlenumberstateurlrelatedMessageIdfields | | leave_message_card | 留言卡片 | leaveMessageStatusfieldsdealRemarkdealTimedealUserNumberdealUserNicknameadditionalRemarks | | inquiry_form_card | 询前表单 | fieldssubmitCount | | systemfallback | 系统或兜底 | status |

各类型字段明细
textrich_text:文本消息

用于普通文本、富文本和大模型文本。

| 字段 | 类型 | 说明 | |---|---|---| | kind | "text""rich_text" | 消息展示类型。 | | html | stringundefined | 富文本 HTML 内容。 | | aiGeneratedText | stringundefined | 大模型生成的文本。 | | feedback | objectundefined | 大模型反馈信息;字段为 answerEnabledllmEnabledpromptsatisfiedTextunsatisfiedTextresultText。 |

image:图片消息

用于普通图片和自定义表情图片。

| 字段 | 类型 | 说明 | |---|---|---| | kind | "image" | 消息展示类型。 | | url | string | 原图地址。 | | previewUrl | stringundefined | 预览图地址。 | | width | numberundefined | 图片宽度。 | | height | numberundefined | 图片高度。 | | variant | "image""emoji" | 普通图片或表情图片。 |

audio:语音消息

| 字段 | 类型 | 说明 | |---|---|---| | kind | "audio" | 消息展示类型。 | | url | string | 音频地址。 | | durationSeconds | numberundefined | 音频时长,单位秒。 | | transcript | stringundefined | 语音转写文本。 |

video:视频消息

| 字段 | 类型 | 说明 | |---|---|---| | kind | "video" | 消息展示类型。 | | url | string | 视频地址。 |

file:文件消息

| 字段 | 类型 | 说明 | |---|---|---| | kind | "file" | 消息展示类型。 | | url | string | 文件地址。 | | downloadUrl | stringundefined | 下载地址。 | | fileName | stringundefined | 文件名。 | | fileType | stringundefined | 文件类型。 | | fileSizeLabel | stringundefined | 格式化后的文件大小。 | | uploadProgress | numberundefined | 上传进度。 | | uploadState | "uploading""failed"undefined | 上传状态。 |

reply_quote:引用回复

| 字段 | 类型 | 说明 | |---|---|---| | kind | "reply_quote" | 消息展示类型。 | | html | stringundefined | 当前回复的富文本内容。 | | quote | object | 被引用消息;字段为 targetMessageIdsenderLabeltextrevoked。 |

article_list:图文列表

| 字段 | 类型 | 说明 | |---|---|---| | kind | "article_list" | 消息展示类型。 | | items | array | 图文项列表。每项包含 titledescriptionimageUrllinkUrl,字段均可能为空。 |

option_card:选项卡片

用于机器人导航、知识问答、欢迎问题和其他选项消息。

| 字段 | 类型 | 说明 | |---|---|---| | kind | "option_card" | 消息展示类型。 | | mode | "guide""guide_robot""more_qa""welcome_questions"undefined | 卡片业务模式。 | | title | stringundefined | 卡片标题。 | | footer | stringundefined | 卡片底部说明。 | | imageUrl | stringundefined | 卡片图片。 | | pageSize | numberundefined | 每页展示数量。 | | disableBatch | booleanundefined | 是否禁止批量操作。 | | items | OptionCardPresentationItem[] | 选项列表;每项包含 textknowledgeIdmsgIdidintent。 | | groups | array | 分组列表;每组包含 titleitems。 |

crosswise_card:横向卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "crosswise_card" | 消息展示类型。 | | items | array | 卡片项列表,每项包含 titleimageUrlimagePositionintent。 |

html_card:HTML 卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "html_card" | 消息展示类型。 | | html | string | HTML 内容。渲染时应按客户页面的安全策略处理。 |

order_card:订单或工单卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "order_card" | 消息展示类型。 | | items | OrderCardPresentationItem[] | 卡片项列表。每项可包含 numbertimedescribepicturepricestatusstatusTexturlintent。 |

self_card:独立跳转卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "self_card" | 消息展示类型。 | | items | SelfCardPresentationItem[] | 卡片项列表。每项包含 titletexttypeimageUrlimagePositionbuttonWayurlbuttonsintentsbuttons 每项包含 texturl。 |

info_gather_card:信息收集卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "info_gather_card" | 消息展示类型。 | | theme | stringundefined | 卡片主题。 | | title | stringundefined | 标题。 | | subtitle | stringundefined | 副标题。 | | imageUrl | stringundefined | 卡片图片。 | | imageAlign | 12 | 图片对齐方式。 | | fields | array | 展示字段,包含 labelvaluetypeimageUrlfontSizecolorfontWeighttextDecoration。 | | buttons | array | 操作按钮,包含 label 和可选的 intent。 |

wait_notice:等待提示

| 字段 | 类型 | 说明 | |---|---|---| | kind | "wait_notice" | 消息展示类型。 | | waitType | "queue""leave_message"undefined | 排队等待或留言等待。 |

evaluate_card:满意度评价卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "evaluate_card" | 消息展示类型。 | | title | stringundefined | 评价标题。 | | evaluationStatus | numberundefined | 当前评价状态。 | | evaluationType | numberundefined | 评价类型。 | | expiresAt | numberundefined | 评价失效时间。 | | timeout | numberundefined | 评价超时时间。 | | canUpdate | booleanundefined | 是否允许修改评价。 |

work_order_noticework_order_info:工单消息

| 字段 | 类型 | 说明 | |---|---|---| | kind | "work_order_notice""work_order_info" | 工单消息类型。 | | title | stringundefined | 标题。 | | number | stringundefined | 工单号。 | | state | numberundefined | 工单状态。 | | url | stringundefined | 工单详情地址。 | | relatedMessageId | stringundefined | 关联消息 ID。 | | fields | array | 工单字段,每项包含 labelvaluecustomerVisible。 |

leave_message_card:留言卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "leave_message_card" | 消息展示类型。 | | leaveMessageStatus | numberundefined | 留言处理状态。 | | fields | array | 留言字段,包含 fieldTypeIdfieldNamebuttonTypevalue。附件值包含 nameurlpreviewUrlkind。 | | dealRemark | stringundefined | 处理备注。 | | dealTime | stringundefined | 处理时间。 | | dealUserNumber | stringundefined | 处理人编号。 | | dealUserNickname | stringundefined | 处理人昵称。 | | additionalRemarks | array | 追加处理记录;每项包含 remarkdealUserNumdealUserNicknamedealTime。 |

inquiry_form_card:询前表单卡片

| 字段 | 类型 | 说明 | |---|---|---| | kind | "inquiry_form_card" | 消息展示类型。 | | fields | array | 表单字段,包含 fieldLabelvalueName。 | | submitCount | numberundefined | 已提交次数。 |

systemfallback:系统或兜底消息

| 字段 | 类型 | 说明 | |---|---|---| | kind | "system""fallback" | 消息展示类型。 | | status | { type: string; label: string }undefined | 系统或兜底状态。 |

示例:

import { resolveMessagePresentation } from "icsoc-visitor-sdk";

client.on("message.received", ({ message }) => {
  const presentation = resolveMessagePresentation(message);
  renderByKind(presentation.kind, presentation);
});

2.4.3 其他事件

| 事件 | 回调字段 | 说明 | |---|---|---| | connection.changed | statepreviousState | 连接状态变化。 | | conversation.started | conversation | 新建会话完成。 | | conversation.recovered | conversationinitialMessageCount | 会话恢复完成。 | | conversation.ended | conversationIdreason | 会话结束。 | | history.loaded | conversationIdpage | 历史消息加载完成。 | | history.stateChanged | conversationIdstate | 历史分页状态变化。 | | error | error | SDK、网络或服务端错误。 |

history.loaded.page 字段与 2.2.4 返回值相同。发送消息的成功与失败通过 sendText()sendImage()sendFile() 等方法返回的 Promise 处理。