A AI vende pizza ou como o Voximplant faz amizade com o Dialogflow

Recentemente, apresentamos uma solução comercial chamada Dialogflow Connector: um monte de Dialogflow do Google e nossa nuvem Voximplant. O conector pode funcionar em vez de um operador de call center e aceitar pedidos complexos. Isso se tornou possível porque o Dialogflow permite que você se afaste do cenário usual de URA, onde o cliente é forçado a nomear palavras de um determinado conjunto, ao qual o menu interativo pode responder. A plataforma do Google pode receber seqüencialmente as informações de um cliente e coletá-las juntas - por exemplo, para formar um pedido em uma loja online. Você provavelmente já ouviu a palavra-chave " preenchimento de espaço " , então é isso. Os detalhes estão esperando por você, como fizemos com o bot para pedir pizza - por analogia, você pode cortar algo semelhante e ficar feliz que os tempos do elevador e dos "onze" se foram há muito tempo ...


Número de telefone


Para começar, você deve alugar um número virtual ao qual o bot "responderá". Para fazer isso, no painel de administração do Voximplant, no menu "Números", clique em "Comprar número de telefone".


Na nova tela, coloque o interruptor na posição "Números de teste" - isso permitirá que você alugue um número virtual.


Os números virtuais são muito baratos e permitem que você teste totalmente qualquer solução em nossa plataforma. Alugue um quarto e mais ...

... criar um script


Agora precisamos de um cenário de nuvem, o coração da nossa decisão. É ele quem recebe a chamada, reconhece a fala e a transfere para o Dialogflow. O script deve ser criado dentro do aplicativo. No menu esquerdo, selecione "Aplicativos" , crie um novo aplicativo e dê um nome a ele.


Em seguida, vá para a guia "Scripts" no seu aplicativo e crie o seu próprio clicando no sinal de mais. Lembre-se de dar um nome, como fluxo de diálogo.


Hora de escrever código!

Vamos conectar o módulo AI - ele contém os métodos e eventos do Dialogflow -, bem como o módulo de reconhecimento de fala e o player . Declaramos as variáveis ​​e a função complicada de palavra final , que recebe uma entrada (pizza) e uma matriz com as palavras ('margarita', 'margaritas', 'margaritas') e retorna uma palavra que corresponde ao número do caso. Isso é necessário para que o bot não diga "4 margaritas", mas emita corretamente "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) ]; } 

Agora adicione o manipulador para a chamada recebida e a função auxiliar startASR :

 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); } 

Quando o evento Connected ocorre, a função handleCallConnected é chamada . Na verdade, todo o recheio ocorre nele:

  • um objeto Dialogflow é criado;
  • uma voz sintetizada cumprimenta o cliente e se oferece para fazer um pedido;
  • reconhecimento começa, o cliente faz um pedido;
  • as palavras do cliente são transferidas para o Dialogflow, ocorre um slot de philling;
  • a voz sintetizada exprime a ordem e o endereço do cliente;
  • o bot desliga, a sessão é encerrada.

Listagem de recursos:

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();
})
}


Ainda resta muito pouco. Vá para a guia Roteamento -> "Criar". Uma janela modal com um formulário será exibida. O nome pode ser dado por analogia - dialogflow-rule. Deixe a máscara padrão e o mais importante é anexar o script de fluxo de diálogo. Clique em "Criar regra", a janela modal será fechada.


Agora você precisa anexar o número adquirido ao aplicativo. Para fazer isso, vá para a seção "Números" dentro do seu aplicativo, clique em "Disponível" e depois em "Anexar" ao lado do número selecionado. Uma janela modal será aberta, resta apenas selecionar a regra desejada aqui e clicar em "anexar".


Clique em "Salvar". Agora, o script sabe o que precisa para responder a qualquer número discado que você alugou. Dado que temos um número, é disso que precisamos.

Ótimo, agora tudo está conectado e deve funcionar!

Agente de Diálogo


Em termos de Dialogflow, um agente é o bot. Já descrevemos em detalhes como criar seu agente e como se comunicar com ele, mas desta vez sugerimos o uso de nossa peça de trabalho.

Você precisa se registrar no dialogflow.com e criar um novo agente. Não se esqueça de especificar o idioma russo:


Por padrão, o agente não conhece uma única instrução (intenções) e geralmente não pode fazer nada. Faça o download dos ativos do nosso agente e faça o upload para o seu: nas configurações do agente, vá para a guia "Exportar e importar" -> "Importar do ZIP".


Agora você tem um conjunto de frases para pedir pizza! Você pode estudá-los na seção "Intents"; observe que o agente possui instruções auxiliares pizza.sizehelp e pizza.typehelp . Graças a eles, depois de cumprimentar a pizzaria, o cliente pode perguntar "Que tipo de pizza você tem" e o bot diz o que está no menu.

Verifique se a segunda versão da API está selecionada nas configurações na guia Geral.


Por fim, faça o download do JSON da sua conta de serviço do Google - isso é feito em alguns cliques .

Vincular agente ao aplicativo Voximplant


No menu à esquerda no aplicativo Voximplant, selecione “Dialogflow connector”, clique em “Add”, no formulário modal exibido carregue JSON e clique em “Add” novamente.


Você verá que o arquivo JSON aparece na lista, o que significa que está anexado ao aplicativo.

Feito! O pacote Dialoglow + Voximplant está configurado, todos os elos da cadeia são montados juntos.

Caso você tenha preguiça de executar todas essas etapas, sinta a nossa demonstração da pizzaria:

  • vá para http://demos05.voximplant.com/pizza/ ;
  • digite o número de telefone (para a Rússia será 7900 ...) e clique em "NEXT";
  • do número indicado, disque +74999384952;
  • aproveite o bot milagroso :)

Source: https://habr.com/ru/post/pt412663/


All Articles