--> -->

skimemo


skimemo - 日記/2018-06-16/Google検索するalexaスキルを作成して実機で使う のバックアップ差分(No.2)


  • 追加された行はこの色です。
  • 削除された行はこの色です。
#blog2navi()
*Google検索するalexaスキルを作成して実機で使う [#wc11c3d7]

Amazon Echoは時間を測ってくれたり、家電を制御してくれたり、電気を点灯/消灯してくれたりそれなりに便利なのですが、調べたいことを聞いてもなかなか教えてくれない(汎用的な検索はしてくれない)のが不満でした。~
~
そこで「無ければ作ればいいじゃないの」の精神に則って、作ってみました。~
** 必要なもの [#pd94e135]
1. alexa自作スキル~
https://techblog.kayac.com/lets-make-alexa-skill-2017 ~
~
* 必要なもの [#pd94e135]
** alexa自作スキル [#nfcbcdbf]
** Google Custom Search APIの設定 [#eafa2e80]
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()