用户识别
识别用户可将匿名聊天会话与真实用户资料关联起来。
工作原理
当您调用 Respondo.identify() 时,所提供的字段会被附加到对话上。 所有字段都是可选的 —— 只传您已有的字段。例如,您可以只发送 userId 而不带 email 或姓名。客服人员会在对话详情面板中看到这些数据。
参数#
| 属性 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| string | 可选 | 用户的电子邮箱地址 | |
| name | string | 可选 | 显示名称 |
| userId | string | 可选 | 您的内部用户 ID 或显示 ID —— 会原样显示在仪表盘中 |
| userHash | string | 可选 | 用于身份校验的 HMAC-SHA256 签名 |
| metadata | object | 可选 | 自定义字段的键值对(plan、company 等) |
| properties | object | 可选 | 在 Agent Settings 中定义的自定义联系人属性。键必须与属性定义匹配。值会以 cp_ 前缀存储,并可在 Inbox 中用于筛选。 |
示例:单页应用(SPA)javascript
// 登录成功后
async function onLogin(user) {
await authenticateUser(user);
Respondo.identify({
email: user.email,
name: user.fullName,
userId: user.id,
metadata: {
plan: user.subscription.plan,
company: user.company.name,
role: user.role,
signedUp: user.createdAt
},
properties: { // 自定义联系人属性
account_type: user.accountType, // 必须与 Agent Settings 中的键匹配
industry: user.industry,
contract_tier: user.tier
}
});
}使用标准安装代码片段时,您可以在任意时刻调用
identify() —— 在 widget.js 加载完成之前发起的调用会被代码片段排入队列,并在挂件初始化后自动重放。只有当您自行加载 widget.js,并在从未调用过 init() 的情况下就调用 identify() 时,身份数据才会被丢弃(并在控制台给出警告)—— 在手动接入方案中请始终先调用 init()。匿名访客#
如果您不调用 identify(),挂件会自动分配一个持久的 访客 ID,存储在 localStorage 中(键为 respondoai_visitor_id)。在仪表盘里,该对话会显示为 Guest · Web widget。
| 模式 | 仪表盘显示 | 是否需要 HMAC |
|---|---|---|
不调用 identify() | Guest · Web widget | 否 |
identify({ email, name }) | 显示姓名 + 邮箱 | 否 —— 除非启用了身份校验;届时未签名的 email/姓名会被静默剥离,会话保持匿名 |
identify({ userId }) | userId 原样显示 | 否 —— 除非启用了身份校验;届时必须提供有效的 userHash,否则身份会被剥离 |
identify({ userId, userHash }) | 已校验的用户身份 | 是 —— 经加密校验 |
当渠道启用了身份校验时,任何携带 email 或 userId、但不带有效 userHash 的 identify() 都会在服务器端被剥离,访客保持匿名 —— 详见下方的身份校验(HMAC)。
访客 ID 会在同一浏览器上跨会话保留。它永远不会作为经过身份验证的身份发送给 Respondo —— 仅用于匿名对话的连续性。
仅使用 userId 的识别(无 email 或姓名)#
如果您的平台没有用户邮箱或姓名 —— 例如您只有一个内部显示 ID —— 您可以只传 userId 。无需其他字段。仪表盘会在对话详情中原样显示该 userId。
userId + metadata(无 email 或姓名)javascript
// 您的平台只有一个显示 ID —— 这就够了
Respondo.identify({
userId: user.displayId, // 例如 "USR-4821" —— 会显示在仪表盘中
metadata: { // 可选的额外上下文
plan: 'premium',
region: 'eu-west'
}
});
// 无需 email 或姓名 —— 挂件只用 userId 就能工作为防止 userId 被伪造,请将其与
userHash 配对使用 (见下方的身份校验)。没有 HMAC,任何人都可以在浏览器控制台里传入任意 userId。Google Tag Manager / 延迟调用 identify()#
通过 GTM 嵌入时,用户数据在页面加载时可能尚不可用。有两种方式:
方案 A:localStorageKey(无需任何 JS)javascript
// 如果您的平台已经把用户 ID 写入 localStorage:
Respondo.init({
agentId: 'YOUR_AGENT_ID',
localStorageKey: 'myapp_user_id' // 自动读取 localStorage.getItem('myapp_user_id')
});
// 无需调用 identify() —— 挂件会自行获取 userId方案 B:通过 dataLayer 延迟调用 identify()javascript
// 1. 立即初始化挂件(GTM 标签)
Respondo.init({ agentId: 'YOUR_AGENT_ID' });
// 2. 稍后,当用户数据出现时(例如来自 dataLayer 或您的应用):
var waitForUser = setInterval(function() {
var uid = localStorage.getItem('myapp_user_id');
if (uid && window.Respondo && typeof window.Respondo.identify === 'function') {
clearInterval(waitForUser);
Respondo.identify({ userId: uid });
}
}, 500);localStorageKey 仅在尚未通过 identify() 设置 userId 时才会使用。显式调用 identify() 始终优先。身份校验(HMAC)#
如果不进行校验,任何人都可以通过传入伪造的 userId 或 email 来冒充某个用户。身份校验使用 HMAC-SHA256 从加密学上证明用户身份是由您的服务器设置的,而非客户端代码。
工作原理#
- 在渠道设置中启用身份校验 —— 您会获得一个 密钥。
- 在您的服务器上计算
HMAC-SHA256(secret, userId)—— secret 作为密钥,userId 作为消息 —— 并将结果发送到前端。如果您只通过 email 识别用户 (没有 userId),则改为签名 email:签名的载荷在有 userId 时是 userId,否则是 email。如果两者都传,则签名 userId;它的优先级更高。 - 将该哈希作为
userHash传入Respondo.identify()。 - Respondo 在服务器端校验该哈希。如果无效,身份信息会被剥离,用户被视为匿名。
切勿在前端代码中暴露您的密钥。HMAC 必须在您的后端计算。
一旦启用校验,每一次携带
userId 或 email 的 identify() 都必须包含有效的 userHash —— 否则身份字段会被剥离,访客将被视为匿名。服务器端示例#
Node.jsjavascript
const crypto = require('crypto');
const SECRET = process.env.RESPONDO_IDENTITY_SECRET;
function generateUserHash(userId) {
return crypto
.createHmac('sha256', SECRET)
.update(userId)
.digest('hex');
}
// 在您的 API 端点中:
app.get('/api/respondo-hash', (req, res) => {
const hash = generateUserHash(req.user.id);
res.json({ userHash: hash });
});Pythonpython
import hmac, hashlib, os
SECRET = os.environ['RESPONDO_IDENTITY_SECRET']
def generate_user_hash(user_id: str) -> str:
return hmac.new(
SECRET.encode(),
user_id.encode(),
hashlib.sha256
).hexdigest()
# 在您的视图 / 端点中:
user_hash = generate_user_hash(request.user.id)Gogo
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
)
func GenerateUserHash(userID, secret string) string {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(userID))
return hex.EncodeToString(mac.Sum(nil))
}前端用法#
启用身份校验javascript
// 从您自己的服务器获取哈希
const { userHash } = await fetch('/api/respondo-hash').then(r => r.json());
Respondo.identify({
email: user.email,
name: user.name,
userId: user.id,
userHash: userHash // HMAC-SHA256 签名
});