質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon DynamoDB

Amazon DynamoDBは、 AWS上のNoSQLデータベースサービスです。フルマネージド型のサービスで、スキーマレス、高速且つ安定性のある動作、自動的に容量を変更する自動スケーリングなどの特徴を持ちます。

Node.js

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

JavaScript

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

Q&A

解決済

1回答

1895閲覧

コールバック関数から戻り値を取得したい

yuta_kg

総合スコア24

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

Amazon DynamoDB

Amazon DynamoDBは、 AWS上のNoSQLデータベースサービスです。フルマネージド型のサービスで、スキーマレス、高速且つ安定性のある動作、自動的に容量を変更する自動スケーリングなどの特徴を持ちます。

Node.js

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

JavaScript

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

0グッド

0クリップ

投稿2019/09/21 01:37

編集2019/09/21 02:16

DynamoDBから取得したgroupIDを使い、グループにメッセージを送るAlexaをトリガーとしたLINE botを作成しています。
現在DynamoDBからgroupIDを取得するgetメソッドにコールバック関数を指定しています。
groupId宣言時に、"0123"を代入していますが、コールバック関数内で取得した値を代入したいです。
ですが、以下のコードではgroupIdに取得した値が代入されず、groupId="0123"のままです。
groupIdにコールバック関数内で取得した値を代入する方法を教えてください。

以下、コードになります。

Javascript

1const MindFullnessIntentHandler = { 2 canHandle(handlerInput) { 3 return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest' 4 && Alexa.getIntentName(handlerInput.requestEnvelope) === 'MindFullnessIntent'; 5 }, 6 async handle(handlerInput) { 7 // ----------LINEでメッセージを送信----------// 8 // Userごとのアクセストークン 9 const accessToken = handlerInput.requestEnvelope.session.user.accessToken; 10 console.log(accessToken); 11 12 var options = { //http リクエスト 13 method: 'GET', //method 14 uri: 'https://api.line.me/v2/profile', //エンドポイント 15 headers: { 16 'Authorization': `Bearer ${accessToken}` //ヘッダーにアクセストークンを追加しないと、エンドポイントで認証できない 17 } 18 }; 19 20 // 時間の取得 21 const slots = handlerInput.requestEnvelope.request.intent.slots; 22 const time = slots.time.value; 23 24 // アクセストークンより、LINEのUser情報を取得 25 const lineData = JSON.parse(await rp(options)); 26 27 const userName = lineData.displayName; 28 29 const message = { 30 type: 'text', 31 text: `${userName}さんは${time}分しました.` 32 }; 33 34 const userId = lineData.userId; 35 36 //DynamoDBからgroupIDを取得 37 AWS.config.update({ 38 region: "ap-northeast-1", 39 endpoint: "https://dynamodb.ap-northeast-1.amazonaws.com" 40 }); 41 42 const docClient = new AWS.DynamoDB.DocumentClient(); 43 44 const table = "line_user"; 45 46 const params = { 47 TableName: table, 48 Key: { 49 "userId": userId 50 } 51 }; 52 53 var groupId = "0123"; //groupIdの雛形を作成。userIdから取得出来なければこのgroupId 54 55 docClient.get(params, function(err, data) { 56 if (err) { 57 console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); 58 } else { 59 console.log("GetItem succeeded:", JSON.stringify(data, null, 2)); 60 groupId = data.Item.groupId; 61 console.log(groupId); 62 return groupId; 63 } 64 }); 65 66 console.log("groupId:" + groupId); 67 68 // botに通知を送信 69 await lineclient.pushMessage(groupId, message); 70 71 const speakOutput = `${time}分ですね。それでは始めましょう!`; 72 73 return handlerInput.responseBuilder 74 .speak(speakOutput) 75 .getResponse(); 76 } 77};

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2019/09/21 02:03

コールバックの中に書くのではダメなのですか?
R.Mizukami

2019/09/21 02:03

コールバック関数の外に書かれている方の console.log で 'groupId:0123' の代わりに 'groupId:(data.Item.groupId で取得した値)' となってほしいということでしょうか。
yuta_kg

2019/09/21 02:07

コールバック関数の中に書くと、「Parsing error: Unexpected token lineclient」とエラーが表示されてしまいます。
yuta_kg

2019/09/21 02:07

R.Mizukamiさん そうです。
Lhankor_Mhy

2019/09/21 02:10

コールバックの外だと、Unexpected token lineclient のエラーは出ないのですか?
yuta_kg

2019/09/21 02:12

出ないです。 質問に載せたコードは全体の一部です。 var groupId = "0123";よりも前にlineclientを宣言しているのでエラーは出ないと思われます。
yuta_kg

2019/09/21 04:23

Promiseは検討していないです。 R.Mizukamiさんの回答を参考にコードを書いてみます!
guest

回答1

0

ベストアンサー

多分処理の流れに勘違いがあり、今回の問題が発生しているように思います。

AWS で提供される関数などのように、ネットワーク処理のような時間のかかる処理を行う関数の多くはコールバックを受け取り、受け取った関数を時間のかかる処理が終わるまで 待ってから 呼び出します。

したがって、質問者さんのコードの処理順番は以下のようになります(一部だけ抜き出しています)。

javascript

1var groupId = "0123"; 2 // 1: ここから処理が始まる 3docClient.get(params, function(err, data) {  4 // 3: 後になって呼び出される 5 if (err) { 6 /* 略 */ 7 } else { 8 console.log("GetItem succeeded:", JSON.stringify(data, null, 2)); 9 groupId = data.Item.groupId; 10 console.log(groupId); 11 return groupId; 12 } 13}) 14 15// 2: 先にこっちが呼び出される 16console.log("groupId:" + groupId);

いうまでもなく、 // 2: ~ となっているところでまだ実行されていない // 3: ~ の結果を受け取ることは不可能です。代わりに、3 の処理が終わった後に必要な処理を実行するようにしてください。

以下のように await 構文を使うことで、 質問者さんのコードの handle のような async 関数内ではある処理が終わった後に続きの処理を呼び出すというようなことができます(詳しくは Promise オブジェクトについて学習してください)。

javascript

1var groupId = "0123"; 2 3groupId = await new Promise(function(resolve, reject) { 4 docClient.get(params, function(err, data) { 5 if (err) { 6 reject(err) 7 } else { 8 resolve(data.Item.groupId); 9 // return の代わりと思ってください。 10 } 11 }); 12}); 13console.log("groupId:" + groupId); 14 // きちんと上で resolve(...) で渡された値が代入されている。 15 // reject() が実行された場合は例外が投げられ、ここは実行されない。

投稿2019/09/21 02:41

R.Mizukami

総合スコア1086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yuta_kg

2019/09/21 04:25

ご指摘通り非同期処理で誤った理解をしていました。 非同期処理、Promiseオブジェクトを学習してコードを書いてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問