Reputation: 265
I am experimenting with Twilio Flex. What we are trying to build is chat(bot) application integrating two or three participants (user + cc human agent + chabot versus user + cc human agent).
I am able to join Twilio chat channel (both from web application based on Node.js started app https://www.twilio.com/docs/chat/javascript/quickstart and our server side code utilizing npm package twilio-chat). Then I am creating Flex Task using the following code:
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'
})
Task is successfully created and pops up in Twilio Flex agent dashboard but when I accept it:
CHAT tab is completely empty
INFO tab contains only general information, e.g.:
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
my custom attributes (type/message) are not included at all
I was not able to find any complex example of using flex with twilio chat, just very generic (and not overly explanatory) high level overview here: https://www.twilio.com/docs/taskrouter/contact-center-blueprint/chat-taskrouter
Has somebody experience with integrating chat (not necessarily Twilio Chat) with Twilio Flex?
How to achieve subsequent user messages will be routed into existing Flex Task and not create new task instead? In other words how to keep the track of conversations between chat and Flex?
Anybody having code snippet showing how original "Flex Create Chat" Twilio function looked like before it was removed from Twilio console and replaced with Twilio Proxy Service integration?
Upvotes: 2
Views: 1734
Reputation: 21
I'm trying to do something similar (Programmable Chat, Twilio Flex) and here is what got me to a working state:
// 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
});
I was able to figure out that for channels I create manually when I accept a task as an Agent the Agent doesn't join a Channel. So the number of participants is 1 instead of 2.
This means that Agent basically can't see Channel data and send messages to it. Maybe my Channel is missing some metadata in attributes but I wasn't able to figure it out yet.
What I did is I used a callback that you get whenever the task status changes and in particulary, I used reservation.accepted
event to add the Agent as a member of a channel manually. You can add callback under TaskRouter Settings at the bottom.
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"
});
});
});
Here is a full code
// 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"
});
});
});
I still have a lot to figure out. Unfortunately, Flex documentation isn't great at this point and misses some very basic tutorials like "Configuring Twilio Programmable Chat with Flex from ground up". This kind of tutorials would help everyone to understand how all Twilio APIs come together in such a powerful tool like Flex.
Anyway, hope my answer helps. I can try to elaborate further if you have questions.
Upvotes: 2