Changed so that it only does Google -> notion sync, and only grabs events occuring AFTER the time of syncing
This script utilizes the unofficial Notion API and the Google Calendar API to sync a calendar directly between Notion and Google Calendar. Set this up as a cron job to have it sync changes between calendars automatically!
-
Clone the github repo and open up
main.py
. In here, you'll find a list of set-up variables you'll want to provide values for: your Notion token (retrieved from a cookie), the URL of the Notion calendar you'd like to use, your timezone, and the calendar ID of the Google Calendar you want to use. Here's how to get these things:a) Notion token: Open the notion workspace for the calendar you want to sync in your browser. Open the developer console using
Inspect
. Tab over toApplication
and select theCookies
sub-menu. Look for the cookie namedtoken_v2
and copy its value. Inmain.py
, setnotion_token
equal to this value as a string.
b) Notion calendar: Navigate to the notion calendar you want to sync and copy the link. Make sure it's shareable so that it's viewable by anyone. Inmain.py
, setnotion_cal
equal to this value as a string.
c) Timezone: Again inmain.py
, settimezone
equal to the timezone of your Notion calendar. Format your timezone according to your timezone'sTZ database name
, found here.
d) Google Calendar: Navigate to the settings page for the google calendar that you have edit access to that you want to sync. Scroll down to theIntegrate calendar
section, and find theCalendar ID
. Inmain.py
, setcalendar_id
equal to this value as a string. -
In your Notion, open the menu bar (indicated by three dots in the top right corner of the calendar view. Click
properties
, and add a property titledlast edited
with an advanced type oflast edited time
. -
Add any additional event properties you have in the script in the try-catch block around line 100 if you want to include extra things like location, description, etc.
-
Follow the first step of this google calendar quickstart by clicking
Enable the Google Calendar API
. Name your project and clickNEXT
. SelectDesktop App
to Configure your OAuth Client. Then, obtain yourcredentials.json
file by clickingDOWNLOAD CLIENT CONFIGURATION
. Add the file to your project workspace, and set the value ofcredentials_file
to the name of this file as a string. You will need this in order to later authenticate your account and obtain your Google Calendar data. -
Run the script locally on your computer. The first time this script is run, you will be taken through Google's authentication flow. Sign in with the account that owns the Google Calendar whose ID you used.
Your calendars should now be sucessfully synced! You can continue to run your script whenever you want the calendars to resync, or continue with setting up a cron job to have this process happen automatically!
-
Install Google Cloud Command Line Tools (skip if you already have)
You will need to initialize GCloud's SDK in order to deploy the script. Download the SDK here and follow the instructions to initialize.
-
Create a Cloud Function:
Navigate to Google Cloud Platform. On the dashboard for your new project, openGo to APIs Overview
, and clickENABLE APIS AND SERVICES
. Search for and enable theGoogle Build API
andGoogle Calendar API
. Next, navigate back to the API & Services home page, and into theCredentials
tab. In theService Accounts
section, there should be an App Engine default service account already created. Copy the email address, go toSettings and sharing
for the Google Calendar you want synced, and share the calendar with the service account, providing it permission toMake changes
.
Open the terminal on your computer and navigate to the folder themain.py
script is located in. Run the following command in your terminal:gcloud functions deploy main --trigger-http --runtime=python37 --project=INSERT_PROJECT_ID
, replacingINSERT_PROJECT_ID
with your project's ID. This value should be available in theProject info
section of your Google Cloud Platform Dashboard. When the command runs, it should provide you the option to run authenticated/allow unauthenticated. Make sure toallow unauthenticated
, and the function should take a few minutes to deploy to your Google Cloud Console. Once it has successfully deployed, you can schedule it to run as often as you'd like! -
Schedule Cloud Function as a Cron Job: Again, open the menu bar on the left side of the page and navigate to
Cloud Scheduler
underTOOLS
. ClickCREATE JOB
.
a) Fill out the space forName
.
b) Fill out the rule forFrequency
according to how often you want the script to be run. We use "* * * * *" to indicate the cron job would run every minute.
c) Fill out the space forTimezone
. For our frequency, it didn't matter what the timezone was, but if you want your script to run at a more specific time (ie. everyday @ 3pm), consider this in selecting your timezone.
d) ChangeTarget
to beHTTP
.
e) Insert theURL
to send a request to. This is theURL
that was returned from deploying the cloud function.
f) ClickCREATE
.
It may take a few minutes to set-up, but the script should now automatically run according to the frequency rule you selected.
- Timezones: From testing, using
os.environ["TZ"]
does not work on windows computers. If you plan to use this calendar with people in other timezones, they must manually configure the timezone of the event that they add in the Notion calendar to match the timezone of the person who created the calendar. - Recurring Events:
Syncing a calendar with recurring events will remove the recurrence rule property from events in google calendar. Since notion does not allow for specifying IDs, we are unable to maintain sync while also upholding the requirements for google calendar IDs and RecurringEventIDs. Syncing will still display all recurring and non-recurring events on your calendar, but will not maintain the recurrence rule property of recurring google calendar events.
This script is far from perfect, and we're trying to make the script as efficient as possible to minimize the rate at which Google Calendar's API is called as well as the number of times it needs to be called.
Setting up the script as a cron job will cause a violation in the rate limit beyond a calendar of ~120 events, which is not a lot.