ساخت ربات های صوتی برای اندروید با Dialogflow Essentials & بال زدن

۱. قبل از شروع

در این آزمایشگاه کد، یاد خواهید گرفت که چگونه یک ربات متنی و صوتی ساده Dialogflow Essentials (ES) را در یک برنامه Flutter ادغام کنید. Dialogflow ES یک مجموعه توسعه برای ساخت رابط‌های کاربری محاوره‌ای است. بنابراین چت‌بات‌ها، ربات‌های صوتی، دروازه‌های تلفن. همه شما می‌توانید آن را با همان ابزار بسازید و حتی می‌توانید از چندین کانال در بیش از 20 زبان مختلف پشتیبانی کنید. Dialogflow با بسیاری از پلتفرم‌های مکالمه محبوب مانند Google Assistant، Slack و Facebook Messenger ادغام می‌شود. اگر می‌خواهید برای یکی از این پلتفرم‌ها یک عامل بسازید، باید از یکی از گزینه‌های ادغام متعدد استفاده کنید. با این حال، برای ایجاد یک چت‌بات برای دستگاه‌های تلفن همراه، باید یک ادغام سفارشی ایجاد کنید. شما با مشخص کردن عبارات آموزشی برای آموزش یک مدل یادگیری ماشین زیربنایی، اهدافی ایجاد خواهید کرد.

این آزمایشگاه به گونه‌ای طراحی شده است که منعکس کننده یک تجربه مشترک توسعه دهنده فضای ابری باشد:

  1. تنظیمات محیط
  • Dialogflow: یک عامل ES جدید Dialogflow ایجاد کنید
  • دیالوگ‌فلو: پیکربندی دیالوگ‌فلو
  • گوگل کلود: ایجاد یک حساب کاربری سرویس
  1. فلاتر: ساخت یک برنامه چت
  • ایجاد یک پروژه فلاتر
  • پیکربندی تنظیمات و مجوزها
  • اضافه کردن وابستگی‌ها
  • اتصال به حساب سرویس.
  • اجرای برنامه روی دستگاه مجازی یا دستگاه فیزیکی
  1. فلاتر: ساخت رابط چت با پشتیبانی از تبدیل گفتار به متن
  • ایجاد رابط چت
  • پیوند دادن رابط چت
  • ادغام پکیج gRPC مربوط به Dialogflow در برنامه
  1. Dialogflow: مدل‌سازی عامل Dialogflow
  • پیکربندی اهداف خوشامدگویی و بازگشت به حالت اولیه
  • از پایگاه دانش سوالات متداول استفاده کنید

پیش‌نیاز

  • تجربه اولیه دارت/فلاتر
  • تجربه اولیه پلتفرم ابری گوگل
  • تجربه اولیه با Dialogflow ES

آنچه خواهید ساخت

این آزمایشگاه کد به شما نشان می‌دهد که چگونه یک ربات پرسش و پاسخ موبایل بسازید، که می‌تواند به رایج‌ترین سوالات در مورد ابزار Dialogflow پاسخ دهد. کاربران نهایی می‌توانند با رابط متنی تعامل داشته باشند یا از طریق میکروفون داخلی دستگاه تلفن همراه، صدا را پخش کنند تا به پاسخ‌ها برسند.

آنچه یاد خواهید گرفت

  • نحوه ایجاد چت‌بات با Dialogflow Essentials
  • نحوه ادغام Dialogflow در یک برنامه Flutter با بسته gRPC Dialogflow
  • نحوه تشخیص اهداف متن با Dialogflow
  • نحوه پخش صدا از طریق میکروفون به Dialogflow
  • نحوه استفاده از رابط پایگاه دانش برای وارد کردن سوالات متداول عمومی
  • چت‌بات را از طریق رابط متنی و صوتی در یک دستگاه مجازی یا فیزیکی آزمایش کنید

آنچه نیاز دارید

  • برای ایجاد یک عامل Dialogflow به یک آدرس Google Identity / Gmail نیاز دارید.
  • برای دانلود حساب کاربری سرویس، به دسترسی به پلتفرم ابری گوگل نیاز دارید.
  • یک محیط توسعه فلاتر

محیط توسعه فلاتر خود را تنظیم کنید

  1. سیستم عاملی که Flutter را روی آن نصب می‌کنید، انتخاب کنید.
  1. شما می‌توانید با استفاده از هر ویرایشگر متنی که با ابزارهای خط فرمان ما ترکیب شده است، با Flutter برنامه‌هایی بسازید. با این حال، این کارگاه از اندروید استودیو استفاده خواهد کرد. افزونه‌های Flutter و Dart برای اندروید استودیو، تکمیل کد، هایلایت کردن سینتکس، کمک به ویرایش ویجت، پشتیبانی از اجرا و اشکال‌زدایی و موارد دیگر را در اختیار شما قرار می‌دهند. مراحل زیر را در https://flutter.dev/docs/get-started/editor دنبال کنید.

۲. تنظیمات محیطی

Dialogflow: یک عامل ES جدید Dialogflow ایجاد کنید

  1. را باز کنید
  2. در نوار سمت چپ، درست زیر لوگو، از منوی کشویی، گزینه « ایجاد نماینده جدید » را انتخاب کنید. (توجه داشته باشید، روی منوی کشویی که نوشته «جهانی» کلیک نکنید، ما برای استفاده از پایگاه دانش سوالات متداول به یک نمونه Dialogflow سراسری نیاز داریم.)
  3. نام عامل را با استفاده yourname-dialogflow مشخص کنید (از نام خودتان استفاده کنید)
  4. به عنوان زبان پیش‌فرض، انگلیسی - انگلیسی را انتخاب کنید.
  5. به عنوان منطقه زمانی پیش‌فرض، منطقه زمانی نزدیک به خودتان را انتخاب کنید.
  6. مگا ایجنت (Mega Agent) را انتخاب نکنید . (با این ویژگی می‌توانید یک ایجنت فراگیر ایجاد کنید که می‌تواند بین ایجنت‌های «زیرمجموعه» هماهنگی ایجاد کند. اکنون به این مورد نیاز نداریم.)
  7. روی ایجاد کلیک کنید.

ایجاد صفحه نمایش پروژه جدید

پیکربندی دیالوگ فلو

  1. روی نماد چرخ دنده ، در منوی سمت چپ، کنار نام پروژه خود کلیک کنید.

منوی کشویی ایجاد پروژه جدید

  1. توضیحات زیر را برای اپراتور وارد کنید: سوالات متداول Dialogflow، ربات گفتگو
  2. ویژگی‌های بتا را فعال کنید ، دکمه را بزنید.

ملزومات دیالوگ فلو نسخه ۲ بتا ۱

  1. روی برگه گفتار کلیک کنید و مطمئن شوید که کادر «تطبیق خودکار گفتار» فعال است.
  2. به صورت اختیاری، می‌توانید اولین سوئیچ را نیز فعال کنید، این کار مدل گفتار را بهبود می‌بخشد، اما فقط زمانی در دسترس است که نسخه آزمایشی Dialogflow را ارتقا دهید.
  3. روی ذخیره کلیک کنید

گوگل کلود: یک حساب کاربری سرویس دریافت کنید

پس از ایجاد یک عامل در Dialogflow، یک پروژه Google Cloud باید در کنسول Google Cloud ایجاد شود.

  1. کنسول ابری گوگل را باز کنید:
  2. مطمئن شوید که با همان حساب گوگلی که در Dialogflow استفاده می‌کنید، وارد سیستم شده‌اید و در نوار آبی بالا، project: yourname-dialogflow انتخاب کنید.
  3. سپس، در نوار ابزار بالا، Dialogflow API را جستجو کنید و روی نتیجه Dialogflow API در منوی کشویی کلیک کنید.

فعال کردن API دیالوگ فلو

  1. روی دکمه آبی مدیریت (Manage) کلیک کنید و در نوار منوی سمت چپ روی اعتبارنامه‌ها (Credentials) کلیک کنید. (وقتی Dialogflow هنوز فعال نشده است، ابتدا روی فعال کردن (Enable ) کلیک کنید)

کنسول GCP اعتبارنامه‌ها

  1. روی «ایجاد اعتبارنامه‌ها» (در بالای صفحه) کلیک کنید و «حساب سرویس» را انتخاب کنید.

ایجاد اعتبارنامه

  1. نام حساب سرویس را مشخص کنید: flutter_dialogflow ، شناسه و توضیحات، و روی ایجاد کلیک کنید.

ایجاد حساب کاربری سرویس

  1. در مرحله ۲، باید نقش را انتخاب کنید: Dialogflow API Admin ، روی Continue و سپس Done کلیک کنید.
  2. روی حساب سرویس flutter_dialogflow کلیک کنید، روی تب Keys کلیک کنید و Add Key > Create new key را بزنید.

ایجاد کلید

  1. یک کلید JSON ایجاد کنید. نام آن را به credentials.json تغییر دهید و آن را در جایی امن از هارد دیسک خود ذخیره کنید. بعداً از آن استفاده خواهیم کرد.

کلید JSON

عالی بود، تمام ابزارهای مورد نیاز به درستی تنظیم شده‌اند. حالا می‌توانیم ادغام Dialogflow را در برنامه‌مان شروع کنیم!

۳. فلاتر: ساخت اپلیکیشن چت

ایجاد برنامه Boilerplate

  1. اندروید استودیو را باز کنید و گزینه Start a new Flutter project را انتخاب کنید.
  2. نوع پروژه را Flutter Application انتخاب کنید. سپس روی Next کلیک کنید.
  3. تأیید کنید که مسیر Flutter SDK، محل SDK را مشخص می‌کند (اگر فیلد متن خالی است، گزینه Install SDK... را انتخاب کنید).
  4. یک نام برای پروژه وارد کنید (برای مثال، flutter_dialogflow_agent ). سپس روی Next کلیک کنید.
  5. نام بسته را تغییر دهید و روی Finish کلیک کنید.

ایجاد برنامه جدید Flutter

این یک برنامه نمونه با کامپوننت‌های متریال ایجاد می‌کند.

منتظر بمانید تا اندروید استودیو SDK را نصب کند و پروژه را ایجاد کند.

تنظیمات و مجوزها

  1. کتابخانه ضبط صدا sound_stream که ما استفاده خواهیم کرد، به minSdk حداقل ۲۱ نیاز دارد. بنابراین بیایید این را در android/app/build.gradle در بلوک defaultConfig تغییر دهیم. (توجه داشته باشید، ۲ فایل build.gradle در پوشه android وجود دارد، اما فایلی که در پوشه app است، فایل صحیح است.)
defaultConfig {
   applicationId "com.myname.flutter_dialogflow_agent"
   minSdkVersion 21
   targetSdkVersion 30
   versionCode flutterVersionCode.toInteger()
   versionName flutterVersionName
}
  1. برای دادن مجوز به میکروفون و همچنین برای اینکه برنامه بتواند به عامل Dialogflow که در فضای ابری اجرا می‌شود، دسترسی پیدا کند، باید مجوزهای INTERNET و RECORD_AUDIO را به فایل app/src/main/AndroidManifest.xml اضافه کنیم. چندین فایل AndroidManifest.xml در پروژه Flutter شما وجود دارد، اما به فایلی که در پوشه اصلی قرار دارد نیاز خواهید داشت. می‌توانید خطوط را درست داخل تگ‌های manifest اضافه کنید.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />

اضافه کردن وابستگی‌ها

ما از بسته‌های sound_stream ، rxdart و dialogflow_grpc استفاده خواهیم کرد.

  1. وابستگی 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. وابستگی 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. وابستگی 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!

بارگیری حساب سرویس و اطلاعات پروژه Google Cloud

  1. در پروژه خود یک دایرکتوری ایجاد کنید و نام آن را assets بگذارید.
  2. فایل credentials.json را که از کنسول Google Cloud دانلود کرده‌اید، به پوشه assets منتقل کنید.
  3. فایل pubspec.yaml را باز کنید و حساب کاربری سرویس را به بلوک flutter اضافه کنید.
flutter:
  uses-material-design: true
  assets:
    - assets/credentials.json

اجرای برنامه روی یک دستگاه فیزیکی

وقتی دستگاه اندروید دارید، می‌توانید گوشی خود را از طریق کابل USB به دستگاه وصل کنید و آن را اشکال‌زدایی کنید. برای تنظیم این مورد از طریق صفحه گزینه‌های توسعه‌دهندگان در دستگاه اندروید خود، این مراحل را دنبال کنید.

اجرای برنامه روی دستگاه مجازی

در صورتی که می‌خواهید برنامه را روی یک دستگاه مجازی اجرا کنید، از مراحل زیر استفاده کنید:

  1. روی ابزارها > مدیر AVD کلیک کنید. (یا مدیر AVD را از نوار ابزار بالا انتخاب کنید، در شکل زیر با رنگ صورتی مشخص شده است)

نوار ابزار بالای اندروید استودیو

  1. ما یک دستگاه مجازی اندروید هدف ایجاد خواهیم کرد تا بتوانیم برنامه خود را بدون دستگاه فیزیکی آزمایش کنیم. برای جزئیات بیشتر، به مدیریت AVDها مراجعه کنید. پس از انتخاب یک دستگاه مجازی جدید، می‌توانید روی آن دوبار کلیک کنید تا شروع به کار کند.

مدیریت AVDها

دستگاه مجازی

  1. در نوار ابزار اصلی اندروید استودیو، از طریق منوی کشویی، یک دستگاه اندروید را به عنوان هدف انتخاب کنید و مطمئن شوید که main.dart انتخاب شده است. سپس دکمه Run (مثلث سبز) را فشار دهید.

در پایین IDE، گزارش‌ها را در کنسول مشاهده خواهید کرد. متوجه خواهید شد که در حال نصب اندروید و برنامه‌ی اولیه‌ی Flutter شما است. این کار یک دقیقه طول می‌کشد، به محض آماده شدن دستگاه مجازی، اعمال تغییرات بسیار سریع خواهد بود. وقتی کارتان تمام شد، برنامه‌ی اولیه‌ی Flutter باز می‌شود.

برنامه‌ی قالبی

  1. بیایید میکروفون را برای برنامه چت‌بات خود فعال کنیم. برای باز کردن گزینه‌ها، روی دکمه تنظیمات دستگاه مجازی کلیک کنید. در تب میکروفون، هر 3 سوئیچ را فعال کنید.

گزینه‌های AVD

  1. بیایید قابلیت بارگذاری سریع (Hot Reload) را امتحان کنیم تا نشان دهیم که تغییرات چقدر سریع می‌توانند اعمال شوند.

در فایل lib/main.dart ، عنوان MyHomePage را در کلاس MyApp به Flutter Dialogflow Agent تغییر دهید. و primarySwatch را به Colors.orange تغییر دهید.

کد اول

فایل را ذخیره کنید ، یا روی آیکون پیچ در نوار ابزار اندروید استودیو کلیک کنید. باید تغییر را مستقیماً در دستگاه مجازی مشاهده کنید.

۴. فلاتر: ساخت رابط چت با پشتیبانی STT

ایجاد رابط چت

  1. یک فایل ویجت Flutter جدید در پوشه lib ایجاد کنید. (روی پوشه lib کلیک راست کنید، New > Flutter Widget > Stateful widget را انتخاب کنید)، این فایل را chat.dart بنامید.

کد زیر را در این فایل قرار دهید. این فایل دارت رابط چت را ایجاد می‌کند. Dialogflow هنوز کار نمی‌کند، فقط طرح‌بندی همه اجزا و ادغام مؤلفه میکروفون برای امکان پخش جریان‌ها باقی مانده است. نظرات موجود در فایل، به جایی که بعداً 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),
      ),
    );
  }
}

در فایل chat.dart به دنبال Widget build بگردید. این کد رابط چت‌بات را می‌سازد که شامل موارد زیر است:

  • ListView که شامل تمام بالن‌های چت از کاربر و ربات چت است. این ListView از کلاس ChatMessage استفاده می‌کند که پیام‌های چت را با آواتار و متن ایجاد می‌کند.
  • فیلد متنی برای وارد کردن کوئری‌های متنی
  • IconButton با آیکون ارسال، برای ارسال کوئری‌های متنی به Dialogflow
  • IconButton با میکروفون برای ارسال جریان‌های صوتی به Dialogflow، که پس از فشردن، حالت را تغییر می‌دهد.

پیوند دادن رابط چت

  1. فایل main.dart را باز کنید و Widget build تغییر دهید، به طوری که فقط رابط Chat() را نمونه‌سازی کند. سایر کدهای نمایشی قابل حذف هستند.
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. برنامه را اجرا کنید. ( اگر برنامه قبلاً شروع شده است. دستگاه مجازی را متوقف کنید و main.dart را دوباره اجرا کنید ). وقتی برنامه خود را برای اولین بار با رابط چت اجرا می‌کنید، یک پنجره بازشو برای اجازه دسترسی به میکروفون دریافت خواهید کرد. کلیک کنید: هنگام استفاده از برنامه .

مجوزها

  1. با ناحیه متن و دکمه‌ها بازی کنید. وقتی یک کوئری متنی تایپ می‌کنید و اینتر را می‌زنید یا دکمه ارسال را لمس می‌کنید، کوئری متنی را در تب Run اندروید استودیو مشاهده خواهید کرد. وقتی دکمه میکروفون را لمس می‌کنید و آن را متوقف می‌کنید، جریان صوتی را در تب Run مشاهده خواهید کرد.

گزارش جریان صوتی

عالی، اکنون آماده ادغام برنامه با Dialogflow هستیم!

ادغام برنامه Flutter شما با Dialogflow_gRPC

  1. فایل chat.dart را باز کنید و ایمپورت‌های زیر را اضافه کنید:
import 'package:dialogflow_grpc/dialogflow_grpc.dart';
import 'package:dialogflow_grpc/generated/google/cloud/dialogflow/v2beta1/session.pb.dart';
  1. در بالای فایل، درست زیر // TODO DialogflowGrpcV2Beta1 class instance ، خط زیر را برای نگهداری نمونه کلاس Dialogflow اضافه کنید:
DialogflowGrpcV2Beta1 dialogflow;
  1. متد initPlugin() را جستجو کنید و کد زیر را درست زیر کامنت TODO اضافه کنید:
    // Get a Service account
    final serviceAccount = ServiceAccount.fromString(
        '${(await rootBundle.loadString('assets/credentials.json'))}');
    // Create a DialogflowGrpc Instance
    dialogflow = DialogflowGrpcV2Beta1.viaServiceAccount(serviceAccount);

این یک نمونه از Dialogflow ایجاد می‌کند که با حساب کاربری سرویس به پروژه Google Cloud شما مجاز است. (مطمئن شوید که فایل credentials.json را در پوشه assets دارید!)

باز هم، برای اهداف نمایشی در مورد نحوه کار با Dialogflow gRPC، این مورد اشکالی ندارد، اما برای برنامه‌های کاربردی، شما نمی‌خواهید فایل credentials.json را در پوشه assets ذخیره کنید، زیرا این کار امن تلقی نمی‌شود.

انجام فراخوانی detectIntent

  1. حالا متد handleSubmitted() را پیدا کنید، اینجاست که جادو وارد عمل می‌شود. درست زیر کامنت TODO، کد زیر را اضافه کنید. این کد پیام تایپ شده توسط کاربر را به ListView اضافه می‌کند:
ChatMessage message = ChatMessage(
 text: text,
 name: "You",
 type: true,
);

setState(() {
 _messages.insert(0, message);
});
  1. حالا، درست زیر کد قبلی، فراخوانی detectIntent را انجام می‌دهیم، متن را از ورودی و یک languageCode ارسال می‌کنیم. - نتیجه (درون data.queryResult.fulfillment ) در 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. دستگاه مجازی را راه‌اندازی کنید و فراخوانی detect intent را آزمایش کنید. hi را تایپ کنید. باید با پیام خوشامدگویی پیش‌فرض به شما خوشامد بگوید. وقتی چیز دیگری تایپ کنید، پیام جایگزین پیش‌فرض را به شما برمی‌گرداند.

ایجاد فراخوانی streamingDetectIntent

  1. حالا متد handleStream() پیدا کنید، اینجاست که جادوی استریمینگ صدا به کار می‌آید. ابتدا درست زیر اولین TODO، یک InputConfigV2beta1 صوتی با یک biasList برای بایاس کردن مدل صدا ایجاد کنید. از آنجایی که ما از یک تلفن (دستگاه مجازی) استفاده می‌کنیم، sampleHertz برابر با ۱۶۰۰۰ و encoding برابر با Linear 16 خواهد بود. این به سخت‌افزار دستگاه / میکروفونی که استفاده می‌کنید بستگی دارد. برای میکروفون داخلی مک‌بوک من، ۱۶۰۰۰ خوب بود. (به اطلاعات بسته 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. در مرحله بعد، متد streamingDetectIntent را روی شیء dialogflow که جلسه Dialogflow ما را در خود جای داده است، فراخوانی خواهیم کرد:
final responseStream = dialogflow.streamingDetectIntent(config, _audioStream);
  1. با responseStream، بالاخره می‌توانیم به رونوشت ورودی، کوئری شناسایی‌شده‌ی کاربر و پاسخ منطبق با هدف شناسایی‌شده گوش دهیم. ما این را در یک ChatMessage روی صفحه چاپ خواهیم کرد:
// 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');
});

همین است، برنامه خود را اجرا کنید و آن را روی دستگاه مجازی آزمایش کنید، دکمه میکروفون را فشار دهید و بگویید: "سلام" .

این کار باعث فعال شدن پیام خوشامدگویی پیش‌فرض Dialogflow می‌شود. نتایج روی صفحه نمایش چاپ می‌شوند. اکنون که Flutter به خوبی با Dialogflow یکپارچه شده است، می‌توانیم روی مکالمه با ربات چت خود کار کنیم.

۵. Dialogflow: مدل‌سازی عامل Dialogflow

Dialogflow Essentials یک مجموعه توسعه برای ساخت رابط‌های کاربری محاوره‌ای است. بنابراین چت‌بات‌ها، ربات‌های صوتی، درگاه‌های تلفن. همه شما می‌توانید آن را با همان ابزار بسازید و حتی می‌توانید از چندین کانال در بیش از 20 زبان مختلف پشتیبانی کنید. طراحان تجربه کاربری Dialogflow (مدل‌سازان عامل، زبان‌شناسان) یا توسعه‌دهندگان با مشخص کردن عبارات آموزشی برای آموزش یک مدل یادگیری ماشین زیربنایی، اهداف را ایجاد می‌کنند.

یک اینتنت، قصد کاربر را دسته‌بندی می‌کند. برای هر عامل Dialogflow ES، می‌توانید چندین اینتنت تعریف کنید، که در آن اینتنت‌های ترکیبی شما می‌توانند یک مکالمه کامل را مدیریت کنند. هر اینتنت می‌تواند شامل پارامترها و پاسخ‌ها باشد.

تطبیق یک هدف (Intent) همچنین به عنوان طبقه‌بندی هدف (Intent Classification) یا تطبیق هدف (Intent Matching) شناخته می‌شود. این مفهوم اصلی در Dialogflow ES است. هنگامی که یک هدف تطبیق داده شد، می‌تواند یک پاسخ برگرداند، پارامترها را جمع‌آوری کند (استخراج موجودیت) یا کد وب‌هوک (اجرای دستورات) را فعال کند، برای مثال، برای واکشی داده‌ها از یک پایگاه داده.

وقتی یک کاربر نهایی چیزی را در یک چت‌بات می‌نویسد یا می‌گوید، که به آن عبارت یا گفته کاربر گفته می‌شود، Dialogflow ES بر اساس عبارات آموزشی، این عبارت را با بهترین منظور عامل Dialogflow شما مطابقت می‌دهد. مدل یادگیری ماشینی Dialogflow ES در پشت صحنه بر اساس آن عبارات آموزشی آموزش دیده است.

Dialogflow ES با مفهومی به نام زمینه کار می‌کند. درست مانند یک انسان، Dialogflow ES می‌تواند زمینه را در نوبت دوم و سوم به خاطر بسپارد. به این ترتیب می‌تواند گفته‌های قبلی کاربر را پیگیری کند.

در اینجا اطلاعات بیشتری در مورد اهداف Dialogflow آمده است .

تغییر هدف پیش‌فرض خوشامدگویی

وقتی یک عامل Dialogflow جدید ایجاد می‌کنید، دو هدف پیش‌فرض به طور خودکار ایجاد می‌شوند. هدف خوشامدگویی پیش‌فرض ، اولین جریانی است که هنگام شروع مکالمه با عامل با آن مواجه می‌شوید. هدف جایگزین پیش‌فرض ، جریانی است که پس از اینکه عامل نتواند منظور شما را بفهمد یا نتواند یک هدف را با آنچه شما گفته‌اید مطابقت دهد، دریافت خواهید کرد.

پیام خوشامدگویی برای هدف خوشامدگویی پیش‌فرض به صورت زیر است:

کاربر

عامل

سلام

«سلام، من ربات سوالات متداول Dialogflow هستم، می‌توانم به سوالات در Dialogflow پاسخ دهم.»

«چی دوست داری بدونی؟»

  1. روی Intents > Default Welcome Intent کلیک کنید.
  2. به پایین اسکرول کنید تا به پاسخ‌ها برسید .
  3. تمام پاسخ‌های متنی را پاک کنید.
  4. در برگه پیش‌فرض، دو پاسخ زیر را ایجاد کنید:
  • سلام، من ربات سوالات متداول Dialogflow هستم، می‌توانم به سوالات شما در Dialogflow پاسخ دهم. چه چیزی می‌خواهید بدانید؟
  • سلام، من ربات سوالات متداول Dialogflow هستم، آیا در مورد Dialogflow سوالی دارید؟ چگونه می‌توانم کمک کنم؟

تنظیمات باید مشابه این اسکرین شات باشد.

ویرایش هدف خوشامدگویی پیش‌فرض

  1. روی ذخیره کلیک کنید
  2. بیایید این intent را آزمایش کنیم. ابتدا می‌توانیم آن را در Dialogflow Simulator.Type: Hello آزمایش کنیم. باید یکی از این پیام‌ها را برگرداند:
  • سلام، من ربات سوالات متداول Dialogflow هستم، می‌توانم به سوالات شما در Dialogflow پاسخ دهم. چه چیزی می‌خواهید بدانید؟
  • سلام، من ربات سوالات متداول Dialogflow هستم، آیا در مورد Dialogflow سوالی دارید؟ چگونه می‌توانم کمک کنم؟

تغییر هدف پیش‌فرض پشتیبان

  1. روی Intents > Default Fallback Intent کلیک کنید.
  2. به پایین اسکرول کنید تا به پاسخ‌ها برسید .
  3. تمام پاسخ‌های متنی را پاک کنید.
  4. در برگه پیش‌فرض، پاسخ زیر را ایجاد کنید:
  • متأسفانه من جواب این سوال را نمی‌دانم. آیا وب‌سایت ما را بررسی کرده‌اید؟ http://www.dialogflow.com؟
  1. روی ذخیره کلیک کنید

اتصال به پایگاه دانش آنلاین

رابط‌های دانش، مکمل اهداف تعریف‌شده هستند. آن‌ها اسناد دانش را برای یافتن پاسخ‌های خودکار تجزیه می‌کنند. (برای مثال، سوالات متداول یا مقالات از فایل‌های CSV، وب‌سایت‌های آنلاین یا حتی فایل‌های PDF!) برای پیکربندی آن‌ها، یک یا چند پایگاه دانش تعریف می‌کنید که مجموعه‌ای از اسناد دانش هستند.

درباره رابط‌های دانش بیشتر بخوانید.

بیایید این را امتحان کنیم.

  1. دانش (بتا) را از منو انتخاب کنید.

پایگاه دانش

  1. روی دکمه آبی سمت راست کلیک کنید: ایجاد پایگاه دانش
  2. نام پایگاه دانش را تایپ کنید؛ سوالات متداول Dialogflow را وارد کنید و ذخیره را بزنید.
  3. روی ایجاد اولین لینک کلیک کنید

پایگاه دانش اول

  1. این یک پنجره باز می‌کند.

از کانفیگ زیر استفاده کنید:

نام سند: DialogflowFAQ نوع دانش: FAQ نوع MIME: text/html

  1. آدرس اینترنتی (URL) که داده‌ها از آن بارگذاری می‌شوند:

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

  1. روی ایجاد کلیک کنید

یک پایگاه دانش ایجاد شده است:

پایگاه دانش ایجاد شد

  1. به بخش پاسخ‌ها (Responses) بروید و روی افزودن پاسخ (Add Response) کلیک کنید.

پاسخ‌های زیر را ایجاد کنید و ذخیره را بزنید.

$Knowledge.Answer[1]
  1. روی مشاهده جزئیات کلیک کنید

مشاهده جزئیات

  1. برای دریافت خودکار تغییرات هنگام به‌روزرسانی صفحه وب سوالات متداول، گزینه «فعال کردن بارگذاری مجدد خودکار» را انتخاب کنید و سپس ذخیره را بزنید.

این تمام سوالات متداولی را که در Dialogflow پیاده‌سازی کرده‌اید نمایش می‌دهد. به همین راحتی!

توجه داشته باشید که می‌توانید به یک وب‌سایت HTML آنلاین با سوالات متداول نیز مراجعه کنید تا سوالات متداول را به نماینده خود وارد کنید. حتی می‌توانید یک فایل PDF با یک بلوک متن آپلود کنید و Dialogflow خودش سوالات را مطرح خواهد کرد.

اکنون سوالات متداول باید به عنوان «افزونه‌هایی» برای اضافه کردن به عامل‌های شما، در کنار جریان‌های هدف شما، در نظر گرفته شوند. سوالات متداول پایگاه دانش نمی‌توانند مدل را آموزش دهند. بنابراین پرسیدن سوالات به روشی کاملاً متفاوت، ممکن است مطابقت نداشته باشد زیرا از درک زبان طبیعی (مدل‌های یادگیری ماشین) استفاده نمی‌کند. به همین دلیل است که گاهی اوقات ارزش دارد سوالات متداول خود را به اهداف تبدیل کنید.

  1. سوالات را در شبیه‌ساز سمت راست امتحان کنید.
  2. وقتی همه چیز درست شد، به برنامه Flutter خود برگردید و چت و ربات صوتی خود را با این محتوای جدید آزمایش کنید! سوالاتی را که در Dialogflow بارگذاری کرده‌اید، بپرسید.

نتیجه

۶. تبریک

تبریک می‌گویم، شما با موفقیت اولین برنامه Flutter خود را با ادغام چت‌بات Dialogflow ایجاد کردید، آفرین!

آنچه ما پوشش داده‌ایم

  • نحوه ایجاد چت‌بات با Dialogflow Essentials
  • نحوه ادغام Dialogflow در یک برنامه Flutter
  • نحوه تشخیص اهداف متن با Dialogflow
  • نحوه پخش صدا از طریق میکروفون به Dialogflow
  • نحوه استفاده از رابط پایگاه دانش

بعدش چی؟

از این آزمایشگاه کد لذت بردید؟ نگاهی به این آزمایشگاه‌های عالی Dialogflow بیندازید!

به نحوه ساخت پکیج gRPC مربوط به Dialogflow برای Dart/Flutter علاقه‌مند هستید؟