Geolocation を使うAlexaスキルを作ってみた


2019年4月6日に神戸で行われたAlexa Day2019、その中の「神戸スキルコンテスト」に出撃して、玉砕してきました。この記事では、スキルを作る時に気づいたTipsを書いていきます。

ストア申請してないので、この形で一般公開できるかはわかりません。
もしリリースできたらGeolocation使用国内初になるのかな。。いやまさか。
まだまだ申請できるとこまで作れてないので、もし出せたらまたエントリ書きます。

参考にさせていただいた記事

スキルを手探りでつくってる時に、大変参考にさせていただきました!(^o^) ありがとうございます!

Alexaから位置情報を取得可能になったので試してみた
https://alexa.wp-kyoto.net/archives/1364/

[Alexa] 位置情報サービスを使ってスキルからモバイルデバイスの位置情報を取得する
https://dev.classmethod.jp/voice-assistant/amazon-alexa/get-geo-location-using-location-services/

スキル概要


(Lambda関数のランタイム:Node.js8.0)

  • スマホのAlexaアプリ(注1)でスキルを起動すると、Lambdaにrequestが飛んでくる。
  • このrequestに緯度経度(Geolocation)が入っている。
  • Lambda関数の中から「ぐるなびAPI」を呼び、付近のお店を検索する。
  • ページネーションのために必要な部分をセッションIDと紐づけてDynamoDBに書く。
  • アレクサスキルに結果を返却して、読み上げてもらう。

(注1)
スマホのAlexaアプリというのは、Echo Dotなどの画面なし端末をセットアップする時に必須だったアレです。
iOS:https://itunes.apple.com/jp/app/amazon-alexa/id944011620?mt=8
Android:https://play.google.com/store/apps/details?id=com.amazon.dee.app&hl=ja
Echo Spotなど画面付き端末では、こやつらを使わなくてもAlexaが使えるので、存在を知らない人もいるようですが。。(^^;)

Tips

その1. パーミションや動作環境について

Alexaスキルの「アクセス権限」の設定

Alexa Developer consoleで該当Alexaスキルの「位置情報サービス」を有効にしておくこと。

ユーザーパーミション

該当Alexaスキルを「有効」にするとき、位置情報サービスをOnにしてもらわないと、Geolocationはとれません。

機種判別

Geolocationが取得できるかどうか、試してみたところ、以下のようになりました。

  • Echo dot:取得NG
  • Echo Show:取得NG
  • Echo input:取得NG
  • iOS/AndroidのAlexaアプリ:取得OK

そこで、このスキルの起動時に、機種判別のようなものをする必要があります。
しかし対応機種が明確に公開されてないのと、ユーザーエージェント(?)の取り方がよくわからないので、LaunchRequestHandlerでレスポンスに入ってくるかどうかで判別をしました。

index.js
const Alexa = require('ask-sdk');

//中略

  //LaunchRequestHandlerの中
  if ('Geolocation' in handlerInput.requestEnvelope.context) {
    var speechText = 'Alexaアプリの緯度経度を使い、近くのお店を検索します。和食、洋食、中華、スイーツ、のどれにしますか?';
    var withShouldEndSession = false;
  } else {
    var speechText = 'このスキルは、現在地の位置情報を使うため、スマホのAlexaアプリから起動する必要があります。お使いのデバイスでは対応しておりません。ご了承ください。'
    var withShouldEndSession = true;
  }
  return handlerInput.responseBuilder
    .speak(speechText)
    .reprompt(speechText)
    .withShouldEndSession(withShouldEndSession)
    .getResponse();


その2. Geolocationの取り方について

requestのjsonからとれます

handlerInput.requestEnvelope.context の中に格納されています。

index.js

const Alexa = require('ask-sdk');
//中略

  //それぞれのIntentHandlerの中
  if ('Geolocation' in handlerInput.requestEnvelope.context) {
    //緯度
    var lat = handlerInput.requestEnvelope.context.Geolocation.coordinate.latitudeInDegrees;
    //経度
   var long = handlerInput.requestEnvelope.context.Geolocation.coordinate.longitudeInDegrees;
  }

取得できるGeolocationの中身

現在地の緯度経度、高度、方向、移動スピードが取得できます。
以下はスキルのRequestの抜粋です。
気になる精度ですが、私のiPhone6では充分に自宅の住所を検出しちゃってたのでフェイクにしてます。

    "Geolocation": {
      "timestamp": "2019-05-01T10:07:04Z",
      "coordinate": {
        "latitudeInDegrees": 35.1234567(フェイク。実際は小数点以下14桁),
        "longitudeInDegrees": 139.1234567(フェイク。実際は小数点以下14桁),
        "accuracyInMeters": 10
      },
      "altitude": {
        "altitudeInMeters": 28.1234567(フェイク。実際は小数点以下15桁),
        "accuracyInMeters": 10
      },
      "heading": {
        "directionInDegrees": 172.59243774414062
      },
      "speed": {
        "speedInMetersPerSecond": 1
      }
    }

なおGoogleMapも採用している10進数表記の緯度経度の場合、小数点以下四桁で10m、五桁で1m単位の精度となります。
それなのに、14桁って。。
スマホのOSは、まだこんな精度で位置情報を出せませんので、アマゾンさんの計算の都合で生じちゃったのだと思います。

なおaccuracyInMetersという値が「10」になってるので、いくら小数点以下14桁の緯度経度を出していても、東西南北どっちかに10m以内でずれてるやで、という意味になります。

バッテリー消費量について

ところで、「accuracyInMeters」の「10」という値は、
iOSのdesiredAccuracyを"kCLLocationAccuracyNearestTenMeters"に指定した時の値と同じですね。偶然ではないでしょう。
10mだとすると、iOSの最高精度ではないにしても5段階中2番目ですので精度は高いほうです。

desiredAccuracy:
 kCLLocationAccuracyBest:最高精度
 kCLLocationAccuracyNearestTenMeters:10m
 kCLLocationAccuracyHundredMeters:100m
 kCLLocationAccuracyKilometer:1km
 kCLLocationAccuracyThreeKilometers:3km

iOSの人は、Alexaアプリの位置情報設定をオンにするときは、「アプリを使用中のみ」にして置くのが良いかもしれませんね。。

その3.ぐるなびAPIについて

APIの仕様書はこちら。
無料です。
ぐるなびさん太っ腹(^o^)!

自分は「レストラン検索API」を使いました。
緯度経度を指定して呼び出すと、付近のお店を教えてくれます。
飲食店のカテゴリも指定できるので、和食洋食中華スイーツなどと分けました。

当初は「応援口コミAPI」も使って、口コミの点数を平均をだそうかなとしたのですが、Alexa Dayには間に合わず、あとでぽちぽちいじってたところ、ぐるなびの口コミの点数は別サービスと連携してるらしく、webサイトでは口コミの乗ってるどのお店も、返却データには点数がなく。。見送りました。

なお、アカウント作成の申請には1〜2日かかると思います。
@imajoriri さんが「幹事くん」というLINE Botを作られたという記事を読み、密かに自分も何かに使いてえなーと思って、開発者アカウントを取得してたので、すぐ使えました。よかったよかった。(^o^)

おまけ

去年の年末、Alexaアプリに、「location Routines」という機能が追加されました。
日本版のAlexaアプリにはまだ来てないですが、USでは動画をアップしてる方がいらっしゃいました。
https://www.youtube.com/watch?v=o4hAr6M4exg

自宅とか職場のまわりに円形のナワバリを指定して、Alexaアプリの入ったスマホを持ってそこに入ったり出たりした時に、何かを起こすという機能だそうです。たとえば毎週火曜、「家」に着いたら「ゴミを捨てる」というリマインダーをAmazon Echoに送るとか、毎日「家」に帰るとき、Hueをつけるとか。

このlocationは、iOS/AndroidのGeofenceだと思います。IFTTTでも人気のトリガーですね(私も使ってます(^o^)

desiredAccuracyが10だとすると、バッテリー消費量はまぁまぁ高いでしょうから、
ずっと起動しっぱなしだと、バッテリーが心配かも。。
車のバッテリーチャージャーで給電しながら使う、というUXだったら受け入れられる気がします。echo auto早く来ないかなぁ〜。

以上となります!