20190819のNode.jsに関する記事は7件です。

【Node.js】Custome Search APIを使って何か作ってみる

初投稿です。※初投稿っぽい前置きや自己紹介は割愛
なんとなくプライベートでもなんか作っていけたらなあという浅い考えで作ってみました。

目的(テキトー)  

Node.jsを使ってREST APIとの連携をなんか作ってみたい。
そこでテキトーな練習台を思いついた。
「なんか料理屋さんをCustome Search APIで検索してみて、食べログURLがあれば抜き出す。」

使っているもの

Node.js
Custome Search API

Custome Search APIって?

Custome Search APIはGCP上でGoogleが提供しているGoogle検索のAPIです。
これを使うにも何かと手順があります。※気が向いた時にこちらも軽くまとめるかも
参考になる情報は数多くありますので、自分が参考にさせていただいたものを抜粋して貼っておきます。
Custom Search APIを使ってGoogle検索結果を取得する
Google Custom Search API を使ってみる

ここからが作ったものについて

APIに必要なパラメータは大前提にURL、あとは検索エンジンID、APIキー、検索ワードが必要です。
詳細なAPIの情報は公式のページを参照してください。
簡単に三つのパラメータを説明すると、

検索エンジンID

ユーザーが作成したカスタム検索エンジンのユニークIDのこと。Custome Search APIの利用にはこのカスタム検索エンジンの作成が必要です。

APIキー

APIコール時のユーザー認証に必要な情報です。
本来は漏洩等による不正利用を防ぐため、API呼び出すアプリケーションの制限(IPアドレスやドメインなどで設定可能)や呼び出せるAPIの制限といった制限をかけるべきです。今回は遊びなので特に制限は設定していません。※生成したAPIキーは削除済み

検索ワード

そのまんま。ググる時同様の検索したいワードです。今回はラーメン界に名を轟かす「中華蕎麦とみた」さんを検索ワードに。

クエリパラメータの外出し

さっきのパラメータはメインのソースコードにベタ書いても遊びとしては良かったのですが、あまりにも工夫がないなと思い、設定ファイルに外出ししました。node-configというモジュールを使い、下記のようにdefault.jsonというJSONファイルを作成し、そこに各パラメータを記述しています。

default.json
{
    "url":"https://www.googleapis.com/customsearch/v1",
    "key":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "cx":"000000000000000000000:xxxxxxxxxxx",
    "q":"中華蕎麦とみた"
}

ちなみに、node-configは下記のコマンドでインストールします。
npm install --save-dev config

requestモジュールを使ったhttp通信

Node.jsのhttp標準モジュール(http/httpsモジュール)でもいいのですが、せっかくなのでより楽に処理を実現できるrequestモジュールを今回は使用しました。optionとして引数にURLやhttpメソッドを渡します。また、json:trueとすることでレスポンスのJSONをパースしてくれます。
下記のコマンドでインストールします。
npm install request --save
このモジュールを使いながら処理を書いて、実行したらこんなエラーが。
path contains unescaped characters
どうやら原因は検索ワードの2バイト。初歩的なミスですね。URLエンコードが必要ですので、javascriptではencodeURIComponentを使います。

コード完成!

そんなこんなで完成したコードがこちら。

getGoogleResult.js
var req = require('request');
var conf = require('config');
var options = {
    url: conf.url + "?key=" + conf.key + "&cx=" + conf.cx + "&q=" + encodeURIComponent(conf.q),//設定ファイルから各パラメータを取得し、URLを生成している
    method: 'GET',//GETでリクエスト
    json: true//これでJSONをパースしてくれる
}
req(options, function (error, response, body) {
    if (error) {
        console.log('Error: ' + error.message);
        return;
    }
    var items  = body.items;
    for (var i in items) {
        var itemLink = items[i].displayLink;
        var strLink= String(itemLink);
        var itemTitle = items[i].title;
        var strTitle = String(itemTitle);
        if(strLink.indexOf('tabelog.com') != -1 ){
            console.log(conf.q + "の食べログは\nURL:" + strLink + "です。\n" + "タイトル:" + strTitle)
        }
    }
})

ざっくり言うと、コールバック関数の中でerrorがあれば、ログに出して終了、errorが無ければ、bodyからitemリスト(Custome Search APIの検索結果リスト)からURLに「tabelog.com」が含まれるものを判定してログ出力!って感じです。
注意点としては、ループでitemsから取得できるもの(コード中のiのこと)はインデックスなので、ループの中ではこのインデックスを使ってリストの要素を取り出す必要があります。

いざ、実行!

node getGoogleResult.js

結果は、

中華蕎麦とみたの食べログは
URL:tabelog.comです。
タイトル:中華蕎麦 とみ田 - 松戸/ラーメン [食べログ]
中華蕎麦とみたの食べログは
URL:tabelog.comです。
タイトル:日本の中華そば富田 - 成田空港/ラーメン [食べログ]

富田さんの食べログサイトが取れました。(ほんとは松戸本店だけのつもりだった・・・)
あと、displayLinkだとどちらもtabelog.comになっちゃいますね。普通のlinkにしなければいけなかった・・・
まあ、なんとなく遊べたので満足です。これをなんらか使い勝っていい感じに発展させたら面白そうだけど、それは気が向いたらやります。笑

終わりに

何かしら自分が面白いと思ったことを発信できたら、それ自体が面白そうだなと思って投稿してみました。
どれだけ役立つ情報発信ができるか分からないし、そもそもそんなマメに投稿するかも怪しいけど、また何か思いついたら自分の備忘録も兼ねて書きます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

nodeのバージョン上げたらビルドこけた

nodeのバージョンを上げたらエラーが起こってビルドがコケていたので備忘録。
ターミナルのエラー文見ると下記が表示されていた。

Node Sass could not find a binding for your current environment: OS X 64-bit with Node.js 12.x

node-sassが何やら大切な物を見つけられないでいるみたいです。

This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass` to download the binding for your current environment.

続けてエラー文を見ていきます。
すると、環境が変わった時に起こる現象らしく、npm rebuild node-sassコマンドを打て、と言われています。

npm run rebuild

解決!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Alexa APL, 第13回 リソースを使用してスタイルの設定(文字装飾をスタイルで実施)

はじめに

Alexaを搭載した画面付きデバイスの画面レイアウトを作成します。
今回は、文字サイズや文字色などの文字装飾をリソースとスタイルを設定しながら実施します。
対象とするコンポーネントは、Textです。

スタイルは、HTMLで使用されるものとコンセプトは同じで、文字装飾などの設定をひとつのスタイルに定義して、その作成したスタイルをコンポーネントに設定するように使います。
例えば、「スタイルA」として、「文字は太字で色は赤色」と定義して、あるテキストに「スタイルA」を指定すると、そのテキストは「文字は太字で色は赤色」になるということです。

リソースは、その設定値などを定数化するものです。
例えば、「リソースA」として、「#ff0000」と定義して、あるプロパティで「@リソースA」を指定すると、そのプロパティの値は「#ff0000」になるということです。

今回実施する内容

Textの文字装飾のスタイルを作成し、Textにスタイルを設定します。スタイルを使うときにリソースも使います。

中型デバイス(Echo Show用)
中型デバイス4.jpg

環境

OS:Windows 10 JP
Alexaスキル言語:Node.js
Editor:Visual Studio Code
APLバージョン:1.0, 1.1

参考

Alexa ハローAPL、Alexaスキルの画面への対応
第1回のAlexa APLの記事です。タイトル通り、ハローAPLを表示させるだけのAPLです。

Alexa APL, 第12回 文字サイズ、文字色
第12回のAlexa APLの記事です。TextにcolorやfontFamilyなどを直接設定して動作を確認する記事です。

APLドキュメント リソース
AmazonのAPLドキュメントにあるリソースの説明です。

APLドキュメント スタイル
AmazonのAPLドキュメントにあるスタイルの説明です。

APLトレーニングシリーズ第2回: APLドキュメントの概要
AmazonのAlexa BlogsにAPLのレイアウト方法の記載がありました。
whenの使い方についてしれっと重要なことが書かれていました。

用語

APL

Alexa Presentation Language
amazonの画面つきのAlexaの画面表示用の言語。
JSONを使用した記載方法です。
インターネットのホームページはHTMLとCSSで作成しますが、AlexaはAPLで作成するということです。

APLオーサリングツール

APL作成を視覚的に見ながらAPLのJSONファイルを作成するツール。
サンプルテンプレートも準備されており、その中から選択していくだけで、だいたいの画面は作成できる。

スタイル

文字色、文字サイズ、フォントや背景色などのプロパティを集めた集合のこと。CSSなどで使うスタイルと意味は同じです。

前提条件

前提条件はとくにないといえばないですが、本まとめを読むにあたり、以下がわかっていることが前提です。
・alexa developer consoleのアカウントがある
・Alexaスキルを開発したことがある
・JSONの記載方法を知っている
・「Alexa ハローAPL、Alexaスキルの画面への対応」、および「Alexa APL, 第12回 文字サイズ、文字色」の記事をみている

今回使用するレイアウト

今回は、文字サイズや文字色などを変更して、その動きを確認します。
そのために基本となるレイアウトを以下の通り作成します。
「レイアウト画面」はこんな感じです。
レイアウト.jpg

  1. APLオーサリングツールを起動して「最初から作成」を選択する。
  2. 「レイアウト画面」の「mainTemplate」を選択し、「Container」を追加する。
  3. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
  4. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].text}
5. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
6. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].detail}
・ paddingLeft:10vw
7. 5, 6を3回繰り返す。sampleArrayの配列部分は1~3に設定する。
※今回は文字サイズや文字色を試すために、あえて配列をSequenceではなく、Textの繰り返しで設定しました。

JSONデータの作成

以下の通り、JSONデータを作成する。

JSONデータ
{
    "sample": {
        "sampleArray": [
            {
                "text": "コーヒー(coffee)",
                "detail": "コーヒー(coffee)です。",
                "imageURL": "https://coffee_480x480.jpg"
            },
            {
                "text": "カプチーノ(cappuccino)",
                "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                "imageURL": "https://cappuccino_480x480.jpg"
            },
            {
                "text": "カフェラテ(latte)",
                "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                "imageURL": "https://latte_480x480.jpg"
            },
            {
                "text": "エスプレッソ(espresso)",
                "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                "imageURL": "https://espresso_480x480.jpg"
            }
        ]
    }
}

上記で作成した画面の確認

上記で作成した画面をみると、以下のようになります。
中型デバイス(Echo Show)
中型デバイス1.jpg

スタイルを使う

スタイルの作成(赤色+Bold)

まずは単純なモデルで、「コーヒー」や「カプチーノ」などを赤色の文字にしてBoldにするスタイルを作成します(配色は最悪ですが機能確認のためです)。
APLオーサリングツール上で、APLを開いて、"styles"に直接編集します。
以下のように記載します。

APL
...
    "styles": {
        "menuNameStyle": {
            "values": [
                {
                    "color": "#ff0000",
                    "fontWeight": "bold"
                }
            ]
        }
    },
...

スタイルはこれだけです。
簡単に説明します。

  • menuNameStyleはスタイル名であり、自分で好きなものをつけることができます。
  • valuesは配列で、複数記載でき、whenと組み合わせて状態によって、配列に記載したマッチするスタイルを変更できます。今回は一つだけ設定しました。
  • colorfontWeightでそのスタイルで使用する文字装飾を設定する。

スタイルの適用

APLオーサリングツール上で、以下のようにします。
1. 「レイアウト画面」の上で作成した1番目の「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ style:menuNameStyle
2. 1の内容を3、5、7番目の「Text」で同様に実施する。

以下のようになります。
中型デバイス(Echo Show)
中型デバイス2.jpg

スタイルは、Textに対して、ひとつを設定するだけで複数の文字装飾を一気に適用できるため、個別に設定するよりも手間が省けますし、統一感をもって設定できるため有用です。

whenをスタイルで使ってみる(要注意)

valuesが配列で設定し、whenを使って動作をわけられるということで動作を試してみます。
APLトレーニングシリーズ第2回: APLドキュメントの概要に、whenの使い方についてしれっと重要なことが書かれていました。

when プロパティは、リソースやスタイル、レイアウトなどで幅広く利用できます。 いずれも when プロパティが true のとき、そのオブジェクトが採択されますが、リソースやスタイルの配列では true になった後者の定義で上書きされるのに対し、レイアウトのコンポーネント配列では最初に true になったコンポーネントが採択されます。

要素 説明
リソース、スタイル 後者の定義で上書き。どんどん継承。
レイアウト trueになった時点のコンポーネントが採択。

ということで、whenは使う場所によって、適用され方が違うのです。そんなに細かいレベルではなく大きな分類のためなれれば問題ないかと思いますが、最初勘違いしてスタイルが期待通り動かなかったため、記載しました。
whenの使い方.jpg

では、小型デバイス用(Echo Spot)に、タイトルの色を緑色に変えます。

  1. importalexa-viewport-profilesを追加する。
  2. menuNameStylevalues内を配列の2番目にwhenを使って、小型デバイス(Echo Spot)用の識別をいれて、色を以下の通り緑色にする。
APL
    ...
    "import": [
        {
            "name": "alexa-viewport-profiles",
            "version": "1.1.0"
        }
    ],
    ...
        "menuNameStyle": {
            "values": [
                {
                    "color": "#ff0000",
                    "fontWeight": "bold"
                },
                {
                    "when": "${viewport.shape == 'round'}",
                    "color": "#00ff00",
                    "fontWeight": "bold"
                }
            ]
        },

試した結果は以下です。小型デバイスだけ変更されます。
小型デバイス(Echo Spot)
小型デバイス1.jpg

whenを文字装飾内で使ってみる

スタイルを作っていて、Amazonの例を見ていて気付きましたが、whenはcolorなどの設定でも記載ができます。
三項演算子のような記載もできるようです。
では、小型デバイス用(Echo Spot)に、タイトルの色を緑色に変えます。
1. importalexa-viewport-profilesを追加する。
2. menuNameStylevalues内を配列の2番目にwhenを使って、小型デバイス(Echo Spot)用の識別をいれて、色を以下の通り緑色にする。

APL
    ...
    "import": [
        {
            "name": "alexa-viewport-profiles",
            "version": "1.1.0"
        }
    ],
    ...
        "menuNameStyle": {
            "values": [
                {
                    "color": "${viewport.shape == 'round' ? '#00ff00' : '#ff0000'}",
                    "fontWeight": "bold"
                }
            ]
        },

上の「whenをスタイルで使ってみる(要注意)」に載せたものと同じ結果が得られます。
今回のようにcolorを一か所だけ変更したいといった場合には、三項演算子のような記載もよいですが、感触的にはひとつだけではすまなさそうなため、上位でwhenを使う前項の使い方のほうが良いかなと思いました。
もしくは、スタイル名を完全にデバイスごとに変えて作成するというのもありますが、スタイル名が長くなりそうですし、やはり一つのスタイル内でwhenでわけるのがよさそうかなと思いました。

スタイルのプロパティ

スタイルのプロパティには、以下があります。

プロパティ 説明
description 文字列 スタイルの説明を記載します。自分への備忘。
extend スタイル名の配列 継承元のスタイルの一覧。後のものが上書き。
values valueオブジェクトの配列 スタイルを設定するオブジェクトの配列。

スタイルの作成(extend)

extendを使って、継承動作を確認します。
APLオーサリングツール上で、APLを開いて、"styles"に直接編集します。
以下のように記載します。

APL
...
    "styles": {
        "menuNameStyle": {
            "values": [
                {
                    "color": "#ff0000",
                    "fontWeight": "bold"
                }
            ]
        },
        "detailBase": {
            "values": [
                {
                    "color": "#00ff00",
                    "fontSize": "24dp"
                }
            ]
        },
        "detailStyle": {
            "extend": [
                "detailBase"
            ],
            "values": [
                {
                    "color": "#0000ff",
                    "fontWeight": "bold"
                }
            ]
        }
    },
...

図で説明します。
extend説明.jpg
図の通りであり、extendは配列を設定できますが、複数設定するとどんどん上書きされるようです。

リソースを使う

リソースの作成(薄い黄色)

まずは単純なモデルで、薄い黄色のリソースを作成します。
APLオーサリングツール上で、APLを開いて、"resources"に直接編集します。
以下のように記載します。

APL
...
    "resources": [
        {
            "colors": {
                "lghtYlw": "#ffff99",
                "pnk": "#ff99ff"
            }
        }
    ],
...

リソースはこれだけです。
簡単に説明します。

  • colorsはリソースのプロパティ名であり、文字色に関する色を設定するためのものです。
  • lghtYlwpnkはリソース名であり、自分で好きなものをつけることができます。
  • colorsはオブジェクトであり複数個設定できます。

リソースの適用

APLオーサリングツール上で、以下のようにします。
1. APLを開いて、menuNameStylecolor@lghtYlwを設定する。
2. detailStylecolor@pnkを設定する。
以下のようになります。
中型デバイス(Echo Show)
中型デバイス4.jpg

リソースのプロパティ

リソースのプロパティには、以下があります。

プロパティ 説明
description 文字列 スタイルの説明を記載します。自分への備忘。
boolean ブール値のマップ ブール値の名前をマッピング。
colors 色のマップ 色の名前のマッピング。
dimensions ディメンションのマップ ディメンションの名前のマッピング。
strings 文字列の配列 名前を文字列にマッピング。
when ブール値 trueの場合にこのリソースを適用。

要するにbooleancolorsdimensionsstringsの型名を指定して、その型の定数をその配下で定義するということです。
resourcesの使い方.jpg

descriptionも説明を記載するだけのため、説明を割愛します。

whenを使ってみる

リソースにwhenをつけてみます。
これをつけることで、同じ名前のリソースをwhenでわけることができます。
では、小型デバイス用(Echo Spot)に、タイトルの色を赤色に変えます。
スタイルのところで作成したAPLに変更を加えます。
1. resourcescolorsの下にもうひとつcolorsを追加する。そのとき、whenもつける。

APL
...
    "resources": [
        {
            "colors": {
                "lghtYlw": "#ffff99",
                "pnk": "#ff99ff"    <=ピンク色を設定
            }
        },
        {
            "when": "${viewport.shape == 'round'}",
            "colors": {
                "pnk": "#ff0000"   <=赤色を設定
            }
        }
    ],
...

これによって、以下のようになります。
小型デバイス(Echo Spot)
小型デバイス2.jpg

デバイスによるイメージの差分は、スタイルのwhenを用いるか、リソースのwhenを用いるか、どちらでも可能です。
どちらを用いるかは悩ましいですが、感覚的にはスタイルかなと思います。
リソースは値に名前を付けているものですが、名前はその値の特徴を示すものだと思います。
その特徴がデバイスの差分で違うというのは違和感があるため、スタイルでわけたほうが望ましいのかなと思いました。
といいつつも、dimensionsのような数値を相対的に設定する場合(例えば、中型デバイスは32dpだけど小型デバイスは24dpを使うなど)は、リソースでもいいなと思うので、悩ましいですね。

APLソースコード

出来上がったAPLのフルソースコードとデータJSONを載せます。実際にスキルで表示を試す場合は、Alexa ハローAPL、Alexaスキルの画面への対応を参考しに実施します。

APL
{
    "document": {
        "type": "APL",
        "version": "1.1",
        "settings": {},
        "theme": "dark",
        "import": [
            {
                "name": "alexa-viewport-profiles",
                "version": "1.1.0"
            }
        ],
        "resources": [
            {
                "colors": {
                    "lghtYlw": "#ffff99",
                    "pnk": "#ff99ff"
                }
            },
            {
                "when": "${viewport.shape == 'round'}",
                "colors": {
                    "pnk": "#ff0000"
                }
            }
        ],
        "styles": {
            "menuNameStyle": {
                "values": [
                    {
                        "color": "@lghtYlw",
                        "fontWeight": "bold"
                    },
                    {
                        "when": "${viewport.shape == 'round'}",
                        "color": "#00ff00",
                        "fontWeight": "bold"
                    }
                ]
            },
            "detailBase": {
                "values": [
                    {
                        "color": "#00ff00",
                        "fontSize": "24dp"
                    }
                ]
            },
            "detailStyle": {
                "extend": [
                    "detailBase"
                ],
                "values": [
                    {
                        "color": "@pnk",
                        "fontWeight": "bold"
                    }
                ]
            }
        },
        "onMount": [],
        "graphics": {},
        "commands": {},
        "layouts": {},
        "mainTemplate": {
            "parameters": [
                "payload"
            ],
            "items": [
                {
                    "type": "Container",
                    "items": [
                        {
                            "type": "Text",
                            "style": "menuNameStyle",
                            "text": "${payload.sample.sampleArray[0].text}"
                        },
                        {
                            "type": "Text",
                            "style": "detailStyle",
                            "paddingLeft": "10vw",
                            "text": "${payload.sample.sampleArray[0].detail}"
                        },
                        {
                            "type": "Text",
                            "style": "menuNameStyle",
                            "text": "${payload.sample.sampleArray[1].text}"
                        },
                        {
                            "type": "Text",
                            "style": "detailStyle",
                            "paddingLeft": "10vw",
                            "text": "${payload.sample.sampleArray[1].detail}"
                        },
                        {
                            "type": "Text",
                            "style": "menuNameStyle",
                            "text": "${payload.sample.sampleArray[2].text}"
                        },
                        {
                            "type": "Text",
                            "style": "detailStyle",
                            "paddingLeft": "10vw",
                            "text": "${payload.sample.sampleArray[2].detail}"
                        },
                        {
                            "type": "Text",
                            "style": "menuNameStyle",
                            "text": "${payload.sample.sampleArray[3].text}"
                        },
                        {
                            "type": "Text",
                            "style": "detailStyle",
                            "paddingLeft": "10vw",
                            "text": "${payload.sample.sampleArray[2].detail}"
                        }
                    ]
                }
            ]
        }
    },
    "datasources": {
        "sample": {
            "sampleArray": [
                {
                    "text": "コーヒー(coffee)",
                    "detail": "コーヒー(coffee)です。",
                    "imageURL": "https://coffee_480x480.jpg"
                },
                {
                    "text": "カプチーノ(cappuccino)",
                    "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                    "imageURL": "https://cappuccino_480x480.jpg"
                },
                {
                    "text": "カフェラテ(latte)",
                    "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                    "imageURL": "https://latte_480x480.jpg"
                },
                {
                    "text": "エスプレッソ(espresso)",
                    "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                    "imageURL": "https://espresso_480x480.jpg"
                }
            ]
        }
    }
}

おわりに

リソースとスタイルを使った文字装飾について記載しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.jsのgRPC Clientツール:grpc-caller

Node.jsがクライアントとしてgRPCのメソッドを呼び出したい場合は、
https://github.com/grpc/grpc-node
にてやり方を記載しておりますが、一番シンプルなClientのCallerとして、「grpc-caller」は便利だと思います。

「node-grpc-client」というツールも試しましたが、やはり「grpc-caller」ですね。

インストール

npm install grpc-caller

サンプル

const path = require('path')
const caller = require('grpc-caller')

const PROTO_PATH = path.resolve(__dirname, './protos/cassandra.proto')
const client = caller('localhost:50051', PROTO_PATH, 'Calendar')

client.getCalendar({ calendarId: '20191010abc' }, (err, res) => {
  console.log(res)
})

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsを仮想ウインドウ化するモジュールをnpmに登録してみる

Vue.jsを仮想ウインドウ化するモジュールをnpmに登録してみる

1.動作画面

動作画面

 
見ての通り、Vue.jsを仮想ウインドウ化してみました。
内容的には大したことはしていません。
以前作成したJavaScript-Window-Framework(JWF)にVueのコンポーネントをマウントする処理を入れただけです。

2.使い方

モジュールのインストール

npm -D i @jswf/vue

 npmでjwfスコープを取りたかったのですが、すでに取得済みだったようなのでjswfになっています。
 そのうちJWF本体をこちらのスコープに移すかもしれません。
 ちなみにnpmのスコープ登録の仕方を知ったのは最近になってからです。

サンプルコード

以下はrouterを有効にしたテンプレートに、必要なコードを追加したものです。

main.ts
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import { VueWindow } from '@jswf/vue';

Vue.config.productionTip = false;

new Vue({router, render: (h) => h(App)}).$mount('#app');

//---------------------
//Create Virtual Window
const win = new VueWindow(
  new Vue({router,render: h => h(App)})
);

win.setTitle('WindowTest');  //タイトル設定
win.setPos();               //位置を中心に揃える
//---------------------

3.まとめ

 JWF自体はウインドウ生成や子ウインドウの配置を主にしているフレームワークなので、クライアント領域に表示するコンテンツには干渉しない形になっています。そのためJWFに標準機能として付いているTreeViewやListViewは、かなり大きめのコードになっています。この状態で機能を追加しようと思ったら、自由はききますが、がっつりコードを書かなければなりません。今回はVue.jsを入れることによって、Vueのコンポーネントを簡単に持ってこられるようにしました。これでユーザからの入出力が頻繁に起こる部分の作成がかなり楽になると思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Alexa APL, 第12回 文字サイズ、文字色

はじめに

Alexaを搭載した画面付きデバイスの画面レイアウトを作成します。
今回は、文字サイズ、文字色などを使ったレイアウトを作成します。
対象とするコンポーネントは、AlexaHeaderとTextです。
スタイルを使ったレイアウトについては次回以降にします。

今回実施する内容

AlexaHeaderにはthemeを設定してみます。
Textに文字サイズや文字色などを設定して、画面レイアウトを作成します。

中型デバイス(Echo Show用)
中型デバイス13.jpg

環境

OS:Windows 10 JP
Alexaスキル言語:Node.js
Editor:Visual Studio Code
APLバージョン:1.0, 1.1

参考

Alexa ハローAPL、Alexaスキルの画面への対応
第1回のAlexa APLの記事です。タイトル通り、ハローAPLを表示させるだけのAPLです。

Alexa APL, 第5回 ヘッダーの追加
第5回のAlexa APLの記事です。AlexaHeaderの追加するAPLです。

APLドキュメント スタイル
AmazonのAPLドキュメントにあるスタイルの説明です。

APLドキュメント スタイルを設定可能なプロパティ
AmazonのAPLドキュメントにあるスタイルに設定内能なプロパティの説明です。

APLドキュメント theme
AmazonのAPLドキュメントにあるテーマの説明です。

用語

APL

Alexa Presentation Language
amazonの画面つきのAlexaの画面表示用の言語。
JSONを使用した記載方法です。
インターネットのホームページはHTMLとCSSで作成しますが、AlexaはAPLで作成するということです。

APLオーサリングツール

APL作成を視覚的に見ながらAPLのJSONファイルを作成するツール。
サンプルテンプレートも準備されており、その中から選択していくだけで、だいたいの画面は作成できる。

スタイル

文字色、文字サイズ、フォントや背景色などのプロパティを集めた集合のこと。CSSなどで使うスタイルと意味は同じです。

前提条件

前提条件はとくにないといえばないですが、本まとめを読むにあたり、以下がわかっていることが前提です。
・alexa developer consoleのアカウントがある
・Alexaスキルを開発したことがある
・JSONの記載方法を知っている
・「Alexa ハローAPL、Alexaスキルの画面への対応」、および「Alexa APL, 第5回 ヘッダーの追加」の記事をみている

今回使用するレイアウト

今回は、文字サイズや文字色などを変更して、その動きを確認します。
そのために基本となるレイアウトを以下の通り作成します。
「レイアウト画面」はこんな感じです。
レイアウト.jpg

  1. APLオーサリングツールを起動して「最初から作成」を選択する。
  2. APL JSONの画面を開いて、importに以下の値を設定して、AlexaHeaderを利用可能にする。

    APL
    ...
     "import": [
        {
            "name": "alexa-layouts",
            "version": "1.0.0"    <=途中で1.1.0に更新します。
        }
    ],
    ...
    
  3. 「レイアウト画面」の「mainTemplate」を選択し、「Container」を追加する。

  4. 「レイアウト画面」の「Container」を選択し、「ALexaHeader」を追加する。

  5. 「レイアウト画面」の「AlexaHeader」を選択し、「詳細設定画面」で、以下を設定する。

・ headerTitle:タイトル
・ headerSubtitle:サブタイトル
6. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
7. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].text}
8. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
9. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].detail}
・ paddingLeft:10vw
10. 8, 9を3回繰り返す。sampleArrayの配列部分は1~3に設定する。
※今回は文字サイズや文字色を試すために、あえて配列をSequenceではなく、Textの繰り返しで設定しました。

JSONデータの作成

以下の通り、JSONデータを作成する。

JSONデータ
{
    "sample": {
        "sampleArray": [
            {
                "text": "コーヒー(coffee)",
                "detail": "コーヒー(coffee)です。",
                "imageURL": "https://coffee_480x480.jpg"
            },
            {
                "text": "カプチーノ(cappuccino)",
                "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                "imageURL": "https://cappuccino_480x480.jpg"
            },
            {
                "text": "カフェラテ(latte)",
                "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                "imageURL": "https://latte_480x480.jpg"
            },
            {
                "text": "エスプレッソ(espresso)",
                "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                "imageURL": "https://espresso_480x480.jpg"
            }
        ]
    }
}

上記で作成した画面の確認

上記で作成した画面をみると、以下のようになります。
中型デバイス2.jpg

  • AlexaHeaderについて

    • タイトルとサブタイトルは、文字サイズが異なる。
    • タイトルはBoldされているよう。
    • 文字色はすべて白色。
    • フォントはすべてsans-serif系のフォント。
  • Textについて

    • 文字サイズはすべて同じ。
    • 文字色はすべて白色。
    • フォントはすべてsans-serif系のフォント。

ということで、

  • フォントサイズはデフォルト40dp。
  • 文字色は、Amazon APLのcolorによると、themedarkの場合#FAFAFAとなり、lightの場合#1E2222
  • フォントは、文字の表現によると、日本語は、Noto Sans CJK。まだこれ以外だサポートされていないようです。 sans-serif系のフォントになるようですね。

AlexaHeaderの文字色について

AlexaHeaderには文字色や文字サイズなどに関連するパラメーターが存在しません。
そのため、文字色や文字サイズを変更することができません。
色は変えられないのか?と思い、themeを変えてみることにします。

themedarkからwhite

APLのJSONの最初のほうにthemeがあります。
APLオーサリングツールを使って作成するとデフォルトでdarkが設定されています。
themeはAPLの画面の基本となる色などのセットであり、これを設定すると一律で文字色や背景が設定されます。
themeによると、

light: 明るい背景に暗いテキスト
dark: 暗い背景に明るいテキスト

ということで、APL JSONの画面を開いてthemeの"dark"をlightに変えます。
APLオーサリングツール上の画面は以下です。
中型デバイス3.jpg

実機のEcho Show 5の画面は以下です。
echo_show1.jpg

実家での確認をしようと試したところ、APLオーサリングツールと差があることがわかりました。
- APLオーサリングツールと実機のEcho Show 5の違い
- 背景色が白(APLオーサリングツール)と黒(Echo Show 5)の違い
なぜですかね。期待動作はAPLオーサリングツールの表示だと思うのですけどね。まだデバイスが対応していないのかな。

  • AlexaHeaderについて
    • タイトルとサブタイトルは、文字色は白色のまま。そのためAPLオーサリングツール上では、文字が見えません。
  • Textについて
    • 文字色はすべて黒色。そのためEcho show 5では、ほとんど文字が見えません。

いやいや、おかしいでしょと思い、次はAPL 1.1が導入され、alexa-layoutsパッケージも1.0.0から1.1.0に更新されて、AlexaHeaderにthemeプロパティが追加されたことに気づきましたので、このthemelightにしてみました。

一部だけAPLを記載しておくと、以下です。

APL
{
    "type": "APL",
    "version": "1.1",
    "settings": {},
    "theme": "light",    <=light
    "import": [
        {
            "name": "alexa-layouts",
            "version": "1.1.0"        <=1.1.0に更新
        }
    ],
...
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "items": [
            {
                "type": "Container",
                "items": [
                    {
                        "headerTitle": "タイトル",
                        "headerSubtitle": "サブタイトル",
                        "theme": "light",        <=lightを設定
                        "type": "AlexaHeader"
...

APLオーサリングツールでの結果は以下の通りです。
中型デバイス4.jpg

AlexaHeaderの文字は、きちんと黒色にかわり、背景色は白でも見えるようになりました。
ただし、タイトルはBoldされていたのですが、そうではなくなりました。
これは意図的なのかどうかわかりません。

実機のEcho Show 5で試したところ、同じように文字は黒色にかわりましたが、背景は黒色のままであり、ほとんど文字は読めませんでした(写真は割愛)。

AlexaHeader内にthemeを記載しなくても、APLの最初に設定しているthemeで変わってくれたほうがスマートなのではと思いました。
何か理由はありそうですけどね。
まだまだAPLはBeta版ですし発展途上といったところでしょうか。

Text関連のプロパティを設定してみる

Textに設定可能なスタイルのプロパティについて、スタイルを使わずに設定し、動作を確認します。
注:ここでは最初に作成したAPLから変更していきます。AlexaHeaderの説明で実施した変更は反映しません。

color

colorは文字色設定プロパティであり、設定方法は、以下があります。
に説明があります。

種類 説明
16進数 #xxyyzzのように記載する。xxはRGBの赤、yyはRGBの緑、zzはRGBの青を示す。#ffffffなら白色、#000000なら黒色。
関数 rgb、rgba、hsl、hslaの関数を記載する。rgbとrgbaはRGBと透明度αを設定する関数でrgba(white, 0)のように使います。hslとhslaは色合いと彩度と明度と透明度αを設定する関数で、hsl(0, 100%, 50%)のように使います。
シンボル HTML言語で定義済みの色名であり、blackやblueなどです。Color Names Supported by All Browsersに定義があります。

では、順に設定してみます。

Textの順番 プロパティ
1 color #ff0000
2 color rgba(green, 1)
3 color hsla(240, 1, 0.5, 1)
4 color green

APLオーサリングツール上での結果は以下です。
中型デバイス5.jpg
これは期待値通りです。

fontFamily

フォントを設定します。
デバイスによりインストール済みのフォントが異なることから、フォントは複数設定しておくことがガイドされています。
複数のフォントの中から、先頭から順番に利用可能なフォントを探し、見つかった場合そのフォントが使用されます。
また、最後には必ず「serif」、もしくは「sans-serif」を設定しておくようにガイドされています。この二つは必ずインストールされているフォントということになります。
利用可能なフォントはよくわからなかったため、APLドキュメントに記載のあるフォントを設定してみます。

Textの順番 プロパティ
1 fontFamily なし
2 fontFamily sans-serif
3 fontFamily なし
4 fontFamily Noto Sans CJK
5 fontFamily times new roman, times, georgia, serif
6 fontFamily serif

APLオーサリングツール上での結果は以下です。
中型デバイス6.jpg

すでに記載しましたが、- フォントは、文字の表現によると、日本語は、Noto Sans CJKになるとのことでした。

  • たしかに「設定なし」、「sans-serif」、「Noto Sans CJK」を設定した日本語の記載はそう見えます。
  • cappuccinoは、「Noto Sans CJK」のはずですが、serif体のようになりました。
  • 「latteです。」と記載した個所は、「serif」なのですが、sans-serif体のようになりました。 なんか変ですね。設定方法が誤っているのでしょうか? 変なので、実機Echo Show 5でも確認してみました。 echo_show2.jpg

その結果、すべてsans-serif系のフォントになりました。設定したフォントは無視されているのかもしれません。
日本語は、「Noto Sans CJK」しか利用できないことは記載されていましたので、これで正常な動作なのかなと思います。
APLオーサリングツール自体は、日本語環境かどうかまで判断できておらず、米国などでは他のフォントもサポートしているため、そのあたりで期待通りの動作にはならないのかなと思いました。

当面、日本語環境では、fontFamilyは設定しても仕方ないかなと思いました。進歩は早いのですぐにサポートされるかもしれないですけどね。

fontSize

フォントサイズはデフォルトは40dpです。
Amazon サイズには、デバイスとユーザの距離によって、文字サイズを設定するように記載がありますが、ここでの最少は24dpとなっています。
このことから、説明文は一律24dpに設定します。
中型デバイス7.jpg

期待通りですが、24dpより小さいのは確かに避けたほうがよさそうです。

fontWeight

フォントの太さを示しデフォルトはnormalです。
その他は、boldや100, 200といった100単位で900まであるようですが、フォントによりキーワードや数字は差があるようです。

Textの順番 プロパティ
1 fontWeight なし
2 fontWeight なし
3 fontWeight bold
4 fontWeight bold
5 fontWeight 600
6 fontWeight 600

APLオーサリングツール上での結果は以下です。
中型デバイス8.jpg

boldは効きましたが、数字は600で太さがかわるだけでした。
実機ではわからないですが、boldだけ使うのが無難なように思いました。

letterSpacing

文字と文字の間のスペースで、デフォルトは0です。
「dp」、「px」、「vw」、「vh」で設定できます。
レイアウト作成では、「px」は使わず、「dp」か「vw」がいいかなとは思いました。「vh」は垂直方向の比率なため予想がつきにくいですし。
基本0でいいのかなという感触です。

Textの順番 プロパティ
1 letterSpacing 10dp
2 fletterSpacing 10dp
3 fletterSpacing 5vw
4 fletterSpacing 5vw
5 fletterSpacing 5vh
6 fletterSpacing 5vh

APLオーサリングツール上での結果は以下です。
中型デバイス9.jpg

ligeHeight

行の高さで、デフォルトはフォントの1.25倍。
|Textの順番|プロパティ|値|
|:--------|:----------|:--|
|1|ligeHeight|1.25|
|2|ligeHeight|1.25|
|3|ligeHeight|1.5|
|4|ligeHeight|1.5|
APLオーサリングツール上での結果は以下です。
中型デバイス10.jpg

maxlines

表示する行数で、デフォルトは設定なし。
行数以上に文字列がある場合、「...」を表示してすべてでなく折り畳みがあることが示される。
タッチして折り畳みが展開されるわけではない。
|Textの順番|プロパティ|値|
|:--------|:----------|:--|
|1|maxlines|なし|
|2|maxlines|なし|
|3|maxlines|なし|
|4|maxlines|2|
|5|maxlines|なし|
|6|maxlines|2|
APLオーサリングツール上での結果は以下です。
中型デバイス11.jpg

カフェラテの説明が「スチーム」までで、「...」がありませんが、実機Echo Show 5では表示されました。

textAlign

Text内での文字の位置で、デフォルトはautoです。
auto、left、right、centerを設定できますが、autoはleftと今のところ同じです。

Textの順番 プロパティ
1 textAlign left
2 textAlign left
3 textAlign right
4 textAlign right
5 textAlign center
6 textAlign center

APLオーサリングツール上での結果は以下です。
中型デバイス12.jpg

textAlignVertical

Text内の垂直方向の文字列で、デフォルトはtopです。
auto、top、bottom、centerを設定できますが、autoはフォントにより変わるとのことですが、日本語ではtopのようです。
また、この設定は、Textをheightなどでコンポーネントのサイズを文字のサイズ以上にしないとほとんど効果ありません。

Textの順番 プロパティ
1 textAlignVertical bottom
2 textAlignVertical left
3 textAlignVertical right
4 textAlignVertical right
5 textAlignVertical center
6 textAlignVertical center

APLオーサリングツール上での結果は以下です。
中型デバイス13.jpg

1番目のは効果がほぼなし。
2番目はわかりづらいですが、垂直方向で中央。
3番目は垂直方向で下側になりました。

その他のHTMLのマークアップ

Textのtextに直接、HTMLのマークアップで文字装飾することができます。
Textコンポーネントは、ブロック要素であり、インライン要素ではないため、文字列内で装飾したいときは、基本的にはマークアップで対応するしかありません。

マークアップ 説明
<br> 改行。 次改行。
改行しました。
<strong>, <b> 太字。 太字
<em>, <i> 斜線。イタリック。 斜体
<strike> 取り消し線。 取り消し線
<u> 下線。
<tt>, <code> テキストを等幅にする。
<sup>, <sub> 上付き、下付き文字にする。

APLソースコード

出来上がったAPLのフルソースコードとデータJSONを載せます。実際にスキルで表示を試す場合は、Alexa ハローAPL、Alexaスキルの画面への対応を参考しに実施します。

APL
{
    "document": {
        "type": "APL",
        "version": "1.1",
        "settings": {},
        "theme": "dark",
        "import": [
            {
                "name": "alexa-layouts",
                "version": "1.0.0"
            }
        ],
        "resources": [],
        "styles": {},
        "onMount": [],
        "graphics": {},
        "commands": {},
        "layouts": {},
        "mainTemplate": {
            "parameters": [
                "payload"
            ],
            "items": [
                {
                    "type": "Container",
                    "items": [
                        {
                            "headerTitle": "タイトル",
                            "headerSubtitle": "サブタイトル",
                            "type": "AlexaHeader"
                        },
                        {
                            "type": "Text",
                            "textAlign": "left",
                            "textAlignVertical": "bottom",
                            "color": "#ff0000",
                            "text": "${payload.sample.sampleArray[0].text}",
                            "letterSpacing": "10dp",
                            "lineHeight": 1.25
                        },
                        {
                            "type": "Text",
                            "height": "10vw",
                            "paddingLeft": "10vw",
                            "textAlign": "left",
                            "textAlignVertical": "center",
                            "color": "rgba(green, 1)",
                            "fontFamily": "sans-serif",
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[0].detail}",
                            "letterSpacing": "10dp",
                            "lineHeight": 1.25
                        },
                        {
                            "type": "Text",
                            "height": "20vw",
                            "textAlign": "right",
                            "textAlignVertical": "bottom",
                            "color": "hsla(240, 1, 0.5, 1)",
                            "text": "${payload.sample.sampleArray[1].text}",
                            "fontWeight": "bold",
                            "letterSpacing": "5vw",
                            "lineHeight": 1.5
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "textAlign": "right",
                            "color": "green",
                            "fontFamily": "Noto Sans CJK",
                            "maxLines": 2,
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[1].detail}",
                            "fontWeight": "bold",
                            "letterSpacing": "5vw",
                            "lineHeight": 1.5
                        },
                        {
                            "type": "Text",
                            "textAlign": "center",
                            "fontFamily": "times new roman, times, georgia, serif",
                            "text": "${payload.sample.sampleArray[2].text}",
                            "fontWeight": "600",
                            "letterSpacing": "5vh"
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "textAlign": "center",
                            "fontFamily": "serif",
                            "maxLines": 2,
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[2].detail}",
                            "fontWeight": "600",
                            "letterSpacing": "5vh"
                        },
                        {
                            "type": "Text",
                            "text": "${payload.sample.sampleArray[3].text}"
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[3].detail}"
                        }
                    ]
                }
            ]
        }
    },
    "datasources": {
        "sample": {
            "sampleArray": [
                {
                    "text": "コーヒー(coffee)",
                    "detail": "コーヒー(coffee)です。",
                    "imageURL": "https://coffee_480x480.jpg"
                },
                {
                    "text": "カプチーノ(cappuccino)",
                    "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                    "imageURL": "https://cappuccino_480x480.jpg"
                },
                {
                    "text": "カフェラテ(latte)",
                    "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                    "imageURL": "https://latte_480x480.jpg"
                },
                {
                    "text": "エスプレッソ(espresso)",
                    "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                    "imageURL": "https://espresso_480x480.jpg"
                }
            ]
        }
    }
}

注意すべき動作

以下に注意が必要そうな動作を記載します。

  • AlexaHeaderは、APL v1.0では文字色は変更できない。
  • Alexaheaderは、APL v1.1にすれば、AlexaHeader内でthemeを設定すれば文字色を白色から黒色に変更できる。
  • APLの最初のthemeは、lightに変えても、現時点(2019/8)のEcho Show 5では背景色は白色にならない。
  • fontFamilyは、現時点ではNoto Sans CJKしか利用できない。
  • fontSizeの最少は、24dp程度までが好ましい。
  • fontWdightは、使いたい場合はboldを使用し、数値は使用しないほうがよい(数値によって効果がない数値がある)。
  • textAlignVerticalは、heightを設定して余白がある場合に有効。

おわりに

今回はTextの文字サイズ、文字色などについて動作を確認しました。
まだまだ開発中なのかなという部分もありましたので、「注意すべき動作」に記載したように、利用は注意いながらしたほうがいいかなと思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Alexa APL, 第12回 文字サイズ、文字色などの文字装飾

はじめに

Alexaを搭載した画面付きデバイスの画面レイアウトを作成します。
今回は、文字サイズ、文字色などの文字装飾を使ったレイアウトを作成します。
対象とするコンポーネントは、AlexaHeaderとTextです。
スタイルを使ったレイアウトについては次回以降にします。

今回実施する内容

AlexaHeaderにはthemeを設定してみます。
Textに文字サイズや文字色などの文字装飾を設定して、画面レイアウトを作成します。

中型デバイス(Echo Show用)
中型デバイス13.jpg

環境

OS:Windows 10 JP
Alexaスキル言語:Node.js
Editor:Visual Studio Code
APLバージョン:1.0, 1.1

参考

Alexa ハローAPL、Alexaスキルの画面への対応
第1回のAlexa APLの記事です。タイトル通り、ハローAPLを表示させるだけのAPLです。

Alexa APL, 第5回 ヘッダーの追加
第5回のAlexa APLの記事です。AlexaHeaderの追加するAPLです。

APLドキュメント スタイル
AmazonのAPLドキュメントにあるスタイルの説明です。

APLドキュメント スタイルを設定可能なプロパティ
AmazonのAPLドキュメントにあるスタイルに設定内能なプロパティの説明です。

APLドキュメント theme
AmazonのAPLドキュメントにあるテーマの説明です。

用語

APL

Alexa Presentation Language
amazonの画面つきのAlexaの画面表示用の言語。
JSONを使用した記載方法です。
インターネットのホームページはHTMLとCSSで作成しますが、AlexaはAPLで作成するということです。

APLオーサリングツール

APL作成を視覚的に見ながらAPLのJSONファイルを作成するツール。
サンプルテンプレートも準備されており、その中から選択していくだけで、だいたいの画面は作成できる。

スタイル

文字色、文字サイズ、フォントや背景色などのプロパティを集めた集合のこと。CSSなどで使うスタイルと意味は同じです。

前提条件

前提条件はとくにないといえばないですが、本まとめを読むにあたり、以下がわかっていることが前提です。
・alexa developer consoleのアカウントがある
・Alexaスキルを開発したことがある
・JSONの記載方法を知っている
・「Alexa ハローAPL、Alexaスキルの画面への対応」、および「Alexa APL, 第5回 ヘッダーの追加」の記事をみている

今回使用するレイアウト

今回は、文字サイズや文字色などを変更して、その動きを確認します。
そのために基本となるレイアウトを以下の通り作成します。
「レイアウト画面」はこんな感じです。
レイアウト.jpg

  1. APLオーサリングツールを起動して「最初から作成」を選択する。
  2. APL JSONの画面を開いて、importに以下の値を設定して、AlexaHeaderを利用可能にする。

    APL
    ...
     "import": [
        {
            "name": "alexa-layouts",
            "version": "1.0.0"    <=途中で1.1.0に更新します。
        }
    ],
    ...
    
  3. 「レイアウト画面」の「mainTemplate」を選択し、「Container」を追加する。

  4. 「レイアウト画面」の「Container」を選択し、「ALexaHeader」を追加する。

  5. 「レイアウト画面」の「AlexaHeader」を選択し、「詳細設定画面」で、以下を設定する。

・ headerTitle:タイトル
・ headerSubtitle:サブタイトル
6. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
7. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].text}
8. 「レイアウト画面」の「Container」を選択し、「Text」を追加する。
9. 「レイアウト画面」の上で作成した「Text」を選択し、「詳細設定画面」で、以下を設定する。

・ text:${payload.sample.sampleArray[0].detail}
・ paddingLeft:10vw
10. 8, 9を3回繰り返す。sampleArrayの配列部分は1~3に設定する。
※今回は文字サイズや文字色を試すために、あえて配列をSequenceではなく、Textの繰り返しで設定しました。

JSONデータの作成

以下の通り、JSONデータを作成する。

JSONデータ
{
    "sample": {
        "sampleArray": [
            {
                "text": "コーヒー(coffee)",
                "detail": "コーヒー(coffee)です。",
                "imageURL": "https://coffee_480x480.jpg"
            },
            {
                "text": "カプチーノ(cappuccino)",
                "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                "imageURL": "https://cappuccino_480x480.jpg"
            },
            {
                "text": "カフェラテ(latte)",
                "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                "imageURL": "https://latte_480x480.jpg"
            },
            {
                "text": "エスプレッソ(espresso)",
                "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                "imageURL": "https://espresso_480x480.jpg"
            }
        ]
    }
}

上記で作成した画面の確認

上記で作成した画面をみると、以下のようになります。
中型デバイス2.jpg

  • AlexaHeaderについて

    • タイトルとサブタイトルは、文字サイズが異なる。
    • タイトルはBoldされているよう。
    • 文字色はすべて白色。
    • フォントはすべてsans-serif系のフォント。
  • Textについて

    • 文字サイズはすべて同じ。
    • 文字色はすべて白色。
    • フォントはすべてsans-serif系のフォント。

ということで、

  • フォントサイズはデフォルト40dp。
  • 文字色は、Amazon APLのcolorによると、themedarkの場合#FAFAFAとなり、lightの場合#1E2222
  • フォントは、文字の表現によると、日本語は、Noto Sans CJK。まだこれ以外だサポートされていないようです。 sans-serif系のフォントになるようですね。

AlexaHeaderの文字色について

AlexaHeaderには文字色や文字サイズなどに関連するパラメーターが存在しません。
そのため、文字色や文字サイズを変更することができません。
色は変えられないのか?と思い、themeを変えてみることにします。

themedarkからlight

APLのJSONの最初のほうにthemeがあります。
APLオーサリングツールを使って作成するとデフォルトでdarkが設定されています。
themeはAPLの画面の基本となる色などのセットであり、これを設定すると一律で文字色や背景が設定されます。
themeによると、

light: 明るい背景に暗いテキスト
dark: 暗い背景に明るいテキスト

ということで、APL JSONの画面を開いてthemedarklightに変えます。
APLオーサリングツール上の画面は以下です。
中型デバイス3.jpg

実機のEcho Show 5の画面は以下です。
echo_show1.jpg

実家での確認をしようと試したところ、APLオーサリングツールと差があることがわかりました。
- APLオーサリングツールと実機のEcho Show 5の違い
- 背景色が白(APLオーサリングツール)と黒(Echo Show 5)の違い
なぜですかね。期待動作はAPLオーサリングツールの表示だと思うのですけどね。まだデバイスが対応していないのかな。

  • AlexaHeaderについて
    • タイトルとサブタイトルは、文字色は白色のまま。そのためAPLオーサリングツール上では、文字が見えません。
  • Textについて
    • 文字色はすべて黒色。そのためEcho show 5では、ほとんど文字が見えません。

いやいや、おかしいでしょと思い、次はAPL 1.1が導入され、alexa-layoutsパッケージも1.0.0から1.1.0に更新されて、AlexaHeaderにthemeプロパティが追加されたことに気づきましたので、このthemelightにしてみました。

一部だけAPLを記載しておくと、以下です。

APL
{
    "type": "APL",
    "version": "1.1",
    "settings": {},
    "theme": "light",    <=light
    "import": [
        {
            "name": "alexa-layouts",
            "version": "1.1.0"        <=1.1.0に更新
        }
    ],
...
    "mainTemplate": {
        "parameters": [
            "payload"
        ],
        "items": [
            {
                "type": "Container",
                "items": [
                    {
                        "headerTitle": "タイトル",
                        "headerSubtitle": "サブタイトル",
                        "theme": "light",        <=lightを設定
                        "type": "AlexaHeader"
...

APLオーサリングツールでの結果は以下の通りです。
中型デバイス4.jpg

AlexaHeaderの文字は、きちんと黒色にかわり、背景色は白でも見えるようになりました。
ただし、タイトルはBoldされていたのですが、そうではなくなりました。
これは意図的なのかどうかわかりません。
また、alexa-layoutsのバージョンを1.1.0に設定して小型デバイス(Echo Spot)で確認すると、文字が消えてしまいました。APLオーサリングツールはまだ完成していないのかもしれません。ベータ版ですから。

実機のEcho Show 5で試したところ、同じように文字は黒色にかわりましたが、背景は黒色のままであり、ほとんど文字は読めませんでした(写真は割愛)。

AlexaHeader内にthemeを記載しなくても、APLの最初に設定しているthemeで変わってくれたほうがスマートなのではと思いました。
何か理由はありそうですけどね。
まだまだAPLはBeta版ですし発展途上といったところでしょうか。

Text関連のプロパティを設定してみる

Textに設定可能なスタイルのプロパティについて、スタイルを使わずに設定し、動作を確認します。
注:ここでは最初に作成したAPLから変更していきます。AlexaHeaderの説明で実施した変更は反映しません。

color

colorは文字色設定プロパティであり、設定方法は、以下があります。
に説明があります。

種類 説明
16進数 #xxyyzzのように記載する。xxはRGBの赤、yyはRGBの緑、zzはRGBの青を示す。#ffffffなら白色、#000000なら黒色。
関数 rgb、rgba、hsl、hslaの関数を記載する。rgbとrgbaはRGBと透明度αを設定する関数でrgba(white, 0)のように使います。hslとhslaは色合いと彩度と明度と透明度αを設定する関数で、hsl(0, 100%, 50%)のように使います。
シンボル HTML言語で定義済みの色名であり、blackやblueなどです。Color Names Supported by All Browsersに定義があります。

では、順に設定してみます。

Textの順番 プロパティ
1 color #ff0000
2 color rgba(green, 1)
3 color hsla(240, 1, 0.5, 1)
4 color green

APLオーサリングツール上での結果は以下です。
中型デバイス5.jpg
これは期待値通りです。

fontFamily

フォントを設定します。
デバイスによりインストール済みのフォントが異なることから、フォントは複数設定しておくことがガイドされています。
複数のフォントの中から、先頭から順番に利用可能なフォントを探し、見つかった場合そのフォントが使用されます。
また、最後には必ず「serif」、もしくは「sans-serif」を設定しておくようにガイドされています。この二つは必ずインストールされているフォントということになります。
利用可能なフォントはよくわからなかったため、APLドキュメントに記載のあるフォントを設定してみます。

Textの順番 プロパティ
1 fontFamily なし
2 fontFamily sans-serif
3 fontFamily なし
4 fontFamily Noto Sans CJK
5 fontFamily times new roman, times, georgia, serif
6 fontFamily serif

APLオーサリングツール上での結果は以下です。
中型デバイス6.jpg

すでに記載しましたが、- フォントは、文字の表現によると、日本語は、Noto Sans CJKになるとのことでした。

  • たしかに「設定なし」、「sans-serif」、「Noto Sans CJK」を設定した日本語の記載はそう見えます。
  • cappuccinoは、「Noto Sans CJK」のはずですが、serif体のようになりました。
  • 「latteです。」と記載した個所は、「serif」なのですが、sans-serif体のようになりました。 なんか変ですね。設定方法が誤っているのでしょうか? 変なので、実機Echo Show 5でも確認してみました。 echo_show2.jpg

その結果、すべてsans-serif系のフォントになりました。設定したフォントは無視されているのかもしれません。
日本語は、「Noto Sans CJK」しか利用できないことは記載されていましたので、これで正常な動作なのかなと思います。
APLオーサリングツール自体は、日本語環境かどうかまで判断できておらず、米国などでは他のフォントもサポートしているため、そのあたりで期待通りの動作にはならないのかなと思いました。

当面、日本語環境では、fontFamilyは設定しても仕方ないかなと思いました。進歩は早いのですぐにサポートされるかもしれないですけどね。

fontSize

フォントサイズはデフォルトは40dpです。
Amazon サイズには、デバイスとユーザの距離によって、文字サイズを設定するように記載がありますが、ここでの最少は24dpとなっています。
このことから、説明文は一律24dpに設定します。
中型デバイス7.jpg

期待通りですが、24dpより小さいのは確かに避けたほうがよさそうです。

fontWeight

フォントの太さを示しデフォルトはnormalです。
その他は、boldや100, 200といった100単位で900まであるようですが、フォントによりキーワードや数字は差があるようです。

Textの順番 プロパティ
1 fontWeight なし
2 fontWeight なし
3 fontWeight bold
4 fontWeight bold
5 fontWeight 600
6 fontWeight 600

APLオーサリングツール上での結果は以下です。
中型デバイス8.jpg

boldは効きましたが、数字は600で太さがかわるだけでした。
実機ではわからないですが、boldだけ使うのが無難なように思いました。

letterSpacing

文字と文字の間のスペースで、デフォルトは0です。
「dp」、「px」、「vw」、「vh」で設定できます。
レイアウト作成では、「px」は使わず、「dp」か「vw」がいいかなとは思いました。「vh」は垂直方向の比率なため予想がつきにくいですし。
基本0でいいのかなという感触です。

Textの順番 プロパティ
1 letterSpacing 10dp
2 fletterSpacing 10dp
3 fletterSpacing 5vw
4 fletterSpacing 5vw
5 fletterSpacing 5vh
6 fletterSpacing 5vh

APLオーサリングツール上での結果は以下です。
中型デバイス9.jpg

ligeHeight

行の高さで、デフォルトはフォントの1.25倍。

Textの順番 プロパティ
1 ligeHeight 1.25
2 ligeHeight 1.25
3 ligeHeight 1.5
4 ligeHeight 1.5

APLオーサリングツール上での結果は以下です。
中型デバイス10.jpg

maxlines

表示する行数で、デフォルトは設定なし。
行数以上に文字列がある場合、「...」を表示してすべてでなく折り畳みがあることが示される。
タッチして折り畳みが展開されるわけではない。
|Textの順番|プロパティ|値|
|:--------|:----------|:--|
|1|maxlines|なし|
|2|maxlines|なし|
|3|maxlines|なし|
|4|maxlines|2|
|5|maxlines|なし|
|6|maxlines|2|
APLオーサリングツール上での結果は以下です。
中型デバイス11.jpg

カフェラテの説明が「スチーム」までで、「...」がありませんが、実機Echo Show 5では表示されました。

textAlign

Text内での文字の位置で、デフォルトはautoです。
auto、left、right、centerを設定できますが、autoはleftと今のところ同じです。

Textの順番 プロパティ
1 textAlign left
2 textAlign left
3 textAlign right
4 textAlign right
5 textAlign center
6 textAlign center

APLオーサリングツール上での結果は以下です。
中型デバイス12.jpg

textAlignVertical

Text内の垂直方向の文字列で、デフォルトはtopです。
auto、top、bottom、centerを設定できますが、autoはフォントにより変わるとのことですが、日本語ではtopのようです。
また、この設定は、Textをheightなどでコンポーネントのサイズを文字のサイズ以上にしないとほとんど効果ありません。

Textの順番 プロパティ
1 textAlignVertical bottom
2 textAlignVertical left
3 textAlignVertical right
4 textAlignVertical right
5 textAlignVertical center
6 textAlignVertical center

APLオーサリングツール上での結果は以下です。
中型デバイス13.jpg

1番目のは効果がほぼなし。
2番目はわかりづらいですが、垂直方向で中央。
3番目は垂直方向で下側になりました。

その他のHTMLのマークアップ

Textのtextに直接、HTMLのマークアップで文字装飾することができます。
Textコンポーネントは、ブロック要素であり、インライン要素ではないため、文字列内で装飾したいときは、基本的にはマークアップで対応するしかありません。

マークアップ 説明
<br> 改行。 次改行。
改行しました。
<strong>, <b> 太字。 太字
<em>, <i> 斜線。イタリック。 斜体
<strike> 取り消し線。 取り消し線
<u> 下線。
<tt>, <code> テキストを等幅にする。
<sup>, <sub> 上付き、下付き文字にする。

APLソースコード

出来上がったAPLのフルソースコードとデータJSONを載せます。実際にスキルで表示を試す場合は、Alexa ハローAPL、Alexaスキルの画面への対応を参考しに実施します。

APL
{
    "document": {
        "type": "APL",
        "version": "1.1",
        "settings": {},
        "theme": "dark",
        "import": [
            {
                "name": "alexa-layouts",
                "version": "1.0.0"
            }
        ],
        "resources": [],
        "styles": {},
        "onMount": [],
        "graphics": {},
        "commands": {},
        "layouts": {},
        "mainTemplate": {
            "parameters": [
                "payload"
            ],
            "items": [
                {
                    "type": "Container",
                    "items": [
                        {
                            "headerTitle": "タイトル",
                            "headerSubtitle": "サブタイトル",
                            "type": "AlexaHeader"
                        },
                        {
                            "type": "Text",
                            "textAlign": "left",
                            "textAlignVertical": "bottom",
                            "color": "#ff0000",
                            "text": "${payload.sample.sampleArray[0].text}",
                            "letterSpacing": "10dp",
                            "lineHeight": 1.25
                        },
                        {
                            "type": "Text",
                            "height": "10vw",
                            "paddingLeft": "10vw",
                            "textAlign": "left",
                            "textAlignVertical": "center",
                            "color": "rgba(green, 1)",
                            "fontFamily": "sans-serif",
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[0].detail}",
                            "letterSpacing": "10dp",
                            "lineHeight": 1.25
                        },
                        {
                            "type": "Text",
                            "height": "20vw",
                            "textAlign": "right",
                            "textAlignVertical": "bottom",
                            "color": "hsla(240, 1, 0.5, 1)",
                            "text": "${payload.sample.sampleArray[1].text}",
                            "fontWeight": "bold",
                            "letterSpacing": "5vw",
                            "lineHeight": 1.5
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "textAlign": "right",
                            "color": "green",
                            "fontFamily": "Noto Sans CJK",
                            "maxLines": 2,
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[1].detail}",
                            "fontWeight": "bold",
                            "letterSpacing": "5vw",
                            "lineHeight": 1.5
                        },
                        {
                            "type": "Text",
                            "textAlign": "center",
                            "fontFamily": "times new roman, times, georgia, serif",
                            "text": "${payload.sample.sampleArray[2].text}",
                            "fontWeight": "600",
                            "letterSpacing": "5vh"
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "textAlign": "center",
                            "fontFamily": "serif",
                            "maxLines": 2,
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[2].detail}",
                            "fontWeight": "600",
                            "letterSpacing": "5vh"
                        },
                        {
                            "type": "Text",
                            "text": "${payload.sample.sampleArray[3].text}"
                        },
                        {
                            "type": "Text",
                            "paddingLeft": "10vw",
                            "fontSize": "24dp",
                            "text": "${payload.sample.sampleArray[3].detail}"
                        }
                    ]
                }
            ]
        }
    },
    "datasources": {
        "sample": {
            "sampleArray": [
                {
                    "text": "コーヒー(coffee)",
                    "detail": "コーヒー(coffee)です。",
                    "imageURL": "https://coffee_480x480.jpg"
                },
                {
                    "text": "カプチーノ(cappuccino)",
                    "detail": "カプチーノ(cappuccino)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?",
                    "imageURL": "https://cappuccino_480x480.jpg"
                },
                {
                    "text": "カフェラテ(latte)",
                    "detail": "カフェラテ(latte)です。<br>ミルク入りのコーヒーです。スチームミルク入りが一般的?<br>カプチーノとはミルクの量が違う?",
                    "imageURL": "https://latte_480x480.jpg"
                },
                {
                    "text": "エスプレッソ(espresso)",
                    "detail": "エスプレッソ(espresso)です。<br>加圧して抽出したもので、コーヒーよりもかなり濃いです。",
                    "imageURL": "https://espresso_480x480.jpg"
                }
            ]
        }
    }
}

注意すべき動作

以下に注意が必要そうな動作を記載します。

  • AlexaHeaderは、APL v1.0では文字色は変更できない。
  • Alexaheaderは、APL v1.1にすれば、AlexaHeader内でthemeを設定すれば文字色を白色から黒色に変更できる。
  • APLの最初のthemeは、lightに変えても、現時点(2019/8)のEcho Show 5では背景色は白色にならない。
  • fontFamilyは、現時点ではNoto Sans CJKしか利用できない。
  • fontSizeの最少は、24dp程度までが好ましい。
  • fontWdightは、使いたい場合はboldを使用し、数値は使用しないほうがよい(数値によって効果がない数値がある)。
  • textAlignVerticalは、heightを設定して余白がある場合に有効。

おわりに

今回はTextの文字サイズ、文字色などについて動作を確認しました。
まだまだ開発中なのかなという部分もありましたので、「注意すべき動作」に記載したように、利用は注意いながらしたほうがいいかなと思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む