ESP32とAWSIoTとAlexaを繋げてみた(AlexaとDynamoDB編)

#AlexaとDynamoDBを繋ごう
AlexaとDynamoDBを繋ぐためには
Alexa skillからLmabda関数を呼び起こし
Lambda関数からDynamoDB上のデータを取得します

#Alexaのスキルを作ろう
登録の方法などは省略します`スキル一覧＞スキル`の作成を選択します
名前は適当に決めましょう次にスキルのテンプレートを選択しますがカスタムとします
開発画面に入りました！
<img width="1243" alt="スクリーンショット 2018-05-01 18.19.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/d3ba6c3f-3a9a-6be1-623c-e7d520bea162.png">

最初に呼び出し名を決めましょう。

この呼び出し名をAlexaに話しかけるとスキルを開いてくれます。
<img width="621" alt="スクリーンショット 2018-05-01 18.22.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/a3fac180-4b7c-2990-be3b-f5746e640aeb.png">

とりあえず気温を取れるようにしたいのでこんな感じのインテントを作ります
インテントとは設定したワードを聞き取ると起動するやつです。
このインテントがLambda関数の呼び出しをします。
<img width="904" alt="スクリーンショット 2018-05-01 18.23.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/b0bef035-4f45-b8f5-8e0a-7c606d94921f.png">

#Lambda関数を作ろう
Alexaで何かするにはAlexaスキルからLambda関数を呼び起こしLambda関数でAlexaを操作するというような感じになってます
`Lambda＞関数＞関数の作成`
と進み、設計図から`alexa-skill-kit-sdk-factskill`を選択します

LambdaからAlexaスキルとDynamoDBに接続するためのロールを作ります

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "dax:*",
                "lambda:*",
                "dynamodb:*",
                "logs:CreateLogGroup",
                "logs:PutLogEvents",
                "a4b:*"
            ],
            "Resource": "*"
        }
    ]
}
```

#Alexaのエンドポイントを設定してあげよう
Lambdaにトリガーを設定します。左からAlexa Skill Kitを選択し
<img width="918" alt="スクリーンショット 2018-05-01 18.48.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/9210883b-5555-3bc4-2730-019578d53e71.png">
一度AlexaSkillコンソールに戻りエンドポイントを設定してあげます。
スキルIDをコピーしてLambdaのAlexa Skill kitトリガーに設定してあげます。
<img width="927" alt="スクリーンショット 2018-05-01 18.52.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/82fb9dd9-e570-a23b-c45f-1c18ebff9be2.png">
次はLambdaの右上あたりにあるARNをコピーして
デフォルトの地域に設定してあげます。エンドポイントの保存が完了したらエンドポイントの設定は完了です！

#Lambda関数でDynamoDBにアクセスしよう
こんな感じのDBになっているとします
<img width="941" alt="スクリーンショット 2018-05-01 20.33.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/247ee9d7-36ad-0901-a731-a799c305c68c.png">

```index.js
const Alexa = require('alexa-sdk');
const AWS = require("aws-sdk");
var docClient = new AWS.DynamoDB.DocumentClient();
const SKILL_NAME = 'SensAlexa';
const HELP_MESSAGE = '欲しいデータを教えてください';
const HELP_REPROMPT = '何か手伝いますか？';
const STOP_MESSAGE = 'さようなら';

const handlers = {
    'LaunchRequest': function () {
    this.emit(':ask');
    },
    
    'gettempreture': function () {
        var speechOutput = "";
        let self = this;
        const params = {
            TableName: "BME280", // DynamoDBのテーブル名
            ExpressionAttributeNames: {
                '#clientid': 'client_id' //lambda関数内で処理する変数に
            },
            ExpressionAttributeValues: {
                ':id': 'ESP-32-1'  //検索するID
            },
            KeyConditionExpression: '#clientid = :id', //client_id=idだったら
            ScanIndexForward: false, // 昇順か降順か(デフォルトはtrue=昇順)
            Limit: 1 // 取得するデータ件数
        };
        docClient.query(params, function(err, data){
            if(err){
                speechOutput = "気温が取得できませんでした"
            }else{
                data.Items.forEach(function(value, index){
                speechOutput = "今の気温は" + value.tempreture + "です";
                });
            }
            self.response.speak(speechOutput);
            self.emit(':responseReady');
        })
    },
    'AMAZON.HelpIntent': function () {
        const speechOutput = HELP_MESSAGE;
        const reprompt = HELP_REPROMPT;

        this.response.speak(speechOutput).listen(reprompt);
        this.emit(':responseReady');
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':responseReady');
    },
    'AMAZON.StopIntent': function () {
        this.emit(':responseReady');
    },
};


exports.handler = function (event, context) {
    const alexa = Alexa.handler(event, context);
    // To enable string internationalization (i18n) features, set a resources object.;
    alexa.registerHandlers(handlers);
    alexa.execute();
};
```

最終的にこんな感じになりました。AWS.DynamoDB.DocumentClient();については調べてみてください

#テストしてみよう
Alexaスキルをビルドし、テストへ移りましょう

<img width="432" alt="スクリーンショット 2018-05-01 20.36.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/243994/5a0e03c4-a2ce-f0bb-1755-c8808bc7c129.png">

取得できました！！！完成！！！

LambdaからHTTPゲットリクエスト投げてESP32から直接もらったほうが早かったのではという話はなしにしましょう