質問編集履歴

1 いくつか追加で処理を変更してみたので、修正しました。回答お願いします!

hamar1

hamar1 score 18

2018/04/21 16:05  投稿

alexaの情報をdynamoDBにupdateしてから返答したい
### 前提・実現したいこと
Alexaを購入したので、アプリを自宅用に作成しています。
node.jsでalexaの情報を受けて、dynamoを更新してから返答を返したいです。
slack連携のアプリをnode.jsで作っているのでnode.jsにトライしています。  
(普段はPythonを利用していることが多いです)  
かなり長いですが、よろしくお願いします。
 
### 発生している問題・エラーメッセージ  
 
JavaScriptの非同期処理の順序立てのためのcallbackをうまく使えないのと、記法がよく分からないです。  
```  
speechOutput is undefined  
```  
### 該当のソースコード
```JavaScript
// define and require
const Alexa = require("alexa-sdk");
const APP_ID = undefined;
var AWS = require('aws-sdk');
var dynamoDoc = new AWS.DynamoDB.DocumentClient({region: 'ap-northeast-1'});
const languageStrings = {
   "ja": { "translation": {"STOP_MESSAGE": "スキルを終了します。",...}}};
dataEmitter = new myEmitter();  
// dynamo process
function dynamoLogHandler(userGaveUp) {
function dynamoLogHandler(data) {
   var params_update = {
       TableName:'test_table',
       Key:{"eventId":this.request.intent.solts.test.name},
       Key:{"eventId":data.request.intent.solts.test.name},
       AttributeUpdates:{
               "points":{'Action':'ADD','Value': (- this.request.intent.solts.test.value)}},
           ReturnValues:"UPDATED_NEW"
       };
       dynamoDoc.update(params_update,function(err,data_updated){
           let speechOutput = String(data_updated.Attributes.points)+"更新しました";
   });
   this.response.speak(speechOutput);
   this.emit(':responseReady');
   // 今回修正した処理
   dataEmitter.emit('data',speechOutput)
   // 前回質問していた時の処理-> thisがundefinedになる
   //this.response.speak(speechOutput);
   //this.emit(':responseReady');
}
// test intent handler
function handlerTest(userGaveUp){
   let speechOutput = dynamoHandler(this);
   dynamoLogHandler(this);
   // 現在の処理   -> ここまでで有れば正常にdynamoUpdateが走る
   let speechOutput = dataEmitter.on('data',function(speechOutput){return speechOutput;}));
   // トライした処理 -> この先を入れるとresponseが[Object Object]
   // this.response.speak(speechOutput);
   // this.emit(':responseReady');
}
// intent integrated handler
const handlers = {
   "LaunchRequest": function () {...},
   'Unhandled': function () {...},
   "testIntent": function() {
       handlerTest.call(this, false);
   }
}
exports.handler = function (event, context) {
   const alexa = Alexa.handler(event, context);
   alexa.APP_ID = APP_ID;
   alexa.resources = languageStrings;
   alexa.registerHandlers(handlers);
   alexa.execute();
};
```
### 全体の流れ  
 
1. alexa handlerでtestIntentが設定されます。  
2. testIntentHandlerが実行され、dynamoLogHandlerが呼び出されます。  
3. dynamoDBを更新します(ここにはミスはないです)  
4. dynamoLogHandlerの処理が終了すると、emitterでtestIntentHandlerに戻ります  
 (let speechOutput = dataEmitter.on('data',function);  
5. `this.emit(':tell',speechOutput)`で発話内容をAlexaに返します  
 
### 問題点  
4番までで実行すると、全てが正常に実行されて進むのですが、  
この、5番を入れると、emitterが[Object Object]として定義されてしまい、3,4を実行せずに終了してしまいます。  
 
### 試したこと&分かっていないこと
`emitter`を利用することで、  
`this.emit`の位置を変えたり、`return`を使ったり、`emitter`を使ったりしましたが、
`this`がscopeを超えて引き継がれなかったり、そもそもreturnの位置が間違えていたりと、
全くうまくいっていません。
また、sdkを参照して作っているのですが、`userGaveUp`が何を指すのかどのような使い方ができるのかが不明です。
全ての処理は記載していないですが、うまくいっていない部分は上記になります。
### 補足情報(FW/ツールのバージョンなど)
node.js
  • JavaScript

    20419 questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    2360 questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Alexa

    17 questions

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る