场景概述
Zendesk是客户支持、销售和其他客户沟通中最流行的SaaS产品之一。同时,根据Gartner的数据,腾讯聊天在中国市场中取得了领先地位,并且是全球通信平台即服务(CPaaS)中最具竞争力的提供商之一。自然,我们为您带来了将聊天与Zendesk集成的解决方案。
在这篇文章中,我们将讨论如何构建一个客户端-代理实时通信系统,扩展Zendesk支持团队的边界,使支持团队能够在任何平台上与客户聊天。我们已经完成了Zendesk票据栏的聊天应用程序,您所需要做的就是按照以下说明安装它并发布自己的客户端。
如果这不是您感兴趣的集成解决方案,不要急于关闭按钮。请继续阅读这篇文章,通过TUIKit构建您自己的私人Zendesk应用,这并不是您待办事项中的一项繁琐任务,而是根据您想要构建的应用复杂性,仅需几个小时或几天。
应用产品
基本集成指南
前提条件
如果您尚未注册Zendesk,请尝试 免费试用。
要使用聊天的任何服务,您必须注册腾讯RTC,该服务包含许多基于云的服务。之后,在控制台 上单击创建应用程序
以获取您的SDKAppID
,这是启动聊天服务所需的。


对于客户端构建,您还需要一个网络服务器,这在本文中不包括。
集成图
此集成解决方案的目标明确而清晰:监听代理的分配并邀请代理加入与客户的对话,以便在Zendesk外讨论票据中的问题或咨询。
以下是一般集成图:
一般工作流程如下:
1. 终端用户登录到聊天。
2. 终端用户向您的后端服务器提交票据。
3. 根据提交的信息,为Zendesk创建票据。
4. 在聊天中创建一个组,等待代理加入该组。
5. 一名代理接受票据或被分配给某名代理。
6. 指定的代理加入聊天组。
7. 现在客户和代理可以自由聊天。
客户端侧的工作流程如下:
在登录之前,客户可以选择重用上次创建的票据。为此,只需登录聊天服务器。
否则,提交新的Zendesk票据。
登录服务器并使用返回的ticket.id创建一个组。
Zendesk的聊天流程如下:
更新票据的过程如下:
场景特定实现
客户端侧构建
您需要开发一个前端项目来实现聊天功能,以及一个后端项目来调用Zendesk请求。不必惊慌,前端可以顺利完成,使用TUIKit就像搭积木一样。TUIKit是一套基于聊天SDK的TUI组件,提供独立的组件,包括会话、聊天、搜索、关系链、群组以及音视频通话。TUIKit目前覆盖iOS、Android、Web和Flutter平台,我们也在努力开发React Native。请关注频道以获取最新状态。通过应用TUIKit,您只需定义调用createTicket
API的策略。
以下是构建后端项目的所有代码:
const express = require('express');
const axios = require('axios').default;
var TLSSigAPIv2 = require('tls-sig-api-v2'); // 为TIM生成UserSig
require('dotenv').config();
const app = express();
app.use(express.json());
const port = process.env.PORT || 15000;
const YOUR_SDKAPPID = process.env.YOUR_SDKAPPID || 0;
const YOUR_SECRET = process.env.YOUR_SECRET || '';
const ADMIN_USERID = process.env.ADMIN_USERID || '';
const zendeskAxioInstance = axios.create({
baseURL: `https://${process.env.SUB_DOMAIN}.zendesk.com/api/v2/`,
auth: {
username: process.env.EMAIL || '',
password: process.env.TOKEN || ''
},
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
timeout: 35000
});
app.use(express.json());
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', '*');
next();
});
app.post('/createticket', async (req, res) => {
const { userId, caseInfo } = req.body;
if (!userId) return res.status(500).send('缺少userId');
const zendeskCase = await createTicket(caseInfo);
if (!zendeskCase.success) return res.status(500).send('票据创建失败');
const groupId = zendeskCase.id;
const result = await createGroup(
groupId,
userId,
caseInfo.subject || groupId
);
if (result.ErrorCode !== 0)
return res.status(500).send('组创建失败');
sendGreeting(result.GroupId);
res.status(200).send(result);
});
const createTicket = async function (caseInfo) {
const { subject, desc, name, email } = caseInfo;
const data = {
request: {
requester: {
name: name || '匿名客户',
email: email
},
subject: subject,
comment: {
body: desc
}
}
};
try {
const result = await zendeskAxioInstance({
method: 'POST',
url: '/requests.json',
data: data
});
return {
id: result.data.request.id,
success: true
};
} catch (e) {
return { id: undefined, success: false, error: e };
}
};
const generateUserSig = function () {
const expires = 600;
const api = new TLSSigAPIv2.Api(YOUR_SDKAPPID, YOUR_SECRET);
return api.genSig(ADMIN_USERID, expires);
};
const generateRandom = function () {
return Math.floor(Math.random() * 4294967295);
};
const createGroup = async function (groupId, userId, groupName) {
const sig = generateUserSig();
const random = generateRandom();
const data = {
Type: 'Public',
Name: groupName,
GroupId: `ZENDESK#${groupId}`,
ApplyJoinOption: 'FreeAccess',
MemberList: [{ Member_Account: userId }]
};
const url = `https://console.tim.qq.com/v4/group_open_http_svc/create_group?sdkappid=${YOUR_SDKAPPID}&identifier=${ADMIN_USERID}&usersig=${sig}&random=${random}&contenttype=json`;
try {
const groupRes = await axios.post(url, data);
return groupRes.data;
} catch (e) {
return { ErrorCode: -1, ErrorInfo: e };
}
};
const sendGreeting = async function (groupId) {
const sig = generateUserSig();
const random = generateRandom();
const data = {
GroupId: groupId,
Content: "我们正在为您的主题指派一名代理,请稍候..."
};
const url = `https://console.tim.qq.com/v4/group_open_http_svc/send_group_system_notification?sdkappid=${YOUR_SDKAPPID}&identifier=${ADMIN_USERID}&usersig=${sig}&random=${random}&contenttype=json`;
try {
const groupRes = await axios.post(url, data);
return groupRes.data;
} catch (e) {
return { ErrorCode: -1, ErrorInfo: e };
}
};
app.listen(process.env.PORT || port, () =>
console.log(`示例应用正在监听端口 ${port}!`)
);
让我们来解析一下代码。
const port = process.env.PORT || 15000;
const YOUR_SDKAPPID = process.env.YOUR_SDKAPPID || 0;
const YOUR_SECRET = process.env.YOUR_SECRET || '';
const ADMIN_USERID = process.env.ADMIN_USERID || '';
第一部分要求您将聊天标识信息设置为环境变量。您可以在这里找到所有信息。警告:请勿将您的密钥记录在代码中,以免泄露到互联网上。
const zendeskAxioInstance = axios.create({
baseURL: `https://${process.env.SUB_DOMAIN}.zendesk.com/api/v2/`,
auth: {
username: process.env.EMAIL || '',
password: process.env.TOKEN || ''
},
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
timeout: 35000
});
其次,配置Zendesk请求。
// 创建Zendesk票据
const createTicket = async function (caseInfo) {
const { subject, desc, name, email } = caseInfo;
const data = {
request: {
requester: {
name: name || '匿名客户',
email: email
},
subject: subject,
comment: {
body: desc
}
}
};
try {
const result = await zendeskAxioInstance({
method: 'POST',
url: '/requests.json',
data: data
});
return {
id: result.data.request.id,
success: true
};
} catch (e) {
return { id: undefined, success: false, error: e };
}
};
// 创建聊天组
const createGroup = async function (groupId, userId, groupName) {
const sig = generateUserSig();
const random = generateRandom();
const data = {
Type: 'Public',
Name: groupName,
GroupId: `ZENDESK#${groupId}`,
ApplyJoinOption: 'FreeAccess',
MemberList: [{ Member_Account: userId }]
};
const url = `https://console.tim.qq.com/v4/group_open_http_svc/create_group?sdkappid=${YOUR_SDKAPPID}&identifier=${ADMIN_USERID}&usersig=${sig}&random=${random}&contenttype=json`;
try {
const groupRes = await axios.post(url, data);
return groupRes.data;
} catch (e) {
return { ErrorCode: -1, ErrorInfo: e };
}
};
最后,根据输入参数创建Zendesk票据,并使用返回的zendeskCase.id
作为groupID创建聊天组,该groupID以ZENDESK#
作为前缀。
测试并在线发布服务器代码以供客户端使用。
TIM for Zendesk 安装
通过在Zendesk市场中搜索“Chat for Zendesk”来安装它。
接下来,输入您的SDKAppId以完成安装。
该应用将在票据栏区域显示。
它使用代理的ID作为聊天的UserID,您需要为此UserID获取UserSig。有关如何检索的详细信息,请参阅UserSig。一旦登录,聊天中的用户名将自动更新为代理的姓名,可以在个人资料页面使用其他个人资料信息进行更新。一旦登录,您将保持登录状态,直到UserSig过期或触发注销。
当代理被分配到票据时,他/她将被邀请进入聊天组,并与客户进行各种类型的消息交流。
此外,您还可以私下安装该应用,联系tencentcloud_im@tencent.com以获取最新的TIM包或源代码。按照说明在这里上传私人应用。
如果提供的应用不符合您的预期,您也可以开发自己的私人应用。您可以申请TUIKit来提升UI构建,并按照说明创建自己的应用。更多Zendesk API参考文献列在这里。
这就是您所需的将聊天与Zendesk集成的全部内容。到目前为止,您可能已了解集成过程及Zendesk的工作流程,并建立了自己的客户端-代理实时通信应用。如果您有任何不清楚的地方或对与Zendesk的集成有更多想法,请随时联系我们。
立即订购
点击这里快速访问购买页面进行订单。