###前提・実現したいこと
AWSでLINEbotを作成しており、ユーザ全員にメッセージをマルチキャストしたいでうす。
dynamodbの中に入っているuseridの一覧をスキャン ->
jsonに代入してpostしたいのですが、どうしてもスキャンを待たずしてjsonのpostが始まってしまいます。
非同期処理について私なりに調べ、コードを工夫したのですがうまくいきませんでした。
どう書けば望み通りの処理ができるのか、ご教授いただけないでしょうか。
###発生している問題・エラーメッセージ
メッセージ送信とデータのスキャンが逆転してしまいます。
(前半略) 13:39:40 2017-04-04T13:39:40.345Z ea66573c-27aa-46a0-8c34-dffe44c07e69 2. Scan User and multicast message 13:39:40 2017-04-04T13:39:40.744Z ea66573c-27aa-46a0-8c34-dffe44c07e69 Start sending message... 13:39:40 2017-04-04T13:39:40.744Z ea66573c-27aa-46a0-8c34-dffe44c07e69 let send stat! 13:39:40 2017-04-04T13:39:40.746Z ea66573c-27aa-46a0-8c34-dffe44c07e69 let send End! 13:39:41 2017-04-04T13:39:41.006Z ea66573c-27aa-46a0-8c34-dffe44c07e69 onScan start 13:39:41 2017-04-04T13:39:41.006Z ea66573c-27aa-46a0-8c34-dffe44c07e69 onScan succeeded. 13:39:41 2017-04-04T13:39:41.006Z ea66573c-27aa-46a0-8c34-dffe44c07e69 This is message after Scan -> 13:39:41 2017-04-04T13:39:41.006Z ea66573c-27aa-46a0-8c34-dffe44c07e69 { to: [ 'user12345', 'user67890' ], messages: [ { type: 'text', text: 'こんにちは!' } ] } 13:39:41 END RequestId: ea66573c-27aa-46a0-8c34-dffe44c07e69
###該当のソースコード
node.js
1'use strict'; 2 3// console.log("Start code!"); 4 5const https = require('https'); 6var AWS = require("aws-sdk"); 7 8AWS.config.update({region: "us-east-1",}); 9var docClient = new AWS.DynamoDB.DocumentClient(); 10 11var message = {}; 12var params = {}; 13 14let send = (data, callback) => { 15 console.log("let send stat!"); 16 let body = JSON.stringify(data); 17 18 let req = https.request({ 19 hostname: "api.line.me", 20 port: 443, 21 path: "/v2/bot/message/multicast", 22 method: "POST", 23 headers: { 24 "Content-Type": "application/json", 25 "Content-Length": Buffer.byteLength(body), 26 "Authorization": "Bearer " + process.env.CHANNEL_ACCESS_TOKEN 27 } 28 }); 29 30 req.end(body, (err) => { 31 err && console.log(err); 32 callback(err); 33 }); 34 console.log("let send End!"); 35}; 36 37exports.handler = (event, context, callback) => { 38 console.log("Start Handler!"); 39 console.log('EVENT:', JSON.stringify(event, null, 2)); 40 41 console.log("1. Generate Message Template"); 42 43 let content = event.Records[0]; 44 console.log("content ->"); 45 console.log(content); 46 47 let sayThis = "こんにちは!"; 48 49 message = genNotification(sayThis, url); 50 console.log("This is message ->"); 51 console.log(message); 52 53 params = gen_scan_params(); 54 55 sendMessage4Scan(params, 56 () => {send(message, 57 () => {callback(); 58 }); 59 } 60 ); 61}; 62 63// sendMethodはコールバック関数なのだから、スキャン後に呼ばれることを期待していたのですが... 64function sendMessage4Scan(params,sendMethod){ 65 docClient.scan(params, onScan); 66 console.log("Start sending message..."); 67 sendMethod(); 68} 69 70function genNotification(sayThis, url){ 71 console.log("gen notify"); 72 message = { 73 "to":[], 74 "messages": [ 75 { 76 "type": "text", 77 "text": sayThis 78 } 79 ] 80 }; 81 return message; 82} 83 84function gen_scan_params(){ 85 params = { 86 TableName: process.env.TABLE_USERS, 87 ProjectionExpression: "id" 88 }; 89 return params; 90} 91 92function onScan(err, data) { 93 console.log("onScan start"); 94 if (err) { 95 console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2)); 96 } else { 97 console.log("onScan succeeded."); 98 data.Items.forEach(function(user) { 99 message.to.push(user.id); 100 }); 101 console.log("This is message after Scan ->"); 102 console.log(message); 103 104 // continue scanning if we have more movies, because 105 // scan can retrieve a maximum of 1MB of data 106 if (typeof data.LastEvaluatedKey != "undefined") { 107 console.log("Scanning for more..."); 108 params.ExclusiveStartKey = data.LastEvaluatedKey; 109 docClient.scan(params, onScan); 110 } 111 } 112}
###試したこと
非同期処理について調べ、コールバック関数を利用すれば順番に処理できると知ってそう書いてみました。しかし、やり方がよくないのか処理順が変わりません。
###補足情報(言語/FW/ツール等のバージョンなど)
node.js 6.10
AWS lambda
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/04 22:41