Amazon Echo のニューススキルを利用して自分で運営しているブログのRSSを配信する方法をお伝えします。 当ブログはURL末尾に”/feed”を付け加えるとRSSが確認できます。 https://xp-cloud.jp/blog/feed
使用するサービスや用意する物は下記のものです。 サービス ・ASK(Alexa Skill Kit)のフラッシュブリーフィングスキル ・AWS(API Gateway) ・AWS(Lambda(Node.js))
用意する物 ・AndroidかiPhone系のスマートホン ・Node.jsが実行できる環境
データフローは次のようになります。
AlexaはニュースのあるURLへアクセスすることしかできないため、直接Lambdaを呼ぶことはできません。 API Gatewayを挟むことによってURLを生成し、AlexaからLambdaを呼べるようにします。
当記事では前編としてAPI Gateway〜AWS Lambda〜RSSの部分を実装してみます。 Echo〜Alexa〜API Gatewayの部分は後半の記事で記載していきます。
AWS LambdaからRSSを読み込む
アレクサのスキル用に新しいLambda関数を作成し、RSSを読み込む処理を作っていきます。 AWSの管理コンソールからLambdaを開いてください “関数の作成”を押して新しいLambda関数を作成していきます。
“名前”を入力し、”ロール”は”カスタムロール”を選択します。 “既存のロールを選択”にしても大丈夫ですが、後々、スキル単位でメンテナンスすることを考えると、Lambda毎にロールを用意した方が都合が良いです。
ロールを作成する画面が開きますので、 “IAMロール”は”新しいIAMロールの作成” “ロール名”は任意の名前を指定して”許可”を押します。
名前を入力した画面に戻って来ますので”関数の作成”を押します。
ローカルPCでソースコードを編集する必要があるため、適当なフォルダを作成してください。 作成したフォルダにWindowsならコマンドプロンプト、MACならterminalで移動してください。 コマンド
cd <作成したフォルダのパス>
RSSを読み込むために”cheerio-httpcli”を使用します。 https://www.npmjs.com/package/cheerio-httpcli
コマンドプロンプトかterminalでコマンドを実行し、”cheerio-httpcli”をインストールします
npm install cheerio-httpcli
“node_modules”というフォルダができました。 “index.js”を新規作成し、下記コードを貼り付けてください。
'use strict'; const client = require('cheerio-httpcli'); let event; let context; let callback; exports.handler = (_event, _context, _callback) => { event = _event; context = _context; callback = _callback; // "cheerio-httpcli"を使いRSSを取得 client.fetch('https://xp-cloud.jp/blog/feed/', {}, 'utf-8', searchRss); }; let searchRss = function (err, $, res, body) { // 日付をechoが認識できる形式に整形 var nowTime = new Date(); var time = nowTime.getFullYear() + '-'; time += ("0" + (nowTime.getMonth() + 1)).slice(-2) + '-'; time += ("0" + nowTime.getDate()).slice(-2) + 'T'; time += ("0" + nowTime.getHours()).slice(-2) + ':'; time += ("0" + nowTime.getMinutes()).slice(-2) + ':'; time += ("0" + nowTime.getSeconds()).slice(-2) + '.0Z'; try { // RSSのアイテムを1つづつ読み込んで整形 var resultList = []; $('item').each(function(i, elem) { // タイトル取得 var title = $(elem).find('title').text(); // 説明文を取得 var description = $(elem).find('description').text().trim().replace(/\n/g, '').replace(/\r/g, '').replace(/\t/g, ''); resultList.push({ "uid": title, "updateDate": time, "titleText": title, "mainText": description }); if (resultList.length == 5) { return false; } }); //アイテムが取れていた場合だけ正常終了 if (resultList.length > 0) { callback(null, resultList); return; } } catch(e) { } callback(null, { "uid": time, "updateDate": time, "titleText": 'エラー', "mainText": 'ニュースが読み取れませんでした。' }); };
フォルダ構成は下記のようになっていると思います。 新しいフォルダ ┝ index.js └ node_modules
“index.js”と”node_modules”を選択し、zipに圧縮します。 新しいフォルダごとは圧縮しないでください。Lambdaで読めなくなります。
管理コンソールからLambdaを開き、先ほどのzipファイルをアップロードします。
“テスト”を押して実行してましょう
Lambdaへ渡す引数を聞かれますが、引数は使わないので適当に入力してください。
“テスト”を押して実行してみましょう
“詳細”を押して結果を見てみましょう。 もし実行結果が”異常”になっていたら、どこかで落ちています。 Lambdaの更新が遅れている場合は1分後くらいに再度テストすると上手くいくことがあります。
API GatewayからLambdaを呼ぶようにしましょう
AWSの管理コンソールからAPI Gatewayを開きます。 “APIの作成”を押してAPIを作成していきます。
“新しいAPI”を選択、”API名”に適当な名前を指定し、”APIの作成”を押します。 “API名”は公開される情報ではないため、好きな分かりやすい名前でOKです。
後にURLが発行されるAPIが作られますので、HTTP GETリクエストで動作できるようにGETメソッドを作成します。 “アクション” > “メソッドの作成” を選択
“統合タイプ”は"Lambda関数" “Lambdaリージョン”はLambdaを作成したリージョン “Lambda関数”は先ほど作成したLambdaの名前を指定して”保存”。 Lambda関数はスペースを入力すると関数の候補が表示されるため、そこから選択しても大丈夫です。
権限を追加する必要があるため”OK”を選択
これでおおよそ出来上がりですが、日本語を扱う場合、レスポンスヘッダーを変更する必要があります。 “メソッドレスポンス”を選択します
“HTTPのステータス 200”を編集します。この”200”とは正常終了した場合に返されるレスポンスのことです。
“コンテンツタイプ”を”application/json;charset=UTF-8"に変更します
設定が終わったのでURLを生成するため”APIのデプロイ”を行います。
“デプロイされるステージ”は”新しいステージ”を選択、 “ステージ名”はURLに使われるため、後でAlexaに設定することになります。 “デプロイ”をクリックしてデプロイ完了です。
生成されたURLを開くと、先ほどLambdaで返って来たようなレスポンスが確認できます。
次回はいよいよEchoから作成したAPI Gatewayを呼び出して完成させてみます。