Alexa デバイスの所在地情報の取得

2019年9月17日

はじめに

Alexa デバイスの所在地情報の取得方法について。

準備

  • デバイスの所在地情報を設定しておく。
  • Alexa 開発者コンソールでスキルを選び、左下の [アクセス権限] の [デバイスのアドレス] を有効にし、[住所] を選択する。
  • Alexa アプリの [スキル・ゲーム] の [有効なスキル] でスキルを選び、[設定] - [アクセス権を管理] で [住所] について許可する。

スキルの実行時、入力の JSON の context.System.user の以下に permissions.consentToken という項目が出てくれば OK。

デバイスの所在地情報の取得

Alexa.SkillBuilders.custom() の後に ".withApiClient(new Alexa.DefaultApiClient())" を入れる。

exports.handler = Alexa.SkillBuilders.custom()
    .addRequestHandlers(
        LaunchRequestHandler,
        ...
    .withApiClient(new Alexa.DefaultApiClient()) // これを入れる
    .lambda();

所在地は以下のコードで取得できる。

const { requestEnvelope, serviceClientFactory } = handlerInput;
const { deviceId } = requestEnvelope.context.System.device;
const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
const address = await deviceAddressServiceClient.getFullAddress(deviceId);

address には以下のものが含まれる。

  • addressLine1
  • addressLine2
  • addressLine3
  • city
  • stateOrRegion
  • districtOrCounty
  • countryCode
  • postalCode

所在地取得が許可されているかどうかは、 requestEnvelope.context.System.user.permissions および requestEnvelope.context.System.user.permissions.consentToken が存在するかどうかで判断できる。

住所の設定

Alexa デバイスの住所の設定は、Alexa アプリで行う。住所は、すべての項目に何かしら入れないと設定が保存されない (不要な項目でも "null" とか何か適当なものを入れる)。また、addressLine3 は Web アプリでないと設定できないようである。

参考

住所の取得が可能か調べる

実用的には、住所の取得がそもそも可能か、調べる必要がある。

// 住所の取得が可能か
function getAddressPermision(handlerInput)
{
    const requestEnvelope = handlerInput.requestEnvelope;
    const permissions = requestEnvelope.context.System.user.permissions;
    return permissions && permissions.consentToken;
}

// 住所を取得する
function getAddress(handlerInput) {
    const { requestEnvelope, serviceClientFactory } = handlerInput;
    const { deviceId } = requestEnvelope.context.System.device;
    const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
    return deviceAddressServiceClient.getFullAddress(deviceId);
}

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    async handle(handlerInput) {
        if (!getAddressPermision(handlerInput)) {
            let speechText += 'ごめんなさい。';
            speechText += 'デバイスの住所を取得できませんでした。';
            speechText += 'アクセス権の設定を見直してください。';

          return handlerInput.responseBuilder
            .speak(speechText)
            .getResponse();
        }

        const address = await getAddress(handlerInput);

        if (address === undefined) {
            let speechText += 'ごめんなさい。';
            speechText += 'デバイスの住所を取得できませんでした。';

            return handlerInput.responseBuilder
                .speak(speechText)
                .getResponse();
        }
        ...