Alexa ASK CLI v2用のスキルプロジェクトをセットアップする


# はじめに

ASK CLIがv2になったので、スキルプロジェクトをv2用にセットアップした。v1を使っていて、v1用のスキルプロジェクトがある場合は、スキルプロジェクトをマイグレーション方法もあるけど、今回は、手動でv2用のスキルプロジェクトをセットアップしてみた。また、Alexaスキルを作っているけれど、ASK CLIを使っていない場合も、この方法でv2用のプロジェクトが作成できる。

実際に公開しているスキルに対して、この手順でデプロイができて、スキルが正しく動作することは確認済み。

# 前提

- Alexaスキルを作成している
- ASK CLI v2がインストールされている
- インタラクションモデルとLambda関数の整合性がとれている
- エンドポイントはAWS Lambdaを使ってる

# セットアップの流れ

<img width="70%" alt="セットアップ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/fd58cfc3-b4df-a5dd-19c8-0ffc4717ca4e.png">


1. スキルプロジェクトフォルダを作成する
2. Lambda関数をエクスポートする
3. スキルパッケージをエクスポートする
4. スキルプロジェクトを初期化する
5. スキルをデプロイする

# スキルプロジェクトフォルダを作成する

適当に、管理しやすいところにフォルダを作成する。場所はどこでも大丈夫です。
ここでは`skillproject`というフォルダ名で進める。スキル名に近い名前が管理しやすいと思う。

```:スキルプロジェクトフォルダ
c:\
└─skillproject
```


# Lambda関数をエクスポートする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/ea158824-848e-f7db-d6a4-a64b2fb3d591.png)


AWSからLambda関数をエクスポートして展開しておく。git等で管理していたり、ローカルで管理できているのであれば、わざわざ関数をエクスポートしなくても良い。
.zipを展開した時のフォルダ名でも問題はないが、マイグレーション時に生成されるフォルダ名に合わせて`lambda/lambcacustom`に変更してみた。フォルダ名は `ask init` で設定するので任意の名前でよい。

```:スキルプロジェクトフォルダ
c:\
└─skillproject
   └─lambda
      └─lambdacustom
         │  index.js
         │  local-debugger.js
         │  package-lock.json
         │  package.json
         │  util.js
         │  
         └─node_modules
             │      :

```

なので、以下のように `lambda` 配下に置いても大丈夫。

```:スキルプロジェクトフォルダ
c:\
└─skillproject
   └─lambda
      │  index.js
      │  local-debugger.js
      │  package-lock.json
      │  package.json
      │  util.js
      │  
      └─node_modules
          │      :

```


# スキルパッケージをエクスポートする

`skillproject`フォルダに移動して、下記コマンドを実行する。
ステージは`development`か`live`のいずれかを指定する。デフォルトは`development`
今回 試したスキルは `live` のskill-packageをエクスポートした。

`-g` オプションは必ず指定しないと動作しなくなってた。（2022年7月16日更新）

自分でskill-packageフォルダ以下にファイルを配置したり、ディレクトリを作れば、skill-packageもわざわざエクスポートしなくても良い。ただし、skill-package配下のフォルダ構成は以下のようにする必要がある。任意の名前ではダメ。

```
ask smapi export-package -s <スキルID> -g <ステージ>
```

フォルダ名は`skill-package`で固定となっているみたいで、そのフォルダの配下にスキルの情報が生成される。もともと`skill-package`フォルダが存在している状態で、このコマンドを実行すると、既にフォルダが存在していると言われエラーとなる。

```:スキルプロジェクトフォルダ
c:\
└─skillproject
   ├─lambda
   │  └─lambdacustom
   │     │  index.js
   │     │  local-debugger.js
   │     │  package-lock.json
   │     │  package.json
   │     │  util.js
   │     │  
   │     └─node_modules
   │         │      :
   │                  
   └─skill-package
      │  skill.json
      │  
      ├─assets
      │  └─images
      │          ja-JP_largeIconUri.png
      │          ja-JP_smallIconUri.png
      │          
      └─interactionModels
          └─custom
                 ja-JP.json
```

# スキルプロジェクトを初期化する


```
ask init
```
このコマンドによりスキルのデプロイに使用する`ask-resources.json`と`.ask\ask-states.json`ファイルを作成できる。
最も一般的なアトリビュートが網羅されており、エンドポイントとしてAWS Lambdaを使用して目的に合ったデフォルト値を提案します。とマニュアルには記載されている。

```
PS C:\skillproject> ask init
This utility will walk you through creating an ask-resources.json file to help deploy
your skill. This only covers the most common attributes and will suggest sensible
defaults using AWS Lambda as your endpoint.

This command is supposed to be running at the root of your ask-cli project, with the
Alexa skill package and AWS Lambda code downloaded already.
- Use "ask smapi export-package" to download the skill package.
- Move your Lambda code into this folder depending on how you manage the code. It can
be downloaded from AWS console, or git-cloned if you use git to control version.

This will utilize your 'default' ASK profile. Run with "--profile" to specify a
different profile.

Press ^C at any time to quit.

? Skill Id (leave empty to create one):  amzn1.ask.skill.64f3c973-xxxx-xxxx-xxxx-4403c381e7b9
? Skill package path:  ./skill-package
? Lambda code path (for default region):  ./lambda/lambdacustom/
? Use AWS CloudFormation to deploy Lambda?  No
? Lambda runtime:  nodejs10.x
? Lambda handler:  index.handler
```

- スキルIDを入力する。
- スキルパッケージのパスを入力する。`skill-package` であればデフォルトのままでＯＫ。
- Lambda関数のパスを入力する。ここはフォルダ名を変更しているため、手入力する。
- AWS CloudFormationを使用する場合は`Y`使用しない場合は`N`を入力する。
- Lambda関数のランタイムのバージョンを選択する。
- Lambda関数のハンドラーを選択する。

AWS CloudFormationは使ったことがなかったので`N`にした。`Y`にした場合は、CloudFormationで使用する`YAML`(skill-stack.yaml)が生成され、そしてlambda-deployerではなく、cfn-deployerとなる。


ランタイムバージョン、ハンドラはLambda関数の設定画面で確認できるので同じものを設定する。
![Lambda関数のランタイムバージョン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/1df4fd59-62cb-aeab-e501-ad473b7c654e.png)

全ての項目に答えたら、`ENTER`をクリックすると以下が表示される。

```
Writing to C:\skillproject\ask-resources.json:
{
  "askcliResourcesVersion": "2020-03-31",
  "profiles": {
    "default": {
      "skillMetadata": {
        "src": "./skill-package"
      },
      "code": {
        "default": {
          "src": "./lambda/lambdacustom/"
        }
      },
      "skillInfrastructure": {
        "type": "@ask-cli/lambda-deployer",
        "userConfig": {
          "runtime": "nodejs10.x",
          "handler": "index.handler"
        }
      }
    }
  }
}

Writing to C:\skillproject\.ask\ask-states.json:
{
  "askcliStatesVersion": "2020-03-31",
  "profiles": {
    "default": {
      "skillId": "amzn1.ask.skill.64f3c973-xxxx-xxxx-xxxx-4403c381e7b9",
      "skillInfrastructure": {
        "@ask-cli/lambda-deployer": {
          "deployState": {}
        }
      }
    }
  }
}

? Does this look correct? 
```

`ask-resources.json`と`.ask\ask-states.json`ファイルを生成するが内容が正しいかと聞かれる。正しいかわからないけど、Lambda、スキルパッケージのパスとスキルIDが正しいことぐらいは確認して、`Y`を入力して`ENTER`を押す。

```
? Does this look correct?  Yes
Project bootstrap from deployer "@ask-cli/lambda-deployer" succeeded.

Success! Run "ask deploy" to deploy your skill.
```

`ask-resources.json`と`.ask\ask-states.json`ファイルが生成され、v2 用のスキルプロジェクトが完成。

```
c:\
└─skillproject
   │  ask-resources.json  
   │  
   ├─.ask
   │      ask-states.json
   │  
   ├─infrastructure
   │  └─lambda-deployer    
   │  
   ├─lambda
   │  └─lambdacustom
   │     │  index.js
   │     │  local-debugger.js
   │     │  package-lock.json
   │     │  package.json
   │     │  util.js
   │     │  
   │     └─node_modules
   │         │      :
   │                  
   └─skill-package
      │  skill.json
      │  
      ├─assets
      │  └─images
      │          ja-JP_largeIconUri.png
      │          ja-JP_smallIconUri.png
      │          
      └─interactionModels
          └─custom
                 ja-JP.json
```

# スキルをデプロイする

メッセージ的には、`Run "ask deploy" `と表示されるので、このままデプロイしたいところだけど、このままやると、新規でLambda関数が作成されてしまう。既存のスキルに影響しないという利点はあるが、現在、使用しているスキルのLambda関数を継続して使用したいのであれば`ask-states.json`の`"deployState"`にiamRoleのarnとlambdaのarnを追記する。

```
          "deployState": {
            "default": {
              "iamRole": "arn:aws:iam::032972243388:role/ask-lambda-xxxxxxx",
              "lambda": {
                "arn": "arn:aws:lambda:us-east-1:032972243388:function:ask-custom-xxxxxxx-default",
                "lastModified": "",
                "revisionId": ""
              }
            }
          }
```

で、デプロイすると、今までのLambda関数が上書きされるようになる。
テキストエディタなどでファイルを編集する場合、ファイルを開きっぱなしでロックされた状態のままだとデプロイできないので、編集したらファイルは閉じておく。

```
ask deploy
```

# スキルをテストする

スキルが動作するかテストする。

# おわりに

けっこう簡単にできると思う。
Lambda関数をデプロイする際に、AWS CloudFormationを使用する場合は、マイグレーションするよりも、セットアップしちゃった方が良いかもしれないと思った。CloudFormationの.yamlを生成してくれるから。

# 参考

- [ASK CLIコマンドリファレンス（v2）（※Amazon公式サイト）](https://developer.amazon.com/ja-JP/docs/alexa/smapi/ask-cli-command-reference.html)

# 関連

- [Alexa ASK CLI を v2 にして、スキルプロジェクトを v2 用にマイグレーション](https://qiita.com/takara1121/items/a90a5576807d73d8e752)
- [Alexa ASK CLI を v2 へバージョンアップしてスキルを新規作成](https://qiita.com/takara1121/items/54d34036d108fea04982)