コマンドラインでAlexaスキルを開発（デプロイ）する方法

# 1. はじめに
2018年4月に、AlexaSDKのV2（ask-adk）がリリースされたことにより、これまでGUIオンリーで簡単に開発できていたV1（alexa-adk）とことなり、V2ではSDKのサイズが大きく、AWS Lambdaへの、ZIP圧縮＆ZIPアップロードが大変になってきました。
今回は、自分自身への備忘録をかねて、コマンドラインでAlexaスキルを開発する方法をお伝えしたいと思います。

## 1-1. この記事を読んでできること
- **コマンドラインを用いて、AlexaスキルをAmazon Developer Portalへデプロイできるようになる。**
- **コマンドラインを用いて、AlexaモデルをAmazon Developer Portalへデプロイできるようになる。**
- **コマンドラインを用いて、Lambda関数をAWS Lambdaへデプロイできるようになる。**

## 1-2. 前提条件
今回は、以下の開発環境を前提条件としています、ご自身の開発環境に合わせて、記事を読みかえて頂ければと思います。
- Windows10上のUbuntuコマンドラインの利用を想定。（参考：[Windows 10でLinuxプログラムを利用可能にするWSL（Windows Subsystem for Linux）をインストールする](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)
- ask cli コマンドの利用を想定。（参考：[Alexa Skills Kitコマンドラインインターフェース（ASK CLI）クイックスタートガイド](https://developer.amazon.com/ja/docs/smapi/quick-start-alexa-skills-kit-command-line-interface.html)）
- slsコマンド（serverlessコマンド）の利用を想定。（参考：[今から始めるServerless Frameworkで簡単Lambda開発環境の構築](https://dev.classmethod.jp/cloud/aws/easy-deploy-of-lambda-with-serverless-framework/)）
- Windows10上の作業フォルダは、『c:\Alexa』となります。Ubuntuコマンドでは、『/mnt/c/Alexa』が該当します。

## 1-3. 参考サイト
今回のセットアップ手順の参考サイトは、[@t2h5](https://qiita.com/t2h5)さんの[ask-cli, serverlessを併用したAlexaカスタムスキル開発](https://qiita.com/t2h5/items/a24f2365e12729a9f8ed)となります。合わせてご参考ください。
（今回の記事は私なりのアレンジ、解釈や開発環境もありますので、[@t2h5さんの記事](https://qiita.com/t2h5/items/a24f2365e12729a9f8ed)と、私の記事を読み比べてもらって、両方『いいね』してもらえるとうれしいです！）

# 2. Alexaサンプルスキルの入手
Alexaサンプルスキル（skill-sample-nodejs-fact）を、ask newコマンドで入手します。ポイントは、--templateオプションで入手したいテンプレート名を指定することです。
指定可能なテンプレート名は、[templates.json](https://s3.amazonaws.com/ask-cli/templates.json)からご確認いただけます。また、[GitHub](https://github.com/alexa)からもご確認いただけます。

```shell:Ubuntuコマンドライン
#作業ディレクトリ（任意）に移動
$ cd /mnt/c/Alexa

#サンプルスキルの入手
$ ask new --skill-name Fact --template Fact
```

# 3. skill.jsonの修正（日本語化）
さきほどのコマンド（ask new）により、factディレクトリが自動作成され、factディレクトリ内にskill.jsonファイルが生成されていますので、このskill.jsonファイルを英語から、日本語へ、手修正します。ポイントは、"en-US" のところを"ja-JP"に修正することと、"examplePhrases"を「アレクサ、宇宙豆知識を開いて」などの、日本語のスキル呼び出しサンプルフレーズに書き替えることです。
定義の詳しい内容は、[スキルマニュフェスト](https://developer.amazon.com/ja/docs/smapi/skill-manifest.html#custom-with-events)をご確認ください。

```shell:skill.json
{
  "manifest": {
    "publishingInformation": {
      "locales": {
        "ja-JP": {
          "summary": "短い説明文を書くところ",
          "examplePhrases": [
            "宇宙豆知識を開いて"
          ],
          "name": "宇宙豆知識",
          "description": "長い説明文を書くところ"
        }
      },
      "isAvailableWorldwide": true,
      "testingInstructions": "Amazonテスター向けのお願いごとを書くところ",
      "category": "EDUCATION_AND_REFERENCE",
      "distributionCountries": []
    },
    "apis": {
      "custom": {
        "endpoint": {
          "sourceDir": "lambda/custom"
        }
      }
    },
    "manifestVersion": "1.0"
  }
}
```

# 4. スキルのデプロイ
Amazon Developer Portalへのデプロイを、スキル部分と、モデル部分に分けてデプロイします。ここでは、スキル部分のデプロイをおこないます。スキル部分のデプロイが成功すると、Amazon Developer Portalに、skill.json設定に従いスキルが作成されます。

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（factディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact

#スキルのデプロイ（skill.jsonと同じディレクトリ内でコマンド実行してください）
$ ask deploy --target skill
```

※ スキルのデプロイ先は、.askフォルダの中のconfigファイルに、skill_idという設定値で設定されています。手順2で ask new コマンドを利用していない方は、既に作成済みのスキルを上書きしてしまわないか、configファイルをご確認ください。

# 5. ja-JP.jsonの作成（日本語化）
modelsディレクトリ内にen-US.jsonファイルがあると思いますので、このファイルをコピーし、ファイル名をリネー『ja-JP.json』し、ja-JP.jsonファイルを日本語化します。
定義の詳しい内容は、[対話モデルのスキーマ（2018/05/20時点だと少し内容が古いV1ですね。）](https://developer.amazon.com/ja/docs/smapi/interaction-model-schema.html)をご確認ください。

```shell:ja-JP.json
{
  "interactionModel": {
    "languageModel": {
      "invocationName": "宇宙豆知識",
      "types": [],
      "intents": [{
          "name": "AMAZON.CancelIntent",
          "samples": []
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": []
        },
        {
          "name": "GetNewFactIntent",
          "slots": [

          ],
          "samples": [
            "豆知識",
            "豆知識を教えて",
            "他の豆知識",
            "雑学",
            "雑学を教えて",
            "他の雑学",
            "知識",
            "何か",
            "何か教えて"
          ]
        }
      ]
    }
  }
}
```

# 6. モデルのデプロイ
Amazon Developer Portalへのデプロイを、スキル部分と、モデル部分に分けてデプロイします。ここでは、モデル部分のデプロイをおこないます。モデル部分のデプロイが成功すると、Amazon Developer Portalに、skill.json設定に従いスキルが反映されます。
AlexaスキルのアプリケーションIDも生成されるはずですので、メモしておきましょう。（AWS Lambda側にて、アプリケーションIDを利用することとなります。）

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（factディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact

#スキルのデプロイ（skill.jsonと同じディレクトリ内でコマンド実行してください）
$ ask deploy --target model
```

# 7. index.jsファイルの日本語化
あとからでも大丈夫ですが、余力があれば、ここでlambda/customディレクトリ内のindex.jsファイルを日本語化しておきましょう。日本語化しなかった場合は、Alexaが、かたことの日本語で英語を話し始めることになるかと思います。

# 8. serverless.ymlファイルの作成
次は、AWS Lambdaにデプロイをするための、lambda/customディレクトリ内にserverless.ymlを新規作成します。
ここで、ask cliコマンドを利用しない理由は、2018年5月20日現在では、東京リージョン（ap-northeast-1）へのデプロイがaskコマンドで出来ないことが理由となります。このため、serverlessコマンド（slsコマンド）を利用し、東京リージョンにデプロイするための設定をおこないます。
先ほどメモしておいた、アプリケーションIDは、『amzn1.ask.skill.xx-xx-xx-xx』の部分に張り付けておいてください。
（余談ですが、.ymlファイルは、通称『ヤムルファイル』と呼ばれています。）

```shell:serverless.yml
service: Fact

provider:
  name: aws
  region: ap-northeast-1

functions:
  skillHandler:
    name: Fact
    description: 宇宙豆知識
    runtime: nodejs6.10
    handler: index.handler
    memorySize: 128
    timeout: 8

    events: # The Events that trigger this Function
        - alexaSkill:
            appId: amzn1.ask.skill.xx-xx-xx-xx
            enabled: true

```

# 9. Lambdaのデプロイ
AWS Lambdaへデプロイします。
- デプロイが成功すると、ARNが確定しますので、メモしておきましょう。
- このARNは、Amazon Developer Portal側のスキルのエンドポイントに、ARNを設定してください。
- その他の注意点としては、既存のロールに『新しい専用ロール』が自動さ作成されます。（S3アクセス、DynamoDBアクセスができないぞ！という場合は、ロールを確認してください。）

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（lambda/customディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact/lambda/custom

#Lambdaのデプロイ（serverless.ymlと同じディレクトリ内でコマンド実行してください）
$ sls deploy
```

# 10. この後の開発
これで、コマンドラインでAlexaスキルを作成することができました。
あとは、ローカル上のindex.jsを必要に応じて修正し、再度、デプロイコマンドを実行すればOKです。GUI開発でおこなっていた、ZIP圧縮＆ZIPファイルのアップロード作業をおこなわなくても、デプロイ作業が完了します。とっても開発作業がはかどります。

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（lambda/customディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact/lambda/custom

#Lambdaの再デプロイ（serverless.ymlと同じディレクトリ内でコマンド実行してください）
$ sls deploy
```

#11. さいごに
みなさん、コマンドラインでAlexaスキルを開発する方法はいかがでしたでしょうか？AWS LambdaへのZIPアップロード作業の時間を短縮できるかと思いますので、ぜひ、参考にしてください。
今後も、スマートスピーカ関連の記事を、アップしていきますので、お楽しみに。

2018/05/20 TAKAHIRO NISHIZONO

# 12. おまけ（既存スキルのダウンロード）

```shell:Ubuntuコマンドライン
#作業ディレクトリ（任意）に移動
$ cd /mnt/c/Alexa/fact

#既存スキルのダウンロード
$ ask api get-skill -s amzn1.ask.skill.xxxxxx-xxxx-xxxx-xxxxx-xxxxxx > skill.json
```

# 13. おまけ（既存モデルのダウンロード）

```shell:Ubuntuコマンドライン
#作業ディレクトリ（任意）に移動
$ cd /mnt/c/Alexa/fact/models

#既存モデルのダウンロード
$ ask api get-model --skill-id amzn1.ask.skill.xxxxxx-xxxx-xxxx-xxxxx-xxxxxx --locale ja-JP > ja-JP.json
```

# 14. おまけ（既存Lambdaのダウンロード）

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（lambda/customディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact/lambda/custom

#既存Lambdaのダウンロード
$ ask lambda download --function arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:functionName
```

# 15. おまけ（既存スキルの一括クローン）
既に作成済みのスキル、モデル、Lambdaの一括クローン（上書きダウンロード）がおこなえます。
この技を習得できれば、slsコマンド（serverlessコマンド）を利用しなくても、東京リージョンへのLambdaデプロイをおこなえます。
方法としては、一度バージニアリージョンにLambdaを作成後、まったく同じLambdaを東京リージョンにも作成し、Amazon Developer Portalからエンドポイントの接続先を新たに作成した東京リージョンにつなぎかえます。その後、一括クローンをおこなうことで、その後は、slsコマンド不要のaskコマンドオンリーでの操作が可能となります。

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（この配下に新規フォルダが生成される想定）
$ cd /mnt/c/Alexa

#既存スキルのまるまる一括ダウンロード
$ ask clone -s amzn1.ask.skill.xxxxxx-xxxx-xxxx-xxxxx-xxxxxx
```

# 15. おまけ（デプロイいろいろ）

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（factディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact

#スキル全体をデプロイ
$ ask deploy

#対話モデルだけをデプロイ
$ ask deploy -t model

#Lambdaコードだけをデプロイ
$ ask deploy -t lambda
```

# 16. おまけ（差分diffいろいろ）

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（factディレクトリ内に移動してください）
$ cd /mnt/c/Alexa/fact

#スキル全体を差分diff
$ ask diff -t all

#対話モデルだけを差分diff
$ ask diff -t model

#Lambdaコードだけを差分diff
$ ask diff -t lambda
```

# 17. おまけ（インストール済みaskコマンドのアップデート）
ask diffコマンドが動かない！などの時は、askコマンドのバージョンをうたがってみてください。最新バージョンにアップデートすることで解消するかもしれません。

```shell:Ubuntuコマンドライン
#作業ディレクトリに移動（任意ディレクトリで結構です）
$ cd /mnt/c/Alexa

#askコマンドのバージョンを確認
$ ask --version

#askコマンドをアップデート
$ sudo npm update -g ask-cli
```