Prepare the browser script - AWS SDK for JavaScript

Help us improve the AWS SDK for JavaScript version 3 (V3) documentation by providing feedback using the Feedback link, or create an issue or pull request on GitHub.

The AWS SDK for JavaScript V3 API Reference Guide describes in detail all the API operations for the AWS SDK for JavaScript version 3 (V3).

Prepare the browser script

This topic is part of a tutorial about building an app that transcribes and displays voice messages for authenticated users. To start at the beginning of the tutorial, see Build a transcription app with authenticated users.

There are three files, index.html, recorder.js, and helper.js, which you are required to bundle into a single main.js using Webpack. This topic describes in detail only the functions in index.js that use the SDK for JavaScript, which is available here on GitHub.

Note

recorder.js and helper.js are required but, because they do not contain Node.js code, are explained in the inline comments here and here respectively GitHub.

First, define the parameters. COGNITO_ID is the endpoint for the Amazon Cognito User Pool you created in the Create the AWS resources topic of this tutorial. It is formattedcognito-idp.AWS_REGION.amazonaws.com/USER_POOL_ID. The user pool id is ID_TOKEN in the AWS credentials token, which is stripped from the app URL by the getToken function in the 'helper.js' file. This token is passed to the loginData variable, which provides the Amazon Transcribe and Amazon S3 client objects with logins. Replace "REGION" with the AWS Region, and "BUCKET" with the Replace "IDENTITY_POOL_ID" with the IdentityPoolId from the Sample page of the Amazon Cognito identity pool you created for this example. This is also passed to each client object.

Note

                    Preparing an Amazon Cognito identity pool for the browser script
// Import the required AWS SDK clients and commands for Node.js import "./helper.js"; import "./recorder.js"; import { CognitoIdentityClient } from"@aws-sdk/client-cognito-identity"; import { fromCognitoIdentityPool, } from"@aws-sdk/credential-provider-cognito-identity"; import { CognitoIdentityProviderClient, GetUserCommand, } from"@aws-sdk/client-cognito-identity-provider"; import { S3RequestPresigner } from"@aws-sdk/s3-request-presigner"; import { createRequest } from"@aws-sdk/util-create-request"; import { formatUrl } from"@aws-sdk/util-format-url"; import { TranscribeClient, StartTranscriptionJobCommand, } from"@aws-sdk/client-transcribe"; import { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsCommand, DeleteObjectCommand, } from"@aws-sdk/client-s3"; import fetch from "node-fetch"; // Set the parameters. // 'COGINTO_ID' has the format 'cognito-idp.eu-west-1.amazonaws.com/COGNITO_ID'. let COGNITO_ID = "COGNITO_ID"; // Get the Amazon Cognito ID token for the user. 'getToken()' is in 'helper.js'. let idToken = getToken(); let loginData = { [COGNITO_ID]: idToken, }; const params = { Bucket: "BUCKET", // The Amazon Simple Storage Solution (S3) bucket to store the transcriptions. Region: "REGION", // The AWS Region identityPoolID: "IDENTITY_POOL_ID", // Amazon Cognito Identity Pool ID. }; // Create an Amazon Transcribe service client object. const client = new TranscribeClient({ region: params.Region, credentials: fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region: params.Region }), identityPoolId: params.identityPoolID, logins: loginData, }), }); // Create an Amazon S3 client object. const s3Client = new S3Client({ region: params.Region, credentials: fromCognitoIdentityPool({ client: new CognitoIdentityClient({ region: params.Region }), identityPoolId: params.identityPoolID, logins: loginData, }), });

When the HTML page loads, the updateUserInterface creates a folder with the user's name in the Amazon S3 bucket if its the first time they've signed in to the app. If not, it updates the user interface with any transcripts from the user's previous sessions.

let updateUserInterface; window.onload = updateUserInterface = async () => { // Set the parameters. const userParams = { // Get the access token. 'GetAccessToken()' is in 'helper.js'. AccessToken: getAccessToken(), }; // Create a CognitoIdentityProviderClient client object. const client = new CognitoIdentityProviderClient({ region: params.Region }); try { const data = await client.send(new GetUserCommand(userParams)); const username = data.Username; // Export username for use in 'recorder.js'. exports.username = username; try { // If this is user's first sign-in, create a folder with user's name in Amazon S3 bucket. // Otherwise, no effect. const Key = `${username}/`; try { const data = await s3Client.send( new PutObjectCommand({ Key: Key, Bucket: params.Bucket }) ); console.log("Folder created for user ", data.Username); } catch (err) { console.log("Error", err); } try { // Get a list of the objects in the Amazon S3 bucket. const data = await s3Client.send( new ListObjectsCommand({ Bucket: params.Bucket, Prefix: username }) ); // Create a variable for the list of objects in the Amazon S3 bucket. const output = data.Contents; // Loop through the objects, populating a row on the user interface for each object. for (var i = 0; i < output.length; i++) { var obj = output[i]; const objectParams = { Bucket: params.Bucket, Key: obj.Key, }; // Get the name of the object from the Amazon S3 bucket. const data = await s3Client.send(new GetObjectCommand(objectParams)); // Extract the body contents, a readable stream, from the returned data. const result = data.Body; // Create a variable for the string version of the readable stream. let stringResult = ""; // Use 'yeidlUnit8Chunks' to convert the readable streams into JSON. for await (let chunk of yieldUint8Chunks(result)) { stringResult += String.fromCharCode.apply(null, chunk); } // The setTimeout function waits while readable stream is converted into JSON. setTimeout(function () { // Parse JSON into human readable transcript, which will be displayed on user interface (UI). const outputJSON = JSON.parse(stringResult).results.transcripts[0] .transcript; // Create name for transcript, which will be displayed. const outputJSONTime = JSON.parse(stringResult) .jobName.split("/")[0] .replace("-job", ""); i++; // // Display the details for the transcription on the UI. // 'displayTranscriptionDetails()' is in 'helper.js'. displayTranscriptionDetails( i, outputJSONTime, objectParams.Key, outputJSON ); }, 1000); } } catch (err) { console.log("Error", err); } } catch (err) { console.log("Error creating presigned URL", err); } } catch (err) { console.log("Error", err); } }; // Convert readable streams. async function* yieldUint8Chunks(data) { const reader = data.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) return; yield value; } } finally { reader.releaseLock(); } }

When the user records a voice message for transcriptions, the upload uploads the recordings to the Amazon S3 bucket. This function is called from the recorder.js file.

// Upload recordings to Amazon S3 bucket window.upload = async function (blob, userName) { // Set the parameters for the recording recording. const Key = `${userName}/test-object-${Math.ceil(Math.random() * 10 ** 10)}`; // Create a presigned URL to upload the transcription to the Amazon S3 bucket when it is ready. try { // Create an Amazon S3RequestPresigner object. const signer = new S3RequestPresigner({ ...s3Client.config }); // Create the request. const request = await createRequest( s3Client, new PutObjectCommand({ Key, Bucket: params.Bucket }) ); // Define the duration until expiration of the presigned URL. const expiration = new Date(Date.now() + 60 * 60 * 1000); // Create and format the presigned URL. let signedUrl; signedUrl = formatUrl(await signer.presign(request, expiration)); console.log(`\nPutting "${Key}"`); } catch (err) { console.log("Error creating presigned URL", err); } try { // Upload the object to the Amazon S3 bucket using a presigned URL. response = await fetch(signedUrl, { method: "PUT", headers: { "content-type": "application/octet-stream", }, body: blob, }); // Create the transcription job name. In this case, it's the current date and time. const today = new Date(); const date = today.getFullYear() + "-" + (today.getMonth() + 1) + "-" + today.getDate(); const time = today.getHours() + "-" + today.getMinutes() + "-" + today.getSeconds(); const jobName = date + "-time-" + time; // Call the "createTranscriptionJob()" function. createTranscriptionJob( "s3://" + params.Bucket + "/" + Key, jobName, params.Bucket, Key ); } catch (err) { console.log("Error uploading object", err); } }; // Create the AWS Transcribe transcription job. const createTranscriptionJob = async (recording, jobName, bucket, key) => { // Set the parameters for transcriptions job const params = { TranscriptionJobName: jobName + "-job", LanguageCode: "en-US", // For example, 'en-US', OutputBucketName: bucket, OutputKey: key, Media: { MediaFileUri: recording, // For example, "https://transcribe-demo.s3-REGION.amazonaws.com/hello_world.wav" }, }; try { // Start the transcription job. const data = await client.send(new StartTranscriptionJobCommand(params)); console.log("Success - transcription submitted", data); } catch (err) { console.log("Error", err); } };

deleteTranscription deletes a transcription from the user interface, and deleteRow deletes an existing transcription from the Amazon S3 bucket. Both are triggered by the Delete button on the user interface.

// Delete a transcription from the Amazon S3 bucket. window.deleteJSON = async (jsonFileName) => { try { const data = await s3Client.send( new DeleteObjectCommand({ Bucket: params.Bucket, Key: jsonFileName, }) ); console.log("Success - JSON deleted"); } catch (err) { console.log("Error", err); } }; // Delete a row from the user interface. window.deleteRow = function (rowid) { const row = document.getElementById(rowid); row.parentNode.removeChild(row); };

Finally, run the following at the command prompt to bundle the JavaScript for this example in a file named main.js:

webpack index.js --mode development --target web --devtool false -o main.js
Note

For information about installing webpack, see Bundling applications with webpack.