From 4f13fa605971026ae8d6c99a2f946f9d32c0f9da Mon Sep 17 00:00:00 2001 From: kakakakakku Date: Sat, 4 Oct 2025 21:19:41 +0900 Subject: [PATCH 1/4] apigw-lambda-sfn-transcribe-translate-polly-sam: Update runtime to nodejs22.x --- .../template.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/template.yaml b/apigw-lambda-sfn-transcribe-translate-polly-sam/template.yaml index 715a4033e..a904f055e 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/template.yaml +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/template.yaml @@ -54,7 +54,7 @@ Resources: Properties: Handler: src/transcribeLaunch.handler FunctionName: "translator-dev-transcribeLaunch" - Runtime: nodejs20.x + Runtime: nodejs22.x Architectures: - x86_64 MemorySize: 128 @@ -65,7 +65,7 @@ Resources: Properties: Handler: src/transcribeCheck.handler FunctionName: "translator-dev-transcribeCheck" - Runtime: nodejs20.x + Runtime: nodejs22.x Architectures: - x86_64 MemorySize: 128 @@ -76,7 +76,7 @@ Resources: Properties: Handler: src/translate.handler FunctionName: "translator-dev-translate" - Runtime: nodejs20.x + Runtime: nodejs22.x Architectures: - x86_64 MemorySize: 128 @@ -87,7 +87,7 @@ Resources: Properties: Handler: src/speech.handler FunctionName: "translator-dev-speech" - Runtime: nodejs20.x + Runtime: nodejs22.x Architectures: - x86_64 MemorySize: 128 @@ -111,7 +111,7 @@ Resources: InvokerLambda: Type: AWS::Serverless::Function Properties: - Runtime: "nodejs16.x" + Runtime: "nodejs22.x" FunctionName: "translator-dev-invokeTranslator" Timeout: 300 MemorySize: 1024 @@ -134,7 +134,7 @@ Resources: Type: AWS::Lambda::Function Properties: FunctionName: "translator-dev-authorizer" - Runtime: "nodejs18.x" + Runtime: "nodejs22.x" Timeout: 300 MemorySize: 1024 Handler: index.handler From 4fc582f61c26e396142c3c5879f0f56b82a9ec87 Mon Sep 17 00:00:00 2001 From: kakakakakku Date: Sat, 4 Oct 2025 22:28:26 +0900 Subject: [PATCH 2/4] apigw-lambda-sfn-transcribe-translate-polly-sam: Update SDK to v3 for nodejs22.x runtime --- .../src/invokeTranslator.js | 14 +++++++------- .../src/speech.js | 17 ++++++++++------- .../src/transcribeCheck.js | 8 ++++---- .../src/transcribeLaunch.js | 6 +++--- .../src/translate.js | 15 ++++++++------- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js index d4cd49d71..c6cadb6e5 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js @@ -1,6 +1,7 @@ -const AWS = require('aws-sdk'); -const stepfunctions = new AWS.StepFunctions(); -const apig = new AWS.ApiGatewayManagementApi({ +const { SFNClient, StartSyncExecutionCommand } = require('@aws-sdk/client-sfn'); +const { ApiGatewayManagementApiClient, PostToConnectionCommand } = require('@aws-sdk/client-apigatewaymanagementapi'); +const stepfunctions = new SFNClient({}); +const apig = new ApiGatewayManagementApiClient({ endpoint: process.env.APIG_ENDPOINT, }); @@ -25,12 +26,11 @@ module.exports.handler = async (event, context) => { stateMachineArn: process.env.statemachine_arn, input: body } - let response = await stepfunctions.startSyncExecution(params).promise(); - await apig - .postToConnection({ + let response = await stepfunctions.send(new StartSyncExecutionCommand(params)); + await apig.send(new PostToConnectionCommand({ ConnectionId: connectionId, Data: response?JSON.stringify( {"url" : JSON.parse(response.output).url} ):"No data" - }).promise(); + })); if ( response && response.output) response = {"url" : JSON.parse(response.output).url} return { diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js index ed48a789a..aad06cc46 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js @@ -1,6 +1,9 @@ -const AWS = require('aws-sdk'); -const s3 = new AWS.S3(); -const polly = new AWS.Polly(); +const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); +const { PollyClient, SynthesizeSpeechCommand } = require('@aws-sdk/client-polly'); +const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); +const { GetObjectCommand } = require('@aws-sdk/client-s3'); +const s3 = new S3Client({}); +const polly = new PollyClient({}); const uuidv1 = require('uuidv1'); @@ -62,7 +65,7 @@ module.exports.handler = async (event, context) => { console.log(speechParams) - const response = await polly.synthesizeSpeech(speechParams).promise(); + const response = await polly.send(new SynthesizeSpeechCommand(speechParams)); let audioStream = response.AudioStream; let key = uuidv1(); let params = { @@ -71,12 +74,12 @@ module.exports.handler = async (event, context) => { Body: audioStream }; - const s3Response = await s3.putObject(params).promise(); + const s3Response = await s3.send(new PutObjectCommand(params)); let s3params = { Bucket: outputBucket, Key: key + '.mp3', }; - let url = s3.getSignedUrl("getObject", s3params); + let url = await getSignedUrl(s3, new GetObjectCommand(s3params)); console.log(url); return { url, outputBucket, key: key + '.mp3' }; -} \ No newline at end of file +} diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeCheck.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeCheck.js index a92899b4c..e78438450 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeCheck.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeCheck.js @@ -1,5 +1,5 @@ -const AWS = require('aws-sdk'); -const transcribe = new AWS.TranscribeService(); +const { TranscribeClient, GetTranscriptionJobCommand } = require('@aws-sdk/client-transcribe'); +const transcribe = new TranscribeClient({}); module.exports.handler = async (event, context) => { console.log(event) @@ -12,7 +12,7 @@ module.exports.handler = async (event, context) => { TranscriptionJobName: jobName }; - let jobData = await transcribe.getTranscriptionJob(params).promise(); + let jobData = await transcribe.send(new GetTranscriptionJobCommand(params)); let jobStatus = jobData.TranscriptionJob.TranscriptionJobStatus; if ( jobStatus == 'COMPLETED' || jobStatus == 'FAILED') { let s3Loc = jobData.TranscriptionJob.Transcript.TranscriptFileUri; @@ -25,4 +25,4 @@ module.exports.handler = async (event, context) => { else { return { continue: true, jobName, outputBucket, inputLanguageCode, outputLanguageCode } } -} \ No newline at end of file +} diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeLaunch.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeLaunch.js index f46fb0b70..7d0950f45 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeLaunch.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/transcribeLaunch.js @@ -1,6 +1,6 @@ const path = require('path'); -const AWS = require('aws-sdk'); -const transcribe = new AWS.TranscribeService(); +const { TranscribeClient, StartTranscriptionJobCommand } = require('@aws-sdk/client-transcribe'); +const transcribe = new TranscribeClient({}); module.exports.handler = async (event, context) => { console.log(event) @@ -25,6 +25,6 @@ module.exports.handler = async (event, context) => { OutputBucketName: OUTPUT_BUCKET }; console.log(params); - await transcribe.startTranscriptionJob(params).promise(); + await transcribe.send(new StartTranscriptionJobCommand(params)); return { jobName, outputBucket:OUTPUT_BUCKET, inputLanguageCode, outputLanguageCode }; }; diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/translate.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/translate.js index e6c1e2032..d5f6b8036 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/translate.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/translate.js @@ -1,6 +1,7 @@ -const AWS = require('aws-sdk'); -const s3 = new AWS.S3(); -const translate = new AWS.Translate(); +const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3'); +const { TranslateClient, TranslateTextCommand } = require('@aws-sdk/client-translate'); +const s3 = new S3Client({}); +const translate = new TranslateClient({}); module.exports.handler = async (event, context) => { @@ -102,8 +103,8 @@ module.exports.handler = async (event, context) => { } } - const s3Body = await s3.getObject(params).promise() - const transcribedOutput = s3Body.Body.toString('utf-8'); + const s3Body = await s3.send(new GetObjectCommand(params)) + const transcribedOutput = await s3Body.Body.transformToString(); console.log(transcribedOutput) const originalText = JSON.parse(transcribedOutput).results.transcripts[0].transcript; let translateParams = { @@ -111,9 +112,9 @@ module.exports.handler = async (event, context) => { SourceLanguageCode: sourceLanguageCode, TargetLanguageCode: targetLanguageCode } - const translatedResponse = await translate.translateText(translateParams).promise(); + const translatedResponse = await translate.send(new TranslateTextCommand(translateParams)); const translatedText = translatedResponse.TranslatedText console.log(translatedText) return { translatedText, outputBucket, outputLanguageCode } -} \ No newline at end of file +} From 175507b2ade55bb6c4f5e167b253c2427a7fa1f9 Mon Sep 17 00:00:00 2001 From: kakakakakku Date: Sun, 5 Oct 2025 22:54:10 +0900 Subject: [PATCH 3/4] apigw-lambda-sfn-transcribe-translate-polly-sam: Fix README.md --- apigw-lambda-sfn-transcribe-translate-polly-sam/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/README.md b/apigw-lambda-sfn-transcribe-translate-polly-sam/README.md index 5699afca3..4b8c1bc72 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/README.md +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/README.md @@ -60,7 +60,7 @@ API Gateway handles incoming traffic and sends it to the lambda which in turn in Follow the steps to test the pattern: -1. Copy the audio to the input bucket (available from the output of the cloudformation stack). +1. Copy the audio to the input bucket (available from the output of the CloudFormation stack). ```bash aws s3 cp audio.ogg s3://{input-bucket-name} ``` @@ -70,7 +70,7 @@ Follow the steps to test the pattern: ``` 1. Run websocket client to invoke the API Gateway. Get the API ID from the output of the deployment step ```bash - wscat -c wss://.execute-api..amazonaws.com/dev?proto=https + wscat -c wss://.execute-api..amazonaws.com/dev?proto=https ``` 1. On the next prompt, add the input parameters. Replace the input bucket name. It can be tested with other language codes as well. ```bash @@ -90,4 +90,4 @@ Follow the steps to test the pattern: ---- Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: MIT-0 \ No newline at end of file +SPDX-License-Identifier: MIT-0 From 861cdd4ee3ac0b76be674ed5b90afc0b94caba9f Mon Sep 17 00:00:00 2001 From: kakakakakku Date: Sun, 5 Oct 2025 23:20:37 +0900 Subject: [PATCH 4/4] apigw-lambda-sfn-transcribe-translate-polly-sam: Fix Internal server error in wscat --- .../src/invokeTranslator.js | 2 +- .../src/speech.js | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js index c6cadb6e5..92d765b1d 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/invokeTranslator.js @@ -2,7 +2,7 @@ const { SFNClient, StartSyncExecutionCommand } = require('@aws-sdk/client-sfn'); const { ApiGatewayManagementApiClient, PostToConnectionCommand } = require('@aws-sdk/client-apigatewaymanagementapi'); const stepfunctions = new SFNClient({}); const apig = new ApiGatewayManagementApiClient({ - endpoint: process.env.APIG_ENDPOINT, + endpoint: `https://${process.env.APIG_ENDPOINT}`, }); module.exports.handler = async (event, context) => { diff --git a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js index aad06cc46..169f3a576 100644 --- a/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js +++ b/apigw-lambda-sfn-transcribe-translate-polly-sam/src/speech.js @@ -2,9 +2,9 @@ const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3'); const { PollyClient, SynthesizeSpeechCommand } = require('@aws-sdk/client-polly'); const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); const { GetObjectCommand } = require('@aws-sdk/client-s3'); +const { randomUUID } = require('crypto'); const s3 = new S3Client({}); const polly = new PollyClient({}); -const uuidv1 = require('uuidv1'); module.exports.handler = async (event, context) => { @@ -67,11 +67,18 @@ module.exports.handler = async (event, context) => { const response = await polly.send(new SynthesizeSpeechCommand(speechParams)); let audioStream = response.AudioStream; - let key = uuidv1(); + + const chunks = []; + for await (const chunk of audioStream) { + chunks.push(chunk); + } + const audioBuffer = Buffer.concat(chunks); + + let key = randomUUID(); let params = { Bucket: outputBucket, Key: key + '.mp3', - Body: audioStream + Body: audioBuffer }; const s3Response = await s3.send(new PutObjectCommand(params));