Skip to content
This repository was archived by the owner on Mar 17, 2026. It is now read-only.

Commit 6d8ff59

Browse files
nodejs20.x - migrate sample from aws-sdk v2 to v3 (#10)
1 parent 7f84c71 commit 6d8ff59

File tree

11 files changed

+224
-179
lines changed

11 files changed

+224
-179
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ jobs:
2121
runs-on: ubuntu-latest
2222
steps:
2323
- name: Checkout
24-
uses: actions/checkout@v3
24+
uses: actions/checkout@v4
2525

2626
- name: Setup Python
27-
uses: actions/setup-python@v4
27+
uses: actions/setup-python@v5
2828
with:
29-
python-version: '3.9'
29+
python-version: '3.10'
3030

3131
- name: Setup Nodejs
32-
uses: actions/setup-node@v3
32+
uses: actions/setup-node@v4
3333
with:
34-
node-version: 16
34+
node-version: 20.x
3535

3636
- name: Install dependencies
3737
run: |
@@ -86,7 +86,7 @@ jobs:
8686
8787
- name: Upload the Diagnostic Report
8888
if: failure()
89-
uses: actions/upload-artifact@v3
89+
uses: actions/upload-artifact@v4
9090
with:
9191
name: diagnose.json.gz
9292
path: ./diagnose.json.gz

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ usage:
1111
install:
1212
@which localstack || pip install localstack
1313
@which awslocal || pip install awscli-local
14-
@which serverless || npm install -g serverless
14+
@which serverless || npm install -g serverless@3.38.0
1515
npm install
1616

1717
## Deploy the Transcribe sample
1818
deploy:
19+
1920
sls deploy --stage local --verbose
2021
make configure
2122

package.json

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
{
2-
"dependencies": {
3-
"aws-sdk": "^2.1386.0",
4-
"serverless": "^3.31.0",
5-
"serverless-lift": "^1.26.1",
6-
"serverless-localstack": "^1.1.1"
7-
}
2+
"type":"module",
3+
"dependencies": {
4+
"aws-sdk": "^2.1386.0",
5+
"serverless": "^3.38.0",
6+
"serverless-lift": "^1.26.1",
7+
"serverless-localstack": "^1.1.1",
8+
"@aws-sdk/client-s3": "^3.0.0",
9+
"@aws-sdk/client-sqs": "^3.0.0",
10+
"@aws-sdk/client-ses": "^3.0.0",
11+
"@aws-sdk/client-transcribe": "^3.0.0"
12+
}
813
}
9-

serverless.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ plugins:
1414
custom:
1515
defaultStage: local
1616
profile: default
17-
runtime: nodejs14.x
17+
runtime: nodejs20.x
1818
localstack:
1919
stages: [local]
2020

2121
provider:
2222
name: aws
23-
runtime: nodejs14.x
23+
runtime: nodejs20.x
2424
environment:
2525
S3_AUDIO_BUCKET: ${self:service}-${opt:stage, self:provider.stage}-records
2626
S3_TRANSCRIPTION_BUCKET: ${self:service}-${opt:stage, self:provider.stage}-transcriptions
@@ -45,7 +45,7 @@ provider:
4545

4646
functions:
4747
transcribe:
48-
handler: src/transcribe.process
48+
handler: src/transcribe.transcribe_process
4949
events:
5050
- s3:
5151
bucket: ${self:provider.environment.S3_AUDIO_BUCKET}

src/jobs.js renamed to src/jobs.mjs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
'use strict';
22

3-
const awsSdk = require('aws-sdk');
3+
import { S3, ListObjectsCommand } from "@aws-sdk/client-s3";
44

55
const endpoint = process.env.AWS_ENDPOINT_URL
6-
const s3 = new awsSdk.S3({endpoint: endpoint, s3ForcePathStyle: true});
6+
const s3 = new S3({
7+
endpoint: endpoint,
8+
forcePathStyle: true,
9+
credentials: {
10+
accessKeyId:'test',
11+
secretAccessKey:'test'
12+
},
13+
});
714

815
// This function is triggered by an HTTP request using the GET method.
916
// The function returns a list of all the transcription jobs stored in the S3 bucket.
10-
exports.list = async (event, context, callback) => {
17+
export const list = async (event, context, callback) => {
1118
var htmlStr = `
1219
<!DOCTYPE html>
1320
<html>
@@ -33,8 +40,8 @@ exports.list = async (event, context, callback) => {
3340
};
3441

3542
try {
36-
const { Contents } = await s3.listObjects(params).promise();
37-
const keys = Contents.map(({ Key }) => Key);
43+
const data = await s3.send(new ListObjectsCommand(params));
44+
const keys = data.Contents.map(({ Key }) => Key);
3845
keys.forEach(object => {
3946
htmlStr += `<li><a href="https://s3.localhost.localstack.cloud:4566/${bucketName}/${object}">${object}</a></li>`
4047
});

src/presign.js renamed to src/presign.mjs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1-
const AWS = require('aws-sdk');
2-
const credentials = new AWS.Credentials({
3-
accessKeyId: 'test',
4-
secretAccessKey: 'test'
1+
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
2+
import { PutObjectCommand, S3 } from '@aws-sdk/client-s3';
3+
4+
const s3 = new S3({
5+
endpoint: 'https://s3.localhost.localstack.cloud:4566',
6+
forcePathStyle: true,
7+
credentials: {
8+
accessKeyId:'test',
9+
secretAccessKey:'test'
10+
},
511
});
6-
AWS.config.credentials = credentials;
7-
8-
const s3 = new AWS.S3(
9-
{
10-
endpoint: 'https://s3.localhost.localstack.cloud:4566',
11-
s3ForcePathStyle: true,
12-
}
13-
);
1412

1513
// This function is triggered by an HTTP request using the POST method.
1614
// The function returns a presigned URL to upload a file to S3.
17-
exports.post = async (event) => {
15+
export const post = async (event) => {
1816
const bucketName = 'aws-node-sample-transcribe-s3-local-records';
1917
const key = event.queryStringParameters.filename;
2018
const expiration = 3600;
2119

2220
try {
23-
const url = await s3.getSignedUrlPromise('putObject', {
21+
const url = await getSignedUrl(s3, new PutObjectCommand({
2422
Bucket: bucketName,
2523
Key: key,
26-
Expires: expiration,
24+
}), {
25+
expiresIn: expiration,
2726
});
27+
console.log('Presigned URL: ', url);
2828
return {
2929
statusCode: 200,
3030
body: {"url": url},

src/queue.js

Lines changed: 0 additions & 101 deletions
This file was deleted.

src/queue.mjs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import { S3, GetObjectCommand } from "@aws-sdk/client-s3";
2+
import { SES, SendEmailCommand } from "@aws-sdk/client-ses";
3+
import { SQS, SendMessageCommand } from "@aws-sdk/client-sqs";
4+
5+
const endpoint = process.env.AWS_ENDPOINT_URL;
6+
const sqs = new SQS({
7+
endpoint: endpoint,
8+
credentials: {
9+
accessKeyId:'test',
10+
secretAccessKey:'test'
11+
},
12+
});
13+
const ses = new SES({
14+
endpoint: endpoint,
15+
credentials: {
16+
accessKeyId:'test',
17+
secretAccessKey:'test'
18+
},
19+
});
20+
const s3Client = new S3({
21+
endpoint: endpoint,
22+
forcePathStyle: true,
23+
credentials: {
24+
accessKeyId:'test',
25+
secretAccessKey:'test'
26+
},
27+
});
28+
const queueUrl = `${endpoint}/000000000000/aws-node-sample-transcribe-s3-local-jobs`;
29+
const transcriptionBucket = process.env.S3_TRANSCRIPTION_BUCKET
30+
31+
// This function consumes the event from s3 PutObject and pushes a new message to SQS.
32+
const producer = async (event, context, callback) => {
33+
let statusCode = 200;
34+
let message;
35+
36+
try {
37+
// Get the record from the s3 event
38+
const records = event.Records;
39+
const sqsSendMessagePromises = records.map(async (record) => {
40+
const params = {
41+
Bucket: transcriptionBucket,
42+
Key: record.s3.object.key,
43+
};
44+
45+
try {
46+
const data = await s3Client.send(new GetObjectCommand(params));
47+
const str = await data.Body.transformToString();
48+
console.log("str: ", str);
49+
50+
const jsonContent = await JSON.parse(str);
51+
console.log("jsonContent: ", jsonContent);
52+
53+
// Send message to SQS queue
54+
const sendMessageParams = {
55+
QueueUrl: queueUrl,
56+
MessageBody: jsonContent.results.transcripts[0].transcript,
57+
MessageAttributes: {
58+
AttributeName: {
59+
StringValue: "Attribute Value",
60+
DataType: "String",
61+
},
62+
},
63+
};
64+
await sqs.send(new SendMessageCommand(sendMessageParams));
65+
} catch (err) {
66+
console.error("Error getting object from S3 bucket: ", transcriptionBucket, err);
67+
throw err;
68+
}
69+
});
70+
71+
await Promise.all(sqsSendMessagePromises);
72+
callback(null, { message: 'Message sent successfully' });
73+
message = "Message accepted!";
74+
} catch (error) {
75+
console.log(error);
76+
message = error.message;
77+
statusCode = 500;
78+
}
79+
80+
return {
81+
statusCode,
82+
body: JSON.stringify({
83+
message,
84+
}),
85+
};
86+
};
87+
88+
// The function is triggered by the SQS queue.
89+
// A function is triggered whenever there is a new message in the queue.
90+
// When the function is triggered, it sends an email to 'sender@example.com'
91+
const consumer = async (event) => {
92+
for (const record of event.Records) {
93+
const params = {
94+
Destination: {
95+
ToAddresses: ["recipient@example.com"] // Email address/addresses that you want to send your email
96+
},
97+
Message: {
98+
Body: {
99+
Text: {
100+
Charset: "UTF-8",
101+
Data: `Hey there! Here is your generated transcribed file:\n${record.body}`
102+
}
103+
},
104+
Subject: {
105+
Charset: "UTF-8",
106+
Data: "Test Email - JOB COMPLETED SUCCESSFULLY"
107+
}
108+
},
109+
Source: "sender@example.com" // Sender email address
110+
};
111+
112+
try {
113+
// Send email to recipient
114+
const result = await ses.send(new SendEmailCommand(params));
115+
console.log("Email sent successfully: ", result);
116+
} catch (error) {
117+
console.error("Error sending email: ", error);
118+
}
119+
}
120+
};
121+
122+
export { producer, consumer };

0 commit comments

Comments
 (0)