第1回では、音声による権限付与を使い、Timer APIを呼び出してAlexaスキルでタイマーをセットする方法をご紹介しました。第2回では、読み取り、一時停止、再開、削除などのTimer APIで行う操作をご紹介します。
注: このチュートリアルのサンプルコードはすべて、Node.js ASK SDKを使って作成しています。
読み取りの操作を実行するには、スキルで権限を有効にする必要があります。スキルがTimer APIを使ってタイマーを作成するたびに、一意の「ID」がスキルへの応答に返されます。この「ID」は、Alexaデバイスでセットされた特定のタイマーを識別するのに使用します。
以後、この「ID」は読み取り、削除、一時停止、再開のすべての操作に使います。
以下は、読み取りのTimer APIを呼び出すサンプルリクエストです。
GET /v1/alerts/timers/{id}
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
このAPI呼び出しは次に応答を返します。応答には、タイマーのid、status、duration、triggerTime、createdTime、updatedTimeが含まれます。
応答の例
{
"id": "a3aac326-c504-458b-8520-15fd048f086a",
"status": "ON",
"duration": "PT10M",
"triggerTime": "2021-08-13T10:25:30Z",
"createdTime": "2021-08-13T10:15:30Z",
"updatedTime": "2021-08-13T10:15:30Z"
}
作成されたタイマーが以前に一時停止されていた場合、「remainingTimeWhenPaused」プロパティが応答に追加されます。以下は、残り時間が3分3秒のタイマーの例です。
{
"id": "a3aac326-c504-458b-8520-15fd048f086a",
"status": "PAUSED",
"duration": "PT5M",
"timerLabel": "ピザ",
"createdTime": "2019-12-03T10:15:30Z",
"updatedTime": "2019-12-03T10:12:03Z",
"remainingTimeWhenPaused": "PT3M3S"
}
指定したユーザーのタイマーを取得します。スキル内で作成されたタイマーはAlexaアカウントに登録されたすべてのデバイスに表示されます。返される際、設定時間が最短のものから最長のものの順に並べられます。
GET /v1/alerts/timers
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
このAPIは、スキルを通してこのユーザーが作成したすべてのタイマーの詳細を返します。
以下は、あるタイマーがアクティブで別のタイマーが一時停止されている場合の応答例です。
{
"timers": [
{
"id": "a3aac326-c504-458b-8520-15fd048f086a",
"status": "ON",
"duration": "PT10M",
"triggerTime": "2019-12-03T10:25:30Z",
"createdTime": "2019-12-03T10:15:30Z",
"updatedTime": "2019-12-03T10:15:30Z",
},
{
"id": "a3aac326-c504-458b-8520-15fd048f086a",
"status": "PAUSED",
"duration": "PT5M",
"timerLabel": "ピザ",
"createdTime": "2019-12-03T10:15:30Z",
"updatedTime": "2019-12-03T10:12:03Z",
"remainingTimeWhenPaused": "PT3M3S"
}
],
"totalCount": 2,
"nextToken": null
}
読み取り操作の実行をサポートするASK SDKも提供しているため、API呼び出しのコードを一から作成する必要はありません。
async handle(handlerInput) {
const {serviceClientFactory} = handlerInput;
try {
const timerServiceClient = serviceClientFactory.getTimerManagementServiceClient();
// getTimers()で作成されたすべてのタイマーのリストを取得します。
const timersList = await timerServiceClient.getTimers();
console.log('タイマーの読み取り:' + JSON.stringify(timersList));
const totalCount = timersList.totalCount;
if(timerId || totalCount > 0) {
timerId = timerId ? timerId : timersList.timers[0].id;
// getTimer(timerId)は、"timerId"で指定された"id"に従って特定のタイマーの詳細を取得します。
let timerResponse = await timerServiceClient.getTimer(timerId);
console.log('タイマーの読み取り:' + JSON.stringify(timerResponse));
const timerStatus = timerResponse.status;
return handlerInput.responseBuilder
.speak("タイマーの読み取り操作が完了しました")
.getResponse();
} else {
return handlerInput.responseBuilder
.speak("作成されたタイマーはありません")
.getResponse();
}
} catch (error) {
console.log('タイマーの読み取りエラー' + JSON.stringify(error));
// エラーコードが401の場合、音声による権限付与をユーザーに送信してタイマーの権限を付与します。
if(error.statusCode === 401) {
console.log('権限がありません');
// 音声で有効にするリクエストを送信します
// 結果を処理する別のハンドラーが必要です。AskForResponseHandlerを参照してください
return handlerInput.responseBuilder
.addDirective({
type: 'Connections.SendRequest',
'name': 'AskFor',
'payload': {
'@type': 'AskForPermissionsConsentRequest',
'@version': '1',
'permissionScope': TIMERS_PERMISSION
},
token: 'verifier'
}).getResponse();
}
else
return handlerInput.responseBuilder
.speak("タイマーがセットされていません。「タイマーをセットして」と言ってみてください。")
.getResponse();
}
}
このAPIを呼び出すと、現在のデバイスの特定のタイマーを削除できます。「id」は特定のタイマーを識別する一意の識別子です。
DELETE /v1/alerts/timers/{id}
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
このAPIを呼び出すと、ユーザーが作成したすべてのタイマーを削除できます。
DELETE /v1/alerts/timers
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
ここでASK SDKを使って、以下のように削除操作を作成することもできます。
async handle(handlerInput) {
const {serviceClientFactory} = handlerInput;
try {
const timerServiceClient = serviceClientFactory.getTimerManagementServiceClient();
const timersList = await timerServiceClient.getTimers();
console.log('タイマーの読み取り:' + JSON.stringify(timersList));
const totalCount = timersList.totalCount;
if(totalCount === 0) {
return handlerInput.responseBuilder
.speak("作成されたタイマーはありません。")
.getResponse();
}
// キャンセルするタイマーIDがない場合の警告です
await timerServiceClient.deleteTimers();
console.log('タイマーを削除しました');
return handlerInput.responseBuilder
.speak("作成したすべてのタイマーを削除しました")
.getResponse();
} catch (error) {
console.log('タイマーの削除エラー:' + JSON.stringify(error));
if(error.statusCode === 401) {
console.log('権限がありません');
// 音声で有効にするリクエストを送信します
// 結果を処理する別のハンドラーが必要です。AskForResponseHandlerを参照してください
return handlerInput.responseBuilder
.addDirective({
type: 'Connections.SendRequest',
'name': 'AskFor',
'payload': {
'@type': 'AskForPermissionsConsentRequest',
'@version': '1',
'permissionScope': TIMERS_PERMISSION
},
token: 'verifier'
}).getResponse();
}
else
return handlerInput.responseBuilder
.speak("削除操作の実行中に問題が発生しました")
.getResponse();
}
}
セットされていてまだ鳴動していないタイマーのみを一時停止できます。タイマーは停止し、残り時間が保存されます。たとえば、45分後に鳴動するタイマーを一時停止すると、そのタイマーは再開した時点から45分後に鳴動します。
POST /v1/alerts/timers/{id}/pause
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
以下は、ASK SDKを使って特定のタイマーの一時停止操作を行うサンプルコードです。
async handle(handlerInput) {
const {serviceClientFactory} = handlerInput;
try {
const timerServiceClient = serviceClientFactory.getTimerManagementServiceClient();
const timersList = await timerServiceClient.getTimers();
console.log('タイマーの読み取り:' + JSON.stringify(timersList));
const totalCount = timersList.totalCount;
if(totalCount === 0) {
return handlerInput.responseBuilder
.speak("作成されたタイマーはありません。")
.getResponse();
}
// すべてのタイマーを一時停止します
for(const timer of timersList.timers ) {
if(timer.status === 'ON'){
// これにより“timer.id”で指定された特定のタイマーが一時停止します。
await timerServiceClient.pauseTimer(timer.id);
}
};
return handlerInput.responseBuilder
.speak("タイマーが一時停止されました。")
.getResponse();
} catch (error) {
console.log('タイマーの一時停止エラー:' + JSON.stringify(error));
if(error.statusCode === 401) {
console.log('権限がありません');
// 音声で有効にするリクエストを送信します
// 結果を処理する別のハンドラーが必要です。AskForResponseHandlerを参照してください
return handlerInput.responseBuilder
.addDirective({
type: 'Connections.SendRequest',
'name': 'AskFor',
'payload': {
'@type': 'AskForPermissionsConsentRequest',
'@version': '1',
'permissionScope': TIMERS_PERMISSION
},
token: 'verifier'
}).getResponse();
}
else
return handlerInput.responseBuilder
.speak("タイマーの一時停止中に問題が発生しました。")
.getResponse();
}
}
このAPIを使うと、一時停止したタイマーを再開できます。タイマーが再開されると、一時停止または停止されない限り、残り時間の経過後に鳴動します。
POST /v1/alerts/timers/{id}/resume
Host: https://api.fe.amazonalexa.com
Authorization: Bearer <アクセストークン>
Content-Type: application/json
このAPIの呼び出しにリクエスト本文は必要ありません。
以下は、ASK SDKを使って再開操作を行うサンプルコードです。
async handle(handlerInput) {
const {serviceClientFactory} = handlerInput;
try {
const timerServiceClient = serviceClientFactory.getTimerManagementServiceClient();
const timersList = await timerServiceClient.getTimers();
console.log('タイマーの読み取り:' + JSON.stringify(timersList));
const totalCount = timersList.totalCount;
if(totalCount === 0) {
return handlerInput.responseBuilder
.speak("作成されたタイマーはありません。")
.getResponse();
}
// すべてのタイマーを再開します
for(const timer of timersList.timers ) {
if(timer.status === 'PAUSED'){
// これにより一時停止されていたタイマーが再開します。
await timerServiceClient.resumeTimer(timer.id);
}
};
return handlerInput.responseBuilder
.speak("タイマーが正常に再開されました。")
.getResponse();
} catch (error) {
console.log('タイマーの再開エラー:' + JSON.stringify(error));
if(error.statusCode === 401) {
console.log('権限がありません');
// 音声で有効にするリクエストを送信します
// 結果を処理する別のハンドラーが必要です。AskForResponseHandlerを参照してください
return handlerInput.responseBuilder
.addDirective({
type: 'Connections.SendRequest',
'name': 'AskFor',
'payload': {
'@type': 'AskForPermissionsConsentRequest',
'@version': '1',
'permissionScope': TIMERS_PERMISSION
},
token: 'verifier'
}).getResponse();
}
else
return handlerInput.responseBuilder
.speak("タイマーの再開操作中に問題が発生しました。")
.getResponse();
}
}
このブログでは、Timer APIで実行できる操作を紹介しました。また、ASK SDKを活用してこのAPIを呼び出し、ユーザーが便利に使えるタイマースキルを作成する方法も説明しました。このブログの内容についてご不明な点がありましたら、こちらの技術資料をご覧ください。