mysql - 使用node.js和aws lambda将Alexa技能连接到mysql数据库

标签 mysql node.js aws-lambda amazon-rds alexa

我正在尝试使用 AWS Lambda 中的 node.js 将我的 Alexa 技能连接到 Amazon RDS mySQL 数据库。我在将其上传到 lambda 之前测试了连接,它可以工作,但是当我上传它时,我收到“完成请求之前进程已退出”或“技能响应存在问题”错误。

'use strict';
const Alexa = require('alexa-sdk');

const APP_ID = 'amzn1.ask.skill.11069fc0-53bc-4cd0-8961-dd41e2d812f8';

var testSQL = 'SELECT weight, height from users where pin=1100';
//=========================================================================================================================================
//Database connection settings
//=========================================================================================================================================
var mysql = require('mysql');
var config = require('./config.json');
// Add connection details for dB
var pool  = mysql.createPool({
    host     : config.dbhost,
    user     : config.dbuser,
    password : config.dbpassword,
    database : config.dbname
  });

// var dbHeight, dbWeight, dbMuscle, dbExerciseOne, dbExerciseTwo, dbExerciseThree, dbExerciseFour; 
var dbResult;

function searchDB(quest) {
    pool.getConnection(function(err, connection) {
      // Use the connection
        console.log(quest);
        connection.query(quest, function (error, results, fields) {
            // And done with the connection.
            connection.release();
            // Handle error after the release.
            if (!!error) {
                console.log('error')
            }
            else {
                console.log(results[0]);
                dbResult = results[0];
                return dbResult;
                console.log(dbResult.height);
            }
            process.exit();
        });
    });
};

//searchDB(testSQL);

//=========================================================================================================================================
//TODO: The items below this comment need your attention.
//=========================================================================================================================================



const SKILL_NAME = 'My Application';
const GET_FACT_MESSAGE = "Here's your fact: ";
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';

var name, pinNumber;


//=========================================================================================================================================
//Editing anything below this line might break your skill.
//=========================================================================================================================================

const handlers = {
    'LaunchRequest': function () {
        if(Object.keys(this.attributes).length === 0){
            this.attributes.userInfo = {
                'userName': '',
                'pinNo': 0
                }
            this.emit('GetPinIntent');
        }
        else{

            name = this.attributes.userInfo.userName;
            pinNumber = this.attributes.userInfo.pinNo;
            var sql = "";
            //var result = searchDB(sql);
            //var uWeight = result.weight;
            //var uHeight = result.height;
            var speechOutput = 'Welcome ' + name + 'Please select an option: Check My BMI, Create Exercise Plan, Create Meal Plan, Update Height and Weight, Update workout status?';
            this.emit(':ask', speechOutput);
        }
    },

    'GetPinIntent': function (){
      this.emit(':ask','Welcome to my Application, as this is your first time please say your name followed by your pin. For example, my name is Jason and my pin is zero one zero one');
      //this.emit(':responseReady');
   },

    'RememberNameID': function (){
        var filledSlots = delegateSlotCollection.call(this);
        this.attributes.userInfo.userName = this.event.request.intent.slots.name.value;
        this.attributes.userInfo.pinNo = this.event.request.intent.slots.pin.value;

        var speechOutput = 'Welcome ' + this.attributes.userInfo.userName + ' we have stored your Pin Number and we will call you by name next time. Please select an option: BMI or exercise';

        this.response.speak(speechOutput);
        this.emit(':responseReady');

    },

    'CheckBMI': function(){

        var sql = 'SELECT height, weight FROM users WHERE pin=' + this.attributes.userInfo.pinNo;
        var heightWeight = searchDB(sql);
        dbHeight = parseInt(heightWeight.height);
        dbWeight = parseInt(heightWeight.weight);
        var speechOutput = bmiCalculator(dbHeight, dbWeight);
        this.emit(':ask', speechOutput);  

    },

    'AMAZON.HelpIntent': function () {
        const speechOutput = HELP_MESSAGE;
        const reprompt = HELP_REPROMPT;

        this.response.speak(speechOutput).listen(reprompt);
        this.emit(':responseReady');
    },
    'AMAZON.CancelIntent': function () {
        this.response.speak(STOP_MESSAGE);
        this.emit(':responseReady');
    },
    'AMAZON.StopIntent': function () {
        this.response.speak(STOP_MESSAGE);
        this.emit(':responseReady');
    },
    'SessionEndedRequest': function() {
        console.log('session ended!');
        this.emit(':saveState', true);
    }
};

exports.handler = function (event, context, callback) {
    var alexa = Alexa.handler(event, context, callback);
    alexa.APP_ID = APP_ID;
    alexa.dynamoDBTableName = 'fitnessDB';
    alexa.registerHandlers(handlers);
    alexa.execute();


};

function delegateSlotCollection(){
  console.log("in delegateSlotCollection");
  console.log("current dialogState: "+this.event.request.dialogState);
    if (this.event.request.dialogState === "STARTED") {
      console.log("in Beginning");
      var updatedIntent=this.event.request.intent;
      //optionally pre-fill slots: update the intent object with slot values for which
      //you have defaults, then return Dialog.Delegate with this updated intent
      // in the updatedIntent property
      this.emit(":delegate", updatedIntent);
    } else if (this.event.request.dialogState !== "COMPLETED") {
      console.log("in not completed");
      // return a Dialog.Delegate directive with no updatedIntent property.
      this.emit(":delegate");
    } else {
      console.log("in completed");
      console.log("returning: "+ JSON.stringify(this.event.request.intent));
      // Dialog is now complete and all required slots should be filled,
      // so call your normal intent handler.
      return this.event.request.intent;
    }
};
function bmiCalculator (userHeight, userWeight ) {


        var speechOutput = " "; 

        var h = userHeight/100;

        var calcBMI = 0;
        calcBMI = userWeight / (h*h);
        calcBMI = calcBMI.toFixed(2);


        if (calcBMI < 18.5) {
            speechOutput += "Based on your weight of " +weight+ " kilograms and your height of " + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently underweight.";
            speechOutput += " I would advise you to increase your calorie intake, whilst remaining active.";
            return speechOutput;

        }
        else if (calcBMI >=18.5 && calcBMI < 25){

            speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently at a normal weight.";
            speechOutput += " I would advise you to stay as you are but ensure you keep a healthy diet and lifestyle to avoid falling above or below this.";
            this.response.speak(speechOutput);
            return speechOutput;
        }
        else if (calcBMI >=25 && calcBMI < 29.9){

            speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently overweight.";
            speechOutput += " I would advise you to exercise more to fall below this range. A healthy BMI is ranged between 18.5 and 24.9";
            this.response.speak(speechOutput);
            return speechOutput;
        }
        else{

            speechOutput += "Based on your weight of " +weight+ " kilograms and your height of" + height + " metres, your BMI is " +calcBMI+ ". Meaning you are currently obese.";
            speechOutput += " I would advise you to reduce your calorie intake, eat more healthy and exercise more. A healthy BMI is ranged between 18.5 and 24.9";
            return speechOutput;

        }


 };

代码概述了我的数据库连接。我将连接查询创建为函数,因为我需要根据上下文对数据库进行不同的查询。有没有办法在exports.handler函数中创建一个函数,该函数仅在需要时调用查询? 或者还有其他关于以这种方式连接数据库的解决方案吗?

最佳答案

您遇到了多个问题,没有使用 Promise 或等待,您的调用正在异步运行,并且您永远不会立即从 RDS 获得 lambda 调用的答案。您需要创建一个函数,该函数将在继续其逻辑之前等待答案。 您将遇到的另一个问题是 MySQL RDS 实例是否持续运行,可能存在冷启动问题。 最后一件事是在 AWS lambda 控制台中确保分配足够的计算资源和时间来运行此函数(默认 128 mb 内存)并且可以调整运行函数的时间以提高性能

关于mysql - 使用node.js和aws lambda将Alexa技能连接到mysql数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50666120/

相关文章:

mysql - nodejs/mysql - 是否可以确保所有行始终只有一个为真

angularjs - 更新$http返回数据到html View

amazon-dynamodb - DynamoDB 到 Kinesis 流

python-2.7 - 如何从 aws lambda 事件对象(在 python 中)获取 POST 请求的 header ,其中传入请求的正文为空,但 header 中有信息

MySQL SET IF 语句

MySQL 游标不工作

node.js - 使用 Node 设置 Varnish 缓存

amazon-web-services - 如何使用 AWS CLI 向 AWS Lambda 函数添​​加触发器?

mysql - 无法使用命令行安装 craft3。测试数据库凭据...失败:

javascript - SSH 进入远程机器并在 Node.js 中执行命令