2020年ask-sdkアップデート簡易まとめ

Note: これはスマートスピーカー Advent Calendar 2020の後出し記事です。

2020年もAlexa系のアップデートがいろいろありました。その中でもask-sdk for Nodejsで追加された機能についていくつか簡単にピックアップしてみました。

2020年はv2.7.0 -> 2.10.0に

2019年最後のリリースはv2.7.0でした。この記事を書いている12月26日時点での最新バージョンは2.10.0ですので、3回のマイナーアップデートが行われたということになります。

2.10.0 (2020-10-08)

2.9.0 (2020-07-22)

2.8.0 (2020-04-01)

https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/blob/2.0.x/CHANGELOG.md

2.8.0 (2020-04-01)で追加された機能

新しく追加されたFeatureは以下の6つです。

Expressでask-sdkを実行するためのAdaptorライブラリがリリース

Lambda以外の環境でAlexaスキルバックエンドを実行する場合、Node.jsのサーバーを用意する必要があります。

Node.jsでサーバーを立てるときに用いられることの多いExpressを使って、Alexaスキルを実行できるようにするask-sdk-express-adaptorがこのバージョンでリリースされました。

以下のような使い方をすることで、HTTPSリクエストに含まれるSigunatureやTimestampなどのVerifyをSDK側に任せることができます。

import express from 'express';
import { ExpressAdapter } from 'ask-sdk-express-adapter';

const app = express();
const skillBuilder = Alexa.SkillBuilders.custom();
const skill = skillBuilder.create();
const adapter = new ExpressAdapter(skill, true, true);

app.post('/', adapter.getRequestHandlers());
app.listen(3000);

SMAPI(Skill Management API)のためのSDKがリリース

開発者は開発者でも、どちらかというとAlexa開発者向けのツールやサービスを作ろうとしている方にとって嬉しいリリースがこちらです。

Alexaスキルのデプロイや公開・モデルの管理といったスキル管理系のAPIは、「SMAPI」とよばれています。このSMAPIを実行するためのSDKとして、ask-smapi-sdkがリリースされました。

Login With Amazonのid / secretなどを取得する処理を自前で用意する必要はありますが、リフレッシュやAPIリクエストの作成などをこのSDKに任せることができます。

import * as Alexa from 'ask-smapi-sdk';
 // specify the refreshTokenConfig with clientId, clientSecret and refreshToken generated in the previous step
 const refreshTokenConfig : Alexa.RefreshTokenConfig = {
     clientId,
     clientSecret, 
     refreshToken
 }

 const smapiClient = new Alexa.StandardSmapiClientBuilder()
     .withRefreshTokenConfig(refreshTokenConfig)
     .client();


 smapiClient.listSkillsForVendorV1(vendorId)
     .then((response) => {
         console.log(JSON.stringify(response));
     })
     .catch((err) => {
         console.log(err.message);
         console.log(JSON.stringify(err.response));
     });

PersistenceAdaptorのキーにPerson IDが指定可能に

PartitionKeyGeneratorsにpersonIdが追加されました。これまではuserIdまたはdeviceId以外については自作のGeneratorを作る必要がありました。ですがこのバージョン以降では、PartitionKeyGenerators.personIdを利用することで、Person Idをキーにデータを保存できるようになります。

また、SDKが提供しているものは、personIdが存在しない場合にuserIdを利用するというフォールバックも設定されています。

参考: https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/commit/59002f423a13fe3d59e7882d013bde40501d3f79

2.9.0 (2020-07-22)

Version 2.9.0はAlexa Live 2020に合わせてリリースされたバージョンです。

追加された新機能は以下の4点でした。

  • add a defaultAttributes parameter in getPersistentAttributes (#626) (5372544)
  • add ask-sdk-controls package (fb7387c)
  • add ask-sdk-local-debug package (a7c22a9)
  • add support for custom lwa endpoint (#617) (839f4ae)

ask-sdk-controlのリリース

Alexa Liveでも発表されたのがこのask-sdk-controlです。

これはライブラリの1つというよりは、「ask-sdkをベースにしたフレームワーク」の1種です。

対話モデルの生成をJSのコードで行えるなど、かなりフルスタックに作られている印象があります。

const { ControlInteractionModelGenerator, Logger } = require('ask-sdk-controls');
 const log = new Logger('HelloWorld:InteractionModel');
 new ControlInteractionModelGenerator()
     .withInvocationName('hello controls')
     .addIntent({ name: 'AMAZON.StopIntent' })
     .addIntent({ name: 'AMAZON.NavigateHomeIntent' })
     .addIntent({ name: 'AMAZON.HelpIntent' })
     .addIntent({ name: 'AMAZON.CancelIntent' })
 // Add a custom intent .addIntent({ name: 'HelloIntent', samples: [     "Say hello",     "Say hi" ]}) // Build and write .buildAndWrite('en-US-generated.json');
 log.info('Wrote ./en-US-generated.json');

ask-sdkのRequestHandlerに近いようでいろいろなメソッドやクラスが生えているので、実質別のフレームワークを使ったスキル開発という印象を受けるかもしれません。

const Alexa = require('ask-sdk-core');
 const { InputUtil, ControlHandler, ControlManager, Control, LiteralContentAct } = require('ask-sdk-controls');

 class HelloControl extends Control {
     canHandle(input) { return InputUtil.isLaunchRequest(input) || InputUtil.isIntent(input, 'HelloIntent'); }
     handle(input, resultBuilder) { resultBuilder.addAct(new LiteralContentAct(this, {promptFragment: 'Hello, world.'})); resultBuilder.endSession(); }
     canTakeInitiative() { return false; }
 }

 class H
elloManager extends ControlManager {
     createControlTree() { return new HelloControl('rootControl'); }
 }

 exports.handler = Alexa.SkillBuilders.custom()
     .addRequestHandlers(new ControlHandler(new HelloManager()))
     .lambda();
 exports.HelloManager = HelloManager;

とはいえSkillBuildersにはRequestHandlerとして登録できるなど、ask-sdkとの互換性もある程度担保されていますので、段階的に試してみるなどでトライされるとよいかなと思います。

余談ですが、このフレームワークのリリースとほぼ同じタイミングで自作のフレームワーク「TalkyJS」をリリースしたため、若干冷や汗をかきました。目指しているところが違いそう & どちらもask-sdk互換なので共存できるかなと感じていますが。

ask-sdk Local Debug tool

ask-sdk-controlに隠れていますが、ひっそりとローカルデバッグツールもリリースされていました。以下のようなコマンドか、VS Codeから実行することで、スキルのデバッグが可能になる様子です。

node ./node_modules/ask-sdk-local-debug/dist/LocalDebuggerInvoker.js
        --accessToken <ACCESS_TOKEN>
       --skillId <SKILL_ID>
       --skillEntryFile <FILE_NAME>
       --handlerName <HANDLER_NAME>
       --region <REGION> # Optional argument. Region defaults to NA.

この記事を書くためにReleaseを見ていて気づいたものなので、これについてはまた後日使い方などを調べて記事を作ろうと思います。

2.10.0 (2020-10-08)

そしておそらく今年最後のアップデートとなるのが、このv2.10.0です。CHANGELOGをみる限り、このバージョンはBug Fixと内部的なアップデートが中心でした。Featuresに上がっている以下の内容についても、コードをみる限りSDK内部で利用している実装か、GitHub Actionsなどのワークフロー系の変更ばかりです。

  • Add special timestamp verification for skill event requests (#651) (9b0dd9f)
  • add UserAgentManager (bc03b55)
  • Adding individual workflows to be triggered on subdir changes (c5eb69f)
  • Update root package.json to fix doc generation (4bf482b)

おわりに

2020年のリリースを改めて確認すると、ask-sdk本体への機能追加はほぼ行われていないことが伺えます。ask-sdk-controlask-smapi-sdkask-sdk-jsx-for-aplのように「ask-sdkをベースとして、より便利に開発が行えるツール」のリリースやアップデートが中心になるのではないかと感じました。

とはいえ「getPersistentAttributesの戻り値にDefault値を設定したい」や「TypeScriptでas使うよりGenerics使う方がシンプルだからgetRequest関数が欲しい」のようにIssue / Pull Requestで要望を出すと、ちゃんとリアクションしてもらえます。

「こういう関数あればいいのに」や「ここ使いにくい or わかりにくい」と感じる部分があれば、ぜひ一度GitHubのIssue / Pull Requestsを開いてみてください。一応自分もWatchしていますので、自分も欲しいなと思うものであれば積極的に援護射撃はしていこうと思います。

Comment