Crea bots de voz para Android con Dialogflow Essentials & Oscilación

1. Antes de comenzar

En este codelab, aprenderás a integrar un bot de texto y voz simple de Dialogflow Essentials (ES) en una app de Flutter. Dialogflow ES es un paquete de desarrollo para compilar IU conversacionales. Por lo tanto, chatbots, bots de voz y puertas de enlace telefónicas. Todos pueden crearla con la misma herramienta y, además, puedes admitir varios canales en más de 20 idiomas diferentes. Dialogflow se integra en muchas plataformas de conversación populares, como Asistente de Google, Slack y Facebook Messenger. Si deseas compilar un agente para una de estas plataformas, debes usar una de las muchas opciones de integración. Sin embargo, para crear un chatbot para dispositivos móviles, deberás crear una integración personalizada. Crearás intents especificando frases de entrenamiento para entrenar un modelo de aprendizaje automático subyacente.

Este lab está ordenado para reflejar una experiencia común de desarrollador de la nube:

  1. Configuración del entorno
  • Dialogflow: Crea un agente nuevo de Dialogflow ES
  • Dialogflow: Configura Dialogflow
  • Google Cloud: Crea una cuenta de servicio
  1. Flutter: Cómo compilar una aplicación de chat
  • Crea un proyecto de Flutter
  • Cómo configurar los permisos y la configuración
  • Cómo agregar las dependencias
  • Vinculación a la cuenta de servicio
  • Ejecutar la aplicación en un dispositivo virtual o físico
  1. Flutter: Cómo compilar la interfaz de chat con compatibilidad de voz a texto
  • Cómo crear la interfaz de chat
  • Vincula la interfaz de chat
  • Cómo integrar el paquete de gRPC de Dialogflow en la app
  1. Dialogflow: Modelado del agente de Dialogflow
  • Configura los intents de bienvenida y de resguardo
  • Aprovecha una base de conocimiento de preguntas frecuentes

Requisitos

  • Experiencia básica con Dart o Flutter
  • Experiencia básica en Google Cloud Platform
  • Experiencia básica con Dialogflow ES

Qué compilarás

En este codelab, se mostrará cómo compilar un bot de preguntas frecuentes para dispositivos móviles que pueda responder las preguntas más comunes sobre la herramienta Dialogflow. Los usuarios finales pueden interactuar con la interfaz de texto o transmitir una voz a través del micrófono integrado de un dispositivo móvil para obtener respuestas.

Qué aprenderás

  • Cómo crear un chatbot con Dialogflow Essentials
  • Cómo integrar Dialogflow en una app de Flutter con el paquete de gRPC de Dialogflow
  • Cómo detectar intents de texto con Dialogflow
  • Cómo transmitir una voz a través del micrófono a Dialogflow
  • Cómo usar el conector de base de conocimiento para importar preguntas frecuentes públicas
  • Probar el chatbot a través de la interfaz de texto y voz en un dispositivo virtual o físico

Requisitos

  • Necesitarás una identidad de Google o una dirección de Gmail para crear un agente de Dialogflow.
  • Necesitarás acceso a Google Cloud Platform para descargar una cuenta de servicio.
  • Un entorno de desarrollo de Flutter

Configura tu entorno de desarrollo de Flutter

  1. Selecciona el sistema operativo en el que instalarás Flutter.
  1. Puedes compilar apps con Flutter usando cualquier editor de texto combinado con nuestras herramientas de línea de comandos. Sin embargo, en este taller se usará Android Studio. Los complementos de Flutter y Dart para Android Studio te brindan finalización de código, resaltado de sintaxis, ayuda para la edición de widgets, asistencia para la ejecución y depuración, y mucho más. Sigue los pasos que se indican en https://flutter.dev/docs/get-started/editor.

2. Configuración del entorno

Dialogflow: Crea un agente nuevo de Dialogflow ES

  1. Abre la .
  2. En la barra izquierda, justo debajo del logotipo, selecciona "Create New Agent" en el menú desplegable. (Nota: No hagas clic en el menú desplegable que dice "Global". Necesitaremos una instancia de Dialogflow que sea global para usar la base de conocimiento de preguntas frecuentes).
  3. Especifica un nombre de agente yourname-dialogflow (usa tu propio nombre).
  4. Como idioma predeterminado, elige Inglés (en).
  5. Como zona horaria predeterminada, elige la más cercana a ti.
  6. No selecciones Agente combinado. (Con esta función, puedes crear un agente general que puede coordinar agentes "secundarios". No lo necesitamos ahora).
  7. Haz clic en Crear.

Pantalla de creación de proyecto nuevo

Configura Dialogflow

  1. Haz clic en el ícono de ajustes, en el menú de la izquierda, junto al nombre de tu proyecto.

Menú desplegable para crear un proyecto nuevo

  1. Ingresa la siguiente descripción del agente: Chatbot de preguntas frecuentes de Dialogflow
  2. Habilita las funciones Beta.

Dialogflow Essentials V2Beta1

  1. Haz clic en la pestaña Voz y asegúrate de que la casilla Adaptación de voz automática esté activa.
  2. De manera opcional, también puedes activar el primer interruptor para mejorar el modelo de voz, pero solo está disponible cuando actualizas la prueba de Dialogflow.
  3. Haga clic en Guardar.

Google Cloud: Obtén una cuenta de servicio

Después de crear un agente en Dialogflow, se debe crear un proyecto de Google Cloud en la consola de Google Cloud.

  1. Abre la consola de Google Cloud: .
  2. Asegúrate de haber accedido con la misma Cuenta de Google que usas en Dialogflow y selecciona el proyecto yourname-dialogflow en la barra azul superior.
  3. A continuación, busca Dialogflow API en la barra de herramientas superior y haz clic en el resultado API de Dialogflow en el menú desplegable.

Habilitar la API de Dialogflow

  1. Haz clic en el botón azul Administrar y, luego, en Credenciales en la barra de menú de la izquierda. (Si Dialogflow aún no está habilitado, primero presiona Habilitar).

Credenciales de la consola de GCP

  1. Haz clic en Crear credenciales (en la parte superior de la pantalla) y elige Cuenta de servicio.

Crear credenciales

  1. Especifica un nombre para la cuenta de servicio: flutter_dialogflow, un ID y una descripción, y presiona Crear.

Crea una cuenta de servicio

  1. En el paso 2, deberás seleccionar el rol: Dialogflow API Admin, hacer clic en Continuar y, luego, en Listo.
  2. Haz clic en la cuenta de servicio flutter_dialogflow, haz clic en la pestaña Claves y presiona Agregar clave > Crear clave nueva.

Crear clave

  1. Crea una clave JSON. Cámbiale el nombre a credentials.json y guárdalo en una ubicación segura de tu disco duro. Lo usaremos más adelante.

Clave JSON

Perfecto. Todas las herramientas que necesitamos están configuradas correctamente. Ahora podemos comenzar a integrar Dialogflow en nuestra app.

3. Flutter: Cómo compilar la aplicación de chat

Crea la app de plantilla

  1. Abre Android Studio y selecciona Start a new Flutter project.
  2. Selecciona Flutter Application como el tipo de proyecto. Luego, haz clic en Siguiente.
  3. Verifica que la ruta del SDK de Flutter especifique la ubicación del SDK (selecciona Install SDK… si el campo de texto está en blanco).
  4. Ingresa un nombre para el proyecto (por ejemplo, flutter_dialogflow_agent) y, luego, haz clic en Siguiente.
  5. Modifica el nombre del paquete y haz clic en Finish.

Crea una nueva aplicación de Flutter

Esto creará una aplicación de ejemplo con Material Components.

Espera a que Android Studio instale el SDK y cree el proyecto.

Configuración y permisos

  1. La biblioteca del grabador de audio sound_stream que usaremos requiere un minSdk de al menos 21. Cambiemos esto en android/app/build.gradle en el bloque defaultConfig. (Ten en cuenta que hay 2 archivos build.gradle en la carpeta android, pero el que está en la carpeta app es el correcto).
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. Para otorgar permisos al micrófono y permitir que la app se comunique con el agente de Dialogflow que se ejecuta en la nube, tendremos que agregar los permisos INTERNET y RECORD_AUDIO al archivo app/src/main/AndroidManifest.xml. Hay varios archivos AndroidManifest.xml en tu proyecto de Flutter, pero necesitarás el que se encuentra en la carpeta principal. Puedes agregar las líneas directamente dentro de las etiquetas del manifiesto.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Cómo agregar las dependencias

Usaremos los paquetes sound_stream, rxdart y dialogflow_grpc.

  1. Cómo agregar la dependencia 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. Cómo agregar la dependencia 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. Cómo agregar la dependencia 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!

Carga de la información de la cuenta de servicio y del proyecto de Google Cloud

  1. En tu proyecto, crea un directorio y asígnale el nombre assets.
  2. Mueve el archivo credentials.json que descargaste de la consola de Google Cloud a la carpeta assets.
  3. Abre pubspec.yaml y agrega la cuenta de servicio al bloque de Flutter.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

Ejecuta la aplicación en un dispositivo físico

Si tienes un dispositivo Android, puedes conectar el teléfono con un cable USB y depurar en el dispositivo. Sigue estos pasos para configurar la función a través de la pantalla Opciones para desarrolladores en tu dispositivo Android.

Cómo ejecutar la aplicación en un dispositivo virtual

Si quieres ejecutar la aplicación en un dispositivo virtual, sigue estos pasos:

  1. Haz clic en Tools> AVD Manager. (O selecciona AVD Manager en la barra de herramientas superior, que se destaca en rosa en la siguiente figura).

Barra de herramientas superior de Android Studio

  1. Crearemos un dispositivo virtual Android de destino para poder probar nuestra aplicación sin un dispositivo físico. Para obtener más información, consulta Administra AVDs. Una vez que hayas seleccionado un nuevo dispositivo virtual, puedes hacer doble clic en él para iniciarlo.

Administra AVDs

Dispositivo virtual

  1. En la barra de herramientas principal de Android Studio, selecciona un dispositivo Android como destino a través del menú desplegable y asegúrate de que main.dart esté seleccionado. Luego, presiona el botón Ejecutar (triángulo verde).

En la parte inferior del IDE, verás los registros en la consola. Notarás que se está instalando Android y tu app de Flutter inicial. Esto tardará un minuto. Una vez que el dispositivo virtual esté listo, realizar cambios será muy rápido. Cuando termines, se abrirá la app inicial de Flutter.

App de plantilla

  1. Habilitaremos el micrófono para nuestra app de chatbot. Haz clic en el botón de opciones del dispositivo virtual para abrir las opciones. En la pestaña Micrófono, habilita los 3 interruptores.

Opciones de AVD

  1. Probemos la recarga en caliente para demostrar la rapidez con la que se pueden realizar cambios.

En lib/main.dart, cambia el título de MyHomePage en la clase MyApp a: Flutter Dialogflow Agent. Y cambia primarySwatch a Colors.orange.

Primer código

Guarda el archivo o haz clic en el ícono de rayo en la barra de herramientas de Android Studio. Deberías ver el cambio directamente en el dispositivo virtual.

4. Flutter: Compila la interfaz de chat con compatibilidad de STT

Cómo crear la interfaz de chat

  1. Crea un nuevo archivo de widget de Flutter en la carpeta lib. (haz clic con el botón derecho en la carpeta lib, New > Flutter Widget > Stateful widget), llama a este archivo: chat.dart

Pega el siguiente código en este archivo. Este archivo Dart crea la interfaz de chat. Dialogflow aún no funcionará, solo se trata del diseño de todos los componentes y la integración del componente del micrófono para permitir transmisiones. Los comentarios del archivo indicarán dónde integraremos Dialogflow más adelante.

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

Busca Widget build en el archivo chat.dart. Esto crea la interfaz del chatbot, que contiene lo siguiente:

  • ListView que contiene todos los globos de chat del usuario y el chatbot. Utiliza la clase ChatMessage, que crea mensajes de chat con un avatar y texto.
  • TextField para ingresar búsquedas de texto
  • IconButton con el ícono de enviar para enviar consultas de texto a Dialogflow
  • IconButton con un micrófono para enviar transmisiones de audio a Dialogflow, que cambia el estado una vez que se presiona.

Vincula la interfaz de chat

  1. Abre main.dart y cambia Widget build para que solo cree una instancia de la interfaz Chat(). Se pueden quitar todos los demás códigos de demostración.
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. Ejecuta la aplicación. (Si la app se inició antes. Detén el dispositivo virtual y vuelve a ejecutar main.dart). Cuando ejecutas tu app con la interfaz de chat por primera vez Aparecerá una ventana emergente de permiso en la que se te preguntará si quieres permitir el uso del micrófono. Haz clic en Mientras la app está en uso.

Permisos

  1. Experimenta con el área de texto y los botones. Cuando escribas una búsqueda por texto y presiones Intro o toques el botón de enviar, verás la búsqueda por texto registrada en la pestaña Run de Android Studio. Cuando presiones el botón del micrófono y lo sueltes, verás el registro de la transmisión de audio en la pestaña Ejecutar.

Registro de transmisión de audio

Excelente. Ahora ya podemos integrar la aplicación con Dialogflow.

Cómo integrar tu app de Flutter con Dialogflow_gRPC

  1. Abre chat.dart y agrega las siguientes importaciones:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. En la parte superior del archivo, justo debajo de // TODO DialogflowGrpcV2Beta1 class instance, agrega la siguiente línea para contener la instancia de la clase Dialogflow:
DialogflowGrpcV2Beta1 dialogflow;
  1. Busca el método initPlugin() y agrega el siguiente código justo debajo del comentario TODO:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

Esto creará una instancia de Dialogflow autorizada para tu proyecto de Google Cloud con la cuenta de servicio. (Asegúrate de tener el archivo credentials.json en la carpeta assets).

Una vez más, para fines de demostración sobre cómo trabajar con gRPC de Dialogflow, esto está bien, pero para las apps de producción, no querrás almacenar el archivo credentials.json en la carpeta de recursos, ya que no se considera seguro.

Cómo hacer una llamada a detectIntent

  1. Ahora busca el método handleSubmitted(), aquí es donde ocurre la magia. Justo debajo del comentario TODO, agrega el siguiente código, que agregará el mensaje escrito por el usuario a ListView:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. Ahora, justo debajo del código anterior, haremos la llamada a detectIntent, pasaremos el texto de la entrada y un languageCode. - El resultado (dentro de data.queryResult.fulfillment) se imprimirá en 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. Inicia el dispositivo virtual y prueba la llamada a detect intent. Tipo: hi. Debería aparecer el mensaje de bienvenida predeterminado. Cuando escribas otra cosa, se te devolverá la respuesta alternativa predeterminada.

Cómo realizar una llamada a streamingDetectIntent

  1. Ahora busca el método handleStream(), que es donde se produce la magia de la transmisión de audio. Primero, justo debajo del primer TODO, crea un InputConfigV2beta1 de audio con un biasList para sesgar el modelo de voz. Como usamos un teléfono (dispositivo virtual), el valor de sampleHertz será 16000 y la codificación será Linear 16. Depende del hardware de tu computadora o del micrófono que uses. Para el micrófono interno de mi MacBook, 16,000 era un buen valor. (Consulta la información del paquete https://pub.dev/packages/sound_stream).
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. A continuación, llamaremos al método streamingDetectIntent en el objeto dialogflow, que contiene nuestra sesión de Dialogflow:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. Con el objeto responseStream, finalmente podemos escuchar la transcripción entrante, la consulta del usuario detectada y la respuesta del intent coincidente detectado. Imprimiremos esto en un ChatMessage en la pantalla:
// 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');
});

Eso es todo. Inicia tu aplicación, pruébala en el dispositivo virtual, presiona el botón de micrófono y di "Hola".

Esto activará el intent de bienvenida predeterminado de Dialogflow. Los resultados se imprimirán en la pantalla. Ahora que Flutter funciona muy bien con la integración de Dialogflow, podemos comenzar a trabajar en la conversación de nuestro chatbot.

5. Dialogflow: Modelado del agente de Dialogflow

Dialogflow Essentials es un paquete de desarrollo para compilar IU conversacionales. Por lo tanto, chatbots, bots de voz y puertas de enlace telefónicas. Todos pueden crearla con la misma herramienta y, además, puedes admitir varios canales en más de 20 idiomas diferentes. Los diseñadores de UX (modeladores de agentes y lingüistas) o los desarrolladores de Dialogflow crean intents especificando frases de entrenamiento para entrenar un modelo de aprendizaje automático subyacente.

Un intent categoriza la intención del usuario. Para cada agente de Dialogflow ES, puedes definir varios intents, de manera que, en conjunto, estos permitan manejar una conversación completa. Cada intención puede contener parámetros y respuestas.

La búsqueda de intents coincidentes también se conoce como clasificación de intent o coincidencia de intent. Este es el concepto principal en Dialogflow ES. Una vez que se detecta una coincidencia con un intent, este puede devolver una respuesta, recopilar parámetros (extracción de entidades) o activar código de webhook (entrega), por ejemplo, para recuperar datos de una base de datos.

Cuando un usuario final escribe o dice algo en un chatbot, lo que se denomina expresión o enunciado del usuario, Dialogflow ES hace coincidir la expresión con el mejor intent de tu agente de Dialogflow, según las frases de entrenamiento. El modelo de aprendizaje automático de Dialogflow ES que se ejecuta en segundo plano se entrenó con esas frases de entrenamiento.

Dialogflow ES funciona con un concepto llamado contexto. Al igual que un humano, Dialogflow ES puede recordar el contexto en el segundo y tercer turno de conversación. Así es como puede hacer un seguimiento de las expresiones anteriores del usuario.

Aquí encontrarás más información sobre las intenciones de Dialogflow.

Cómo modificar el intent de bienvenida predeterminado

Cuando creas un agente de Dialogflow nuevo, se crean automáticamente dos intents predeterminados. El intent de bienvenida predeterminado es el primer flujo al que accedes cuando inicias una conversación con el agente. El intent alternativo predeterminado es el flujo que obtendrás cuando el agente no pueda comprenderte o no pueda hacer coincidir un intent con lo que acabas de decir.

Este es el mensaje de bienvenida para el intent de bienvenida predeterminado:

Usuario

Agent

Hola

"Hola, soy el bot de preguntas frecuentes de Dialogflow y puedo responder preguntas sobre Dialogflow".

"¿Qué te gustaría saber?"

  1. Haz clic en Intents > Default Welcome Intent.
  2. Desplázate hacia abajo hasta Respuestas.
  3. Borra todas las respuestas de texto.
  4. En la pestaña predeterminada, crea las siguientes 2 respuestas:
  • Hola, soy el bot de preguntas frecuentes de Dialogflow y puedo responder preguntas sobre Dialogflow. ¿Qué te gustaría saber?
  • Hola, soy el bot de preguntas frecuentes de Dialogflow. ¿Tienes preguntas sobre Dialogflow? ¿En qué puedo ayudarte?

La configuración debería ser similar a la de esta captura de pantalla.

Edita el intent de bienvenida predeterminado

  1. Haga clic en Guardar.
  2. Probemos este intent. Primero, podemos probarlo en el simulador de Dialogflow.Escribe: Hola. Debería mostrar uno de los siguientes mensajes:
  • Hola, soy el bot de preguntas frecuentes de Dialogflow y puedo responder preguntas sobre Dialogflow. ¿Qué te gustaría saber?
  • Hola, soy el bot de preguntas frecuentes de Dialogflow. ¿Tienes preguntas sobre Dialogflow? ¿En qué puedo ayudarte?

Cómo modificar el intent de resguardo predeterminado

  1. Haz clic en Intents > Default Fallback Intent.
  2. Desplázate hacia abajo hasta Respuestas.
  3. Borra todas las respuestas de texto.
  4. En la pestaña predeterminada, crea la siguiente respuesta:
  • Lamentablemente, no sé la respuesta a esta pregunta. ¿Consultaste nuestro sitio web? http://www.dialogflow.com?
  1. Haga clic en Guardar.

Cómo conectarse a una base de conocimiento en línea

Los conectores de conocimiento complementan los intents definidos. Analizan documentos de conocimiento para encontrar respuestas automáticas. (por ejemplo, preguntas frecuentes o artículos de archivos CSV, sitios web en línea o incluso archivos PDF). Para configurarlos, define una o más bases de conocimiento, que son colecciones de documentos de conocimiento.

Obtén más información sobre los conectores de conocimiento.

Vamos a probarlo.

  1. Selecciona Conocimiento (beta) en el menú.

base de conocimiento

  1. Haz clic en el botón azul de la derecha: Crear una base de conocimiento.
  2. Escribe Preguntas frecuentes de Dialogflow como nombre de la base de conocimiento y presiona Guardar.
  3. Haz clic en el vínculo Crear el primero.

Primera base de conocimiento

  1. Se abrirá una ventana.

Usa la siguiente configuración:

Nombre del documento: DialogflowFAQ Tipo de conocimiento: FAQ Tipo de MIME: text/html

  1. La URL desde la que cargamos los datos es la siguiente:

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

  1. Haz clic en Create.

Se creó una base de conocimiento:

Se creó la base de conocimiento

  1. Desplázate hacia abajo hasta la sección Respuestas y haz clic en Agregar respuesta.

Crea las siguientes respuestas y presiona Guardar.

$Knowledge.Answer[1]
  1. Haz clic en Ver detalles.

Ver detalles

  1. Selecciona Habilitar recarga automática para recuperar automáticamente los cambios cuando se actualice la página web de preguntas frecuentes y presiona Guardar.

Se mostrarán todas las preguntas frecuentes que implementaste en Dialogflow. ¡Es muy fácil!

Ten en cuenta que también puedes dirigir a un sitio web HTML en línea con preguntas frecuentes para importarlas a tu agente. Incluso es posible subir un PDF con un bloque de texto, y Dialogflow generará preguntas por sí solo.

Ahora, las preguntas frecuentes deben considerarse como "extras" para agregar a tus agentes, junto a tus flujos de intents. Las preguntas frecuentes de la base de conocimiento no pueden entrenar el modelo. Por lo tanto, hacer preguntas de una manera completamente diferente podría no generar una coincidencia, ya que no se utiliza la comprensión del lenguaje natural (modelos de aprendizaje automático). Por eso, a veces, vale la pena convertir tus preguntas frecuentes en intents.

  1. Prueba las preguntas en el simulador de la derecha.
  2. Cuando todo funcione, vuelve a tu app de Flutter y prueba tu bot de chat y voz con este contenido nuevo. Hacer las preguntas que cargaste en Dialogflow

Resultado

6. Felicitaciones

¡Felicitaciones! Creaste correctamente tu primera app de Flutter con una integración de chatbot de Dialogflow. ¡Bien hecho!

Temas abordados

  • Cómo crear un chatbot con Dialogflow Essentials
  • Cómo integrar Dialogflow en una app de Flutter
  • Cómo detectar intents de texto con Dialogflow
  • Cómo transmitir una voz a través del micrófono a Dialogflow
  • Cómo usar el conector de base de conocimiento

Próximos pasos

¿Te gustó este codelab? Echa un vistazo a estos excelentes labs de Dialogflow.

¿Te interesa saber cómo compilé el paquete de gRPC de Dialogflow para Dart/Flutter?