我们最近
提供了一种称为Dialogflow连接器
的业务解决方案:一堆Google的Dialogflow和我们的Voximplant云。 连接器可以代替呼叫中心接线员工作,并接受复杂的订单。 这之所以成为可能,是因为Dialogflow允许您摆脱通常的IVR场景,在这种情况下,客户端被迫从给定的集合中命名单词,交互式菜单可以响应这些单词。 Google平台可以顺序地从客户端接收输入并将它们收集在一起-例如,在在线商店中形成订单。 您可能已经听说过流行语“
插槽填充 ”,仅此而已。 正如我们为订购比萨饼的机器人一样,细节正在削减中等待您-以此类推,您可以煮类似的东西,并且很高兴电梯和“十一”的时代早已过去了...
电话号码
首先,您应该租用一个虚拟数字,机器人会将其“应答”到该虚拟数字。 为此,请在Voximplant管理面板的
“号码”菜单中
,单击“购买电话号码”。
在新屏幕上,将开关置于“测试号码”位置-这将允许您租用虚拟号码。
虚拟号码非常便宜,可以让您在我们的平台上全面测试任何解决方案。 租一个房间和更多...
...创建一个脚本
现在我们需要一个云方案,这是我们决策的核心。 将由他接听电话,识别语音并将其转移到Dialogflow。 该脚本必须在应用程序内部创建。 在左侧菜单中,选择
“应用程序” ,创建一个新的应用程序并为其命名。
然后转到应用程序中的“脚本”选项卡,然后单击加号创建自己的脚本。 记住给它起一个名字,例如dialogflow。
是时候写代码了!
让我们连接
AI模块-它包含Dialogflow的方法和事件-以及
语音识别模块和
player 。 我们将声明变量和棘手的
wordend函数,该函数将接收一个输入量(pizza)和一个带有单词('margarita','margaritas','margaritas')的数组,并返回与案例编号匹配的单词。 这是必要的,这样机器人就不会说“ 4 margaritas”,而是正确发出“ 4 margaritas”。
require(Modules.AI); require(Modules.ASR); require(Modules.Player); let mycall = null, voice = Language.Premium.RU_RUSSIAN_YA_FEMALE, account_name = "", dialed_number = "", caller_id = "", flow, lastText = '', player function wordend(num, words) { return words[ ((num=Math.abs(num%100)) > 10 && num < 15 || (num%=10) > 4 || num === 0) + (num !== 1) ]; }
现在添加传入呼叫的处理程序和
startASR helper函数:
VoxEngine.addEventListener(AppEvents.CallAlerting, (e) => { mycall = e.call; mycall.addEventListener(CallEvents.Connected, handleCallConnected); account_name = e.toURI.substring(e.toURI.indexOf('.') + 1); account_name = account_name.substring(0, account_name.indexOf('.')); dialed_number = e.destination; caller_id = e.callerid; mycall.answer(); }); function startASR() { mycall.removeEventListener(CallEvents.PlaybackFinished, startASR); mycall.sendMediaTo(flow); }
发生
Connected事件时,将
调用handleCallConnected函数。 实际上,整个填充发生在其中:
- 创建一个Dialogflow对象;
- 合成语音向客户打招呼,并提出下订单;
- 识别开始,客户下订单;
- 客户词被传送到Dialogflow,出现一个发话槽;
- 合成语音表示客户的命令和地址;
- 机器人挂断,会话关闭。
功能清单:
handleCallConnected | function handleCallConnected(e) { |
| |
| flow = AI.createDialogflow({ |
| lang: "ru" |
| }); |
| |
| if (AI.Events.DialogflowResponse !== undefined) |
| flow.addEventListener(AI.Events.DialogflowResponse, (event) => { |
| if (event.response.queryResult !== undefined) { |
| let result = event.response.queryResult |
| |
| if (result.queryText === undefined) { |
| if (result.languageCode !== undefined) startASR(); |
| return |
| } |
| |
| |
| if (result.fulfillmentText !== undefined) { |
| try { |
| player = VoxEngine.createTTSPlayer(result.fulfillmentText, voice) |
| player.addMarker(-500) |
| player.addEventListener(PlayerEvents.PlaybackMarkerReached, startASR) |
| player.sendMediaTo(mycall) |
| } catch (err) {} |
| |
| if (result.allRequiredParamsPresent == true && |
| result.outputContexts !== undefined && |
| result.parameters.PizzaType != undefined) { |
| |
| let msg = " "; |
| for (let k = 0; k < result.parameters.PizzaType.length; k++) { |
| let count = result.parameters.count[k] !== undefined ? result.parameters.count[k] : 1 |
| switch (count) { |
| case 1: |
| msg += " "; |
| break; |
| case 2: |
| msg += " "; |
| break; |
| default: |
| msg += count + " "; |
| break; |
| } |
| |
| if (result.parameters.PizzaSize[k] !== undefined) { |
| switch (result.parameters.PizzaSize[k]) { |
| case "small": |
| msg += wordend(count, ['', '', '']); |
| break; |
| case "medium": |
| msg += wordend(count, ['', '', '']); |
| break; |
| case "large": |
| msg += wordend(count, ['', '', '']); |
| break; |
| } |
| } |
| msg += " " |
| switch (result.parameters.PizzaType[k]) { |
| case "margarita": |
| msg += wordend(count, ['', '', '']); |
| break; |
| case "fourcheese": |
| msg += wordend(count, ['', '', '']) + " "; |
| break; |
| case "vegetarian": |
| msg += wordend(count, [' ', ' ', ' ']); |
| break; |
| case "pepperoni": |
| msg += wordend(count, ['', '', '']) + " "; |
| break; |
| case "cheese": |
| msg += wordend(count, [' ', ' ', ' ']); |
| break; |
| case "chicken": |
| msg += wordend(count, ['', '', '']) + " "; |
| break; |
| } |
| if (k == result.parameters.PizzaType.length - 1) msg += " , " |
| else msg += " "; |
| } |
| msg = msg.slice(0, msg.length - 2); |
| if (result.parameters.time !== undefined && result.parameters.time != "") { |
| let time = new Date(result.parameters.time), |
| local = time.toTimeString() |
| local = local.split(":") |
| time = local[0] + ":" + local[1] |
| msg += ". " + time |
| } |
| if (result.parameters.deliveryaddress !== undefined) msg += ". " + result.parameters.deliveryaddress |
| msg += ". ?"; |
| |
| player.stop() |
| player = VoxEngine.createTTSPlayer(msg, voice) |
| player.addMarker(-500) |
| player.addEventListener(PlayerEvents.PlaybackMarkerReached, startASR) |
| player.sendMediaTo(e.call) |
| |
| } else { |
| |
| player.stop() |
| lastText = result.fulfillmentText |
| player = VoxEngine.createTTSPlayer(result.fulfillmentText, voice) |
| if (result.action == "pizzaorder.pizzaorder-yes") { |
| player.addEventListener(PlayerEvents.PlaybackFinished, () => mycall.hangup()) |
| player.sendMediaTo(e.call) |
| } else { |
| player.addMarker(-500) |
| player.addEventListener(PlayerEvents.PlaybackMarkerReached, startASR) |
| player.sendMediaTo(e.call) |
| } |
| |
| } |
| } |
| } |
| }) |
| |
| player = VoxEngine.createTTSPlayer("! , !", voice); |
| player.addMarker(-500); |
| player.addEventListener(PlayerEvents.PlaybackMarkerReached, startASR); |
| player.sendMediaTo(e.call); |
| |
| mycall.record(); |
| mycall.addEventListener(CallEvents.Disconnected, (event) => { |
| VoxEngine.terminate(); |
| }) |
| } |
剩下的很少了。 转到“路由”选项卡->“创建”。 带有表格的模态窗口将会出现。 可以通过类比来指定名称-dialogflow-rule。 保留默认掩码,最重要的是附加dialogflow脚本。 单击“创建规则”,模式窗口将关闭。
现在,您需要将购买的号码附加到应用程序。 为此,请转到应用程序内的“数字”部分,单击“可用”,然后单击选定数字旁边的“附加”。 将打开一个模式窗口,仅在此处选择所需的规则并单击“附加”。
点击“保存”。 现在,脚本知道需要什么来响应您租用的任何拨号号码。 鉴于我们只有一个号码,这就是我们所需要的。
太好了,现在一切都连接在一起,应该可以正常工作!
对话流程代理
就Dialogflow而言,代理是机器人。 我们已经
详细描述了如何创建代理以及如何与他通信,但是这次我们建议使用我们的工件。
您需要在
dialogflow.com上注册并创建一个新代理。 不要忘记指定俄语:
默认情况下,代理不知道单个语句(意图),并且通常不执行任何操作。
下载我们代理商的资产并将其上传到您
的资产 :为此,在代理商的设置中,转到“导出和导入”标签->“从ZIP导入”。
现在,您有一套订购披萨的俗语! 您可以在“意图”部分中进行研究; 请注意,代理具有辅助语句
pizza.sizehelp和
pizza.typehelp 。 多亏了他们,在打下比萨饼店之后,客户可以问“您有哪种披萨”,然后机器人会告诉您菜单上的内容。
验证是否在“常规”选项卡上的设置中选择了第二版API。
最后,
点击几下即可下载您的Google服务帐户的JSON。
绑定代理到Voximplant应用程序
在Voximplant应用程序左侧的菜单中,选择“ Dialogflow连接器”,单击“添加”,以出现的模式形式加载JSON,然后再次单击“添加”。
您将看到JSON文件出现在列表中,这意味着它已附加到应用程序。
做完了! 配置了Dialoglow + Voximplant束,链的所有链接都组装在一起。
如果您懒得做所有这些步骤,则可以感觉到我们的比萨店演示: