Build a UGC Live Streaming App with Amazon IVS: Adding Chat to a User's Channel Page (Lesson 8.1)

Build a UGC Live Streaming App with Amazon IVS: Adding Chat to a User's Channel Page (Lesson 8.1)

Welcome to Lesson 8.1 in this series where we're looking at building a web based user-generated content live streaming application with Amazon IVS. This entire series is available in video format on the AWS Developers YouTube channel and all of the code related to the sample application used in this series can be viewed on GitHub. Refer to the links at the end of the post for more information.

Todd Sharp
Amazon Employee
Published Jan 3, 2024

Intro

In lesson 8, we'll focus on the social features of the StreamCat application. We'll start off in this lesson by learning how the application adds live chat to a user's channel page to facilitate interaction between stream participants.

Adding Chat to a User's Channel

If you recall from earlier lessons, when a user registers for a new account, the StreamCat application creates a dedicated Amazon IVS channel, chat room and stage for real-time streams. The chat room information is persisted in a ChatRoom entity. Also note the ChatMessage entity which contains a record of every message posted to a ChatRoom during a Stream.
User, Chat Room, Chat Message Relationship
User, Chat Room, Chat Message Relationship
Because chat is a piece of functionality that is re-used in multiple places in StreamCat, it's bundled into a re-usable component. The HTML markup for this component contains a container that will render the chat messages as they are posted, and an <input> that is used to post a new chat message.
In this component, we're passing the chatArn, chatEndpoint, and the broadcastType (real-time, or low-latency) to Alpine.JS in the chatmodel (line 2).
The init() function of the chat component gets a chat participant token and sets data from that token into scope. It then initializes a WebSocket connection to the chatEndpoint and calls initChat().
The getChatToken() function makes a request to the /api/chat/token endpoint.
The endpoint generates a chat token via the ChatRoomService with the current user's id and username (or a new UUID and random name for anonymous users).
The createChatToken() method of the ChatRoomService uses the AWS SDK for JavaScript (v3) to issue a CreateChatTokenCommand which returns the chat token. By default, all users are granted the SEND_MESSAGE capability. Admin users are granted additional capabilities to handle disconnecting users and deleting messages.
After the token is obtained and the connection is established, the initChat() function adds onopen and onmessage handlers to the connection.
When new messages are received, they are pushed to the messages array which updates the chat view to render the new message and scrolls the container to display the new message.
The sendChat() function calls send() on the chatConnection, passing it an object with an Action of SEND_MESSAGE and a Content key with the sanitized chat message (to prevent HTML injection).
The Utils.stripHtml() static method uses the DOMParser to return only the textContent from the message.

Persisting Chat Messages

In order to provide chat logs and replay chat messages during VOD playback, StreamCat archives all of the chat messages from a live stream in the database. If you remember from the architectural overview in lesson 1.4, we created an IVS Chat Logging configuration which logs all chat messages (or events) to CloudWatch. To make it easier to retrieve these messages, StreamCat copies the chat messages from the CloudWatch logs into its own database after a live stream has concluded. This work is done in the AWS Lambda function that is triggered by the Amazon IVS events via Amazon EventBridge.
When a 'Stream End' event is received, we retrieve the Stream from the database.
And the ChatRoom:
The chat logs in CloudWatch are stored in a log that uses a standard naming convention that includes the last part - the id - of the arn from the ChatRoom.
We can use this chatLogName variable, and the streamStartedAt and streamEndedAt timestamps to retrieve the chat messages that were posted to the user's chat room during a given live stream.
The getChatMessages() function uses the CloudWatch SDK to retrieve the chat messages (events).
💡 Note: The CloudWatch SDK's FilterLogEventsCommand returns up to 1 MB (up to 10,000 log events), so if your chat log is larger, you'll have to implement pagination.
Since CloudWatch stores all chat events, the FilterLogEventsCommandOutput returned via the SDK will not be quite ready to persist to the database. There could be moderation events, for example. To get a proper log of events, we parse the event array and remove any deleted messages.
Finally, the parsed events are inserted into the database.

Summary

In this lesson, we learned how the StreamCat application implements live chat for a user's live stream channel. We also saw how logged chat messages are retrieved from CloudWatch and stored in the application's database for retrieval and display during VOD playback. In a future lesson, we'll look at how VOD playback handles showing chat messages at the proper time in the video. In the next lesson, we'll look at how StreamCat allows streamers to invite a chat user to join their live stream.

Links

Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.

Comments