スキルからAlexaデバイスに設定されたタイムゾーンや単位の情報を取得する

ask-sdkのUpsServiceClientを使うと、Alexaデバイスに設定されたタイムゾーンや温度の単位などをスキル側から取得することができます。
2018.09.04

はじめに

先日リリースされたAlexa Settings APIでは、デバイスに設定されている以下の情報をAlexaのカスタムスキルから取得することができます。

  • 温度の単位
  • 距離の単位
  • タイムゾーン

【Alexa Blogs】Personalize Your Alexa Skill with Customer-Specific Time Zones and Measurements Using the Alexa Settings API

このエントリでは、ask-sdk(v2)のUpsServiceClientを使って、スキルから上記のデバイス情報を取得する方法をご紹介します。

Alexaデバイスの設定

今回スキルから取得する情報は、Alexaデバイスの設定では以下の箇所となります。

ちなみに、Alexaアプリ上での温度と距離の単位の設定は以下です。

項目 オン オフ
温度 摂氏(℃) : CELSIUS 華氏(℉) : FAHRENHEIT
距離 メートル : METRIC インペリアル : IMPERIAL

なお、これらの情報をスキル側から取得する場合は、住所電話番号・メールアドレスの取得とは異なり、以下を設定する必要はありません。

  • スキル側でのアクセス権限の設定
  • Alexaアプリでの、ユーザーによる情報提供の明示的な許可

Lambdaの実装

スキルのバックエンドLambdaの実装は以下となります。

  • Node.js 8.10
  • ask-sdk(v2)をnpmやyarnでインストールしておくこと
const Alexa = require('ask-sdk');

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  async handle(handlerInput) {
    const { requestEnvelope, responseBuilder, serviceClientFactory } = handlerInput;
    const { deviceId } = requestEnvelope.context.System.device;

    try {
      const upsServiceClient = serviceClientFactory.getUpsServiceClient();  // Clientの作成
      const distanceUnits = await upsServiceClient.getSystemDistanceUnits(deviceId); // 距離単位の取得
      const tempUnit = await upsServiceClient.getSystemTemperatureUnit(deviceId); // 温度単位の取得
      const timeZone = await upsServiceClient.getSystemTimeZone(deviceId); // タイムゾーンの取得

      const speechText = '距離は' + distanceUnits + '、温度は' + tempUnit + '、タイムゾーンは' + timeZone;

      return handlerInput.responseBuilder
        .speak(speechText)
        .getResponse();
        
    } catch (error) {
      if (error.name == 'ServiceError') {
        console.log('ERROR StatusCode:' + error.statusCode + ' ' + error.message);
      }
      return responseBuilder
        .speak('デバイスの情報が取得できませんでした。')
        .getResponse();
    }
  },
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler
  )
  .withApiClient(new Alexa.DefaultApiClient())  
  .lambda();

(長くなるため、スキル起動時のLaunchRequestHandler以外のハンドラは省略しています)

ask-sdkを使って情報を取得するには、serviceClientFactorygetUpsServiceClientを呼び出し、以下の各メソッドを利用して情報を取得します。
引数にデバイスIDが必要となるので、こちらもあらかじめ取得しておきます。

const upsServiceClient = serviceClientFactory.getUpsServiceClient();  // Clientの作成
const distanceUnits = await upsServiceClient.getSystemDistanceUnits(deviceId); // 距離単位の取得
const tempUnit = await upsServiceClient.getSystemTemperatureUnit(deviceId); // 温度単位の取得
const timeZone = await upsServiceClient.getSystemTimeZone(deviceId); // タイムゾーンの取得

実機でスキルを実行すると、取得されたデバイスの設定(単位/タイムゾーン)を発話してくれます。
(開発者コンソールのテストシミュレータでは確認できませんので、注意ください)

おわりに

ask-sdkUpsServiceClientを使って、スキルからタイムゾーンなどのデバイス情報を取得する方法をご紹介しました。
日本だけでなく、様々なリージョンをターゲットとしたスキルでうまく有効活用できそうですね。

それでは。

参考リンク

[日本語Alexa] Alexa-SDK Ver2(その6) 所在地情報
[日本語 #Alexa ] スキルからユーザーの名前やメールアドレス、携帯電話番号が取得できるようになりました
[ASK SDK for Node.js]Calling Alexa Service APIs