1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Alexa カスタムタスクの実装と動作確認方法 - Custom Task -

Last updated at Posted at 2020-09-16

はじめに

いつの間にか SMAPIに get-tasksearch-taskなどのタスクを操作するコマンドが追加されていたので使ってみようと思った。現状では、一般開発者がカスタムタスクを作っても、特に何かができるというわけではないので、今回は単純にスキルにタスクを追加してSMAPIで操作してみたというもの。

カスタムタスクでできること。

No. できること 概要
1. Alexa定型アクション 予め指定した値を使ってスキルを起動することができる。
2. Direct Skill Connections 他のスキルと連携する。
3. Quick Links for Alexa スキル起動時に外部から値を渡すことができる。
4. Timer API(LAUNCH_TASK) タイマーが鳴った後にスキルを再開する。

前提

  • ASK CLI v2(ASK CLI v1ではデプロイできない)
  • スキルの公開(カスタムタスクの動作をEchoデバイスで確認する場合)

現在、ASK CLI v1を使用している方は、Alexa ASK CLI を v2 にバージョンアップして、スキルプロジェクトを v2 用にマイグレーション する必要があります。

手順

  1. ask new する。
  2. skill-package/フォルダ配下にtasks/フォルダを手動で作成する。
  3. タスク定義ファイルを手動で作成する。
  4. skill.json にタスク情報を追加する。
  5. Lambda関数にカスタムタスクを判別するコードを追加する。
  6. ask deployする。
  7. カスタムタスクの動作を確認する。
  8. SMAPIコマンドでタスクを確認する。

ask new する

まずスキルを作成する。
任意のフォルダを作成して、ask newする。

ask new

tasksフォルダを作成する

作成したスキルの skill-package/ フォルダ配下に移動し、tasks(※固定)という名称のフォルダを手動で新規作成をする。

スキルプロジェクト
CustomTask:
│  ask-resources.json
│  
├─.ask
│      ask-states.json
│                      
├─lambda
│      index.js
│      package.json
│      util.js
│      
└─skill-package
    │  skill.json
    │  
    ├─assets
    │      ja-JP_largeIcon.png
    │      ja-JP_smallIcon.png
    │      
    ├─interactionModels
    │  └─custom
    │          ja-JP.json
    │          
    └─tasks                   ←‐‐‐  フォルダを作成する
            CountDown.1.json  ←‐‐‐  タスク定義ファイルを作成する

タスク定義ファイルを作成する

tasks/フォルダ配下にタスク定義ファイルを手動で新規作成する。
※タスクの定義ファイルはOpenAPI V3仕様に準拠

制限事項(抜粋)

  • タスク定義ファイルのファイル名は {TaskName}.{TaskVersion}.json の形式となる。
  • タスク名がパスとなる。例)タスク名がCountDownの場合、/CountDown になる。
  • 1タスク定義ファイルにつき1タスクとなる。

詳しくは、公式ドキュメントを参照

タスク定義ファイル

CountDown というタスク名称で、バージョンが 1 の場合、ファイル名は CountDown.1.json となる。 以下のJSONをコピーするだけ。

Amazonマニュアルより転載
{
   "openapi": "3.0.0",
   "info": {
     "title": "Task to perform a count down",
     "version": "1",
     "x-amzn-alexa-access-scope": "vendor-private"
   },
   "tags": [{
     "name": "count down"
   }],
   "paths": {
     "/CountDown": {
       "summary": "Count Down",
       "description": "To start a count down",
       "post": {
         "requestBody": {
           "content": {
             "application/json": {
               "schema": {
                 "$ref": "#/components/schemas/Input"
               }
             }
           }
         },
         "responses": {
           "200": {
             "description": "When the count down finishes successfully",
             "content": {
               "application/json": {
                 "schema": {
                   "$ref": "#/components/schemas/SuccessfulResponse"
                 }
               }
             }
           },
           "400": {
             "description": "When the given parameters fail validations - e.g. lowerLimit cannot be higher than upperLimit"
           },
           "500": {
             "description": "When the count down fails"
           }
         }
       }
     }
   },
   "components": {
     "schemas": {
       "Input": {
         "type": "object",
         "properties": {
           "upperLimit": {
             "type": "number",
             "maximum": 100,
             "minimum": 1
           },
           "lowerLimit": {
             "type": "number",
             "maximum": 100,
             "minimum": 1
           }
         }
       },
       "SuccessfulResponse": {
         "type": "object",
         "properties": {
           "endTime": {
             "type": "string",
             "format": "date-time"
           }
         }
       }
     }
   }
}

skill.json にタスク情報を追加する

タスクを実装するスキルを作成するには、以下のようにskill.jsonにタスク情報を追加する必要がある。

{
  ...
  "apis": {
    "custom": {
      ...
      "tasks": [{
        "name": "CountDown",
        "version": "1"
      }]
    }
  }
}

Lambda関数にカスタムタスクを判別するコードを追加する

カスタムタスクから起動された場合 handlerInput.requestEnvelope.request.task に値が格納される。
タスク名で判別させて目的の処理を実行させる。タスク起動でない場合、task は undefined となる。

index.js
    task = handlerInput.requestEnvelope.request.task;
    if (task.name === 'amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1.CountDown') {
      let campaignsCode = task.input.CampaignsCode;
      console.log(`LaunhcRequestHandler campaignsCode: ${campaignsCode}`);
    }

ask deploy する

ASK CLI v2で、ask deployコマンドを実行する。

ask deploy 

カスタムタスクの動作を確認する

カスタムタスクはスキルを公開していないとEchoデバイスで確認することができない。
そのため、invoke-skill-end-point を使用して動作確認をする。

invoke-skill-end-point
ask smapi invoke-skill-end-point -s amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1 --stage development --skill-request-body file:./input.json --endpoint-region FE

※skill.jsonのregionsにエンドポイントが設定されていないとエラーになる。

skill.json
        "regions": {
          "FE": {
            "endpoint": {
              "uri": "arn:aws:lambda:us-east-1:023972248338:function:ask-custom-SosuDice-default"
            }
          }
        },

input.json のサンプル を参考に input.json を作成してください。自分のスキルを実行したときに CloudWatchログに表示されるRequsetを使っても "message": "Session object of the skill request body does not contain a skill id that matches that of the request path."というメッセージが表示され、実行できなかった。なぜか公式のinput.jsonサンプルだと動作する。なんで?

input.json

{
    "version": "1.0",
    "session": {
        "new": true,
        "sessionId": "amzn1.echo-api.session.aaf7b112-434c-11e7-2563-6bbd1672c748",
        "application": {
            "applicationId": "{YourProviderSkillId}"
        },
        "user": {
            "userId": "amzn1.ask.account.12345ABCDEFGH"
    	}
    },
    "context": {
        "System": {
            "application": {
                "applicationId": "{YourProviderSkillId}"
            },
            "user": {
                "userId": "amzn1.ask.account.12345ABCDEFGH"
            }
        }
    },
    "request": {
        "type": "LaunchRequest",
        "requestId": "amzn1.echo-api.request.da528275-5aa6-4f69-8038-06efc94d1923",
        "timestamp": "2020-01-29T23:11:48Z",
        "locale": "ja-JP",
    "task": {
        "name": "{YourProviderSkillId}.{taskName}",
        "version": "1",
        "input": {
            "upperLimit": 10,
            "lowerLimit": 2
        }
    }
}

結果が戻ってくればOK。

RESPONSE
      "invocationResponse": {
        "body": {
          "version": "1.0",
          "response": {
            "outputSpeech": {
              "type": "SSML",
              "ssml": "<speak>タスク起動です。</speak>"
            }
          },
          "userAgent": "ask-node/2.10.1 Node/v12.18.4",
          "sessionAttributes": {}
        }
      },

SMAPIコマンドでタスクを確認する

スキルが公開されていることが前提。
ASK CLI が v2 になったばかりの頃は、SMAPIにタスクを確認するコマンドはなかったので、v2でタスクを作成して、v1で確認するという、わけのわからない状況だったが、やっと改善され get-tasksearch-taskという2つのコマンドが追加された。

(注意)スキルの公開前に、search-task コマンドや get-task コマンドを使っても、そのタスク情報は返却されない。

get-task

指定されたタスク名とバージョンの組合せでタスク定義の詳細を取得する。
--task-nameCountDownだけでは検索できず、以下のようにamzn1....で始まる名前を指定する必要がある。--task-namesearch-taskコマンドを実行することで確認できる。
get-taskコマンドを実行すると、上記で作成したタスクが画面に表示される。

get-task
ask smapi get-task --skill-id amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1 --task-name amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1.CountDown --task-version 1 

search-task

スキルのタスク情報を取得する。キーワードとプロバイダースキルIDで検索できる。キーワードとプロバイダースキルIDの両方を省略すると、そのスキルのすべてのタスクが返されます。

search-task
ask smapi search-task --skill-id amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1
Response
{
  "nextToken": "AAIAAUQUjdUvlTskvOjFe6MRnJzD5jfhxC2aN3cuMXVhZq_WiANmN4f8x4a45EF4Bbp5sRfdOUm3T===",
  "taskSummaryList": [
    :
    :
    {
      "description": "To start a count down",
      "name": "amzn1.ask.skill.f40f1525-e285-481a-xxxx-4a4665be4fb1.CountDown",
      "version": "1"
    },
    :
    :
  ],
  "totalCount": 47
}

おわりに

現在、一般開発者は、カスタムタスクを作成したとしても何もできない状態であるため、はやくSkill Connections などタスクを使える仕組みを一般開発者にも解放して欲しいと思う。

※記事を書いてから3年ぐらい経過した。カスタムタスクでできることが増えてスキル開発の幅も広がってきたと思う。個人的には、タイマー鳴ったあとにもう一度スキルを起動できる仕組みが気に入っている。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?