前回は、firebaseで外に出れず悩んだところまで行きました。
JavsScript移植するか、どうするか悩んだ結果、WebHookのREST APIを直接飲んでしまえばいいことに気づき、潮汐情報を取得するAPIに仕立てることにしました。
いまさらPHPなんて使いたくないのですが、手っ取り早いのでそのままスタートしてみることにします。
メニューのFulfillmentからWebhookを有効にします。そして、URLを記載します。このとき、URLはhttpsである必要がありますので注意してください。
こうすると、Intentのページにfulfillmentのセクションが追加されます。
ここで、Use Webhookとするとことで、このIntentに対してWebhookが呼び出されます。
次に、このURLに該当するAPIを書き始めます。おそらく、JSONが飛んできているはずなので、JSONをダンプしてみることにします。
<?PHP $entityBody = file_get_contents('php://input'); ob_start(); var_dump(json_decode($entityBody)); $result =ob_get_contents(); ob_end_clean(); $fp = fopen("/tmp/action-on-google-dump.txt", "a+" ); fputs($fp, $result); fclose( $fp );
フレームワーク?なにそれ? という感じでべた書きです。
シミュレーターでテストしてみます。
シミュレーター上の戻りは同じですが、APIが呼ばれたサーバにはJSONが飛んできていることが確認できました。
その内容を見てみるとわかるのですが、resultのセクションに値があります。
["result"]=> object(stdClass)#15 (10) { ["source"]=> string(5) "agent" ["resolvedQuery"]=> string(27) "明日の名古屋の潮は" ["speech"]=> string(0) "" ["action"]=> string(9) "calc_tide" ["actionIncomplete"]=> bool(false) ["parameters"]=> object(stdClass)#16 (2) { ["date"]=> string(10) "2017-11-10" ["geocity"]=> string(9) "名古屋" }
パラメータに指定した、dateに2017-11-10が、geocityに名古屋がはいっていますね。
「明日の名古屋の潮は」と言ったのにちゃんと日付に変換されているところがいいです。
また、もう一つ注意すべきのはactionです。ここで、Intentに指定したActionの名前が入っています。
これがわかれば、あとは応答を返すだけです。とはいっても、どう返せば・・・と調べたところ、一番シンプルな応答は次のようになるようです。
{ 'speech': 'しゃべってほしいメッセージ', 'displayText': '画面に表示するメッセージ', 'source': '適当な名前' }
というわけで、ちょっと書き換えます。
$entityBody = file_get_contents('php://input'); $json = json_decode($entityBody); $action = $json->result->action; function speak($message) { echo " { 'speech': '$message', 'displayText': '$message', 'source': 'webhook-tide' } "; } if($action == "calc_tide") { $date = $json->result->parameters->date; list($year, $month, $day) = split("-", $date); $portName = $json->result->parameters->geocity; $message = sprintf("%sの%sの情報です。", $date, $portName); speak($message); }
日付と港の名前を取得して、返すようにしています。
いいですね! うまくいっています。
あとは、これをちゃんとした情報に変えてやればOKです。
if($action == "calc_tide") { $date = $json->result->parameters->date; list($year, $month, $day) = split("-", $date); $portName = $json->result->parameters->geocity; $message = createTideMessage($year, $month, $day, $portName); speak($message); }
createTideMessageは、独自に持っている、情報をメッセージで取得する関数です。
うまくいきました!
年を言わなくても、ちゃんと見つけてくれます。(年を言っていないのに、来年になっているのがいいですね!)