How I Built a Google Calendar Add-on for Esports Fans
I made Tournacat, an add-on that syncs upcoming Esports tournament schedules to Google Calendar. Three months later, Tournacat has over 90 users and is slowly growing.
Here, I want to walk through my experience of building Tournacat using Cloudflare Worker, Hugo, and Google Apps Script.
Along the way, I encountered some interesting challenges. Specifically, I want to share my anecdotal experience with issues I encountered while developing the Tournacat add-on using Google Apps Script.
Why Did I Make Tournacat
Tournacat started as an idea from D2GCal, a link to a Google Calendar featuring upcoming Dota 2 tournaments available for purchase on Gumroad.
I built Tournacat out of the frustration of missing out on big Dota 2 matches. I was tired of constantly scouring the internet to find out when my favorite matches were happening.
As an avid Esports fan, I knew there had to be a better way (cliché I know). So, I started building Tournacat for my own use.
Today, Tournacat has grown to support major Esports titles including Counter-Strike, Dota 2, LoL, Valorant, Overwatch, and more.
Why Google Calendar
I use Google Calendar extensively in my daily life, from scheduling meetings to keeping track of personal events. So, having an Esports schedule alongside everything in one place is a huge plus.
With Tournacat, you can just install the add-on to your Google Calendar and let it work its magic. It's a seamless solution that integrates perfectly with Google Calendar.
Existing Solutions (Calendars)
I've been on the lookout for a solution like Tournacat for years. I've tried all sorts of public Esports calendars in the past, but they always fell short in one way or another.
Either the author of the calendar stopped updating it, or it was just an unreliable source that was prone to human error. It got to the point where I gave up on ever finding a calendar that actually worked.
Tech Stack
Tournacat is built using a variety of tools and technologies. The tech stack includes:
- Frontend — Hugo
- Backend — Cloudflare Worker
- Add-on — Google Apps Script
Hugo
Hugo is a static site generator that I used to create the Tournacat website. I decided to use Hugo for two main reasons:
- I'm not particularly skilled in front-end development, so I wanted to use a static site generator that would allow me to use pre-built themes without having to write much front-end code myself. Hugo fit the bill perfectly in this regard
- Second, Hugo is known for its speed and ease of use. I wanted to be able to iterate quickly and not have to spend a lot of time fussing with my site's performance or configuration. Hugo's documentation and tooling made it easy to get up and running quickly. With that, I was able to focus on building out the content for Tournacat’s website rather than worrying about technical details.
I then hosted the website on Cloudflare Pages. Using Cloudflare Pages allowed me to keep costs down, as I didn't need to pay for expensive hosting services
Cloudflare Worker
For the backend, I decided to go with Cloudflare Worker. Cloudflare Worker is a serverless computing platform that allows you to run JavaScript code on the edge.
To make my life easier, I decided to build the backend server Tournacat on top of a framework — Worktop, a lightweight Cloudflare Worker web framework that simplifies the development of APIs using TypeScript.
Given the opportunity to start over, I would consider using Hono instead, as it appears to be more actively maintained on GitHub.
My decision to choose Cloudflare Worker was based on my comfort level with it, having done several previous projects with it. The developer experience was nothing short of amazing, and deployment was easy. Furthermore, it was affordable with a generous free tier.
While the performance was impressive, it was not the main reason why I picked it.
Google Apps Script
Google Apps Script is the core technology behind the Tournacat add-on. It is a scripting language based on JavaScript that allows you to extend and automate Google Workspace products like Google Calendar, Sheets, and Drive.
While building Google Workspace add-ons is possible with other coding languages (runtimes), I decided to go for Google Apps Script anyway due to convenience. Frankly, I never thought that I’d be impressed at how simple it is to build a workspace add-on!
Do keep in mind that it does come with some limitations and quotas.
Navigating the Bumps
Creating a Google Workspace add-on is relatively straightforward. The add-on tutorial provided by Google Workspace is pretty easy to follow.
In short, It took me a day to figure out most things and about a week to get the add-on approved and published on Google Workspace Marketplace.
Advantages
- One of the pros of using Google Apps Script is that it literally costs nothing to run
- Since it's JavaScript, it's easy for me to pick up and start working with
Cons
- Although Google claims that Apps Script is now supported by the V8 runtime, it doesn't actually support Promises or async-await (Issue Tracker). Consequently, I had to resort to using workarounds like triggers (Stackoverflow references: 1, 2).
- Rolling out/publishing changes to the Workspace add-on is rather unorthodox. I noticed this when one of my users couldn’t get their time-based triggers to work properly after a new deployment. Turns out the “correct” way to update a workspace add-on is to edit a versioned deployment instead of creating a new one (Stackoverflow reference).
3. It has to respect the limits set by Google. However, it wasn't documented if the limits were shared across all add-on users cumulatively (hint: it is not).
4. Lastly, I came across an authentication-related issue (Stackoverflow references: 1, 2) when attempting to use Google Apps Script as a webhook to allow my users to automatically activate their subscriptions after payment. Some answers suggested temporarily disabling the V8 runtime to fix this.
Despite these hiccups, Google Apps Script is nice to work with. It gets 90% of the job done very effectively and the last 10% is the challenges that I mentioned.
Some Lessons Learned
- Use what makes that the most productive. Don’t worry about picking the perfect tech stack that handles scale.
- Users couldn’t care less about your code. Nobody except you cares about the fancy frameworks, design patterns, or architecture used.
- Keep your deployment simple. This allows for fast iterations. While I could have gone all-in with AWS and set up a sophisticated Terraform setup, I realized that I would have taken more time to ship if I were to go this route.
Closing Thoughts
I have always had the itch to build a micro SaaS as a challenge to myself. So, I decided to build one inconsequentially. I simply enjoy building stuff that people want to use.
Having that said, building a product with real users was not exactly what I thought it would be — keeping my head down and coding away. I had to sometimes interact with users and understand their needs.
I must admit that marketing is not something I truly enjoy. But, I suppose that it's a necessary job that comes with building a product.
Overall, building Tournacat was a rewarding experience. Seeing Tournacat slowly grow and gain traction has been quite fun!