Reddit Live is a unique feature of reddit.com that comes into play during serious ongoing news events with rapidly evolving information. Essentially, volunteers create a Live Thread where they constantly provide updates to visitors who are eagerly following the event. One instance where Reddit Live was heavily utilized was during Russia's invasion of Ukraine, which had a live thread dedicated to it here: https://www.reddit.com/live/18k2410w0vhnd/.
There are a plethora of ways for people to consume news - through Twitter, websites, television, Reddit, and more. Personally, I have found Reddit Live threads to be a helpful tool due to their simple interface and ability to aggregate news and links from multiple sources in one place.
Today, we are embarking on a project to rebuild Reddit Live using the Raytha platform. Our goal is to push its capabilities to the limits and then take it a step further by incorporating SignalR to achieve real-time functionality without the need for visitors to refresh the page. This will enhance the user experience and make our homegrown version of Reddit Live even more valuable during breaking news events.
Create the data model for breaking news updates
Let's begin by setting up a fresh copy of the Raytha platform, which already comes equipped with two content types: Pages and Posts. For our project, we'll repurpose the Posts content type and add some essential fields for building our own Reddit Live.
By default, Raytha provides three fields for Posts:
Title
Content
CreationTime
However, we'll also include the following three fields:
Link to a tweet: This allows us to easily embed tweets into the Live thread.
Breaking news (checkbox): When this box is checked, we can add a badge to indicate that the post is particularly significant and contains an important update in the ongoing news cycle.
Information was wrong (checkbox): By checking this box, we'll let visitors know that the information in the post is no longer accurate.
With these additional fields, we'll be able to make our Reddit Live thread more informative and efficient for visitors who rely on it for real-time updates.
Update the public facing Liquid templates
Now that we've finalized our data model, it's time to update the web templates in Raytha using liquid syntax. To get started, I created several sample posts to demonstrate how our different options will be displayed.
Before we edit the code, we do want to set the Posts' list view as the home page, so we went ahead and published the list view and set it as the default home page when you visit the website.
In the screenshot below, you'll see each post listed in reverse chronological order with its date and time, title, and content. If a post has been flagged as 'breaking news', a red badge will be displayed next to the title. Similarly, if a post contains false information, its content will be crossed out, and a blue badge indicating the false report will be displayed. If a post includes a link to a tweet, the tweet will be embedded at the bottom of the post. Finally, to help visitors track the thread's popularity, we've included a 'Number of visitors currently viewing this page' count in the top right corner. Additionally, we've added a standard Raytha content page called 'Helpful Info,' which serves as a static reference for visitors who want more information during the event.
I'm pleased with the results of our efforts. In less than an hour, we were able to replicate much of Reddit Live's functionality using the Raytha platform. Not bad at all! However, there's still one major feature we're missing: real-time page refresh using web sockets. Visitors to Reddit Live expect the page to update instantly as new posts are added or changes are made to existing ones. This way, visitors don't have to manually refresh the page themselves to see the latest updates. For this, we have to extend Raytha's functionality using .NET / C# and more specifically, SignalR.
ChatGPT gives us the starter boilerplate code conveniently, but we want to integrate SignalR with the Raytha platform, and more specifically, it should trigger an update for a visitor when there is both a new post, and an update to an existing post.
To accomplish this, we create a directory called EventHandlers and create handlers for both ContentItemCreatedEvent and ContentItemUpdatedEvent. For convenience, we place our LiiveUpdatesHub in the folder too.
Here is our ContentItemCreatedEventHandler.
public class ContentItemCreatedEventHandler : INotificationHandler<ContentItemCreatedEvent>
{
private readonly ICurrentOrganization _currentOrganization;
private readonly IHubContext<LiveUpdatesHub> _hubContext;
public ContentItemCreatedEventHandler(
ICurrentOrganization currentOrganization,
IHubContext<LiveUpdatesHub> hubContext)
{
_currentOrganization = currentOrganization;
_hubContext = hubContext;
}
public async Task Handle(ContentItemCreatedEvent notification, CancellationToken cancellationToken)
{
var viewModel = new LiveUpdatesHub_RenderModel
{
Id = notification.ContentItem.Id,
CreationTime = _currentOrganization.TimeZoneConverter.UtcToTimeZone(notification.ContentItem.CreationTime).ToString(),
PublishedContent = notification.ContentItem.PublishedContent
};
await _hubContext.Clients.All.SendAsync("new_live_update", viewModel);
}
}
The ContentItemUpdatedEventHandler is very similar -- only difference is that it sends a 'replace_live_update' signal instead.
LiveUpdatesHub code came from ChatGPT:
using Microsoft.AspNetCore.SignalR;
namespace Raytha.Application.ContentItems.EventHandlers;
public class LiveUpdatesHub : Hub
{
private static int _pageViews = 0;
public override async Task OnConnectedAsync()
{
_pageViews++;
await Clients.All.SendAsync("updatePageViews", _pageViews);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
_pageViews--;
await Clients.All.SendAsync("updatePageViews", _pageViews);
await base.OnDisconnectedAsync(exception);
}
}
public record LiveUpdatesHub_RenderModel
{
public Guid Id { get; init; }
public string CreationTime { get; init; }
public IDictionary<string, object> PublishedContent { get; init; }
}
Wire up the SignalR C# code to Raytha templates
The above backend code modification portion only took about 15 minutes -- that was the easy part in my opinion. The hard part is the client side javascript where we need to update the page's HTML with the new content we receive from SignalR.
In the _Layout, I include a reference to SignalR's javascript CDN:
The code above updates the live page in real time on 3 separate triggers:
updatePageViews - when a new user connects, it will update the content that indicates how many people are currently viewing the page in real time.
new_live_update - add the new post to the top of the page when one is posted to its visitors.
replace_live_update - modify an existing post if a post was updated.
You can see an animation below where we make a new post in one window and you can see the post appear instantly at the top on the other window:
We hope you found this post enjoyable and get to see the power of how the Raytha content management system can get you from 0 to 90% and then tie it all together with a tiny bit of C# if you want to add more functionality.
ENTREPRENEUR & SOFTWARE ENGINEER, AUSTIN, TX I enjoy tackling a wide array of business challenges ranging from front line product support and operations to sales and marketing efforts. My core expertise is in software development building enterprise level web applications.