Crie bots de voz para Android com o Dialogflow Essentials e Godê

1. Antes de começar

Neste codelab, você aprenderá a integrar um bot simples de texto e voz do Dialogflow Essentials (ES) em um app do Flutter. O Dialogflow ES é um pacote de desenvolvimento para criar IUs de conversa. Por exemplo, chatbots, bots de voz e gateways de telefone. Você pode criar todos eles com a mesma ferramenta e oferecer suporte a vários canais em mais de 20 idiomas. O Dialogflow se integra a muitas plataformas de conversação conhecidas, como o Google Assistente, o Slack e o Facebook Messenger. Se você quiser criar um agente para uma dessas plataformas, use uma das diversas opções de integração. No entanto, para criar um chatbot para dispositivos móveis, você terá que criar uma integração personalizada. Você vai criar intents especificando frases de treinamento para treinar um modelo subjacente de machine learning.

A ordem deste laboratório reflete uma experiência comum de desenvolvedor de nuvem:

  1. Configuração do ambiente
  • Dialogflow: crie um novo agente do Dialogflow ES
  • Dialogflow: configure o Dialogflow
  • Google Cloud: criar uma conta de serviço
  1. Flutter: como criar um aplicativo de chat
  • Como criar um projeto do Flutter
  • Como definir as configurações e permissões
  • Como adicionar as dependências
  • Vinculação à conta de serviço.
  • Executar o aplicativo em um dispositivo virtual ou físico
  1. Flutter: como criar a interface de chat com suporte da Speech-to-Text
  • Criar a interface de chat
  • Vincular a interface de chat
  • Como integrar o pacote gRPC do Dialogflow ao aplicativo
  1. Dialogflow: como modelar o agente do Dialogflow
  • Configure as propriedades intents substitutas
  • Usar uma base de conhecimento de Perguntas frequentes

Pré-requisito

  • Experiência básica com Dart/Flutter
  • Experiência básica no Google Cloud Platform
  • Experiência básica com o Dialogflow ES

O que você vai criar

Este codelab mostra como criar um bot de perguntas frequentes para dispositivos móveis que pode responder às dúvidas mais comuns sobre a ferramenta Dialogflow. Os usuários finais podem interagir com a interface de texto ou transmitir uma voz pelo microfone integrado de um dispositivo móvel para receber respostas.

O que você vai aprender

  • Como criar um chatbot com o Dialogflow Essentials
  • Como integrar o Dialogflow a um app do Flutter com o pacote gRPC do Dialogflow.
  • Como detectar intents de texto com o Dialogflow
  • Como transmitir uma voz pelo microfone para o Dialogflow
  • Como usar o conector da base de conhecimento para importar perguntas frequentes públicas
  • Testar o chatbot pela interface de texto e voz em um dispositivo virtual ou físico

O que é necessário

  • Você precisará de um endereço do Google Identity / Gmail para criar um agente do Dialogflow.
  • Você precisa acessar o Google Cloud Platform para fazer o download de uma conta de serviço
  • Um ambiente de desenvolvimento do Flutter

Configurar seu ambiente de desenvolvimento do Flutter

  1. Selecione o sistema operacional em que você está instalando o Flutter.
  1. É possível criar apps com o Flutter usando qualquer editor de texto combinado com nossas ferramentas de linha de comando. No entanto, este workshop vai usar o Android Studio. Os plug-ins do Flutter e do Dart para o Android Studio oferecem preenchimento de código, destaque de sintaxe, assistência para edição de widgets, execução e suporte a depuração e muito mais. Siga as etapas em https://flutter.dev/docs/get-started/editor

2. Configuração do ambiente

Dialogflow: crie um novo agente do Dialogflow ES

  1. Abra o .
  2. Na barra à esquerda, abaixo do logotipo, selecione Criar novo agente. no menu suspenso. Observação: não clique no menu suspenso "Global". Precisaremos de uma instância do Dialogflow que seja global para usar a base de conhecimento das perguntas frequentes.
  3. Especifique um nome de agente yourname-dialogflow (use seu próprio nome)
  4. Como idioma padrão, escolha English - en.
  5. Como fuso horário padrão, escolha o mais próximo de você.
  6. Não selecione Mega-agente. (Com esse recurso, é possível criar um agente abrangente que pode orquestrar entre "subagentes". Não precisamos disso agora.)
  7. Clique em Criar.

Tela "Criar novo projeto"

Configurar o Dialogflow

  1. Clique no ícone de engrenagem no menu à esquerda, ao lado do nome do projeto.

Menu suspenso "Criar novo projeto"

  1. Digite a seguinte descrição do agente: Chatbot de perguntas frequentes sobre o Dialogflow
  2. Ative os recursos Beta e vire a chave.

Dialogflow Essentials V2Beta1

  1. Clique na guia Fala e verifique se a caixa Adaptação automática de fala está ativa.
  2. Também é possível apertar o primeiro interruptor. Isso melhorará o modelo de fala, mas ele só estará disponível quando você fizer upgrade do teste do Dialogflow.
  3. Clique em Salvar.

Google Cloud: receber uma conta de serviço

Depois de criar um agente no Dialogflow, um projeto do Google Cloud deve ser criado no console do Google Cloud.

  1. Abra o console do Google Cloud:
  2. Verifique se você fez login com a mesma Conta do Google usada no Dialogflow e selecione o projeto yourname-dialogflow na barra azul superior.
  3. Em seguida, procure Dialogflow API na barra de ferramentas superior e clique no resultado API Dialogflow no menu suspenso.

Ativar a API Dialogflow

  1. Clique no botão azul Gerenciar e depois em Credenciais na barra de menu à esquerda. Quando o Dialogflow ainda não estiver ativado, clique em Ativar primeiro.

Credenciais: Console do GCP

  1. Clique em Criar credenciais na parte superior da tela e escolha Conta de serviço.

Criar credenciais

  1. Especifique um nome de conta de serviço: flutter_dialogflow, ID e descrição e clique em Criar.

Criar uma conta de serviço

  1. Na etapa 2, selecione a função: Dialogflow API Admin, clique em Continuar e em Concluído.
  2. Clique na conta de serviço flutter_dialogflow, depois na guia Keys e depois em Add Key > Criar nova chave

Criar chave

  1. Crie uma chave JSON. Renomeie-o como credentials.json e armazene-o em um local seguro do seu disco rígido. Vamos usá-lo mais tarde.

Chave JSON

Perfeito. Todas as ferramentas necessárias estão configuradas corretamente. Agora podemos começar a integrar o Dialogflow ao nosso app.

3. Flutter: como criar o aplicativo de chat

Criar o app Boilerplate

  1. Abra o Android Studio e selecione Start a new Flutter project.
  2. Selecione Flutter Application como o tipo de projeto. Em seguida, clique em "Próxima".
  3. Verifique se o caminho do SDK do Flutter especifica o local do SDK. Se o campo de texto estiver em branco, selecione "Install SDK...".
  4. Insira o nome do projeto (por exemplo, flutter_dialogflow_agent). Em seguida, clique em Próxima.
  5. Modifique o nome do pacote e clique em Finish.

Criar novo aplicativo do Flutter

Isso vai criar um aplicativo de amostra com os componentes do Material Design.

Aguarde o Android Studio instalar o SDK e criar o projeto.

Configurações e Permissões

  1. A biblioteca de gravadores de áudio sound_stream que vamos usar requer um minSdk de pelo menos 21. Vamos mudar isso em android/app/build.gradle no bloco defaultConfig. Há dois arquivos build.gradle na pasta Android, mas o que está na pasta do app é o correto.
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. Para dar permissões ao microfone e ao app se comunicar com o agente do Dialogflow executado na nuvem, será necessário adicionar as permissões INTERNET e RECORD_AUDIO ao arquivo app/src/main/AndroidManifest.xml. Existem vários arquivos AndroidManifest.xml no projeto do Flutter, mas você precisará de um que esteja na pasta principal. É possível adicionar as linhas dentro das tags de manifesto.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Como adicionar as dependências

Vamos usar os pacotes sound_stream, rxdart e dialogflow_grpc.

  1. Adicionar a dependência sound_stream
$ flutter pub add sound_stream
Resolving dependencies...
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
  matcher 0.12.10 (0.12.11 available)
+ sound_stream 0.3.0
  test_api 0.4.2 (0.4.5 available)
  vector_math 2.1.0 (2.1.1 available)
Downloading sound_stream 0.3.0...
Changed 1 dependency!
  1. Adicionar a dependência dialogflow_grpc
flutter pub add dialogflow_grpc
Resolving dependencies...
+ archive 3.1.5
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
+ crypto 3.0.1
+ dialogflow_grpc 0.2.9
+ fixnum 1.0.0
+ googleapis_auth 1.1.0
+ grpc 3.0.2
+ http 0.13.4
+ http2 2.0.0
+ http_parser 4.0.0
  matcher 0.12.10 (0.12.11 available)
+ protobuf 2.0.0
  test_api 0.4.2 (0.4.5 available)
+ uuid 3.0.4
  vector_math 2.1.0 (2.1.1 available)
Downloading dialogflow_grpc 0.2.9...
Downloading grpc 3.0.2...
Downloading http 0.13.4...
Downloading archive 3.1.5...
Changed 11 dependencies!
  1. Adicionar a dependência rxdart
$ flutter pub add rxdart
Resolving dependencies...
  async 2.8.1 (2.8.2 available)
  characters 1.1.0 (1.2.0 available)
  matcher 0.12.10 (0.12.11 available)
+ rxdart 0.27.2
  test_api 0.4.2 (0.4.5 available)
  vector_math 2.1.0 (2.1.1 available)
Downloading rxdart 0.27.2...
Changed 1 dependency!

Como carregar a conta de serviço e as informações do projeto do Google Cloud

  1. No seu projeto, crie um diretório e dê o nome assets a ele.
  2. Mova o arquivo credentials.json salvo do console do Google Cloud para a pasta assets.
  3. Abra pubspec.yaml e adicione a conta de serviço ao bloco do Flutter.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

Como executar o aplicativo em um dispositivo físico

Com um dispositivo Android, você pode conectar o smartphone por um cabo USB e depurar no dispositivo. Siga estas etapas para fazer a configuração na tela Opções do desenvolvedor no dispositivo Android.

Como executar o aplicativo em um dispositivo virtual

Caso você queira executar o aplicativo em um dispositivo virtual, siga estas etapas:

  1. Clique em Ferramentas> AVD Manager. (Ou selecione o AVD Manager na barra de ferramentas superior; na figura abaixo, ele está destacado em rosa)

Barra de ferramentas superior do Android Studio

  1. Criaremos um dispositivo virtual Android de destino para que possamos testar nosso aplicativo sem um dispositivo físico. Para mais detalhes, consulte Como gerenciar AVDs. Depois de selecionar um novo dispositivo virtual, clique duas vezes nele para iniciá-lo.

Gerenciar AVDs

Dispositivo virtual

  1. Na barra de ferramentas principal do Android Studio, selecione um dispositivo Android como destino no menu suspenso e confira se main.dart está selecionado. Em seguida, pressione o botão Run (triângulo verde).

Os registros vão aparecer na parte de baixo do ambiente de desenvolvimento integrado no console. Você perceberá que ele está instalando o Android e seu app inicial do Flutter. Isso vai levar um minuto. Quando o dispositivo virtual estiver pronto, as mudanças vão ser muito rápidas. Quando terminar, o app inicial do Flutter será aberto.

App Boilerplate

  1. Vamos ativar o microfone para o aplicativo chatbot. Clique no botão de opções do dispositivo virtual para abrir as opções. Na guia Microfone, ative os três interruptores.

Opções do AVD

  1. Vamos testar a recarga automática para demonstrar como as mudanças podem ser feitas com rapidez.

Em lib/main.dart, mude o título da MyHomePage na classe MyApp para: Flutter Dialogflow Agent. Altere primarySwatch para Colors.orange.

Primeiro código

Salve o arquivo ou clique no ícone de raio na barra de ferramentas do Android Studio. A mudança vai aparecer diretamente no dispositivo virtual.

4. Flutter: como criar a interface do Chat com suporte a STT

Criar a interface de chat

  1. Crie um novo arquivo do widget do Flutter na pasta lib. (clique com o botão direito do mouse na pasta lib, New > Flutter Widget > Widget com estado), chame este arquivo: chat.dart

Cole o código a seguir nesse arquivo. Esse arquivo dart cria a interface de bate-papo. O Dialogflow ainda não funciona, apenas o layout de todos os componentes e a integração do componente do microfone para permitir streams. Os comentários no arquivo apontarão, onde mais tarde integraremos o Dialogflow.

// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sound_stream/sound_stream.dart';

// TODO import Dialogflow


class Chat extends StatefulWidget {
  Chat({Key key}) : super(key: key);

  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {
  final List<ChatMessage> _messages = <ChatMessage>[];
  final TextEditingController _textController = TextEditingController();

  bool _isRecording = false;

  RecorderStream _recorder = RecorderStream();
  StreamSubscription _recorderStatus;
  StreamSubscription<List<int>> _audioStreamSubscription;
  BehaviorSubject<List<int>> _audioStream;

  // TODO DialogflowGrpc class instance

  @override
  void initState() {
    super.initState();
    initPlugin();
  }

  @override
  void dispose() {
    _recorderStatus?.cancel();
    _audioStreamSubscription?.cancel();
    super.dispose();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlugin() async {
    _recorderStatus = _recorder.status.listen((status) {
      if (mounted)
        setState(() {
          _isRecording = status == SoundStreamStatus.Playing;
        });
    });

    await Future.wait([
      _recorder.initialize()
    ]);



    // TODO Get a Service account

  }

  void stopStream() async {
    await _recorder.stop();
    await _audioStreamSubscription?.cancel();
    await _audioStream?.close();
  }

  void handleSubmitted(text) async {
    print(text);
    _textController.clear();

    //TODO Dialogflow Code

  }

  void handleStream() async {
    _recorder.start();

    _audioStream = BehaviorSubject<List<int>>();
    _audioStreamSubscription = _recorder.audioStream.listen((data) {
      print(data);
      _audioStream.add(data);
    });


    // TODO Create SpeechContexts
    // Create an audio InputConfig

    // TODO Make the streamingDetectIntent call, with the InputConfig and the audioStream
    // TODO Get the transcript and detectedIntent and show on screen

  }

  // The chat interface
  //
  //------------------------------------------------------------------------------------
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Flexible(
          child: ListView.builder(
            padding: EdgeInsets.all(8.0),
            reverse: true,
            itemBuilder: (_, int index) => _messages[index],
            itemCount: _messages.length,
          )),
      Divider(height: 1.0),
      Container(
          decoration: BoxDecoration(color: Theme.of(context).cardColor),
          child: IconTheme(
            data: IconThemeData(color: Theme.of(context).accentColor),
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 8.0),
              child: Row(
                children: <Widget>[
                  Flexible(
                    child: TextField(
                      controller: _textController,
                      onSubmitted: handleSubmitted,
                      decoration: InputDecoration.collapsed(hintText: "Send a message"),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.symmetric(horizontal: 4.0),
                    child: IconButton(
                      icon: Icon(Icons.send),
                      onPressed: () => handleSubmitted(_textController.text),
                    ),
                  ),
                  IconButton(
                    iconSize: 30.0,
                    icon: Icon(_isRecording ? Icons.mic_off : Icons.mic),
                    onPressed: _isRecording ? stopStream : handleStream,
                  ),
                ],
              ),
            ),
          )
      ),
    ]);
  }
}


//------------------------------------------------------------------------------------
// The chat message balloon
//
//------------------------------------------------------------------------------------
class ChatMessage extends StatelessWidget {
  ChatMessage({this.text, this.name, this.type});

  final String text;
  final String name;
  final bool type;

  List<Widget> otherMessage(context) {
    return <Widget>[
      new Container(
        margin: const EdgeInsets.only(right: 16.0),
        child: CircleAvatar(child: new Text('B')),
      ),
      new Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(this.name,
                style: TextStyle(fontWeight: FontWeight.bold)),
            Container(
              margin: const EdgeInsets.only(top: 5.0),
              child: Text(text),
            ),
          ],
        ),
      ),
    ];
  }

  List<Widget> myMessage(context) {
    return <Widget>[
      Expanded(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: <Widget>[
            Text(this.name, style: Theme.of(context).textTheme.subtitle1),
            Container(
              margin: const EdgeInsets.only(top: 5.0),
              child: Text(text),
            ),
          ],
        ),
      ),
      Container(
        margin: const EdgeInsets.only(left: 16.0),
        child: CircleAvatar(
            child: Text(
              this.name[0],
              style: TextStyle(fontWeight: FontWeight.bold),
            )),
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.symmetric(vertical: 10.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: this.type ? myMessage(context) : otherMessage(context),
      ),
    );
  }
}

Pesquisar a versão do widget no arquivo chat.dart. Ela cria a interface do bot de bate-papo, que contém:

  • ListView, que contém todos os balões de chat do usuário e do bot de bate-papo. Ele usa a classe ChatMessage, que cria mensagens de chat com um avatar e texto.
  • TextField para inserir consultas de texto
  • IconButton com o ícone de envio para enviar consultas de texto ao Dialogflow
  • IconButton com um microfone para enviar streams de áudio para o Dialogflow, que altera o estado quando é pressionado.

Vincular a interface de chat

  1. Abra main.dart e mude o Widget build para que ele instancia apenas a interface Chat(). Todos os outros códigos de demonstração podem ser removidos.
import 'package:flutter/material.dart';
import 'chat.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.orange,
      ),
      home: MyHomePage(title: 'Flutter Dialogflow Agent'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Chat())
    );
  }
}
  1. Execute o app. Se o app já foi iniciado. Interrompa o dispositivo virtual e execute main.dart novamente). Quando você executa o app com a interface de chat pela primeira vez. Você receberá um pop-up perguntando se deseja permitir o microfone. Clique: Ao usar o app.

Permissões

  1. Brinque com a área de texto e os botões. Ao digitar uma consulta de texto e pressionar Enter, ou tocar no botão "Enviar", a consulta de texto será registrada na guia Executar do Android Studio. Quando você toca no botão do microfone e o interrompe, o stream de áudio é registrado na guia Run.

Registro do stream de áudio

Ótimo! Agora estamos prontos para integrar o aplicativo ao Dialogflow.

Como integrar seu app do Flutter com o Dialogflow_gRPC

  1. Abra chat.dart e adicione as seguintes importações:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. Na parte de cima do arquivo, logo abaixo de // TODO DialogflowGrpcV2Beta1 class instance, adicione a seguinte linha para armazenar a instância da classe Dialogflow:
DialogflowGrpcV2Beta1 dialogflow;
  1. Procure o método initPlugin() e adicione o seguinte código logo abaixo do comentário TODO:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

Isso vai criar uma instância do Dialogflow autorizada para seu projeto do Google Cloud com a conta de serviço. Verifique se você tem o credentials.json na pasta assets.

De novo, para fins de demonstração de como trabalhar com o gRPC do Dialogflow, isso não é um problema. No entanto, para apps de produção, não é recomendável armazenar o arquivo credentials.json na pasta de recursos, já que isso não é considerado seguro.

Como fazer uma chamada detectIntent

  1. Agora encontre o método handleSubmitted(). É aqui que a mágica entra. Logo abaixo do comentário TODO, adicione o seguinte código.Esse código adicionará a mensagem digitada pelo usuário à ListView:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. Agora, logo abaixo do código anterior, vamos fazer a chamada detectIntent, transmitir o texto da entrada e um languageCode. - O resultado (em data.queryResult.fulfillment) será exibido na ListView:
DetectIntentResponse data = await dialogflow.detectIntent(text, 'en-US');
String fulfillmentText = data.queryResult.fulfillmentText;
if(fulfillmentText.isNotEmpty) {
  ChatMessage botMessage = ChatMessage(
    text: fulfillmentText,
    name: "Bot",
    type: false,
  );

  setState(() {
    _messages.insert(0, botMessage);
  });
}
  1. Inicie o dispositivo virtual e teste a chamada de intent de detecção. Tipo: hi. Você deve receber a mensagem de boas-vindas padrão. Quando você digita outra coisa, o substituto padrão é retornado.

Como fazer uma chamada streamingDetectIntent

  1. Agora encontre o método handleStream(). É aqui que entra a mágica do streaming de áudio. Logo abaixo do primeiro TODO, crie um áudio InputConfigV2beta1 com um biasList para direcionar o modelo de voz. Como estamos usando um smartphone (dispositivo virtual), o sampleHertz será 16.000 e a codificação será Linear 16. Isso depende do hardware / microfone da sua máquina que você está usando. No meu microfone interno do Macbook, 16.000 era bom. Consulte as informações do pacote https://pub.dev/packages/sound_stream (em inglês).
var biasList = SpeechContextV2Beta1(
    phrases: [
      'Dialogflow CX',
      'Dialogflow Essentials',
      'Action Builder',
      'HIPAA'
    ],
    boost: 20.0
);

    // See: https://cloud.google.com/dialogflow/es/docs/reference/rpc/google.cloud.dialogflow.v2#google.cloud.dialogflow.v2.InputAudioConfig
var config = InputConfigV2beta1(
    encoding: 'AUDIO_ENCODING_LINEAR_16',
    languageCode: 'en-US',
    sampleRateHertz: 16000,
    singleUtterance: false,
    speechContexts: [biasList]
);
  1. Em seguida, chamaremos o método streamingDetectIntent no objeto dialogflow, que realiza nossa sessão do Dialogflow:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. Com o responseStream, podemos finalmente ouvir a transcrição recebida, a consulta do usuário detectada e a resposta de intent correspondente detectada. Vamos mostrar isso em uma ChatMessage na tela:
// Get the transcript and detectedIntent and show on screen
responseStream.listen((data) {
  //print('----');
  setState(() {
    //print(data);
    String transcript = data.recognitionResult.transcript;
    String queryText = data.queryResult.queryText;
    String fulfillmentText = data.queryResult.fulfillmentText;

    if(fulfillmentText.isNotEmpty) {

      ChatMessage message = new ChatMessage(
        text: queryText,
        name: "You",
        type: true,
      );

      ChatMessage botMessage = new ChatMessage(
        text: fulfillmentText,
        name: "Bot",
        type: false,
      );

      _messages.insert(0, message);
      _textController.clear();
      _messages.insert(0, botMessage);

    }
    if(transcript.isNotEmpty) {
      _textController.text = transcript;
    }

  });
},onError: (e){
  //print(e);
},onDone: () {
  //print('done');
});

Pronto. Inicie o aplicativo e teste-o no dispositivo virtual, pressione o botão de microfone e Diga: "Olá".

Isso acionará a intent de boas-vindas padrão do Dialogflow. Os resultados serão mostrados na tela. Agora que o Flutter funciona muito bem com a integração do Dialogflow, podemos começar a trabalhar na nossa conversa do chatbot.

5. Dialogflow: como modelar o agente do Dialogflow

O Dialogflow Essentials é um pacote de desenvolvimento para criar IUs de conversa. Por exemplo, chatbots, bots de voz e gateways de telefone. Você pode criar todos eles com a mesma ferramenta e oferecer suporte a vários canais em mais de 20 idiomas. Designers de UX do Dialogflow (modeladores de agentes, linguistas) ou desenvolvedores criam intents especificando frases de treinamento para treinar um modelo subjacente de machine learning.

Uma intent categoriza a intenção do usuário. Para cada agente do Dialogflow ES, é possível definir várias intents, em que as intents combinadas podem lidar com uma conversa completa. Cada intent pode conter parâmetros e respostas.

A correspondência de uma intent também é conhecida como classificação ou correspondência de intent. Esse é o conceito principal do Dialogflow ES. Quando uma intent é correspondida, ela pode retornar uma resposta, coletar parâmetros (extração de entidade) ou acionar o código do webhook (fulfillment), por exemplo, para buscar dados de um banco de dados.

Quando um usuário final escreve ou diz algo em um chatbot, conhecido como expressão ou enunciado do usuário, o Dialogflow ES faz a correspondência entre a expressão e a melhor intent do agente do Dialogflow, com base nas frases de treinamento. O modelo interno de machine learning do Dialogflow ES foi treinado com essas frases de treinamento.

O Dialogflow ES trabalha com um conceito chamado contexto. Assim como um ser humano, o Dialogflow ES consegue se lembrar do contexto na segunda e na terceira curvas. É assim que ele pode acompanhar enunciados anteriores do usuário.

Confira mais informações sobre intents do Dialogflow.

Como modificar a intent de boas-vindas padrão

Quando você cria um novo agente do Dialogflow, duas intents padrão são criadas automaticamente. A Default Welcome Intent é o primeiro fluxo que você acessa quando inicia uma conversa com o agente. A Default Fallback Intent é o fluxo exibido quando o agente não entende você ou não consegue associar uma intent ao que você acabou de dizer.

Esta é a mensagem de boas-vindas para a intent de boas-vindas padrão:

Usuário

Agente

Olá

"Olá, sou o bot de perguntas frequentes do Dialogflow. Posso responder a perguntas sobre o Dialogflow."

"O que você quer saber?"

  1. Clique em Intents > Intent de boas-vindas padrão
  2. Role para baixo até Respostas.
  3. Limpar todas as respostas de texto.
  4. Na guia padrão, crie as duas respostas a seguir:
  • Olá, sou o bot de perguntas frequentes do Dialogflow e posso responder a dúvidas sobre o Dialogflow. O que você quer saber?
  • Olá, sou o bot de perguntas frequentes do Dialogflow. Você tem dúvidas sobre o Dialogflow? Como posso ajudar?

A configuração será parecida com esta captura de tela.

Editar a intent de boas-vindas padrão

  1. Clique em Salvar.
  2. Vamos testar essa intent. Primeiro, vamos testá-lo no Dialogflow Simulator.Type: Hello. Ele deve retornar uma destas mensagens:
  • Olá, sou o bot de perguntas frequentes do Dialogflow e posso responder a dúvidas sobre o Dialogflow. O que você quer saber?
  • Olá, sou o bot de perguntas frequentes do Dialogflow. Você tem dúvidas sobre o Dialogflow? Como posso ajudar?

Como modificar a intent de fallback padrão

  1. Clique em Intents > Intent de fallback padrão
  2. Role para baixo até Respostas.
  3. Limpar todas as respostas de texto.
  4. Na guia padrão, crie a seguinte resposta:
  • Infelizmente, eu não sei a resposta para essa pergunta. Você verificou nosso site? http://www.dialogflow.com?
  1. Clique em Salvar.

Conexão com uma base de conhecimento on-line

Os conectores de conhecimento complementam as intents definidas. Eles analisam documentos de conhecimento para encontrar respostas automatizadas. Por exemplo, perguntas frequentes ou artigos de arquivos CSV, sites on-line ou até mesmo arquivos PDF. Para configurá-los, defina uma ou mais bases de conhecimento, que são coleções de documentos de conhecimento.

Leia mais sobre os conectores de conhecimento.

Vamos tentar.

  1. Selecione Conhecimento (Beta) no menu.

Base de conhecimento

  1. Clique no botão azul à direita: Criar base de conhecimento.
  2. Digite como um nome de base de conhecimento. Perguntas frequentes sobre o Dialogflow e clique em salvar.
  3. Clique no link Criar o primeiro.

Primeira base de conhecimento

  1. Uma janela será aberta.

Use a seguinte configuração:

Nome do documento: DialogflowFAQ Tipo de conhecimento: FAQ Tipo MIME: text/html

  1. O URL de onde carregamos os dados é:

https://www.leeboonstra.dev/faqs/

  1. Clique em Criar.

Uma base de conhecimento foi criada:

Base de conhecimento criada

  1. Role para baixo até a seção "Responses" e clique em Add Response.

Crie as respostas a seguir e clique em Salvar.

$Knowledge.Answer[1]
  1. Clique em Ver detalhes.

Ver detalhes

  1. Selecione Ativar atualização automática para buscar alterações automaticamente quando a página de perguntas frequentes for atualizada e clique em salvar.

Isso exibirá todas as perguntas frequentes que você implementou no Dialogflow.Isso é fácil!

Também é possível apontar para um site HTML on-line com perguntas frequentes a fim de importar perguntas frequentes para seu agente. É possível até fazer upload de um PDF com um bloco de texto, e o próprio Dialogflow vai criar perguntas.

Agora as perguntas frequentes devem ser vistas como "extras" para adicionar aos seus agentes, ao lado dos fluxos de intents. As perguntas frequentes da base de conhecimento não podem treinar o modelo. Portanto, fazer perguntas de uma forma completamente diferente pode não ter uma correspondência, porque não faz uso de processamento de linguagem natural (modelos de machine learning). É por isso que às vezes vale a pena converter suas perguntas frequentes em intents.

  1. Teste as perguntas no simulador à direita.
  2. Quando tudo funcionar, volte ao app Flutter e teste o bot de bate-papo e voz com esse novo conteúdo. Faça as perguntas que você carregou no Dialogflow.

Resultado

6. Parabéns

Parabéns! Você criou seu primeiro app Flutter com uma integração de bot de bate-papo do Dialogflow. Muito bem!

O que aprendemos

  • Como criar um chatbot com o Dialogflow Essentials
  • Como integrar o Dialogflow a um app do Flutter
  • Como detectar intents de texto com o Dialogflow
  • Como transmitir uma voz pelo microfone para o Dialogflow
  • Como usar o conector da base de conhecimento

A seguir

Gostou do codelab? Confira esses ótimos laboratórios do Dialogflow!

Tem interesse em saber como criei o pacote gRPC do Dialogflow para Dart/Flutter?