Polly creates MP3 and then uploads it to S3 and calls Lambda back to the URL from another Lambda, but the caller Lambda completes it first without waiting for the caller's response.The MP3 creation by the calling Lambda is now complete after the calling party completes.
How do I wait for Lambda's response before completing Lambda's response?
■ Calling Lambda
var lambda=new AWS.Lambda({apiVersion:'2015-03-31'})
exports.handler=function(event, context, callback){
res=invokeCreateMp3()
console.log(res) // undefined
}
function invokeCreateMp3(name,sec){
lambda.invoke({
FunctionName: 'create_mp3_for_timer',
InvocationType: 'RequestResponse',
Payload: '{"name":"kana", "sec":3}',
}, function(error,data){
if(error){
console.log("error:" + error)
} else{
console.log("response:" + data)
}
});
}
■ Called Lambda
var poll = new AWS.Polly ({apiVersion:'2016-06-10'});
vars3 = new AWS.S3 ({apiVersion:'2006-03-01'});
exports.handler=function(event, context, callback){
varurl=createMp3 (event.name, event.sec);
varres = {
"statusCode": 200,
"headers": { "Additional-Headr1": "1234"},
"body" : JSON.stringify({"response" : "response", "event" : event, "url" : url },
};
callback(null,res);
};
function createMp3(name,sec){
varsml='<speak><break time='+sec+'s"/>'+name+' timer is over.</speak>';
var bucket = 'mp3_book';
varkey = name + '_' + sec + 's.mp3';
var url = 'https://s3-ap-northeast-1.amazonaws.com/' + bucket + '/' + key;
let speechParams={
OutputFormat: 'mp3',
VoiceId: 'Mizuki',
Text: ssml,
SampleRate: '22050',
TextType: 'ssml'
};
poly.synthesizeSpeech(speechParams).promise().then(data)=>{
console.log(data); // successful response
// Parameters for putting to s3
vars3Params = {
ACLs: 'public-read', // S3 privileges
Bucket: buket,
Key: key,
ContentType: 'audio/mp3',
Body: Get new Buffer (data.AudioStream) // AudioStream
};
// put to s3
s3.putObject(s3Params,(err)=>{
if(err){
console.log(err);
} else{
console.log('Success');
}
});
}, (error) = > {
console.log("Failure!", error);
});
return url;
}
The caller does not appear to be waiting for a callback implementation.
I haven't been able to verify the operation, but I think I can do it synchronously if I fix it like this.
var lambda=new AWS.Lambda({apiVersion:'2015-03-31'})
exports.handler=async function(event, context, callback) {
res=wait inviteCreateMp3()
console.log(res) // undefined
}
async function invokeCreateMp3(name,sec){
try{
const data = wait lambda.invoke({
FunctionName: 'create_mp3_for_timer',
InvocationType: 'RequestResponse',
Payload: '{"name":"kana", "sec":3}',
}).promise();
console.log("response:"+data);
return data;
} catch(error){
console.log("error:"+error);
return error;
}
}
I'm not familiar with nodejs, so I may have removed it, but I think InvokeCreateMp3 works asynchronously, so I think I need to wait for it to end by returning a promise.
Similarly, createMP3 part.
I think it is necessary to use promote for putObject.
© 2024 OneMinuteCode. All rights reserved.