CLIベースのAlexaスキル開発で ap-northeast-1 リージョンでスキルを稼働させる手順

## モチベーション

ask-cli 使うと Lambda のデプロイ先が us-east-1 リージョン固定なので ap-northeast-1 リージョンにデプロイしたい。

そのため CLI ベースでスキルを開発する場合、デプロイするコンポーネントによって以下のように `ask` コマンド（ask-cli）と `sls` コマンド（Serverless Framework）を使い分けているが、デプロイの順番などコツがあるので、この記事でその手順を記載する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8219/c43225f2-d8ec-1fca-ee1a-14df28fd7edb.png)


## 環境

* ask-cli 1.5.1
* Serverless Framework 1.32.0

## 手順

### スキルのデプロイ

まず、`ask new` でプロジェクトを作成する。

```terminal
$ ask new
? Please select the runtime Node.js V8
? List of templates you can choose Hello World
? Please type in your skill name:  hello-world
Skill "hello-world" has been created based on the chosen template
```

上記の例だと、`hello-world` というスキル名でディレクトリが作られ、そこにスキルの雛形が作成される。

まず、最初にスキルのみをデプロイする。

```terminal
$ cd hello-world
$ ask deploy -t skill
```

デプロイ成功すると Skill ID が表示されるが、この後の手順で必要になるのでメモっておく（一応`.ask/config`に記載される）

### 対話モデルのデプロイ

続けて対話モデルのみをデプロイ

```
$ ask deploy -t model
```

この時点で、Amazon 開発者コンソール を開くと、`hello-world` というスキルができているのが確認できると思う。



### Lambda Function のデプロイ

続いて、Serverless Framework を使って Lambda Function をデプロイする。

`custom/lambda` ディレクトリに以下のような内容で `serverless.yml` を作成。
`alexaSkill` の箇所はスキルのデプロイ時に表示された Skill ID に置き換えること。

```yaml:lambda/custom/serverless.yml
service: hello-world

provider:
  name: aws
  region: ap-northeast-1
  runtime: nodejs8.10
  memorySize: 128

package:
  include:
    - node_modules/

functions:
  main:
    handler: index.handler
    events:
      - alexaSkill: amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
        enabled: true
```

`sls` コマンドで Lambda Function をデプロイする。

```terminal
$ sls deploy

 :

Service Information
service: hello-world
stage: dev
region: ap-northeast-1
 :
```

結果の出力から `ap-northeast-1` にデプロイされたことを確認

### スキルのエンドポイントに Labmda のエンドポイントを登録

AWSコンソールを開いて、デプロイした Function の ARN を取得

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8219/50536b76-8a30-ac82-bc3f-fba909c70d8e.png)

`skill.json` をエディタで編集し、`manifest.apis.custom.endpoint.uri` の値を Lambda の ARN に書き換える。

```skill.json
{
  "manifest": {
    "publishingInformation": {
      "locales": {
        "en-US": {
          "summary": "Sample Short Description",
          "examplePhrases": [
            "Alexa open hello world",
            "hello",
            "help"
          ],
          "name": "hello-world",
          "description": "Sample Full Description"
        }
      },
      "isAvailableWorldwide": true,
      "testingInstructions": "Sample Testing Instructions.",
      "category": "KNOWLEDGE_AND_TRIVIA",
      "distributionCountries": []
    },
    "apis": {
      "custom": {
        "endpoint": {
          "uri": "arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:hello-world-dev-main"
        }
      }
    },
    "manifestVersion": "1.0"
  }
}
```

スキルにエンドポイントを反映するため、スキルをデプロイ

```
$ ask deploy -t skill
```

念のため、開発者コンソールでスキルのエンドポイントが反映されていることを確認

![image.png](https://qiita-image-store.s3.amazonaws.com/0/8219/3c0005aa-7b69-35be-6e4c-fb5e22a5a6f7.png)

シミュレータで動作確認

```
$ ask simulate -l 'en-US' -t 'hello world'
```

正常なレスポンスJSONが返却されることを確認

これで、スキル開発の作業を CLI ベースで進めることができます。

## さいごに

最後にちょっとだけ自作 npm パッケージを宣伝。
ポッドキャスト対応スキルを最小のコーディングで実装するための npm パッケージを最近リリースしました。

https://www.npmjs.com/package/alexa-podcast-skill-builder

まだ開発中で足りない機能とか多いですが使ってみて感想・要望などいただけると嬉しいです。