Dialogflowによる会議室検索チャットボットの簡単開発


フューチャー Advent Calendar 2019(2)の23日目です。

はじめに

2019年4月に新卒入社しました。
約8ヶ月過ごして会議室の場所を調べるのに手間がかかるなと感じていました。
手間がかかる理由は以下です。

  • 地図がない
  • 会議室に部屋番号がついておらず固有名詞で呼ばれている
  • イントラに会議室の場所が記載されているがモバイル端末からアクセスするにはユーザビリティの低い専用アプリが必要
  • そもそもイントラに場所が記載されていない会議室もある

そこで会議室名を入力すると場所を教えてくれるチャットボットを開発しようと思いました。
弊社はG-Suiteを契約しているためHangouts Chatをチャットアプリとして使用しています。Hangouts Chatでチャットボットを作成する方法はいくつかありますが今回はDialogflowというサービスを使用しました。
後ほど詳しく説明しますが以下のようなチャットボットが簡単に作成できます。

※ニュートン、オイラー、マクスウェルは架空の会議室名です

Dialoflowとは?

ユーザ・サービス間の対話インターフェースを開発できるサービスです。
チャットボットや音声アシスタントがユーザの問いかけに対してどのように応答するのかをGUIベースで簡単に設定することができます。

なぜDialogflow?

DialogflowはGoogleのマシンラーニングによる自然言語処理技術を活用しておりその利便性を体感してみたいなと思ったためです。他の方法と比較してDialogflowを選んだわけではありません。今回の機能であればGASでも実現できると思います。実際に使用してみてGASと比較したメリットは以下の2点と感じました。

  • コーディング量が少ない
    • 自然言語処理に関する部分はGUIから設定できます
    • GUIの設定で実現できない箇所のみコードを書きました
  • 様々なサービスと連携できるためDialogflowでBotを作成すれば再利用が可能
    • Google アシスタントといったGoogleのサービスはもちろんのこと以下のように多くのサービスとの連携機能を提供しています

構成

Cloud Functions for Firebaseを利用する理由は、Dialogflowでは質問に含まれる会議室名に応じて会議室の場所を返すことができないためです。詳細は後述します。

ボットの作成手順

DialogflowではAgentやEntity、Intentといったものを作成する必要があります。各概念の説明は公式ドキュメントとQiita記事:Dialogflow入門が参考になりました。
各概念の説明は少なめに手順を詳細に説明します。

前提

以下のような会議室が存在すると仮定します。(会議室の場所はより詳細に書いても良いと思います)

会議室名 会議室の場所
1 ニュートン 3階の北側
2 オイラー 3階の東側
3 マクスウェル 3階の南側

Dialogflowのコンソールにアクセス

Dialogflowの設定はコンソールから行います。

  • (i) Dialogflowにアクセスします
  • (ii) Go to consoleをクリックします

Agentの作成

Agentはユーザの発言に応じて必要な処理を行い返答します。Agent単位でどんなサービスを提供するのか定義します。今回の場合でいえば、「ニュートンはどこ?」というユーザの発言からニュートンという会議室の名前を特定し、ニュートンの場所を調べ、ニュートンの場所をユーザに返答します。

  • (i) サイドメニューのCreate new agentsをクリックします
  • (ii) Agent nameの入力欄にWhereIsRoomと入力しDefault languageをJapaneseにします
  • (iii) Createボタンをクリックします

Entityの作成

Entityはユーザの発言から何をパラメータとして取り出すのか定義します。今回の場合でいえば会議室の名前をパラメータとして取り出します。

  • (i) サイドメニューのEntitesをクリックします
  • (ii) Create Entityボタンをクリックします
  • (iii) Entity name入力欄にRoomと入力します
  • (iv) Click here to edit entryをクリックしReference valueSynonymを以下の表に従って入力します
    • Synonymにカタカナを入力したらひらがなや英語にも対応できるか試してみましたが駄目だったため、ひらがなと英語も入力しています
Reference value Synonym
1 ニュートン ニュートン、にゅーとん、newton
2 オイラー オイラー、おいらー、euler
3 マクスウェル マクスウェル、まくすうぇる、maxwell
  • (v) Fuzzy mathcingのチェックボックスをチェックします

    • ユーザがtypoした場合にも会議室名を正しく認識させることができます
      • 例えば、ニュートリ、newtomなどとtypoしてもニュートンという会議室名をユーザが意図して発言したと認識させることができます
  • (vi) Saveボタンをクリックします

  • Entityの設定画面は以下のとおりです

Intentの作成

Intentでユーザの問いかけに対してどのような処理をするのか設定します。

  • (i) サイドメニューのIntentsをクリックします
  • (ii) Create intentをクリックします
  • (iii) Intent name入力欄にTell Room Locationと入力します
  • (iv) 以下のようにTraining phrasesを入力します

  • (v) FulfillmentセクションでEnable webhook call for this intentのトグルボタンをOnにします
    • Intentのレスポンス機能では1つの質問の意図(ここでは会議室の場所を知りたい)に対して複数のランダムなレスポンスしか設定できず、質問に含まれる会議室名に応じて場所を返すことができないためFulfillmentを利用します

Fulfillmentの作成

Fulfillmentは外部のサービス(DBやAPI)を利用してユーザにレスポンスを返せるようにする機能です。
DialogflowではCloud Functions for Firebaseを利用して、外部サービスを提供するサーバを立てずともNode.js環境で処理を記述することができます。今回はこれを利用して会議室名に応じて場所を返却する処理を作成します。

  • (i) サイドメニューのFulfillmentをクリックします
  • (ii) Inline Editor (Powered by Cloud Functions for Firebase)のトグルボタンをOnにします

  • (iii) index.jsに以下のコードを記述します
    • 会議室は何年かに一度増えるだけであるため会議室名と場所をコードに直接書いています
index.js
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const roomLocation = {
    "ニュートン": "3階の北側",
    "オイラー": "3階の南側",
    "マクスウェル": "3階の西側"
  };

process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));

  function tellRoomLocation(agent) {
    agent.add(agent.parameters.Room + 'の場所は' + roomLocation[agent.parameters.Room] + 'です');
  }

  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('Tell Room Location', tellRoomLocation);
  agent.handleRequest(intentMap);
});
  • (iv) Deployボタンをクリックします

Hangouts Chatと統合

公式ドキュメントの手順を参考にしました。

  • (i) サイドメニューのIntegrationをクリックします
  • (ii) Hangouts Chatをクリックします
  • (iii) 誰がボットをインストールできるようにするか選択しStartをクリックします

ボットを使ってみる

ボットの追加

  • (i) Hangouts Chatにアクセスします
  • (ii) ボットの検索欄にWhereIsRoomと入力しボットを追加します

会議室の場所を聞く

typoにも対応できます。

チャットルームにボットを追加すれば会議開催時にメンションしてメンバーに場所を知らせることができます。