APL環境構築 & テキスト表示


# やること

[Alexa ハローAPL、Alexaスキルの画面への対応](https://qiita.com/Mount/items/72d9928ff2c0ae5de737)
やることはまんまこの記事。

- APLオーサリングを用いたデザインの作り方
- APLを使えるように設定する
- APLドキュメントを使って画面を描画する。

あたりについて示す。

# 前提
[ASK CLI 環境構築](https://qiita.com/Teach/items/b7901071a646fa974ed6)

# 環境
[APLオーサリングツールドキュメント](https://developer.amazon.com/ja-JP/docs/alexa/alexa-presentation-language/apl-authoring-tool.html)
APL v1.6
所持実機 Echo show 5![スクリーンショット_2021-07-09_20_00_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/6d53dbc0-af03-857d-2d94-0c1983844282.png)


# APLとは
[APLドキュメント](https://developer.amazon.com/ja-JP/docs/alexa/alexa-presentation-language/apl-document.html)
Alexa Presentation Language
画面の情報をJSONでAlexaに渡そうっていうもの。

```.json
{
  "type": "APL",
  "version": "1.6",
  "mainTemplate": {
    "item": {
      "type": "Text",
      "text": "ハローワールド"
    }
  }
}
```

## APLドキュメント
画面情報のJSON
オーサリングツールを使ってつくるのが楽


# APLオーサリングを用いたデザインの作り方

まずは[オーサリングツール](https://developer.amazon.com/alexa/console/ask/displays/?)で空の画面を作る。
![スクリーンショット_2021-07-18_14_04_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/8fee270e-14a1-d833-d523-4a7de26d7e67.png)



![スクリーンショット_2021-07-09_20_00_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/05466c5b-b2e4-1849-6761-e322cb48d448.png)

とりあえずEcho Show 5にしておく

GUI > mainTemplateを押すと+ボタンが押せるようになる

![スクリーンショット_2021-07-09_20_18_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/38ee3a33-20cb-9229-5983-7be5dc4f6f5d.png)

![Add Component.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/5fb51143-d57d-259f-9864-4dad88d8f939.png)


+ボタンを押すとAddComponentのDialogが出る。
Containerを選択するとmainTemplateの子にContainerができる

同様の手順でTextを追加し、右側の情報ビューっぽいのでtextを入力

![maxLines.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/f641634f-116d-7f4d-c3bb-fae5ff361dae.png)


## 文字を真ん中に表示する
Container > justifyContent = center
Text > textAlign = center

![スクリーンショット 2021-07-18 14.22.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/bdbaaf04-47a3-aa90-17d1-139be7e9c9c4.png)


## 文字データをレイアウトデータから逃す

textを${payload.hello.text}に変更し、
Dataに以下のように入力

![hello.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/df1d7bdd-f8ca-64ab-0e44-5ded6e3b04a6.png)

## テンプレートの保存
![スクリーンショット 2021-07-18 14.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/12603934-6269-a10a-fcee-d255ac466f2b.png)


alexa hosted skillに紐づけて保存できる
開くときは

![スクリーンショット 2021-07-09 20.42.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/31a926ca-0199-a673-0b1f-b22da665f3e4.png)

マルチモーダル > visual でいる。

## APLドキュメントのダウンロード
テンプレートを保存 or APLをそのままコピペすることでレイアウトのデータをとってくる。

保存するファイル名は自由だが今回は以下のようにした。

```
lambda > views > hello_apl.json
```

# APLを使えるように設定する
[Alexa Presentation Language（APL）に対応するようスキルを設定する](https://developer.amazon.com/ja-JP/docs/alexa/alexa-presentation-language/apl-support-for-your-skill.html)

これはコンソールでやるのが楽
![スクリーンショット 2021-07-18 14.40.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/9dc754d1-f31f-ea69-4dc3-3d8817c8961d.png)

![スクリーンショット_2021-07-18_14_40_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/547e578d-407b-533a-7219-2d9fb259d95b.png)
Alexa Presentation LanguageのところをONにして、保存

![スクリーンショット_2021-07-18_14_41_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/557b3bdb-3e6b-fd06-e2e4-4f77ed996946.png)

次に、このコンソールで設定した内容をローカルのプロジェクトにとってくる。

設定(manifest)は skill-package > skill.jsonにある。

方針: コンソールの設定を正としてローカルのskill.jsonを上書き保存する。

上書きなので必ずあらかじめコミットしておくこと。

ASK CLIの [get-skill-manifest](https://developer.amazon.com/ja-JP/docs/alexa/smapi/ask-cli-command-reference.html#get-skill-manifest-subcommand) を使用する。

```
$ ask smapi get-skill-manifest [--skill-id | -s <スキルID>]
                               [--stage | -g <ステージ>]
                               [--profile | -p <プロファイル>]
                               [--debug]
```

スキルIDとステージが必須。
スキルIDはプロジェクトの .ask > ask-states.json にある

```.ask/ask-states.json
{
  "askcliStatesVersion": "2020-03-31",
  "profiles": {
    "default": {
      "skillId": "amzn1.ask.skill.hogehoge..."
    }
  }
}
```

初めてやるときには試しにコマンドラインで打ってみると良いと思う。

コマンド叩いてコピペでもできるが、手間なのでjs書いた。

```update_manifest.js
const { execSync } = require('child_process')
const fs = require('fs');

const states = JSON.parse(fs.readFileSync('.ask/ask-states.json', 'utf8'));
const skillId = states.profiles.default.skillId;
const stdout = execSync(`ask smapi get-skill-manifest --skill-id ${skillId} --stage development`);
fs.writeFileSync('./skill-package/skill.json', stdout);
```

これをプロジェクトのルートに配置して

```
$ node update_manifest.js
```

で上書きできる。

# APLドキュメントを使って画面を描画する。

[リクエストハンドラーの応答でRenderDocumentを返す](https://developer.amazon.com/ja-JP/docs/alexa/alexa-presentation-language/use-apl-with-ask-sdk.html#return-renderdocument)

[addDirective](http://ask-sdk-node-typedoc.s3-website-us-east-1.amazonaws.com/classes/responsebuilder.html#adddirective)を用いて、表示する。

```index.js
const Alexa = require('ask-sdk-core');
const hello_apl = require('./views/hello_apl.json'); // (1)　ファイルから読み込む

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = 'Welcome, もう寝る時間だね。';
        return handlerInput.responseBuilder
            .speak(speakOutput)
            .addDirective({ // (2) responseBuilderにaddDirectiveで追加する
                type: 'Alexa.Presentation.APL.RenderDocument',
                version: '1.6',
                document: hello_apl.document,
                datasources: hello_apl.datasources
            })
            .getResponse();
    }
};
```

最短だとこれでできる。
今回はdocumentとdatasourcesを同じファイルにしたが、コピペを楽にするために別ファイルにしておいた方がいいと思う。