Androidアプリから自然言語処理(DialogFlow)


はじめに

以前、AndroidアプリからDialogFlowを利用して自然言語処理機能を実装しました。
DialogFlowを実装するためのSDKがAndroid用にはなく、結構嵌ったのでメモとして投稿しました。
少しでも参考になれば幸いです。

全体構成

AndroidアプリからDialogFlowを呼び出すのために、Cloud functionを利用しています。
Cloud functionを挟むことにより、Androidアプリ+DialogFlowとの認証を簡単にしています。

事前準備

  • AndroidアプリからCloud functions for Firebaseを利用可能にしておく
  • DialogFlowを利用可能にしておく
  • DialogFlowのサービスアカウントを発行する

CloudFunctions

以下、紹介する実装のファイル構成です。

 ├── functions
     ├── index.js              // cloudFunctions実装(アプリから呼ぶ関数定義)
     ├── dialogflow-v2.js      // cloudFunctions実装(DialogFlow呼び出し)
     ├── serviceaccount.json  // サービスアカウント

CloudFunctions実装(index.js)

アプリから呼ぶ関数の定義です。

index.js
const dialogflowv2Module = require('./dialogflow-v2');

exports.callDetectIntent = functions.https.onCall((data, context) => {
  let input = data.input;
  let result = dialogflowv2Module.detectIntentQueryText(input)
      .then(r => {
        return JSON.stringify(r);
      })
      .catch(err => {
        throw new functions.https.HttpsError('callDetectIntent',err);
      });
  return result;
});

CloudFunctions実装(dialogflow-v2.js)

サービスアカウントを使って、DialogFlowのAPIの呼び出しています。

dialogflow-v2.js
"use strict";

const dialogflow = require('dialogflow');
const serviceAccount = require('./serviceaccount.json');

exports.detectIntentQueryText = async function(query) {
    return await detectIntent(query);
}

async function detectIntent(query) {

    // Define config
    const languageCode = "ja";
    const sessionId = "00000000";

    // Instantiate a DialogFlow client.
    const sessionClient = new dialogflow.SessionsClient({
        credentials: {
            private_key: serviceAccount.private_key,
            client_email: serviceAccount.client_email
        }
    });

    // Define session path
    const sessionPath = sessionClient.sessionPath(serviceAccount.project_id, sessionId);

    // The text query request.
    const request = {
        session: sessionPath,
        queryInput: {
            text: {
                text: query,
                languageCode: languageCode,
            },
        },
    };

    // Send request and log result
    const result = await sessionClient
        .detectIntent(request)
        .then(responses => {
            return responses[0];
        })
        .catch(err => {
            console.log(err);
            throw new functions.https.HttpsError('detectIntentSync',err);
        });

    return result;
};

Androidアプリ実装

Androidアプリ実装です。Cloud Functionを呼び出しています。

DialogFlow.kt
    private lateinit var functions: FirebaseFunctions

    private fun callDetectIntent(text: String): Task<String> {
        val data = hashMapOf(
            "input" to text
        )

        return functions
            .getHttpsCallable("callDetectIntent")
            .call(data)
            .continueWith { task ->
                val result = task.result?.data as String
                result
            }
    }

参考文献