SecondMeSecondMe API
SecondMe API

分身对话

与 SecondMe 分身进行实时对话,支持实名和匿名用户

分身对话接口允许第三方应用接入 SecondMe 分身的对话能力。你的用户(登录或匿名)可以与任何 SecondMe 分身进行实时聊天。

Base URL: https://api.mindverse.com/gate/lab


概述

分身对话分为两步:

  1. 初始化 (/visitor-chat/init) — 验证身份 + 创建会话 + 返回 WebSocket 连接凭证
  2. 发送消息 (/visitor-chat/send) — 发送文本消息,AI 回复通过 WebSocket 推送

身份模式

模式认证方式适用场景
实名用户OAuth2 authorization_code Token用户已通过 OAuth 登录你的应用
匿名用户OAuth2 client_credentials Token用户无需登录,你的后端代表用户发起对话

实名用户流程(2 步)

用户已通过 OAuth 登录,直接使用用户的 access token:

1. POST /visitor-chat/init (Authorization: Bearer 用户token, body: {apiKey})
2. POST /visitor-chat/send (Authorization: Bearer 用户token, body: {sessionId, message})

匿名用户流程(3 步)

你的后端先获取应用级 token,再代表匿名用户调用:

1. POST /oauth/token/client  → 获取应用 token(可缓存 7 天)
2. POST /visitor-chat/init   → 初始化对话(需传 visitorId)
3. POST /visitor-chat/send   → 发送消息

注意client_secret 只在你的后端使用,永远不要暴露给前端。匿名用户的前端应通过你的后端 API 代理调用。


获取应用 Token(匿名模式专用)

使用 client_credentials grant 获取应用级 access token。此 token 代表你的应用(而非特定用户),用于匿名用户场景。

POST /api/oauth/token/client

请求

curl -X POST "https://api.mindverse.com/gate/lab/api/oauth/token/client" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=chat.write"

响应

{
  "code": 0,
  "data": {
    "accessToken": "lba_at_xxx...",
    "tokenType": "Bearer",
    "expiresIn": 604800,
    "scope": ["chat.write"]
  }
}
字段说明
accessToken应用 token,用于后续 init 和 send 调用
expiresIn有效期(秒),建议缓存,过期后重新获取

初始化对话

创建 visitor chat 会话,返回 WebSocket 连接凭证。

POST /api/secondme/visitor-chat/init

认证

需要 OAuth2 Token(authorization_codeclient_credentials)。

请求头

必需说明
AuthorizationBearer Token
Content-Typeapplication/json

请求参数

参数类型必需说明
apiKeystring分身 API Key(sk- 开头)
visitorIdstring条件必需匿名用户唯一标识,client_credentials 认证时必填。只允许字母、数字、下划线和连字符,最长 128 字符
visitorNamestring访客显示名称(匿名模式可选),显示在分身中心的对话列表中,最长 200 字符

请求示例

实名用户:

curl -X POST "https://api.mindverse.com/gate/lab/api/secondme/visitor-chat/init" \
  -H "Authorization: Bearer lba_at_user_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "sk-your-avatar-api-key"
  }'

匿名用户:

curl -X POST "https://api.mindverse.com/gate/lab/api/secondme/visitor-chat/init" \
  -H "Authorization: Bearer lba_at_app_token" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "sk-your-avatar-api-key",
    "visitorId": "device_abc123",
    "visitorName": "张三"
  }'

分身中心会显示 {visitorName}({appName})(如「张三(我的应用)」),其中 appName 由系统从你的应用注册信息自动获取。

响应

{
  "code": 0,
  "data": {
    "sessionId": "6ff56704-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "wsUrl": "wss://ws.mindos.com/os/ws?wsId=...&authBody=...",
    "avatarName": "我的分身",
    "opening": "你好!有什么可以帮你的?"
  }
}
字段类型说明
sessionIdstring会话 ID(用于发送消息)
wsUrlstring完整的 WebSocket 连接地址(含认证参数,直接连接即可)
avatarNamestring分身名称
openingstring | null分身开场白

发送消息

发送文本消息到当前会话,AI 回复通过 WebSocket 推送。

POST /api/secondme/visitor-chat/send

认证

需要 OAuth2 Token(与 init 使用相同的 token)。

请求参数

参数类型必需说明
sessionIdstring会话 ID(从 init 返回)
apiKeystring分身 API Key(与 init 相同)
messagestring消息内容,1-10000 字符

token 过期或缓存失效时,/send 会自动用当前 OAuth token + apiKey 恢复会话,无需重新调用 /init

请求示例

curl -X POST "https://api.mindverse.com/gate/lab/api/secondme/visitor-chat/send" \
  -H "Authorization: Bearer lba_at_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "sessionId": "6ff56704-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "apiKey": "sk-your-avatar-api-key",
    "message": "你好,请问你是谁?"
  }'

响应

{
  "code": 0,
  "data": {
    "sent": true
  }
}

WebSocket 消息格式

连接 wsUrl 后,AI 回复会通过 WebSocket 推送。

AI 回复消息

{
  "sender": "umm",
  "sessionId": "6ff56704-...",
  "index": 0,
  "multipleData": [{
    "singleDataType": "text",
    "modal": {
      "answer": "你好!我是..."
    }
  }]
}
字段说明
sender"umm" 表示 AI 回复
index0, 1, 2, ... 为中间块(流式输出),-1 为回复结束
multipleData[0].modal.answerAI 回复文本

消息拼接逻辑

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.sender !== "umm") return;

  if (msg.index === -1) {
    // 回复结束
    return;
  }

  const text = msg.multipleData?.[0]?.modal?.answer;
  if (text) {
    // 追加到当前回复
    currentReply += text;
  }
};

完整示例

// 1. 初始化
const initRes = await fetch("/api/secondme/visitor-chat/init", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ apiKey: "sk-xxx" }),
});
const { data } = await initRes.json();

// 2. 连接 WebSocket
const ws = new WebSocket(data.wsUrl);
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.sender === "umm" && msg.index !== -1) {
    console.log("AI:", msg.multipleData?.[0]?.modal?.answer);
  }
};

// 3. 发送消息
await fetch("/api/secondme/visitor-chat/send", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    sessionId: data.sessionId,
    apiKey: "sk-xxx",
    message: "你好",
  }),
});

错误码

错误码HTTP 状态说明
visitor_chat.visitor_id_required400匿名模式下未传 visitorId
visitor_chat.session_not_found400会话未初始化或已过期,需重新调用 /init
visitor_chat.session_expired400会话缓存已过期,需重新调用 /init
oauth2.invalid_client401client_id 或 client_secret 无效
open.api.key.not.found401分身 API Key 无效
open.api.user.not.found404用户不存在

FAQ

visitorId 可以用什么?

任何你能持久化的用户标识 — 设备 fingerprint、你自己数据库的 user ID、或随机 UUID。相同 visitorId 会复用已有会话。

client_credentials token 要缓存吗?

建议缓存。有效期 7 天,过期后重新获取即可。

WebSocket 断了怎么办?

重新调用 visitor-chat/init,会得到新的 wsUrl(session 会复用)。