[日本語Alexa] 新機能:スキルからリマインダーの追加ができるようになりました

2018.11.02

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

Alexaでは、リマインダー機能があります。リマインダーの設定は、Alexaアプリや音声から可能です。

リマインドを繰り返し設定する例

毎週月曜日の午前7時に****をリマインドして

ユーザーから話しかけるのではなく、Alexaの方から、何らかのお知らせをする機能としては、「通知」が、まだプレビューで使用できない日本語では、「リマインダー」が唯一の方法かも知れません。

先日まで、リマインドは、APIやスキルから自由に設定する方法が、提供されていませんでした。 しかし、本日、新機能として、すべての言語で利用可能になったとアナウンスされました。


Remind Customers of Important Tasks or Events with the Reminders API

2 パーミッション

スキルからリマインダーを操作するためには、以下の2つのパーミッションが必要です。

(1) アクセス権

Alexa開発者コンソールから、対象スキルのアクセス権でリマインダーをONにする必要があります。

(2) ユーザーの許可

上記のアクセス権を設定されたスキルを「有効」にするためには、権限付与の許可が必要です。

3 スキルの実装

REST APIのセットであるAlexa Reminders APIを使用すると、リマインダーの作成、及び管理が可能になります。

(1) apiAccessToken

Alexa Reminders APIを使用するためには、スキルへのリクエストに含まれる、apiAccessTokenが必要になります。

{
  "context": {
    "System": {
      "apiAccessToken": "AxThk...",
      "apiEndpoint": "https://api.amazonalexa.com",
      "device": {
        "deviceId": "string-identifying-the-device",
        "supportedInterfaces": {}
      },
      "application": {
        "applicationId": "string"
      },
      "user": {}
    }
  }
}

apiAccessTokenは、Alexa SDKを使用する場合、以下の要領で取得できます。

async handle(h: Alexa.HandlerInput) {
  const accessToken = h.requestEnvelope.context.System.apiAccessToken;

取得したapiAccessTokenは、REST APIをコールする際に、ヘッダに追加する必要があります。

Authorization: Bearer AxThk...6fnLok

(2) Endpoint

Alexa Reminders APIのエンドポイントは、以下の5種類です。

機能 エンドポイント
Create POST /v1/alerts/reminders
Get GET /v1/alerts/reminders/{id}
Get all GET /v1/alerts/reminders
Update PUT /v1/alerts/reminders/{id}
Delete DELETE /v1/alerts/reminders/{id}

詳しくは、以下のAPIドキュメントご参照下さい。
https://developer.amazon.com/ja/docs/smapi/alexa-reminders-api-reference.html

4 やってみた

ということで、とりあえず、CreateだけですがAPIをコールしてみました。Alexa SDK V2を確認してみたのですが、2018/11/02現在、まだ、ラッパーのサービスは追加されていませんでしたので、Alexa.DefaultApiClientを使用して、自前で雑に書いてみました。

import * as Alexa from 'ask-sdk';
import { RequestEnvelope, services } from 'ask-sdk-model';

let skill: Alexa.Skill;
exports.handler = async function (event: RequestEnvelope, context: any) {
    console.log(JSON.stringify(event));
    if (!skill) {
        skill = Alexa.SkillBuilders.standard()
            .addRequestHandlers(SampleIntentHandler)
            .create();
    }
    return skill.invoke(event, context);
}

const SampleIntentHandler: Alexa.RequestHandler = {
    canHandle(_h: Alexa.HandlerInput) {
        return true;
    },
    async handle(h: Alexa.HandlerInput) {
        const reminderService = new ReminderService();
        const accessToken = h.requestEnvelope.context.System.apiAccessToken;
        if(accessToken) {
            await reminderService.create(accessToken, '散歩の時間です',10);
        }
        let speak = '10秒後にリマインダーをセットしました。';
        return h.responseBuilder.speak(speak).getResponse();
    }
};

class ReminderService {
    private apiClient : Alexa.DefaultApiClient = new Alexa.DefaultApiClient();
    private reminderApiPath = '/v1/alerts/reminders';
    private apiEndpoint = 'https://api.amazonalexa.com';

    public async create(token : string, message: string, offsetInSeconds: number) : Promise<Boolean> {

        const body = {
            requestTime : (new Date()).toISOString(),
            trigger: {
                type : "SCHEDULED_RELATIVE",
                offsetInSeconds : offsetInSeconds,
            },
            alertInfo: {
                spokenInfo: {
                    content: [{
                        locale: "ja-JP",
                        text: message
                    }]
                }
            },
            pushNotification : {                            
                status : "ENABLED"                          
            }
        }

        const request : services.ApiClientRequest = {
            body : JSON.stringify(body),
            headers : [ {key : 'Authorization', value : `Bearer ${token}`} ,
                     {key: 'Content-Type', value : 'application/json'}],
            method : 'POST',
            url : this.apiEndpoint + this.reminderApiPath,
        };
        const response =  await this.apiClient.invoke(request);
        if(response.statusCode == 201){
            return true;
        }
        return false;
    }
}

そして、使用している様子です。

5 最後に

Alexa Reminders APIは、自分(スキル)で設定したリマインダーの管理のみが可能です。 Alexaアプリや、音声で追加したリマインダーにはアクセスできないので注意が必要です。また、ガイドラインが明示されており、公開時には、これに従う必要があります。
Alexa Reminders--Guidelines for Usage

このAPIも、恐らく直ぐにSDKでラッパーが追加され、もっと簡単に利用できるようになるでしょう。また何か、新しいパラダイムのスキルが、発表されそうな予感がします。