我正在试验Twilio Flex。我们正在尝试构建的是集成两个或三个参与者的聊天(机器人)应用程序(用户+ cc人工代理+ chabot与用户+ cc人工代理)。
我可以加入Twilio聊天频道(两者都来自基于Node.js的网络应用程序启动应用程序https://www.twilio.com/docs/chat/javascript/quickstart和我们的服务器端代码利用npm软件包twilio-chat)。然后我使用以下代码创建Flex任务:
let task = await twilioClient.taskrouter.workspaces(TWILIO_FLEX_WORKSPACE)
.tasks.create({attributes: JSON.stringify({
type: 'support',
message: 'some message from chat here'
}),
workflowSid: TWILIO_FLEX_CHAT_WORKFLOW,
taskChannel: 'chat'
})
任务已成功创建并在Twilio Flex代理仪表板中弹出,但是当我接受它时:
TASK CONTEXT
Task type
chat
Task created on
Wed Jan 23 2019 16:01:36 GMT+0100 (Central Europe Standard Time)
Task priority
0
Task queue
Everyone
CUSTOMER CONTEXT
Customer name / phone number
Anonymous
Country
ADDONS
No add-ons enabled. To expand your experience, visit Twilio Marketplace
我的自定义属性(类型/消息)根本不包含在内
我无法找到任何使用flex与twilio聊天的复杂示例,这里只是非常通用(而不是过于解释)的高级概述:https://www.twilio.com/docs/taskrouter/contact-center-blueprint/chat-taskrouter
是否有人将聊天(不一定是Twilio Chat)与Twilio Flex集成?
我正在尝试做类似的事情(可编程聊天,Twilio Flex),这就是让我进入工作状态的原因:
// After creating a Twilio Programmable Chat Channel set up a Studio webhook
app.post("/create-task", function(request, response) {
// see full code below
chatService.channels
.create({
// See full code below
})
.then(channel => {
const webhookUrl = channel.links.webhooks;
const options = {
url: webhookUrl,
method: "POST",
auth: {
user: accountSid,
pass: authToken
},
form: {
Type: "studio",
"Configuration.FlowSid": twilioFlowSid
}
};
return new Promise((resolve, reject) => {
requestLibrary.post(options, function(error, response, body) {
if (!error) {
resolve(channel);
} else {
reject(error);
}
});
});
});
// see full code below
});
我能够弄清楚,当我接受任务作为代理时,我手动创建的频道,代理不加入频道。所以参与者的数量是1而不是2。
这意味着Agent基本上看不到Channel数据并向其发送消息。也许我的频道缺少属性中的一些元数据,但我还是无法搞清楚。
我所做的是我使用a callback,只要任务状态发生变化就会得到,特别是我使用reservation.accepted
事件手动添加Agent作为频道成员。您可以在底部的TaskRouter Settings下添加回调。
app.post("/accept-task-callback", function(request, response) {
const { TaskAttributes, WorkerSid, WorkerName, EventType } = request.body;
const { channelSid } = JSON.parse(TaskAttributes);
console.log("received event", EventType);
if (EventType !== "reservation.accepted") {
response.send("OK");
return;
}
console.log("Adding member", WorkerSid, WorkerName, "on event", EventType);
chatService
.channels(channelSid)
.members.create({ identity: WorkerName })
.then(member => {
response.send({
instruction: "accept"
});
})
.catch(error => {
console.error(error);
response.send({
instruction: "reject"
});
});
});
这是一个完整的代码
// This is Express App
app.post("/create-task", function(request, response) {
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const workspaceSid = process.env.TWILIO_WORKSPACE_SID;
const workflowSid = process.env.TWILIO_WORKFLOW_SID;
const twilioFlowSid = "FW..."
// Identity of the Twilio Programmable Chat user who initiates a dialog. You get it from you signin or whatever
const username = request.body || "Nancy Drew Support";
chatService.channels
.create({
type: "private",
friendlyName: username,
attributes: JSON.stringify({
status: "ACTIVE",
from: username,
channel_type: "web"
})
})
.then(channel => {
const webhookUrl = channel.links.webhooks;
const options = {
url: webhookUrl,
method: "POST",
auth: {
user: accountSid,
pass: authToken
},
form: {
Type: "studio",
"Configuration.FlowSid": twilioFlowSid
}
};
return new Promise((resolve, reject) => {
requestLibrary.post(options, function(error, response, body) {
if (!error) {
resolve(channel);
} else
reject(error);
}
});
});
})
.then(async channel => {
// Join as a Customer requesting Support
return chatService
.channels(channel.sid)
.members.create({ identity: username });
})
.then(member => {
// return back channel sid we created
response.send({ channelSid: member.channelSid });
})
.catch(error => {
console.log(error);
response.fail(error);
});
});
app.post("/accept-task-callback", function(request, response) {
const { TaskAttributes, WorkerSid, WorkerName, EventType } = request.body;
const { channelSid } = JSON.parse(TaskAttributes);
console.log("received event", EventType);
if (EventType !== "reservation.accepted") {
response.send("OK");
return;
}
console.log("Adding member", WorkerSid, WorkerName, "on event", EventType);
chatService
.channels(channelSid)
.members.create({ identity: WorkerName })
.then(member => {
response.send({
instruction: "accept"
});
})
.catch(error => {
console.error(error);
response.send({
instruction: "reject"
});
});
});
我还有很多要弄清楚的。不幸的是,Flex文档在这一点上并不是很好,并且错过了一些非常基本的教程,例如“从头开始配置Flex的Twilio可编程聊天”。这种教程可以帮助每个人理解所有Twilio API如何在像Flex这样强大的工具中融合在一起。
无论如何,希望我的回答有所帮助。如果您有疑问,我可以尝试进一步详细说明。