Creating an Automatic Calendar Translator: A Quirky Solution for Students Abroad!

Hey, fellow coders! πŸš€

First weeks in a new country, at a new university, and BAM! The ELTE university system, Neptun, decided to communicate with me in Hungarian. But hey, I'm a CS student! If there's a problem, there's a code solution waiting to be written. πŸ˜‰

Ever found yourself amidst a bunch of Hungarian phrases when all you wanted was to figure out your next class? Yup, I've been there too. And, as the saying goes, when life gives you lemons... code a solution (Okay, I made that up, but let's roll with it)! πŸ‹πŸ’‘

The problem:

My university's Neptun platform (which takes care of virtually everything - from class schedules to dorm applications) generously allowed me to export my calendar. Fantastic! Except... it was all in Hungarian. Now, while Google Calendar let me sync my schedule, it sadly didn’t translate it for me.

A universal issue, isn’t it? All those Magyar terms swirling in your head, when all you want to know is if you’re late for class!

In a nutshell: I needed to get my class schedule from Neptun into my Google Calendar, but everything was in Hungarian. Sure, Neptun provides an .ics export for the calendar, which can easily be integrated into Google Calendar. However, as an international student (all the way from Karakalpakstan 🌍), I needed my schedule to speak my language (or at least English).

The Over-engineered, Fun Solution

Why not create a service that translates those calendar summaries automatically? This project will involve parsing the .ics file from Neptun, translating the event summaries from Hungarian to English, and then regenerating a new .ics file. Oh, and I'll be using GitHub Actions to do this automagically every week!

"Why not build an automatic translator for this?" I thought to myself. An interesting project, a solution to my problem, and a way to flex my coding muscles - win-win-win! 😜

Node.js: My all-time savior. With a couple of nifty npm packages, like ical, node-ical for parsing and @google-cloud/translate for translating, I whipped up a script that would

Steps & Code Snippets:

  1. Parsing the Calendar:

    Using the node-ical npm package, I parsed the calendar .ics file. Easy-peasy!

    const ical = require('node-ical')
    const webEvents = await ical.async.fromURL(calendarURL)
    
  2. Translating the summaries

    Next, I decided to go for the best (read: Google Translate API). A quick loop, and my events got their English makeover.

    const { Translate } = require('@google-cloud/translate').v2
    const translate = new Translate({ projectId, key })
    const [translatedSummary] = await translate.translate(summary, target)
    

    Note: While Google Translate API is awesome, it requires a billing account on GCP. Good news is that the first few requests are part of the free tier. However, always be wary of potential costs!

  3. Recreating the .ics File

    Since our friendly node-ical only parses (how inconsiderate!), I used another package, ics, to recreate the file.

    const { error, value } = ics.createEvents(events)
    writeFileSync(`${__dirname}/class.ics`, value)
    
  4. Going Public and Persistent

    Alright, so now I had my translated calendar. But I wanted to host it somewhere without burning a hole in my student pocket. Enter: Vercel and its new KV feature! A durable Redis database that's free on the hobby plan - exactly what I needed.

  5. Automation with GitHub Actions

    Using GitHub actions, I created a job that translates my calendar and updates it on Vercel. Here's the meat of how it went

    • Action Definition: Every action starts with a definition. This is like the 'about me' section.

        name: 'Translate calendar summary'
        ...
        runs:
          using: 'node16'
          main: 'dist/index.js'
      
    • Custom GitHub Action: I then converted my code into a custom GitHub Action. Thankfully, GitHub Actions supports Node.js without breaking a sweat.

        const core = require('@actions/core')
        ...
        core.setOutput('result', value)
      
    • Security: Using repository secrets in GitHub Actions ensured none of my sensitive data was on display. A lock is always good!

    • Automating The Process: With a simple cron schedule, I made sure this action ran every Monday. Ready for the week, always!

        on:
          schedule:
            - cron: '0 0 * * mon'
      
    • Publishing: With a bit of curl magic, I send my translated calendar to my Vercel endpoint.

        response=$(curl -X POST -d "$result" "$server_url")
      
  6. Vercel's Magic Touch

    With Vercel's serverless functions, I stored the calendar content into Vercel KV and served it when needed.

    await kv.set('ical', rawBody)
    

Wrapping it up:

So there we have it! At the end of this adventure, my Google Calendar finally understands when and where my classes are, in a language I understand. A quirky problem that led me on a journey through npm packages, Google APIs, Vercel's new offerings, and the magic of GitHub Actions.

Remember, when faced with a challenge (even if it's deciphering Hungarian class names), sometimes, a dash of code, a sprinkle of fun, and a good ol' CS student attitude is all you need!

For my fellow students, if you find any "bugs" in class (or my solution), just remember, they're not bugs. They're undocumented features. πŸ˜‰

Yes, this was absolutely overkill, but hey, we're CS students. We live for this stuff, right?

Btw, speaking of documenting: writing this blog post took more time than actual coding the solution, lol.

Conclusion

Automation, when combined with cloud services and modern development tools, offers immense power. This tutorial highlighted the magic of GitHub Actions, Node.js, and Google Cloud in solving real-world problems. Whether you're looking to translate your calendar or are just intrigued by the capabilities of GitHub Actions, this journey offers a testament to the wonders of today's technology.

Share the Magic!

Just as wizards once shared spells, share your solution with fellow mages! Check it out here and be the envy of every wizard and witch (or just your classmates).

Happy coding! πŸš€πŸ–₯️