以编程方式创建的任务属性未显示在Twilio Flex中

问题描述 投票:2回答:1

我正在试验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代理仪表板中弹出,但是当我接受它时:

  1. CHAT选项卡完全为空
  2. “信息”选项卡仅包含一般信息,例如: 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集成?

  1. 如何正确创建Task Rotuer任务以便在聊天和自定义属性中显示消息在INFO选项卡上可见?
  2. 如何在Flex聊天窗口中实现该代理的响应将被路由回现有聊天?
  3. 如何实现后续用户消息将被路由到现有的Flex任务而不是创建新任务?换句话说,如何跟踪聊天和Flex之间的对话?
  4. 任何人都有代码片段显示原始的“Flex Create Chat”Twilio功能在从Twilio控制台中删除并替换为Twilio代理服务集成之前是什么样子的?
twilio twilio-api twilio-programmable-chat twilio-functions
1个回答
2
投票

我正在尝试做类似的事情(可编程聊天,Twilio Flex),这就是让我进入工作状态的原因:

  1. 我没有手动创建任务,而是选择了初始化Flex时获得的默认Studio流程。我从这个doc开始,但它只给出了理论上的理解。我通过使用Twilio Flex Sample Web App并跟踪它创建的频道找出了实际的webhook。
  2. 每当网络/移动客户端想要聊天时,我都会调用我的自定义端点来执行所需的设置。
// 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. 那只能让你中途走。到目前为止,您应该会在Flex中看到一个任务弹出,但如果Agent接受了该任务,则他无法回复消息,也无法看到来自客户端的消息。我假设你从Twilio Widget那里做了一些魔术。

我能够弄清楚,当我接受任务作为代理时,我手动创建的频道,代理不加入频道。所以参与者的数量是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这样强大的工具中融合在一起。

无论如何,希望我的回答有所帮助。如果您有疑问,我可以尝试进一步详细说明。

© www.soinside.com 2019 - 2024. All rights reserved.