How to poll attendees using Chime SDK Classroom Tutorial

Amazon Chime SDK

The Amazon Chime SDK is a set of real-time communications components that can be used to quickly add audio, video, and screen sharing capabilities to web or mobile applications. Amazon Chime SDK allows companies to leverage the same communication infrastructure and services that power Amazon Chime, an online meeting service from AWS, and deliver engaging experiences in their applications.

Amazon Chime SDK is used to build real-time media applications that can send and receive audio and video while also enabling content sharing. The Amazon Chime SDK works independently of any Amazon Chime administrator accounts and does not interfere with meetings hosted on Amazon Chime. Instead, Amazon Chime SDK provides tools for developers to build and customize their own meeting applications. 

This article is a tutorial that will show readers how to use the Amazon Chime SDK to build an online classroom in Electron and React.

Application Architecture Diagram 

Application Logical Diagram

Video demonstration: https://youtu.be/lQAbndL1J7s

The Project Tree

Screenshot from the project repository

The architecture of the project is divided into several folders:

  • The ‘app’ folder contains the source code of the application (in Typescript) including the code concerning Chime SDK.
  • The folders “configs” and “internals” are reserved for configuring babel, the standard code for the project and internal code for modules. These folders are of no interest to us.
  • Likewise, the third folder “resources” does not interest us. This folder contains resources for the application: mostly icons, images and CSS files.
  • The second-to-last folder, named “script”, allows the deployment of AWS resources and more generally of the application.
  • And finally, there is the “serverless” folder that determines the resources to be deployed for the project. To learn more about Serverless, visit this link.

Creating the Lambdas

Lambda functions are required to respond to the different actions available to users within the application. The lambdas, and more generally the entire project’s resources, are deployed using a CloudFormation stack and a YAML file that gathers all of the necessary resources.

There are 3 possible poll-related actions that users can take: 

  • Create a poll
  • Answer in a poll
  • View the poll responses

As a result, 3 lambdas are required. The polls and answers are stored in a DynamoDB database.

1. Creating a Poll – First Lambda (link)

The polling project is divided into the following folders:

  • The ID of the meeting where the poll takes place
  • The title of the poll
  • Poll responses

This information will be sent in a body of the/an HTTP request. The first part is to check that this information is present (see code HERE)

After that, an ID is generated for this survey poll (see code HERE) and we register it in our database (see code HERE).

2. Answering a Poll – Second Lambda (link)

The logic of this lambda function is exactly the same as the previous one. It verifies the required elements and registers the information in a database. The only difference here is the required elements – only the survey ID and the selected answer are needed.

3. Viewing Poll Responses – Third Lambda (link)

The logic of the third lambda function is different but remains very simple. We make a query to the database containing all the answers by searching for the ID of a survey (see code HERE). All responses are collected and tabulated. (see code HERE).

The deployment of the new lambdas and database is done by adding these newly created resources (the three lambda functions and the two new databases) to the existing “serverless.yml” file.

Add a Component and Create a Basic Interface

A. Source Code Structure

Now that we have a global view of the project’s organization, we’re going to determine what we want to change. Let’s go to the “app” folder.

Here we find a long list of folders. Only a few are of interest to us:

  • “components” which contains all the components of the application (connection page, screenshare interface, chat, etc.)
  • “i18n” which contains the application’s language files. If text is added, it will be placed in the language files of this folder.  More information on i18n can be found here.
  • “enums” which contains different enumerations representing global and important information

B. Add a Component

Now that we have a global view of the project’s architecture, we will finally add our code.

The goal here is to add a poll to the project. To create access to this poll, we add a new icon in the taskbar accessible only when a user is not sharing his screen; the Chime Demo application does not allow users to take actions like participating in a poll when sharing their screens. The “Controls.tsx” file contains code for the action bar that’s displayed at the bottom of the meeting screen. (see screenshot below)

The poll will be available from a modal. We will make two different modals depending on whether the user is a student or a teacher/presenter. It is possible to retrieve the status information of the user using “state.classMode” (see code HERE) These two modals represent two different “hooks” that we will define in a file named “Poll.tsx” that manages the behavior of our poll, regardless of the status of the user.

C. Poll Source Code

Before defining the possible behaviors, let’s set up some useful data such as the status of the current poll, the poll information, a type defining the properties of our hooks, the statistics of the answers to the poll, etc. (see HERE)

With these basic types defined, let’s tackle the main function that teachers/presenters will use to create a poll (see code HERE).

Five steps are declared:

  • First, we retrieve the properties passed to our hooks
  • Then we create a poll with the type we created above.
  • We use ‘Intl’, a library to create text in different languages
  • We recover the Chime SDK wrapper to retrieve the room ID.
  • We create a variable ‘poll stats’ which will be used later when the poll is closed

Now that we have declared our variables, let’s move on to the creation of the display. For our poll, we need one title, four possible answers, a button to confirm, and another to cancel. We will use CSS styles from screenpicker to make it easier.

As seen HERE, the main body contains the results of the poll if present, as well as all possible answers to the poll with an entry for it to be modified.

Then “status” is added so that it is displayed between the body of the program and the bottom (see code HERE)

We end with the confirm button (see code HERE), one of the most important elements of the poll interface. We divided this task into into several smaller ones:

1. If a Poll is Already Active (see code HERE)

If the poll is active, we change the poll status  to “inactive” and everyone is notified of this change. This notification is done by sending a “topic” to users (“topic” being the title of a notification message).

To retrieve the statistics of the poll, we will use the previously created lambda. In the case of a positive response, no error has occurred, so we just interpret the result and update the variable that is stored in the statistics. If any error has occurred, it is important to notify the user through the “status” variable.

Poll results as seen by a teacher/presenter

2. Creation of a New Poll (see code HERE)

This part is similar to the previous one. For the creation of our new poll, we use our previously created lambda “createpoll” that allows us to store poll data (poll title, poll ID, and all the possible answers) in a database. 

For this request, we pass a payload with the necessary information. Note that the meeting ID must be retrieved from the Chime SDK wrapper provided in the demo. 

If everything goes well in the execution of the request, the poll information is updated and all the participants of the meeting are notified of the new poll. This notification is done in the same way as before, with “sendMessage” from the Chime SDK wrapper. Only the “topic” is different.

The user is then notified if there was an error or if the poll was created correctly.

Poll interface seen by a teacher/presenter

D. Attendee’s Part

In this part, there are fewer elements. All the participant has to do is complete the poll: HERE.

You will recognize existing variables seen in the previous part. For example, the ‘intl’ variable for text in several languages, ‘props’ which contains the properties of the previous poll, ‘status’ which informs users of the success or failure of different events, and lastly, ‘poll’ which contains current poll data.

Now we go directly to the display. Two cases are possible, identical to the previous section: if there is a poll in progress, or not:
If no poll is in progress, just an informative message is displayed (see code HERE)

Message indicating that no poll is in progress

Otherwise, the poll and the possible answers are displayed using the same code architecture as the previous part with some changes. In the display, we replace the text for possible answers with buttons containing the answers that allow participants to click and vote. (see code HERE)

Poll interface as seen by attendees/students

The most important thing is the behavior of the button. When an attendee presses it, a request is sent to the lambda to add a vote to the poll. Once this is done, the attendee cannot vote a second time and is informed of the result of his action. Once the presenter/teacher closes the poll, they can access poll results.

Poll interface after an attendee/student votes

Poll results after a poll is closed


Conclusion

In this article, we have demonstrated how to add a component to an already existing demo, specific to AWS Chime SDK. Teachers and presenters interested in adding a polling feature to their meeting platforms could easily do so using this process.