--> -->
#blog2navi() *Google検索するalexaスキルを作成して実機で使う [#wc11c3d7] Amazon Echoは時間を測ってくれたり、家電を制御してくれたり、電気を点灯/消灯してくれたりそれなりに便利なのですが、調べたいことを聞いてもなかなか教えてくれない(汎用的な検索はしてくれない)のが不満でした。~ ~ そこで「無ければ作ればいいじゃないの」の精神に則って、作ってみました。~ ** 必要なもの [#pd94e135] 1. alexa自作スキル~ https://techblog.kayac.com/lets-make-alexa-skill-2017 ~ ~ 2. Google Custom Search APIの設定~ https://qiita.com/megu_ma/items/8cad39f61e35588e5476 ~ http://ryutamaki.hatenablog.com/entry/2014/01/18/171640 ~ ~ 先人達のとっても有用な情報があるので、それぞれ上記参考URLを参照してください。~ ** Google Custom Search APIの検索URL [#u8d39aad] 検索URLは以下の形式となります。 https://www.googleapis.com/customsearch/v1?key={API KEY}&cx={SEARCH ENGINE ID}={検索文字列} {API KEY}、{SEARCH ENGINE ID}は上記参考URL中に取り出し方法が書いてあります。~ 検索文字列はurlencode()が必要です。~ ~ そして実際に書いたalexaスキルコードは以下の通り。 #code(php){{ 'use strict'; var Alexa = require('alexa-sdk'); //========================================================================================================================================= //TODO: このコメント行より下の項目に注目してください。 //========================================================================================================================================= //Replace with your app ID (OPTIONAL). You can find this value at the top of your skill's page on http://developer.amazon.com. //Make sure to enclose your value in quotes, like this: var APP_ID = "amzn1.ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1"; var APP_ID = undefined; //========================================================================================================================================= //「TODO: ここから下のデータを自分用にカスタマイズしてください。」 //========================================================================================================================================= const languageStrings = { "ja": { // 今回は日本語のみ対応します。 translation: { HELP_MESSAGE: "このスキルは、グーグル検索をするスキルです。", HELP_REPROMPT: "何を検索しますか?", STOP_MESSAGE: "スキルを終了します。", }, }, }; //========================================================================================================================================= //この行から下のコードに変更を加えると、スキルが動作しなくなるかもしれません。わかる人のみ変更を加えてください。 //========================================================================================================================================= exports.handler = function(event, context, callback) { var alexa = Alexa.handler(event, context); alexa.APP_ID = APP_ID; alexa.registerHandlers(handlers); alexa.execute(); }; var handlers = { 'LaunchRequest': function () { this.emit('GoogleSearchIntent'); }, 'AMAZON.HelpIntent': function () { var speechOutput = this.t('HELP_MESSAGE'); var reprompt = this.t('HELP_REPROMPT'); this.emit(':ask', speechOutput, reprompt); }, 'AMAZON.CancelIntent': function () { this.emit(':tell', this.t('STOP_MESSAGE')); }, 'AMAZON.StopIntent': function () { this.emit(':tell', this.t('STOP_MESSAGE')); }, // 検索の処理 "GoogleSearchIntent": function() { let word=''; if( typeof( this.event.request.intent.slots ) == 'undefined') { word='slotsがありません'; } else if( typeof( this.event.request.intent ) == 'undefined') { word='intentがありません'; } else if( typeof( this.event.request ) == 'undefined') { word='requestがありません'; } else if( typeof( this.event ) == 'undefined') { word='eventがありません'; } else if( typeof( this ) == 'undefined') { word='thisがありません'; } else { let slots = this.event.request.intent.slots; for( var key in slots) { if( slots.hasOwnProperty(key) ) { if ( ""+slots[key].value != 'undefined' ){ word = "" + slots[key].value; } } } } if( word.length==0 ){ word = '検索対象が不明です'; const speechOutput = this.t(word); this.emit(":tell", speechOutput); } else { // const speechOutput = this.t(word); // this.emit(":tell", speechOutput); getJson(this, word); } } }; exports.handler = function (event, context) { const alexa = Alexa.handler(event, context); alexa.resources = languageStrings; // 言語を設定 alexa.registerHandlers(handlers); // ハンドラの登録 alexa.execute(); // 実行 }; function getJson(obj, word) { let result = '何も得られませんでした'; let https = require('https'); const URL = 'https://www.googleapis.com/customsearch/v1?key={API KEY}&cx={SEARCH ENGINE ID}&q=' + encodeURIComponent(word); https.get(URL, (res) => { let body = ''; res.setEncoding('utf8'); res.on('data', (chunk) => { body += chunk; }); res.on('end', (res) => { res = JSON.parse(body); result = res['items'][0]['snippet']; const speechOutput = obj.t(word+'についてお答えします。'+result); obj.emit(":tell", speechOutput); }); }).on('error', (e) => { //エラー時 result = 'JSONを取得できませんでした'; const speechOutput = obj.t(result); obj.emit(":tell", speechOutput); }); } }} 上記の例では、google検索の最初の結果の「snippet」項目に入っている文言を読み上げます。 ** 実機向けベータテストの設定 [#g7e096ea] 実機でテストするには、このスキルをベータテスト公開しなければなりません。~ 尤も、このスキルを本公開することは''事実上できません''。それは以下を見れば明白です。~ ~ ■Custom Search JSON API~ https://developers.google.com/custom-search/json-api/v1/overview?hl=ja ~ #ref(googl_price.png);~ 1日あたり100検索まで無料、以降1,000検索毎に$5かかります。公開したら破産します・・・。~ &size(9){(実際は無料枠を使い切ってあとはエラーだと思います)};~ ~ 同様にAWSも一定のCPU使用時間やアクセス回数を超えると有料です。~ 大人しく開発用スキルとして個人的に使用しましょう。~ ~ さて、話が逸れましたが、ベータテスト公開です。~ ~ 1. Alexaコンソールの公開タブの入力 「*」の付いている必須項目を埋めます。~ 審査も公開も無いので、適当で構いません。 #ref(e1.png);~ #ref(e2.png);~ #ref(e3.png);~ ~ 2. ベータテストをクリック~ ベータテストできる状態か自動チェックが走り、メールアドレスの入力欄が出ればOKです。~ ~ 3. 招待URLをalexaアプリで開く~ スマホにURLを送って開くと、alexaアプリでスキルを開けます。~ アプリ上でスキルを有効にすれば使用できます。~ ~ 後は、「エコー、グーグルで○○を検索して」とか言えば検索結果を喋ってくれます。~ 意外と役に立たないことが分かり、思わず苦笑いすること間違い無しです(苦笑); #htmlinsert(twitterbutton.html) RIGHT:Category: [[[alexa>日記/Category/alexa]]] - 21:33:05 ---- RIGHT:&blog2trackback(); #comment(above) #blog2navi()