フラッシュニュース向けのAlexa Skillを作る

# フラッシュブリーフィングスキルとは

Alexa Skillには対話形式のスキル以外にも幾つかの種類のスキルがあります。フラッシュブリーフィングスキルは設定＞フラッシュニュースに追加できるニュースのスキルです。会話の応答のような対話はできず一方的に音声を流すだけですが、フラッシュニュースに追加すると

> 最新のニュースを流して

などと話しかけるだけでNHKラジオニュースや天気予報と一緒に音声情報を流すことができます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3324/da509c8b-2baa-d60f-2f68-9ba2fac8326b.png" width="50%">

# スキルの作り方

[Amazon Alexa のDeveloperサイト](https://developer.amazon.com/ja/alexa) でAlexaスキルを作成する時に `フラッシュブリーフィングスキルAPI` を選びます。

<img width="768" alt="スクリーンショット 2018-02-10 14.42.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/3324/a829ff32-e2cf-6859-3124-ba25d23cb4f9.png">

各選択肢については [スキルの種類について]
(https://developer.amazon.com/ja/docs/ask-overviews/understanding-the-different-types-of-skills.html) を確認してください。

フラッシュブリーフィングAPIを使用する場合は対話モデルは既に定義されており設定はできません。

<img width="1015" alt="スクリーンショット 2018-02-10 17.54.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/3324/feda6002-9c38-9d0d-cc69-5edfbf034781.png">

## フラッシュブリーフィングフィードの設定

ニュースとして流す音声はRSSフィードから読み込みます。「新しいフィードの追加」でフィード情報を追加します。つまりフィードは複数追加できるようです。なお、`カスタムエラーメッセージ` はフィードの取得に失敗した場合などに応答するメッセージです。

<img width="1059" alt="スクリーンショット 2018-02-10 17.54.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/3324/5fccabb3-a100-279d-8e4e-89ae14ca9b54.png">

### フィードの追加

最も重要なフィードの情報をここで設定します。 `URL` は参照先がフィードとして正しく読み取れないとエラーとなって保存できないので、必ず正しいフィードが返ってくるURLを指定してください。詳細なフィードの内容については後述します。

<img width="812" alt="スクリーンショット 2018-02-10 17.54.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/3324/91c02807-c4d9-b044-3ff4-baeb01d99038.png">

各項目の内容は以下の通りです。

| 項目名       | 設定する内容  |
|:-----------------|:------------------|
| プリアンプル             | ニュースの前に流れるメッセージ |
| フィード名           | Alexaアプリに表示される名称 |
| コンテンツの更新頻度             | "1時間ごと/毎日/毎週" から選択 |
| コンテンツタイプ               |  テキストの場合はフィードの内容をAlexaが読み上げる/オーディオの場合はファイルを再生  |
| コンテンツジャンル | ニュースの内容に合わせて適宜選択 |
| URL | フィードのURLを指定（詳細は後述） |
| フィードアイコン | Alexaアプリに表示される512x512pxのアイコン |

## ニュースとして流すフィードの内容の準備

フィードとして指定できるのはXMLまたはJSON型式となります。詳細は以下のリファレンスを参照ください。

[フラッシュブリーフィングスキルAPIフィードのリファレンス](https://developer.amazon.com/ja/docs/flashbriefing/flash-briefing-skill-api-feed-reference.html)

例えば、はてなブログに公開している [私のブログ](http://radiocat.hatenablog.com/) の場合はブログURLに `/rss` を付けると [RSSフィードを取得できる](http://radiocat.hatenablog.com/rss) ためこれを指定できます。しかし、XML型式のRSSフィードの場合、Alexaが読み上げるのは `<description>` の内容で、フラッシュブリーフィングスキルAPIの仕様は

> SSML、HTML、XMLのタグなどの特殊文字を含まない、プレーンテキストであること。

となっています。これを満たせば問題ありませんが、Alexaに読み上げてもらう内容を制御したい場合は、RSSフィードをいったんプログラムで取得したうえでAlexaに読み上げさせたい内容に加工してもう１つの対応型式であるJSON型式で生成してやるのが1つの案となります。

例えば、以下のようにしてNode.js+FeedParserを使ってRSSフィードを取得してJSON形式に変換すればブログタイトルをAlexaに読み上げさせることができます。

```javascript
http.get(BLOG_RSS_URL, function(res) {
  res.pipe(new FeedParser({}))
    // 省略
    .on('readable', function() {
      var stream = this, item;

      while (item = stream.read()) {
        feedData.push(
          {
            "uid": item.guid,
            "updateDate": item.pubDate,
            "titleText": item.title,
            "mainText": item.title,
            "redirectionUrl": item.link
          }
        );
      }
    })
    // 省略
});
```

上記リファレンスによるとJSON型式の各属性はそれぞれXML型式の以下の属性に対応します。Alexaが読み取るのは `mainText` となります。最大4,500文字までが読み上げられます。

```javascript
{
  "uid": <guid>,
  "updateDate": <pubDate>,
  "titleText": <title>,
  "mainText": <description>,
  "redirectionUrl": <link>
}
```

複数の場合は上記を配列にします。 `updateDate` が新しい順に最大5件が読み上げられます。

なお、 オーディオファイルを再生させたい場合は `streamUrl` を追加しオーディオファイルのURLを設定することで指定したファイルが再生されるようです。

# フラッシュニュースの動作確認

フィードを準備して無事追加できたら、あとはSkillに関する説明やアイコンなどの情報を登録するとSkillとして公開できる状態になります。試しに会社の開発者ブログのフィードを登録してみました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3324/fa3add80-9778-78f2-4879-933b42dfc79f.png" width="50%">

開発者のアカウントからは設定するとすぐ使える状態になります。厚かましくもそうそうたるニュースコンテンツより前に聴けるようにもできます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/3324/fd0feb04-aa0a-7ed6-988f-a7d308aa4003.png" width="50%" >

# おわりに

以上の流れで動作確認ができたらSkillを申請し、承認されると一般に公開されます。作ってみるとRSSフィードをそのまま登録するだけなら数分程度で作成できますが、使いやすさを考えると今回のようにAlexaに読んでもらいたい内容を生成するようなJSON型式に変換するプログラムを介してやるのが良さそうです。なお、今回試したSkillは現在申請中なので承認の過程で何かあれば後ほど追記します。