How I fully automated my Twitter chess videos with Remotion and AWS♟️
Lately, I've been playing chess regularly and wanted to do a chess-related project. While searching for inspiration, I came across the Chess API and got an idea.
I've also been playing around with Remotion, a video creation tool that lets you programmatically create videos using React. I realized I could use Remotion to make videos showcasing my chess stats and progress♟️
Remotion allows you to fetch data before rendering using an async
function inside the calculateMetadata
prop of your <Composition />
. This means I could fetch my chess data with the Chess API and render a video based on that data.
My Video Template
Given my limited artistic skills, I wanted to keep my videos simple. I decided to create a "weekly overview" video that displays:
The number of games I played
The number of wins, draws, and losses
The highest-rated opponent I defeated
How my rating changed over the week
Since I mostly play Rapid games, I included only those.
I used Figma to sketch the scenes for reference:
Then I created a video based on this design. To start, I used hardcoded placeholder values instead of real data.
The video creation process was quicker than expected. Remotion became intuitive after a few hours, thanks to its well-written documentation. Here’s the video template I made:
Data fetching
Next, I needed to replace the placeholder props with actual data. This turned out to be trickier than I thought. To fetch player's games, you can use this endpoint:
https://api.chess.com/pub/player/{username}/games/{YYYY}/{MM}
Where:
"YYYY" is the four-digit year
"MM" is the two-digit month
To fetch all games for a specific week, I needed to determine the month and year. If the week includes the end and start of a new month, I had to send two requests with the correct month (and year) numbers.
Luckily, this wasn't too hard. I just needed to find the dates of Monday and Sunday to see if two requests were needed and to get the MM
and YYYY
numbers.
The harder part was getting pre-game ratings, which are needed to show the highest-rated opponent I defeated and track my rating changes. Unfortunately, the fetched game data only includes post-game ratings. I realized that a pre-game rating is the same as the post-game rating of the previous game. Unfortunately, this brought up a few issues:
What if the previous game was last month?
Or even worse, what if the player took a break and his previous game was months or years ago?
What if it was the player's first game ever?
To solve these problems, I used the "monthly archives" endpoint:
https://api.chess.com/pub/player/{username}/games/archives
This endpoint returns an array of monthly archives available for the user.
{
"archives":[
...
"https://api.chess.com/pub/player/filip_melka/games/2024/06",
"https://api.chess.com/pub/player/filip_melka/games/2024/07"
]
}
Using this array, I could find the month and year of the previous game to get its post-game rating (which is the pre-game rating for the current game). This took some time to figure out. 😅
Given that my main function uses many helper functions (nine to be precise), I decided to try something new: testing with Jest. I went through the docs and wrote tests for my helper functions. I expected all tests to pass easily, but I found bugs in several functions.
After fixing these bugs, all tests passed.
With these fixes, I could create videos dynamically based on the current data (🔗GitHub). Now, let's automate it!
Remotion Lambda
In addition to rendering videos locally, Remotion also allows you to render videos in the cloud using Remotion Lambda.
Despite my inexperience with AWS, setting up the Lambda function was straightforward with the instructions in Remotion's documentation.
When triggered, the function renders the video in the cloud and stores it in an S3 bucket.
Posting Rendered Videos to Twitter
This led to another idea: writing a Lambda function that takes the rendered video from the S3 bucket and posts it on my Twitter.
I created a Twitter developer account and set up a new project to be able to use the Twitter API.
Then, I created a new 'video-to-twitter' Lambda function. The first task was to figure out how to trigger it when a new video is stored in my S3 bucket. This was relatively easy. I navigated to my S3 bucket, opened the "Properties" tab, and under "Event notifications," I clicked on "Create event notification" and chose my new Lambda function as the destination. This triggered my Lambda function and gave me access to the video. The only difficulty was managing Roles and Permissions due to my inexperience with AWS. Fortunately, Amazon's chatbot 'Q' helped me resolve these issues by providing guidance.
Once all permissions were set, I wrote code to take the newly rendered video from the S3 bucket and post it on Twitter using the Twitter API.
Scheduling
Currently, triggering the Remotion Lambda function manually requires me to open up the project on my laptop and use the CLI. Although this doesn't take much time, I wanted it to run automatically every Monday.
Luckily, apart from using the CLI, you can also trigger the Lambda function using NodeJS, as shown in the docs.
I created a new Lambda function that triggers the Remotion Lambda function. After watching this tutorial on triggering functions using CRON expressions, I set up the function to run every Monday - cron(0 6 ? MON *)
.
How It All Works
Here is a diagram of my automation workflow:
Could this be simplified? Probably. I used a "trial-and-error" approach when building this project, and as I learn more about AWS, I might redesign it to be more efficient.
What I learned
Although it was a bit frustrating sometimes, it was a fun project and something I had never done before. Among other things, I learned:
Creating videos using Remotion
Using Jest for testing
Rendering videos in the cloud
Scheduling and triggering functions
Posting videos on Twitter using the Twitter API
Familiarized myself with AWS
Subscribe to my newsletter
Read articles from Filip Melka directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Filip Melka
Filip Melka
Hi there!👋 I’m Filip, an enthusiastic software development student👨🎓 My passion for learning led me to pursue a path in software development. I believe software has the incredible potential to revolutionize the learning experience, making it more accessible, engaging, and rewarding. With the rapid advancements in AI and other technologies, I'm excited about the potential to make a positive impact in education, and I’m eager to be a part of this transformation. Why did I start this blog? Mainly for two reasons. First, it keeps me motivated. As an aspiring software developer, I encounter 🐞 every day and sometimes feel like giving up. Writing about my side projects and what I’m learning keeps me going💪 Second, writing helps me organize my thoughts and grasp complex topics more thoroughly. If my posts help someone else too, that’s a huge win!