2

Ich bekomme ein Problem mit dem folgenden Code mit Amazon Lambda und dem Alexa Skills Kit. Ich habe unzählige Stunden damit verbracht und kann es nicht zur Arbeit bringen. Ich bekomme diese Nachricht immer wieder und kann nicht herausfinden, warum der http get fehlschlägt. "Bitte versuche es später noch einmal". Es druckt nicht einmal die Konsolenmeldungen.Amazon AWS Lambda Alexa HTTP Problem

var Alexa = require('alexa-sdk'); 
var http = require('http'); 
var APP_ID = "omitted";  
var SKILL_NAME = 'omitted'; 

var options = { 
    host: 'api.forismatic.com', 
    path: '/api/1.0/?method=getQuote&lang=en&format=text', 
    method: 'GET' 
}; 

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('Inspiration'); 
}, 
'IntentRequest': function() { 
    this.emit('Inspiration'); 
}, 
'InspirationIntent': function() { 
    this.emit('Inspiration'); 
}, 
'Inspiration': function() { 
    var speechOutput = ''; 
    var text = ''; 
    http.get(options, function(res) { 
     console.error("Got response: " + res.statusCode); 
     res.on("data", function(chunk) { 
     console.error("BODY: " + chunk); 
     text = chunk; 
    }); 
    }).on('error', function(e) { 
     text = 'error' + e.message; 
     console.error("Got error: " + e.message); 
}); 
    if(text == ''){ 
    speechOutput = "Please try again later"; 
    } 
    else{speechOutput = text;} 
    this.emit(':tellWithCard', speechOutput, SKILL_NAME, text); 
}, 
'AMAZON.HelpIntent': function() { 
    var speechOutput = "You can ask Inspirational Quote for some advice."; 
    var reprompt = "What would you like me to do?"; 
    this.emit(':ask', speechOutput, reprompt); 
}, 
'AMAZON.CancelIntent': function() { 
    this.emit(':tell', 'Goodbye!'); 
}, 
'AMAZON.StopIntent': function() { 
    this.emit(':tell', 'Goodbye!'); 
}, 
'Unhandled': function() { 
    this.emit('AMAZON.HelpIntent'); 
} 
}; 

Antwort

6

Da Java-Script ist asynchron, dieser Code:

if(text == ''){ 
speechOutput = "Please try again later"; 
} 
else{speechOutput = text;} 
this.emit(':tellWithCard', speechOutput, SKILL_NAME, text); 

wird vor dem Aufruf läuft auf die API aus bekommt eine Antwort.

Leider können Sie den obigen Code nicht einfach in den http.get-Block verschieben, da das 'this' in 'this.emit' nicht mehr funktioniert und Sie eine undefinierte Antwort erhalten, an die Sie zurücksenden die Alexa-Fähigkeit.

Ich denke, die beste Lösung wäre, den http-Aufruf in eine separate Funktion zu ziehen. Wenn Sie diese Funktion aufrufen, müssen Sie einen Rückruf verwenden, um das gleiche Problem zu vermeiden, dass der Lambda nicht auf eine Antwort vom http-Aufruf wartet, bevor er zur nächsten Codezeile wechselt. Übergeben Sie also eine Funktion mit dem Funktionsaufruf und senden Sie Ihre Antwort von dort. NB - Damit dies funktioniert, müssen Sie dem Wert von 'this' außerhalb des Funktionsaufrufs eine Variable zuweisen und diese Variable anstelle von 'this' innerhalb des Funktionsaufrufs verwenden.

Beispiel unten:

var Alexa = require('alexa-sdk'); 
var http = require('http'); 
var APP_ID = "omitted";  
var SKILL_NAME = 'omitted'; 

var options = { 
    host: 'api.forismatic.com', 
    path: '/api/1.0/?method=getQuote&lang=en&format=text', 
    method: 'GET' 
}; 

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('Inspiration'); 
    }, 
    'IntentRequest': function() { 
     this.emit('Inspiration'); 
    }, 
    'InspirationIntent': function() { 
     this.emit('Inspiration'); 
    }, 
    'Inspiration': function() { 
     var speechOutput = ''; 
     var text = ''; 
     var self = this; 
     getQuote(options, function (quote){ 
      if(quote == ''){ 
      speechOutput = "Please try again later"; 
      } 
      else{speechOutput = quote;} 
      self.emit(':tellWithCard', speechOutput, SKILL_NAME, text); 
     } 
    )}, 
    'AMAZON.HelpIntent': function() { 
     var speechOutput = "You can ask Inspirational Quote for some advice."; 
     var reprompt = "What would you like me to do?"; 
     res(this.emit(':ask', speechOutput, reprompt)); 
    }, 
    'AMAZON.CancelIntent': function() { 
     this.emit(':tell', 'Goodbye!'); 
    }, 
    'AMAZON.StopIntent': function() { 
     this.emit(':tell', 'Goodbye!'); 
    }, 
    'Unhandled': function() { 
     this.emit('AMAZON.HelpIntent'); 
    } 
}; 

function getQuote(options, callback){ 
    http.get(options, function(res) { 
     console.error("Got response: " + res.statusCode); 
     res.on("data", function(chunk) { 
     console.error("BODY: " + chunk); 
     text = '' + chunk; 
     return callback(text); 
    }); 
    }).on('error', function(e) { 
     text = 'error' + e.message; 
     console.error("Got error: " + e.message); 
}); 
} 
+0

Dank. Das hat es getan – logepoge1

Verwandte Themen