Get Public Holidays By Country Using Google Calendar API
Tags: javascript, webdev, tutorial, beginners
Published: 2022-01-30 16:10:29

This is something that I picked up while working on a client's project. I was tasked with displaying holidays with respect to user's region. One thing led to another and here I'm writing a small tutorial post here.

## Background

It's not that it's super hard. But the major problem I faced was lack of connecting pieces. Everything felt scattered around and I found it cumbersome to join things together. I thought moment.js might offer any such functionality but to no luck. I did find a sister package named [moment-holiday](https://www.npmjs.com/package/moment-holiday) but I felt like it's not completed as I couldn't find my country in it. A similar package [date-holidays](https://www.npmjs.com/package/date-holidays) is also there and it has good API but yeah - it wasn't completed either.

I finally resorted to Google Calendar API thanks to this [stackoverflow](https://stackoverflow.com/questions/32342753/calculate-holidays-in-javascript) answer.

## Google Calendar API
To use Google Calendar API, you need to have API key from Google. Go to [Google Developer Console](https://console.cloud.google.com/) and from the credential section, create a API for yourself. Each request to calendar API would need that key to process successfully.

### Fetching Holidays
Google Calendar [documentation](https://developers.google.com/calendar/api/v3/reference/events/list) provides a good start to help you understand the basic idea. We'll be making a fetch request using this endpoint

```
GET https://www.googleapis.com/calendar/v3/calendars/{calendarId}/events
```

_calendarId_ is the pain point here. A normal search won't give you a clear idea where exactly would one find this id. Stackoverflow queries end up getting few calendar ids but for rest of them, it took me few hours to get on. Thankfully, we have developers who open source their works to help other. I was expecting Google to have their list available in documentation but unfortunately that wasn't the case.

Anyhow, let's start with some JavaScript and do some grinding.
```js
const BASE_CALENDAR_URL = "https://www.googleapis.com/calendar/v3/calendars";
const BASE_CALENDAR_ID_FOR_PUBLIC_HOLIDAY =
  "holiday@group.v.calendar.google.com"; // Calendar Id. This is public but apparently not documented anywhere officialy.
const API_KEY = "YOUR_API_KEY";
const CALENDAR_REGION = "en.usa"; // This variable refers to region whose holidays do we need to fetch
```

There are other parameters available as well. Complete list can be found in the documentation here. Let's make a fetch request now.

```js
/**
 * Making a fetch request
 */
const url = `${BASE_CALENDAR_URL}/${CALENDAR_REGION}%23${BASE_CALENDAR_ID_FOR_PUBLIC_HOLIDAY}/events?key=${API_KEY}`

fetch(url).then(response => response.json()).then(data => {
const holidays = data.items;
})

// A typical holidays would have this JSON structure:
{
  "kind": "calendar#event",
  "etag": "\"3262600847118000\"",
  "id": "20220417_3s7sr1qa2d9o9oe5cbgd3b6ju0",
  "status": "confirmed",
  "htmlLink": "https://www.google.com/calendar/event?eid=MjAyMjA0MTdfM3M3c3IxcWEyZDlvOW9lNWNiZ2QzYjZqdTAgZW4udXNhI2hvbGlkYXlAdg",
  "created": "2021-09-10T19:00:23.000Z",
  "updated": "2021-09-10T19:00:23.559Z",
  "summary": "Easter Sunday",
  "description": "Observance\nTo hide observances, go to Google Calendar Settings > Holidays in United States",
  "creator": {
    "email": "en.usa#holiday@group.v.calendar.google.com",
    "displayName": "Holidays in United States",
    "self": true
  },
  "organizer": {
    "email": "en.usa#holiday@group.v.calendar.google.com",
    "displayName": "Holidays in United States",
    "self": true
  },
  "start": {
    "date": "2022-04-17"
  },
  "end": {
    "date": "2022-04-18"
  },
  "transparency": "transparent",
  "visibility": "public",
  "iCalUID": "20220417_3s7sr1qa2d9o9oe5cbgd3b6ju0@google.com",
  "sequence": 0,
  "eventType": "default"
}
```

In my case, I was mostly concerned with `summary`, `start` and `end` properties. 

### Fetching for Other Regions
My requirement included displaying holidays based on regions. For this purpose, I need list of all supported regions by Google Calendar. Luckily, someone on GitHub already did the hardwork on this part. Shoutout to [mattn](https://gist.github.com/mattn). You can find the list in this gist:
{% gist https://gist.github.com/mattn/1438183
file=google-calendar-list.txt %}
Hopefully this would help save someone's few hours.