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
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.
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
.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.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'sFilterLogEventsCommand
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.
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.
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.