Я пытаюсь сделать нечто подобное (Программируемый чат, Twilio Flex), и вот что привело меня в рабочее состояние:
- Вместо того, чтобы создавать задачу вручную, я включил поток Studio по умолчанию, который вы получаете при инициализации Flex. Я начал с этого doc , но он дает только теоретическое понимание. Я выяснил фактический веб-крючок, используя Образец веб-приложения 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
});
- Это только на полпути. К настоящему времени вы должны увидеть задачу, появляющуюся во Flex, но если агент принимает ее, он не может отправить сообщение назад и не видит сообщений от клиента. Я предполагаю, что когда вы делаете это из Twilio Widget, в этом есть какая-то магия.
Мне удалось выяснить, что для каналов, которые я создаю вручную, когда принимаю задачу в качестве агента, агент не присоединяется к каналу. Таким образом, количество участников 1 вместо 2.
Это означает, что агент в основном не может видеть данные канала и отправлять на него сообщения. Может быть, в моем канале отсутствуют некоторые метаданные в атрибутах, но я пока не смог понять это.
Я использовал обратный вызов , который вы получаете при каждом изменении состояния задачи, и, в частности, я использовал событие reservation.accepted
, чтобы добавить агента в качестве члена канала вручную. Вы можете добавить обратный вызов в настройках TaskRouter внизу.
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 невелика и пропускает некоторые очень простые руководства, такие как «Настройка программируемого чата Twilio с Flex с нуля». Подобные руководства помогут всем понять, как все API Twilio объединяются в таком мощном инструменте, как Flex.
В любом случае, надеюсь, мой ответ поможет. Я могу попытаться уточнить, если у вас есть вопросы.