Auto add Youtube Live streaming schedule to your Google Calendar

#Summary
This script add a live stream reservation of any Youtuber you choose to your Google calendar.
You can automatically get the streaming schedule of your favorite Youtuber.

#Features
This script can
- automatically register the time, URL and description of plan live streaming reserved by Youtube Channel.
- put URL into location slot, streaming description into Calendar description.
- If the detail of reserved live stream is updated, Calendar event gets also updated.
- If stream is cancelled, event will be cancelled.

##Unables
This scrips does not work for
- premiere video.
- member-only stream.


##Privacy
Of course, this script does not deliver any information of you to me.

#Script

```
let scheduleUpcomingLive=()=> {
  let results = YouTube.Search.list(
    'snippet', {
    channelId: 'CHANNEL ID', //change CHANNEL ID to your favorite Youtuber's Channel ID (You can get it from URL of their channel top page)
    safeSearch: 'none',
    eventType:'upcoming',
    type:'video'
    }
    );
  
  let calendarId = 'YOUR CALENDAR ID';// change YOUR CALENDAR ID to your Google calendar's ID
  let now = new Date()
  let optionalArgs = {
    timeMax: (new Date(now.getTime() + (1095 * 24 * 60 * 60 * 1000))).toISOString(),
    timeMin: (new Date(now.getTime() - ( 7 * 24 * 60 * 60 * 1000))).toISOString(),
    showDeleted: false,
    singleEvents: true
    };
  let events = Calendar.Events.list(calendarId, optionalArgs).items;

  let arrayOfLocation = []
  for (let n in events) {
    arrayOfLocation.splice(n,0,events[n].getLocation())
    }

  let arrayOfDescription =[]
  let arrayOfURL =[]
  let VIdIs = "videoID is "

  for(let i in results.items){
    let resultsVideo = YouTube.Videos.list(
      'snippet,liveStreamingDetails',{
        id : results.items[i].id.videoId
        }
      )
    let VideoId = results.items[i].id.videoId

    let URLofStream = 'https://www.youtube.com/watch?v=' + VideoId;
    let descriptionV = resultsVideo.items[0].snippet.description+"\n\n"+"videoID is "+VideoId
    let title = resultsVideo.items[0].snippet.title;
    let startTime = new Date(resultsVideo.items[0].liveStreamingDetails.scheduledStartTime);
    let endTime = new Date(resultsVideo.items[0].liveStreamingDetails.scheduledStartTime);
    endTime.setHours(endTime.getHours() + 1)
    let option = {
      description: descriptionV,
      location: URLofStream
      }

    if (arrayOfLocation.indexOf(URLofStream) < 0 ) {
      CalendarApp.getCalendarById(calendarId).createEvent(title, startTime, endTime, option);

    } else {
      let eventsToUpdate = Calendar.Events.list(
        calendarId, {
          timeMax: (new Date(now.getTime() + (1095 * 24 * 60 * 60 * 1000))).toISOString(),
          timeMin: (new Date(now.getTime() - ( 7 * 24 * 60 * 60 * 1000))).toISOString(),
          maxResults:1,
          singleEvents: true,
          q:VideoId
          }
        );
      let eventId = eventsToUpdate.items[0].id;
      let startTimeVideoISO = new Date(startTime).toISOString()
      let startTimeEventISO = new Date(eventsToUpdate.items[0].start.dateTime).toISOString()

      if (startTimeVideoISO !== startTimeEventISO) {
        CalendarApp.getCalendarById(calendarId).getEventById(eventId).setTime(startTime, endTime).setTitle(title).setDescription(descriptionV)
      }
      if (title !== eventsToUpdate.items[0].summary) {
        CalendarApp.getCalendarById(calendarId).getEventById(eventId).setTitle(title).setDescription(descriptionV)
      }
      if (descriptionV !== eventsToUpdate.items[0].description) {
        CalendarApp.getCalendarById(calendarId).getEventById(eventId).setDescription(descriptionV)
      }
    }
    arrayOfDescription.splice(i,0,descriptionV)
    arrayOfURL.splice(i,0,URLofStream)
  }
  optionalArgs = {
    timeMax: (new Date(now.getTime() + (1095 * 24 * 60 * 60 * 1000))).toISOString(),
    timeMin: (new Date(now.getTime() + (60 * 60 * 1000))).toISOString(),
    showDeleted: false,
    singleEvents: true
    };
  let eventsRemove = Calendar.Events.list(calendarId, optionalArgs).items;

  for (let o in eventsRemove) {
    let descriptionE = eventsRemove[o].getDescription() + "to avoid undef"
    let locationE = eventsRemove[o].getLocation()
    if(descriptionE.indexOf(VIdIs) >= 0){
      if (arrayOfURL.indexOf(locationE) < 0 ) {
        Calendar.Events.remove(calendarId,eventsRemove[o].id)
      }
    }
  }
}
```

#Installation
Before all, please finish following steps.
- Get a Google account
- Start using Google Calendar
- Start using Youtube 
(If you share your Calendar openly with others, your gmail address will be known.
Do not use your private address if you post your sharing link in twitter etc)

I use the channel of Kurono Kureha san for example.

https://www.youtube.com/channel/UCFVkfdFmaOh7BCtrqw8YvaA?sub_confirmation=1

##Prepare Google Apps Script

Access to Google Apps Script (GAS)
https://script.google.com/home

Create a new project
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/1acb9a2b-b43c-e14f-a084-fd3402bcf032.png)

These pre written codes will be shown.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/ed99053c-cdb7-4a6d-2331-9bad3b690b9b.png)

Write over all the pre-written codes with the script above.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/dc7a235d-939e-c471-f5d8-ecb3aa2bb895.png)

You have to change the Calendar ID and Channel ID.
How?
Keep reading! :)

##Get Google calendar ID
(If you want to use a calendar already existing, please skip the next step)

Open Google Calendar
https://calendar.google.com/

###Create new Calendar
Click + icon to add other calendars.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/3ceafa15-a061-b0b6-28ba-4cf3edff66f2.png)


click "Create new calendar"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/f7f8379e-c6fa-a980-10aa-350ff5eed6e5.png)


Change the name as you prefer and click "create Calendar"
![Screenshot 2022-02-03 223528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/02d7707b-a98f-9c10-73f9-4b7ca7a22600.png)


##below this, steps are the same for both new Calendar and existing Calendar.
Back to top menu and click gear icon.
Then click Settings.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/a9e801e3-7bbb-77ae-8d12-d83f8c26d776.png)


From the list in the left column, chooose the calendar you made for the script.
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/8b37bceb-53a7-70b0-5a8d-4b13bc775c66.png)

Find and copy the Calendar ID
![Screenshot 2022-02-03 224644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/f948cad7-d362-367c-a7c0-aa6bb0eb2053.png)

Back to GAS, and change the YOUR Calendar ID in the script.
(Do not erase ' ' quotation marks)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/821a475c-1614-e405-41ea-efe43cdb0fe6.png)

##Get YouTube Channel ID
Access to the channel page of your favorite Youtuber
https://www.youtube.com/channel/UCFVkfdFmaOh7BCtrqw8YvaA

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/8adbf61c-eb91-20a8-55dd-b54d25c05092.png)

The last letters of URL（~channel/*******） is the channel ID.
Copy it!
(delete "?sub_confirmation=1" etc following channel ID)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/c83c172d-19c6-2b3b-dd7f-dd5504e58f3a.png)

Back to GAS and change the Channel ID
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/f895b2e5-3f70-3cdc-e689-0983c8a99e38.png)

##Prepare API
Click the + next to "Service"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/2bbe727f-3bdb-2d68-a342-beee1b8a5d35.png)

Add "Google calendar API" and "Youtube Data API"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/91d30356-f54c-8551-142d-90a1079e898c.png)


##Authorization
Save the script
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/eb24d8eb-e355-1fb2-964f-f729cd9a0d26.png)

Then Run!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/6784804f-eb21-106b-1896-1a5d72df7474.png)

This message will be shown if the script is run for the first time.
Click "Review permissions".
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/f6eb5698-7339-e9c4-e80e-abd5056251c2.png)


Choose your account
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/239b8125-e447-0fe9-04e9-45110a716526.png)

This warning will be shown.
Click "Advanced"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/3a4a6816-b236-7eb2-9377-169cf2d100b2.png)

Developper is you.
If you can trust Google, yourself and me (the author of this script), click "Go to ******* project".
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/640984d2-0785-466b-8673-e8acae553e96.png)

Click "Allow"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/457a8719-39c5-b1df-97f3-31aaa06d0a2e.png)

Back to GAS, then run again.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/c9945b6b-b2dd-0179-4ffd-58e496fbf674.png)

Check your Google Calendar to confirm the script properly worked and the live streaming schedules are registered.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/596a6688-ada4-5124-831f-4710d42b35d7.png)

##Trigger
In order to run the script periodically and check if there is new live streaming reservation, prepare trigger.
There is a limit for the time you can let the script access to Youtube.
From my experience, checking every 15mins is the most frequent available trigger.

If you made two apps, double the time, 30mins.

###手順
Click "Triggers" icon
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/61636802-9901-2b50-3982-6d5c60a190bb.png)

Click "Add trigger"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/33eea634-5cfa-f0e7-de68-102b7f380004.png)

Confirm that "Time-driven" is selected in "Select event source" menu.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/85aa8e35-bf27-cdc9-13ee-822c4e135c49.png)

Change "time based trigger" and "interval" to how often you want to refresh the calendar.
(As written above, 15mins is maybe the most frequent)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/b34b391b-a773-4475-3ceb-219b820cfede.png)

Click "Save"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234568/b09369c5-0b2f-7193-4c73-dc447db4a56d.png)

All done!

#Share your effort
If you kindly want to help others, you can share your calendar to others and save others' time and Youtube API quota.
But be careful.
Your email address of the Google calendar account will be shown to others.
Do not use private email address.

Here is how.
https://support.google.com/calendar/answer/37083?hl=en

#Thank you!