Actions On Google のバックエンド(ランタイム Node.js 6.10)を作るのによさげなフレームワークがあったので紹介。
その名も Jovo。
#経緯
Dialogflow から Firebase Cloud Functionsを 利用して、外部サービスの API を使ってデータを取得したい。取得したデータの内容を Google Home にしゃべらせたい。
↓
Firebase の有料プランに登録していないと外部にリクエスト投げれない(アウトバウンドネットワーキングできない)
↓
有料プランに登録したくないので既に持ってる AWS Lambda を使おう
↓
Dialogflow と AWS Lambda の JSON のやりとりがうまくいかない
↓
そこで見つけた Jovo
Firebase の有料プランに登録しても微々たる課金額、場合によっては無料だったり、Dialogflow と AWS Lambda の JSON やりとりがうまくいかないのは、単純に私の知識がないだけだったりで、別のうまいやり方知ってる人にはあまり紹介しても意味がないかもしれないですが、私みたいなケチな初心者(AWS Lambda さわれる)にオススメのフレームワーク。
Jovo です。
#使い方
チュートリアルに従います。
[Tutorial] Build a Google Action in Node.js with Jovo
Dialogflow の設定のところから解説してくれるので Dialogflow 初心者にもやさしい。
コードは、”Configuration”と”Logic”に分かれていてわかりやすく、Logic の分岐も Dialogflow で設定した Intent Name を指定できるので、Intent で Action の設定をし忘れても大丈夫。
チュートリアルもわかりやすいと思います。
AWS Lambda にアップロードするのに書いた index.js のコードは以下のような感じ。
'use strict';
// =================================================================================
// App Configuration
// =================================================================================
const app = require('jovo-framework').Jovo;
exports.handler = function (event, context, callback) {
app.handleRequest(event, callback, handlers);
app.execute();
};
// =================================================================================
// App Logic
// =================================================================================
var ansWd = '';
const handlers = {
'LAUNCH': function () {
app.toIntent('Default Welcome Intent');
},
'Default Welcome Intent': function () {
app.ask('お尋ねください。');
},
'ResponseIntent': function () {
var https = require('https');
let inputs = app.getInputs();
let inputSt = inputs.QuesObj;
var urlStr = '';
var uriStr = '{GetAPI}?quesobj=';
urlStr = uriStr + inputSt;
console.log(urlStr);
var urlStrEnc = encodeURI(urlStr);
https.get(urlStrEnc, function (res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function (res) {
console.log(body);
res = JSON.parse(body);
if (Object.prototype.toString.call(res.ResultSet.Point) === '[object Array]') {
ansWd = res.ResultSet.Point[0].Answer.word;
} else {
ansWd = res.ResultSet.Point.Answer.word;
}
app.tell(ansWd);
});
}).on('error', function (e) {
console.log(e.message);
app.tell('エラーが発生しました。ネットワークを確認、もしくは管理者にお問い合わせください');
});
},
};
何をしたかったのか詳細はぼかしています。(ぼかすように作り変えてますので動かなかったらごめんなさい。)
外部サービスの API を使ってデータ取得して”app.tell”で返すということを行っています。
Actions SDK っぽい関数が使えるのでかなりイメージしやすいと思います。
#小言
いやなんで Dialogflow と AWS Lambda 間の JSON うまくやりとりできねーんだろ。。。
JSON の parse とかもっと勉強します。