kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

ask-cli v2でAlexa-hostedスキルを作ってみる

2020/07/11追記 治ってるみたいです。ask-cli-2.11.1で確認してます。

2020/07/03追記 ask-cli v2でalexa-hostedの場合に、pushしてもskill-packageが更新されない(lambdaは更新される)という方は以下の手順でやってみてください。

$ ask new
$ cd スキルのディレクトリ
$ git add .gitignore
$ git commit -m "add .gitignore"
$ git push
(以降は自由に編集して、git add/commit/pushしてください)

理由はよくわかっていませんが、ask newしたあとの一番最初のコミットでskill-packageをまとめてcommit/pushするとどうも反映されなくなるようです・・・ 2020/07/03追記ここまで

遅ればせながらask-cli v2の話。

先日GAになったask-cli v2の良さは、AWSリソース(Lambda/S3/DynamoDB)をオールインワンでセットアップしてくれることだと個人的に思ってるので、逆にAlexa-hostedで使う場合の手順があまりない気がする。ということでAlexa-hostedで使う場合です。

ask-cli v2のインストール

ask-cli v1を引き続き使いたい方は本記事の手順だとマルっとv2に置き換わってしまうのでご注意ください。そうするとv1で作ったプロジェクトはv2へのマイグレーションをしないといけなくなります。マイグレについては以下あたりをご参考に。

qiita.com

個人的にはまだ各プロジェクトのマイグレは落ち着いてからやりたいので、nodebrewで環境を分けようと思います。nodenvとか使ってプロジェクト単位にするのもいいんでしょうが、そこまでnode.jsのプロジェクトが多いわけでもないし、コマンドラインはグローバルに切り替えるほうが好みなので。

ということで、まずask-cli v1が動いている現在の環境。

$ nodebrew ls
v10.16.0
...

current: v10.16.0

これを"ask1"というエイリアスにします。

$ nodebrew alias ask1 v10.16.0

ask-cli v2用にnode-10.21.0を入れて、"ask2"というエイリアスをつけます。

$ nodebrew install v10.21.0
$ nodebrew alias ask2 v10.21.0

あとは、nodebrew useで切り替えるだけです。

$ nodebrew use ask2
use v10.21.0

ask-cli v2をインストール

$ npm install -g ask-cli@2

インストールしました。

$ ask --version
2.11.1

ask v1に戻したい場合は以下でいつでも戻せます。

$ nodebrew use ask1

プロジェクトの新規作成

Alexa開発者コンソールとの連携はすでにできているものとします(v1だとask init, v2だとask configure。v2では別にask initがあるのでややこしいですね・・・)

プロジェクトの作成はask newです。対話形式になってるので順に答えていきましょう。

$ ask new

開発言語を聞いてきます。とりあえず NodeJS"で進めます。カーソルキーで選択してENTERします。

Please follow the wizard to start your Alexa skill project ->
? Choose the programming language you will use to code your skill:  (Use arrow keys)
❯ NodeJS
  Python
  Java

スキルのバックエンドを選択します。Alexa-hosted skills/AWS with CloudFormation/AWS Lambda/self-hosted の4つから選択しますが、もちろん"Alexa-hosted"で。

? Choose a method to host your skill's backend resources:  (Use arrow keys)
❯ Alexa-hosted skills
      Host your skill code by Alexa (free).
  AWS with CloudFormation
      Host your skill code with AWS services and provision with AWS CloudFormation (requires AWS account)
  AWS Lambda
      Host your skill code on AWS Lambda (requires AWS account).
  ──────────────
  self-hosted and manage your own hosting

スキル名を入力します。多分日本語通らないと思うのでご注意ください。今回はデフォルトの"Hello World Skill"で進めます。

? Please type in your skill name:  (Hello World Skill)

プロジェクトを保存しておくローカルのディレクトリ名を聞かれます。デフォルトはスキル名とおなじになりますので、そのままENTER。

? Please type in your folder name for the skill project (alphanumeric):  (HelloWorldSkill)

スキルの作成が開始されます。1分ぐらいかかります。

⠼ Creating your Alexa hosted skill. It will take about a minute.

ローカルにディレクトリが作成されます。コマンド実行時のカレントディレクトリの直下にディレクトリが作成されるようです。メッセージ見ている限りは、alexa-hosted側でスキルが作成され、それをローカルにcloneしてる感じですかね。

Project directory for aaa created at
    /Users/kun432/repository/HelloWorldSkill
⠋ Cloning Alexa Hosted Skill...

以下のように表示されれば完了です。

Project directory for Hello World Skill created at
    /Users/kun432/repository/HelloWorldSkill

Lambda code for Hello World Skill created at
    ./lambda

Skill schema and interactionModels for Hello World Skill created at
    ./skill-package

Skill is enabled successfully.
Hosted skill provisioning finished. Skill-Id: amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
Please follow the instructions at https://developer.amazon.com/en-US/docs/alexa/hosted-skills/build-a-skill-end-to-end-using-an-alexa-hosted-skill.html#askcli to learn more about the usage of "git" for Hosted skill.

以下のようにディレクトリが作成されています。

$ ls
HelloWorldSkill

中をちょっと覗いてみましょう。

$ cd HelloWorldSkill
$ tree -a
.
├── .ask
│   └── ask-states.json
├── .git
... snip ...
├── .gitignore
├── ask-resources.json
├── lambda
│   ├── index.js
│   ├── package.json
│   └── util.js
└── skill-package
    ├── interactionModels
    │   └── custom
    │       └── en-US.json
    └── skill.json

28 directories, 45 files

ask-cli v1とは微妙に構成が変わっていますね。あとgit init済みのようなので、ちょっとのぞいてみます。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   .gitignore

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    skill-package/

initial commitされてます。

$ git log
commit XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (HEAD -> master, origin/prod, origin/master, origin/dev, prod)
Author: AlexaHostedSkills <VoiceHubCodeCommitRole/provisioning>
Date:   Sun Jun 28 16:50:04 2020 +0000

    Initial Commit

masterとprodブランチがあります。それぞれのリモートブランチがあって、リモートにはdevもありますね。

$ git branch -a
* master
  prod
  remotes/origin/dev
  remotes/origin/master
  remotes/origin/prod

リモートブランチがCodeCommitにあるようです。

$ git remote -v
origin  https://git-codecommit.us-east-1.amazonaws.com/v1/repos/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX (fetch)
origin  https://git-codecommit.us-east-1.amazonaws.com/v1/repos/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX (push)

ask newが完了したときに表示されていたURLにも書いてあるのですが、AWS CodeCommitやAWS CodeBuildが使われているようです。

おそらくaskコマンドの内部で使っているだけで、自分でgit pushしたりすることはないんじゃないかなーと思っているのですがどうでしょう?逆に自分でgithubあたりでコード管理する場合にどういうふうにすればいいんでしょうか?

まだちょっとよくわかってないのでとりあえず先に進みましょう。次はAlexa開発者コンソールの方です。

f:id:kun432:20200629021806p:plain

スキルが作成されていますね。en-USになるようです。中身も見てみます。

f:id:kun432:20200629022056p:plain

f:id:kun432:20200629022106p:plain

はい、Hello Worldスキルの対話モデルとコードが作成されていますね。これで準備は完了です。

スキルの開発とデプロイ

2020/07/03追記 skill-package以下のファイルが更新されないという事象があるようなので、以下をまず実施してから、各ファイルの編集を行ってください。

$ git add .gitignore
$ git commit -m "add .gitignore"
$ git push

2020/07/03追記ここまで

あとはローカルで開発をしてアップするだけです。まずは練習として日本語に変えてみましょう。この辺が参考になると思います。

qiita.com

skill-package/skill.json

ロケールとスキル名を変更。

    "publishingInformation": {
      "locales": {
        "ja-JP": {
          "name": "ハローワールドスキル"
        }
      }
    }

skill-package/interactionModels/custom

リネームします。

$ mv en-US.json ja-JP.json

ja-JP.jsonの、呼び出し名とHelloWorldIntentのサンプル発話を変更します。

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "ハローワールドスキル",
      "intents": [
        {
          "name": "AMAZON.CancelIntent",
          "samples": []
        },
        {
          "name": "AMAZON.HelpIntent",
          "samples": []
        },
        {
          "name": "AMAZON.StopIntent",
          "samples": []
        },
        {
          "name": "HelloWorldIntent",
          "slots": [],
          "samples": [
            "こんにちは",
            "お元気ですか",
            "こんにちはと言って",
            "ハロー",
            "ハローワールド",
            "ハローといって",
            "ハローワールドと言って"
          ]
        },
        {
          "name": "AMAZON.NavigateHomeIntent",
          "samples": []
        }
      ],
      "types": []
    }
  },
  "version": "1"
}

lambda/index.js

発話部分を変更してください。今回はテストなのでLaunchRequestHanlderとHelloWorldIntentHandlerだけで試します。

const Alexa = require('ask-sdk-core');

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = 'ハローワールドスキルにようこそ。こんにちはと言ってみてください。';
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .reprompt(speakOutput)
            .getResponse();
    }
};
const HelloWorldIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
    },
    handle(handlerInput) {
        const speakOutput = 'こんにちは。私はアレクサです。';
        return handlerInput.responseBuilder
            .speak(speakOutput)
            //.reprompt('add a reprompt if you want to keep the session open for the user to respond')
            .getResponse();
    }
};

... snip ....

なお、上記のQiitaの記事では、ask-resources.jsonやskill-package/assets配下のアイコン画像のリネームもやっているようですが、

  • Alexa-hostedの場合、ask-resouce.jsonは以下のエントリしかないので修正する必要ががなさそう。
{
  "askcliResourcesVersion": "2020-03-31",
  "profiles": {
    "default": {
      "skillInfrastructure": {
        "type": "@ask-cli/hosted-skill-deployer"
      }
    }
  }

Alexa-hostedの場合はとりあえず不要です。

デプロイ

ではデプロイしてみましょう。ask deployを実行します。

$ ask deploy
[Warn]: Alexa hosted skills can be deployed by performing a git push.
The master branch gets deployed to skill's development stage
The prod branch gets deployed to skill's live stage
Please run "git push" at the proper branch to deploy hosted skill to your targeted stage.

おっと、これってもしかしてAlexa-hostedではCodeCommitのレポジトリが使えるってことですかね?

ということでドキュメントを見てみるときちんと書いてありました。

Gitを使ってAlexa-hostedスキルをデプロイする

Alexa-hostedスキルを作成した場合は、Gitを使ってスキルをデプロイします。

git pushコマンドを実行し、ローカルリポジトリmasterブランチから、Alexa-hostedスキルのあるリモートリポジトリ(通常はorigin)のmasterブランチにコードをプッシュします。

$ git push origin master


このコマンドは、最後に確定したバージョンをAlexa-hostedスキルにデプロイする場合に使用します。変更をプッシュすると、Alexa-hostedスキルはスキルパッケージリソースとリモートのmasterからのバックエンドのスキルコードの両方をデプロイします。Alexa-hostedスキルは、リモートのmasterブランチにプッシュするコードのみをデプロイします。

https://developer.amazon.com/ja-JP/docs/alexa/smapi/ask-cli-intro.html#deploy-skill

ということで、Alexa-hostedの場合はask deployは使わないようですね。。。masterが開発中ステージ、prodが公開中ステージということなので、masterにpushします。

$ git add .
$ git commit -m "日本語化"
$ git push
After the code pushed, please check the deployment status
via Alexa Developer console:
https://developer.amazon.com/alexa/console/ask/build/custom/amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/development/ja_JP
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 627 bytes | 627.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/
   XXXXXXX..XXXXXXX  master -> master

では開発者コンソールで見てみましょう。

スキル一覧の表示がきちんと日本語になっています。

f:id:kun432:20200629032552p:plain

対話モデルも変わってますね。

f:id:kun432:20200629032641p:plain

そしてコードも書き換わっています。

f:id:kun432:20200629032612p:plain

これでデプロイ完了です!

まとめ

Alexa−hostedの場合、通常のAWSへのデプロイとはやり方が異なるようですね。gitのレポジトリがCodeCommit上に自動で作成されるようなので、コードも管理もやってくれるのはいいんですが、試してみた限りCodeCommitのUIへはアクセスできないっぽいです。まあhostedだとほぼほぼ個人のプロジェクトだろうし、githubみたいなUIは必要ないってことなんですかね・・・・

まあ普通には使えますので、そのうちCodeCommit見れるようになったらいいなーと期待してます。とりあえず今作っているタイマーAPI使ったスキルは、ask-cli v2で管理するようにしてみよう。

ご参考になれば。