AlexaサービスAPIの呼び出し


AlexaサービスAPIの呼び出し

Alexa Skills Kit(ASK)には、スキルエクスペリエンスをパーソナライズできる複数のサービスAPIが用意されています。SDKには、スキルのロジックからAlexa APIを簡単に呼び出すことができるサービスクライアントが含まれています。

ServiceClientFactory

ServiceClientFactoryは、HandlerInputコンテナオブジェクトからハンドラーで使用できます。個別のサービスクライアントの作成とApiAccessTokenおよびApiEndpointの設定を行います。

利用可能なメソッド

getDeviceAddressServiceClient() : deviceAddress.DeviceAddressServiceClient;
getDirectiveServiceClient() : directive.DirectiveServiceClient;
getEndpointEnumerationServiceClient() : endpointEnumeration.EndpointEnumerationServiceClient;
getListManagementServiceClient() : listManagement.ListManagementServiceClient;
getMonetizationServiceClient() : monetization.MonetizationServiceClient;
getReminderManagementServiceClient(): reminderManagement.ReminderManagementServiceClient;
getUpsServiceClient() : ups.UpsServiceClient;

ApiClient

ApiClientは、Alexaサービスに対してAPIコールを行うときにServiceClientFactoryによって使用されます。SDKを使用して、次のインターフェースに準拠する任意のカスタマイズ済みApiClientを登録できます。

インターフェース

interface ApiClient {
  invoke(request: ApiClientRequest): Promise<ApiClientResponse>;
}

interface ApiClientMessage {
  headers: Array<{key: string; value: string;}>;
  body?: string;
}

interface ApiClientRequest extends ApiClientMessage {
  url: string;
  method: string;
}

interface ApiClientResponse extends ApiClientMessage {
  statusCode: number;
}

DefaultApiClient

ask-sdk-coreパッケージは、DefaultApiClientを提供します。これは、Node.jsのネイティブhttpsクライアントを使用したApiClientの実装です。

コンストラクターの詳細

new DefaultApiClient() => object

DefaultApiClientオブジェクトを構築します。ServiceClientDefaultApiClientを使用して、個別のAlexaサービスにAPI呼び出しを行います。

StandardSkillBuilderはデフォルトでApiClientを登録します。開発者がApiClientをCustomSkillBuilderに登録することもできます。

ApiClientをCustomSkillBuilderに登録する

withApiClient関数を使って、ApiClientをCustomSkillBuilderに登録します。

const skillBuilder = Alexa.SkillBuilders.custom();
skillBuilder.withApiClient(new DefaultApiClient());

DeviceAddressServiceClient

DeviceAddressServiceClientは、デバイスアドレスAPIに対してユーザーのAlexaデバイスに関連付けられた所在地データを照会するために使用できます。この所在地データを使用して、スキルの主要機能を提供したり、ユーザーエクスペリエンスを向上させることができます。たとえば、スキルはこの所在地情報を使って、近くの店舗の所在地一覧を提供したり、おすすめのレストランを紹介したりすることができます。

型定義

class DeviceAddressServiceClient {
  getCountryAndPostalCode(deviceId: string): Promise<services.deviceAddress.ShortAddress>;
  getFullAddress(deviceId: string): Promise<services.deviceAddress.Address>;
};

interface ShortAddress {
  countryCode?: string;
  postalCode?: string;
}

interface Address {
  addressLine1?: string;
  addressLine2?: string;
  addressLine3?: string;
  countryCode?: string;
  stateOrRegion?: string;
  city?: string;
  districtOrCounty?: string;
  postalCode?: string;
}

サンプルコード

以下は、DeviceAddressServiceClientのインスタンスを作成し、ユーザーの住所を取得するリクエストハンドラーの例です。

クリップボードにコピーされました。

const GetAddressIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    const consentToken = requestEnvelope.context.System.user.permissions
        && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Amazon Alexaアプリで位置情報の権限を有効にしてください。')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }

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

      console.log('住所を正常に取得しました。ユーザーに応答しています。');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`住所が設定されていないようです。コンパニオンアプリで住所を設定できます。`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `住所は次のとおりです。${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }
      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('すみません。問題が発生したようです。')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};

クリップボードにコピーされました。

import {
  HandlerInput,
  RequestHandler,
} from 'ask-sdk-core';
import {
  Response,
  services,
} from 'ask-sdk-model';
import Address = services.deviceAddress.Address;

const GetAddressIntent : RequestHandler = {
  canHandle(handlerInput : HandlerInput) : boolean {
    const { request } = handlerInput.requestEnvelope;

    return request.type === 'IntentRequest' && request.intent.name === 'GetAddressIntent';
  },
  async handle(handlerInput : HandlerInput) : Promise<Response> {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;

    const consentToken = requestEnvelope.context.System.user.permissions
                         && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Amazon Alexaアプリで位置情報の権限を有効にしてください。')
        .withAskForPermissionsConsentCard(['read::alexa:device:all:address'])
        .getResponse();
    }
    try {
      const { deviceId } = requestEnvelope.context.System.device;
      const deviceAddressServiceClient = serviceClientFactory.getDeviceAddressServiceClient();
      const address : Address = await deviceAddressServiceClient.getFullAddress(deviceId);

      console.log('住所を正常に取得しました。ユーザーに応答しています。');

      let response;
      if (address.addressLine1 === null && address.stateOrRegion === null) {
        response = responseBuilder
          .speak(`住所が設定されていないようです。コンパニオンアプリで住所を設定できます。`)
          .getResponse();
      } else {
        const ADDRESS_MESSAGE = `住所は次のとおりです。${address.addressLine1}, ${address.stateOrRegion}, ${address.postalCode}`;
        response = responseBuilder
          .speak(ADDRESS_MESSAGE)
          .getResponse();
      }

      return response;
    } catch (error) {
      if (error.name !== 'ServiceError') {
        const response = responseBuilder
          .speak('すみません。問題が発生したようです。')
          .getResponse();

        return response;
      }
      throw error;
    }
  },
};

DirectiveServiceClient

DirectiveServiceClientは、プログレッシブ応答APIにディレクティブを送信するために使用できます。プログレッシブ応答を使用すると、スキルがユーザーのリクエストへの完全な応答を準備している間もユーザーの関心を引き続けることができます。

型定義

class DirectiveServiceClient {
  enqueue(sendDirectiveRequest: services.directive.SendDirectiveRequest): Promise<void>;
}

interface SendDirectiveRequest {
  header: services.directive.Header;
  directive: services.directive.Directive;
}

interface Header {
  requestId: string;
}

type Directive = services.directive.SpeakDirective;

interface SpeakDirective {
  type: 'VoicePlayer.Speak';
  speech?: string;
}

サンプルコード

以下は、DirectiveServiceClientのインスタンスを作成してプログレッシブ応答を送信する関数の例です。

クリップボードにコピーされました。

function callDirectiveService(handlerInput, date) {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;
  const directive = {
    header: {
      requestId,
    },
    directive: {
      type: 'VoicePlayer.Speak',
      speech: `$${date}の情報を検索しています。しばらくお待ちください...`,
    },
  };

  return directiveServiceClient.enqueue(directive);
}

クリップボードにコピーされました。

import { HandlerInput } from 'ask-sdk-core';
import { services } from 'ask-sdk-model';
import SendDirectiveRequest = services.directive.SendDirectiveRequest;

function callDirectiveService(handlerInput : HandlerInput, date : string) : Promise<void> {
  const requestEnvelope = handlerInput.requestEnvelope;
  const directiveServiceClient = handlerInput.serviceClientFactory.getDirectiveServiceClient();

  const requestId = requestEnvelope.request.requestId;

  const directive : SendDirectiveRequest = {
      header: {
          requestId,
      },
      directive: {
          type: 'VoicePlayer.Speak',
          speech: `$${date}の情報を検索しています。しばらくお待ちください...`,
      },
  };

  return directiveServiceClient.enqueue(directive);
}

EndpointEnumerationServiceClient

スキルは、EndpointEnumerationServiceClientを使用して、スキルと対話できるユーザーの接続済みエンドポイントを取得できます。

型定義

class EndpointEnumerationServiceClient extends BaseServiceClient {
  getEndpoints(): Promise<services.endpointEnumeration.EndpointEnumerationResponse>; 
}

interface EndpointEnumerationResponse {
  endpoints?: Array<services.endpointEnumeration.EndpointInfo>; 
}

サンプルコード

以下は、接続済みエンドポイントを取得する関数の例です。

クリップボードにコピーされました。

skill = Alexa.SkillBuilders.custom()
    ....
    .withApiClient(new Alexa.DefaultApiClient())

....

function getConnectedEndpointsResponse(handlerInput)
{
  return handlerInput.serviceClientFactory.getEndpointEnumerationServiceClient().getEndpoints();
}

ListManagementServiceClient

ListManagementServiceClientを使用して、Alexaのデフォルトリストやユーザーが保持しているカスタムリストの読み取りや変更を行うためにリスト管理APIにアクセスできます。

型定義

class ListManagementServiceClient {
  getListsMetadata(): Promise<services.listManagement.AlexaListsMetadata>;
  getList(listId: string, status: string): Promise<services.listManagement.AlexaList>;
  getListItem(listId: string, itemId: string): Promise<services.listManagement.AlexaListItem>;
  createList(createListRequest: services.listManagement.CreateListRequest): Promise<services.listManagement.AlexaListMetadata>;
  createListItem(listId: string, createListItemRequest: services.listManagement.CreateListItemRequest): Promise<services.listManagement.AlexaListItem>;
  updateList(listId: string, updateListRequest: services.listManagement.UpdateListRequest): Promise<services.listManagement.AlexaListMetadata>;
  updateListItem(listId: string, itemId: string, updateListItemRequest: services.listManagement.UpdateListItemRequest): Promise<services.listManagement.AlexaListItem>;
  deleteList(listId: string): Promise<void>;
  deleteListItem(listId: string, itemId: string): Promise<void>;
}

MonetizationServiceClient

MonetizationServiceClientは、スキル内課金サービスAPIを呼び出して現在のスキルに関連付けられたスキル内課金の情報や、有料スキルに関する情報を取得します。応答は、商品またはスキルが購入可能か、現在のユーザーが既に購入済みか(あるいはその両方)を表します。スキル内課金の詳細については、スキル内課金とはを参照してください。有料スキルの詳細については、有料スキルの概要を参照してください。

スキル内課金サービス

スキル内商品サービスには以下のメソッドがあります。

getInSkillProducts(acceptLanguage : string, purchasable? : string, entitled? : string, productType? : string, nextToken? : string, maxResults? : number) : Promise<services.monetization.InSkillProductsResponse>
getInSkillProduct(acceptLanguage : string, productId : string) : Promise<services.monetization.InSkillProduct>
getInSkillProductsTransactions(acceptLanguage: string, productId?: string, status?: string, fromLastModifiedTime?: string, toLastModifiedTime?: string, nextToken?: string, maxResults?: number): Promise<services.monetization.InSkillProductTransactionsResponse>;
getVoicePurchaseSetting(): Promise<boolean>; 
  • acceptLanguageは、リクエストのhandlerInput.requestEnvelope.request.localeから取得できます。
  • purchasableには、すべてのスキル内商品を取得する場合はnull、購入可能かどうかで応答を絞り込む場合はPURCHASABLEまたはNOT_PURCHASABLEを指定できます。
  • entitledには、すべてのスキル内商品を取得する場合はnull、応答を買い切り型商品のステータスで絞り込む場合はENTITLEDまたはNOT_ENTITLEDを指定できます。
  • productTypeには、すべてのタイプのスキル内商品を取得する場合はnull、商品タイプで絞り込む場合はENTITLEMENTCONSUMABLE、またはSUBSCRIPTIONを指定できます。
  • nextTokenは、複数ページのクエリに必要です。
  • maxResultsは、スキルでAPI呼び出しごとに取得されるレコードの数を制御します。デフォルトのページサイズは50レコードです。
  • statusは、PENDING_APPROVAL_BY_PARENTAPPROVED_BY_PARENTDENIED_BY_PARENTEXPIRED_NO_ACTION_BY_PARENTERRORのいずれかで、トランザクションステータスで応答を絞り込みます。statusの値がnullの場合は、すべてのトランザクションが取得されます。
  • fromLastModifiedTimeおよびtoLastModifiedTimeはUTC ISO 8601の形式で指定し、最後に変更されたタイムスタンプに基づいてトランザクションを絞り込みます。例:yyyy-MM-ddTHH:mm:ss.SSSZ。値がnullの場合は、すべてのトランザクションが取得されます。

getInSkillProducts

getInSkillProductsメソッドは、現在のスキルに関連付けられているすべてのスキル内商品を取得し、現在のスキルとユーザーについて、各スキル内商品を購入できるかどうかと買い切り型商品のステータスを示します。

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(result) {
      // inSkillProductsの結果を処理するコードがここに入ります
       const totalProducts = result.inSkillProducts.length;
       const purchasableProducts = result.inSkillProducts.filter(record => record.purchasable == 'PURCHASABLE');
       const entitledProducts = result.inSkillProducts.filter(record => record.entitled == 'ENTITLED');

       return handlerInput.responseBuilder
        .speak('合計' + result.inSkillProducts.length + '個の商品が見つかりました。そのうち' + purchasableProducts.length + '個が購入可能で、' + entitledProducts.length + '個が購入済みです。')
        .getResponse();
    });
  },
}

API応答にはスキル内商品レコードの配列が含まれます。

{
  "inSkillProducts":[
    {
      "productId": "amzn1.adg.product....",
      "referenceName": "<開発者が定義した商品参照名>",
      "type": "SUBSCRIPTION",               // またはENTITLEMENT
      "name": "<開発者が定義したロケール固有の商品名>",
      "summary": "<開発者が定義したロケール固有の商品説明>",
      "entitled": "ENTITLED",              // またはNOT_ENTITLED
      "purchasable": "PURCHASABLE",        // またはNOT_PURCHASABLE
      "purchaseMode": "TEST"               // またはLIVE
      "activeEntitlementCount": 1
    }
  ],
  "isTruncated": true,
  "nextToken": "string"
 }

getInSkillProduct

getInSkillProduct APIは指定されたproductIdで識別される単一のスキル内商品または単一の有料スキルの商品レコードを取得します。有料スキルの場合、productIdをスキルIDに設定します。

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    console.log("In LaunchRequest");

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const productId = 'amzn1.adg.product.<GUID>';
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProduct(acceptLanguage, productId).then(function(result) {
       // inSkillProductの結果を処理するコードがここに入ります
    });
  },
}

API応答には単一のスキル内商品レコードまたは有料スキルレコードが含まれます。

{
  "productId": "amzn1.adg.product....",
  "referenceName": "<開発者が定義した商品参照名>",
  "type": "SUBSCRIPTION",               // またはENTITLEMENT
  "name": "<開発者が定義したロケール固有の商品名>",
  "summary": "<開発者が定義したロケール固有の商品説明>",
  "entitled": "ENTITLED",              // またはNOT_ENTITLED
  "purchasable": "PURCHASABLE",        // またはNOT_PURCHASABLE
  "purchaseMode": "TEST"               // またはLIVE
  "activeEntitlementCount": 1
}

詳細については、スキルコードにISPのサポートを追加する有料スキルのインターフェースリファレンスを参照してください。

getInSkillProductsTransactions

getInSkillProductsTransactionsメソッドは、前回の購入リクエストが拒否されたかどうかなど、スキル内商品のトランザクションに関する情報を提供します。トランザクションステータスや日付を指定してトランザクションを照会できます。このAPIは、子ども向けスキルでのトランザクションの最新結果のみを返します。

  const LaunchRequestHandler = {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    handle(handlerInput) {
      console.log("In LaunchRequest");
 
      const locale = handlerInput.requestEnvelope.request.locale;
      const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
 
      return ms.getInSkillProductsTransactions(locale).then(function(response) {
         // response.results(トランザクションリスト)を処理するコードがここに入ります。
         const totalTransaction = response.results.length;
         const pendingTransactions = response.results.filter(record => record.status == 'PENDING_APPROVAL_BY_PARENT');
         const approvedTransactions = response.results.filter(record => record.status == 'APPROVED_BY_PARENT');
         const deniedTransactions = response.results.filter(record => record.status == 'DENIED_BY_PARENT');
         return handlerInput.responseBuilder
          .speak('合計' + totalTransaction + '個のトランザクションが見つかりました。そのうち' + pendingTransactions.length + '個が保留中で、' + approvedTransactions.length + '個が承認済み、' + deniedTransactions.length + '個が拒否されています。');
          .getResponse();
      });
    },
  }

正常な応答には、lastModifiedTimeで並べ替えられたトランザクションのリストが含まれます。最新のトランザクションのインデックスは0です。デフォルトでは、50個まででリストが切り詰められます。

 
  {
      "results": [
          {
              "status": "PENDING_APPROVAL_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-4",
              "createdTime": "2018-11-23T12:23:10.52Z",
              "lastModifiedTime": "2018-11-23T12:23:10.52Z"
          },
          {
              "status": "PENDING_APPROVAL_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-3",
              "createdTime": "2018-11-23T11:21:10.52Z",
              "lastModifiedTime": "2018-11-23T11:21:10.52Z"
          },
          {
              "status": "EXPIRED_NO_ACTION_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-3",
              "createdTime": "2018-11-20T12:23:10.52Z",
              "lastModifiedTime": "2018-11-21T12:23:10.52Z"
          },
          {
              "status": "DENIED_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-2",
              "createdTime": "2018-11-15T11:03:07.52Z",
              "lastModifiedTime": "2018-11-15T11:03:08.52Z"
          },
          {
              "status": "APPROVED_BY_PARENT",
              "productId": "amzn1.adg.product.unique-id-1",
              "createdTime": "2018-11-14T22:21:00.52Z",
              "lastModifiedTime": "2018-11-14T22:22:00.52Z"
          }
      ],
      "metadata": {
          "resultSet": {
              "nextToken": "EXAMPLE123456789ABCDEFGHI"
          }
      }
  }

このAPIの詳細については、Build Premium Experiences for Kid Skills in the US(英語のみ)を参照してください。

getVoicePurchaseSetting

getVoicePurchaseSettingメソッドは、Alexaアプリでアカウント所有者が選択した購入制御設定を取得します。

  const LaunchRequestHandler = {
    canHandle(handlerInput) {
      return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
    },
    handle(handlerInput) {
      console.log("In LaunchRequest");
 
      const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();
 
      return ms.getVoicePurchaseSetting().then(function(response) {
         // 応答(trueまたはfalse)を処理するコードがここに入ります
         return handlerInput.responseBuilder
          .speak('ユーザーの購入設定の値は' + response);
          .getResponse();
      });
    },
  }

APIの応答にはブール値が入ります。アカウント所有者がAlexaアプリで音声ショッピングを有効にしている場合、この値はtrueです。

詳細については、Build Premium Experiences for Kid Skills in the US(英語のみ)を参照してください。

スキル内課金のインターフェース

addDirective()メソッドは、スキル内課金や有料スキルの購入フローおよびキャンセルフローを開始します。Alexaはユーザーとの音声による対話を管理し、課金トランザクションを処理して、ステータス応答をリクエスト元のスキルに返します。このインターフェースは、以下のタスクをサポートします。

  • Upsell
  • Buy
  • Cancel

これらのタスクと推奨されるユースケースの詳細は、スキルコードにISPのサポートを追加する有料スキルの実装手順を参照してください。

Upsell

スキルは、Upsellタスクを呼び出し、スキルが無料のコンテンツを提供している最中や後など、ユーザーが明示的に頼んでいない場合にコンテキストに応じたスキル内商品を提示できます。Upsellタスクには、productIdとアップセルメッセージが必要です。アップセルメッセージを使うことで、開発者は、購入のお勧めを始める前にユーザーにスキル内商品を提示する方法を指定できます。

// スキルフローで、ユーザーから明示的な依頼なしでも
// スキル内製品を提供することになった場合

return handlerInput.responseBuilder
  .addDirective({
    'type': 'Connections.SendRequest',
    'name': 'Upsell',
    'payload': {
      'InSkillProduct': {
          'productId': '<アップセルしたいISPの商品ID>'
      },
      'upsellMessage': '<スキル内商品のアップセル用紹介説明>'
    },
    'token': 'correlationToken'
  })
  .getResponse();

Buy

ユーザーが特定のスキル内商品や有料スキルの購入をリクエストしたときは、Buyタスクを呼び出します。このタスクには、スキル内課金のproductIdが必要です。有料スキルの場合、productIdをスキルIDに設定します。

以下は、スキル内課金のBuyリクエストの例です。

// スキル内商品を購入するユーザーのインテントをキャプチャするカスタムインテント
// (下記のbuyProductIntent)を実装し、次にAlexaに対してBuyリクエストを開始します。
// 例:'アレクサ、<商品名>を買って'

const buyProductIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'buyProductIntent';
  },
  handle(handlerInput) {
    // inSkillProducts APIを呼び出してリクエストしたスキル内商品の商品IDを取得します。
    // 以下のスロット変数productNameはデモ用です。

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productRef);
      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Buy',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
           'token': 'correlationToken'
          })
          .getResponse();
      }
      else {
        return handlerInput.responseBuilder
          .speak('すみません。その商品は購入できません')
          .getResponse();
      }
    });
  }
};

Cancel

ユーザーがスキル内商品の既存の買い切り型アイテム、またはサブスクリプションのキャンセルをリクエストしたときは、Cancelタスクを呼び出します。このタスクには、スキル内課金のproductIdが必要です。有料スキルの場合、productIdをスキルIDに設定します。

以下は、スキル内課金のCancelリクエストの例です。

const cancelIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'cancelProductIntent';
  },
  handle(handlerInput) {
    // inSkillProducts APIを呼び出してリクエストしたスキル内商品の製品IDを取得します。
    // 以下のスロット変数productNameはデモ用です。

    const acceptLanguage = handlerInput.requestEnvelope.request.locale;
    const ms = handlerInput.serviceClientFactory.getMonetizationServiceClient();

    return ms.getInSkillProducts(acceptLanguage).then(function(res) {
      const slots = handlerInput.requestEnvelope.request.intent.slots;
      const productReferenceName = slots['productName'].value;
      const product_record = res.inSkillProducts.filter(record => record.referenceName == productReferenceName);

      if (product_record.length > 0)  {
        return handlerInput.responseBuilder
          .addDirective({
            'type': 'Connections.SendRequest',
            'name': 'Cancel',
            'payload': {
              'InSkillProduct': {
                'productId': product_record[0].productId
              }
            },
            'token': 'correlationToken'
          })
          .getResponse();
      }
      else  {
        return handlerInput.responseBuilder
          .speak('すみません。よくわかりません。');
          .getResponse();
      }
    });
  }
};

UpsServiceClient

UpsServiceClientを使用して、AlexaユーザープロフィールAPIに対してユーザーの連絡先情報を照会したり、Alexaユーザー設定APIに対してユーザーのタイムゾーン設定や長さの単位、および温度の単位を照会できます。

型定義

class UpsServiceClient {
  getProfileEmail(): Promise<string>;
  getProfileGivenName(): Promise<string>;
  getProfileMobileNumber(): Promise<services.ups.PhoneNumber>;
  getProfileName(): Promise<string>;
  getSystemDistanceUnits(deviceId: string): Promise<services.ups.DistanceUnits>;
  getSystemTemperatureUnit(deviceId: string): Promise<services.ups.TemperatureUnit>;
  getSystemTimeZone(deviceId: string): Promise<string>;
}

ReminderManagementServiceClient

ReminderManagementServiceClientを使用して、スキルからリマインダーを作成、管理するためにAlexaリマインダーAPIを照会できます。

型定義

class ReminderManagementServiceClient extends BaseServiceClient {
  deleteReminder(alertToken: string): Promise<void>;
  getReminder(alertToken: string): Promise<services.reminderManagement.GetReminderResponse>;
  updateReminder(alertToken: string, reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
  getReminders(): Promise<services.reminderManagement.GetRemindersResponse>;
  createReminder(reminderRequest: services.reminderManagement.ReminderRequest): Promise<services.reminderManagement.ReminderResponse>;
}

サンプルコード

以下は、ReminderManagementServiceClientのインスタンスを作成し、新しいリマインダーを作成するリクエストハンドラーの例です。

const CreateReminderIntent = {
  canHandle(handlerInput) {
    const { request } = handlerInput.requestEnvelope;
    return request.type === 'IntentRequest' && request.intent.name === 'CreateReminderIntent';
  },
  async handle(handlerInput) {
    const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
    const consentToken = requestEnvelope.context.System.user.permissions
      && requestEnvelope.context.System.user.permissions.consentToken;
    if (!consentToken) {
      return responseBuilder
        .speak('Amazon Alexaアプリでリマインダーの権限を有効にしてください。')
        .withAskForPermissionsConsentCard(['alexa::alerts:reminders:skill:readwrite'])
        .getResponse();
    }

    try {
      const speechText = "はい。 リマインダーを設定しました。";

      const ReminderManagementServiceClient = serviceClientFactory.getReminderManagementServiceClient();
      const reminderPayload = {
        "trigger": {
          "type": "SCHEDULED_RELATIVE",
          "offsetInSeconds": "30",
          "timeZoneId": "America/Los_Angeles"
        },
        "alertInfo": {
          "spokenInfo": {
            "content": [{
              "locale": "ja-JP",
              "text": "犬の散歩"
            }]
          }
        },
        "pushNotification": {
          "status": "ENABLED"
        }
      };

      await ReminderManagementServiceClient.createReminder(reminderPayload);
      return responseBuilder
        .speak(speechText)
        .getResponse();

    } catch (error) {
      console.error(error);
      return responseBuilder
        .speak('すみません。問題が発生したようです。')
        .getResponse();
    }
  }
};

TimerManagementServiceClient

TimerManagementServiceClientを使用して、スキルからタイマーを作成、管理するためにAlexaタイマーAPIを照会できます。ASK SDK for Node.jsでタイマーAPIを使用する方法の詳細は、TimerManagementServiceClient APIのリファレンス(英語のみ)を参照してください。


このページは役に立ちましたか?

最終更新日: 2023 年 05 月 16 日