Alexa スキルで位置情報を取得する


# はじめに

今後、屋外で使用できるAlexaデバイスが増えてくると、Alexaスキルも屋外で使われる機会が増えてくるので、その時に必要となると思われるAlexaスキル向け位置情報サービスについて学んでみることにした。


# Alexaスキル向け位置情報サービス

GPS搭載Alexaデバイスのリアルタイムの位置情報が取得できるサービス。そのため、スマホ版のAlexaアプリなど、位置情報が取得できるデバイスでないと使用できない。
スキル内で軽度、緯度、高度などのデータを取得することができるようになるので、この情報を使用したスキルの開発が可能となる。

使用するにはスキルの権限設定が必要で、`位置情報サービス` をオンにすることでリクエストに位置情報が含まれるようになる。`Alexa Developer Console` または、`skill.json` で設定する。

# スキル作成の前提条件

- プライバシーポリシーへのリンクが設定されている必要がある。
- 子ども向けスキルでは使用できない。
- スキルが位置情報を受け取る権限が無い場合はリクエストする。
- バックグラウンドで他のユーザーと繋げることは禁止。
- 位置情報を必要とするリクエストでは、毎回位置情報を最新化する。

# 位置情報が取得できる条件

|No.|デバイス|スキル|対応|
|:--|:--|:--|:--|
|1|位置情報取得可|権限設定オン|スキルで位置情報が取得できる状態|
|2|位置情報取得可|権限設定オフ|権限を"オン"にするように促す処理を追加|
|3|位置情報取得不可|権限設定オン|※|
|4|位置情報取得不可|権限設定オフ|※|

(※)ここの処理をどうするか。特に処理せずスキルを終了しても問題ない。


# 位置情報サービスの実装方法

### スキル側の設定

アクセス権限の設定が必要。

#### ①Alexa Developer Console で設定する場合

アクセス権限の `位置情報サービス` をチェックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/08668d22-f455-f559-4ade-1a7c2ffa9998.png)

#### ②skill.json で設定する場合

`skill.json` の場合は `alexa::devices:all:geolocation:read` を設定する。

```JSON:skill.json
{
  "manifest": {
    "permissions": [
      {
        "name": "alexa::devices:all:geolocation:read"
      }
    ]
  }
}
```

### Lambda側の実装

#### ①requestEnvelopeから位置情報を取得

位置情報が取得できるデバイスでAlexaスキルを起動すると `requestEnvelope.context.Geolocation` に位置情報が含まれる。
:point_right:たった<font color="OrangeRed"><b>これだけ</b></font>:point_left:で`requestEnvelope`の中に位置情報が含まれるようになる。

```JavaScript:index.js
    var geoObject = requestEnvelope.context.Geolocation;

    if (isGeoSupported) {
      var ACCURACY_THRESHOLD = 100; // 100メートルの精度が必要
      if (geoObject && geoObject.coordinate && geoObject.coordinate.accuracyInMeters < ACCURACY_THRESHOLD ) { 
        console.log(geoObject);  // 精度が100メートル以内であれば、地理座標系オブジェクトを出力
      }
    } else {
        return handlerInput.responseBuilder
            .speak("サポート外のデバイスです。")
            .withShouldEndSession(true)
            .getResponse();
    }
```

`geoObject` の中身は以下のようになっている。

```JSON:requestEnvelope.context.Geolocation
{
    "locationServices": {
        "status": "RUNNING",
        "access": "ENABLED"
    },
    "timestamp": "2020-08-22T07:50:06Z",
    "coordinate": {
        "latitudeInDegrees": 35.xxx203125,
        "longitudeInDegrees": 139.xxx045967397,
        "accuracyInMeters": 10
    },
    "altitude": {
        "altitudeInMeters": 5.xxx636203765869,
        "accuracyInMeters": 10
    },
    "heading": {
        "directionInDegrees": 119.xxx78881835938
    },
    "speed": {
        "speedInMetersPerSecond": 1
    }
}
```
`geoObject.coordinate.latitudeInDegrees`に緯度情報、`geoObject.coordinate.longitudeInDegrees`に経度情報が格納されている。

緯度経度を取得して、緯度経度情報から何かを返却してくれるAPIにリクエストを送ることで、その位置に合った情報を得ることができる。

ちなみに`geoObject.altitude.altitudeInMeters`は高度。

# 申請時に忘れてはいけない事

アクセス権限が設定されていない場合、権限を設定するように促してあげる必要がある。これを実装しておかないと、審査にパスすることはできない。

```JavaScript:AskForPermissionsConsentカード実装例
var isGeolocationSupported = context.System.device.supportedInterfaces.Geolocation;
if ( isGeolocationSupported ) {   //  デバイスが位置情報ベースの機能をサポートするかどうか 
        var geoObject = context.Geolocation;
        if ( ! geoObject || ! geoObject.coordinate ) {
          return responseBuilder
            .speak('●●●スキルは、お客様の位置情報を使用します。位置情報の共有を有効にするには、Alexaアプリに移動し、指示に従って操作してください。')
            .withAskForPermissionsConsentCard(['alexa::devices:all:geolocation:read'])
            .getResponse();
        } else {
          // 位置情報データを使用
        }
}
```

# スキル有効時にアクセス権限を設定

スキルを有効にした際に、アカウントのアクセス権限を聞かれるのでチェックを入れ、`アクセス権を保存`をクリックする。

Hello Worldスキルを作って、スマホ版Alexaアプリからスキルを起動するだけで、簡単に試すことができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/3ff1066e-3ee7-3dfa-8ccf-9b80a8ec5482.png)



# おわりに

権限をオンにすれば位置情報が簡単に取得できるため、Alexaスキル向け位置情報サービスは、実装するためのテクニックはほぼ不要であり、どちらかというと、実装のアイデアにかかっている部分が大きい。
今後、屋外で使用でいるAlexaデバイスが増えてくれば、間違えなく必要な要素になると思う。

余談だが、位置情報サービスはデバッグが大変だった。なのでデバッグする際は、`Google map`で目的の場所の緯度経度を取得して、位置情報をハードコーディングしてテストを実施した。


# 参考
-[Alexaスキル向け位置情報サービス（Amazon公式サイト）](https://developer.amazon.com/ja-JP/docs/alexa/custom-skills/location-services-for-alexa-skills.html)
-[AEDオープンデータプラットフォーム](http://hatsunejournal.jp/w8/AEDOpendata/)
-[ご当地キャラカタログAPI](http://localchara.jp/services/api)