LoginSignup
4
1

More than 1 year has passed since last update.

react-native-giftedChatとQnA Makerでチャットボットアプリ作成

Last updated at Posted at 2021-12-06

はじめに

reac-native-giftedChatライブラリとQnA Makerサービスを用いてチャットボットアプリを作成します。
ReactNativeのアプリ上にチャットボット機能を実装する事がありましたので、備忘録として記事に纏めます。

react-native-giftedChat

綺麗なチャット画面を作る為のライブラリです。チャットボットに限ったものではない為、いわゆる人間同士のチャット画面として利用できます。今回はUser(利用者)とBot(チャットボット)の2人物のやりとりという形で画面を作成します。

ステートのmessages配列で一連の会話内容を管理します。messageオブジェクトの要素は下記の通りです。

  • _id ...messages内で一意の番号
  • text ...表示する文字列
  • createdAt ...投稿時のタイムスタンプ
  • user ...メッセージの投稿者

QnA Maker

Microsoft社が提供しているコグニティブサービスの1つです。
専用ポータルから質問と回答の組み合わせを登録することで、簡単にボットサービスを作成できます。

詳細なデプロイ方法については割愛しますが、公式のクイックスタートがとても分かりやすかったです。
(https://docs.microsoft.com/ja-jp/azure/cognitive-services/QnAMaker/Quickstarts/create-publish-knowledge-base)

デプロイ完了後にテスト用の質問と回答のペアを登録します。
公式が提供しているチャットのデータセットがあるので、こちらをインポートします。(https://github.com/microsoft/botframework-cli/blob/main/packages/qnamaker/docs/chit-chat-dataset.md)

回答ペア登録完了後、Publishタブから公開することで、回答生成のAPIを確認できます。API呼び出しに使う為、{}で囲まれた3つの値を控えておきます。

  • https://{QnA-Maker-endpoint}/knowledgebases/{knowledge-base-ID}/generateAnswer
  • Authorization: EndpointKey {QnA Makerのエンドポイントキー}

スクリーンショット 2021-12-07 0.16.52.png

処理の流れ

チャットボット画面の全体の処理の流れは下記の通りです。

  1. チャット画面からテキストを入力
  2. 入力内容からmessageオブジェクトを作成(User側)
  3. ステートのmessages配列に追加
  4. QnA MakerのAPIを呼び出し
  5. 返答からmessageオブジェクトを作成(Bot側)
  6. ステートのmessages配列に追加

ライブラリのインストール

'react-native-gifted-chat'をインストールします。

npm install react-native-gifted-chat --save

また、メッセージの採番用に'react-native-uuid'もインストールします。

npm install react-native-uuid --save

コード

App.jsは下記の通りです。expoで動作する事を確認しています。

App.js
import { StyleSheet } from 'react-native';
import { GiftedChat } from 'react-native-gifted-chat';
import React, { useState, useCallback, useEffect } from 'react';
import uuid from 'react-native-uuid';

const CHAT_URL = 'https://{QnA-Maker-endpoint}/knowledgebases/{knowledge-base-ID}/generateAnswer'
const ENDPOINT_KEY = 'EndpointKey {QnA Makerのエンドポイントキー}'

/* 利用者(画面右側) */
const USER = {
  _id: 1,
  name: 'Me',
}
/* ボット(画面左側) */
const BOT = {
  _id: 2,
  name: 'Bot',
  avatar: 'https://placeimg.com/140/140/any',
}

export default function App() {
  /* メッセージを保持するステート */
  const [messages, setMessages] = useState([]);
  useEffect(() => {
    /* 初回画面表示時のメッセージ */
    setMessages([
      {
        _id: uuid.v4(),
        text: '質問はありますか?',
        createdAt: new Date(),
        user: BOT,
      },
    ])
  }, [])

  /* QnA MakerのgenerateAnswerAPIをコール */
  const generateAnswer = async (message) => {
    try {
     const response = await fetch(CHAT_URL, {
      method: 'POST',
      headers: {
        Authorization: ENDPOINT_KEY,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        question: message,
      })
    })
     const json = await response.json();
     const responseMessages = {
       _id: uuid.v4(),
       text: json.answers[0].answer,
       createdAt: new Date(),
       user: BOT,
     }
     /* レスポンスをmessagesに追加 */
     setMessages(previousMessages => GiftedChat.append(previousMessages, responseMessages))
    } catch (error) {
     console.error(error);
   }
 }

 /* テキスト送信時の処理 入力内容をmessagesに追加後、QnA MakerのAPIをコールする */
  const onSend = useCallback((messages = []) => {
    setMessages(previousMessages => GiftedChat.append(previousMessages, messages));
    generateAnswer(messages[0].text);
  }, [])

  return (
    <GiftedChat
      messages={messages}
      onSend={messages => onSend(messages)}
      user={USER}
    />
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

完成イメージ

まとめ

画面はチャット用のライブラリ、バックエンドはAzureのサービスという簡単な構成ではあったのですが、意外とそれっぽく動かせています。Q&Aの内容はポータルからいつでも更新も可能な上、quickRepliesを用いればマルチターン回答(選択肢つきの回答)も実現できそうなので、拡張性もあるのではと思っています。

参考URL

4
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1