π―π΅ ζ₯ζ¬θͺη README γ―γγ‘γ / Japanese README
A Google Apps Script project that provides bidirectional synchronization between Notion databases and Google Calendar.
Automatically sync tasks and schedules managed in Notion to Google Calendar.
- π Auto Sync: Automatically synchronizes Notion items with "Schedule" tags to Google Calendar every 15 minutes
- π Date Processing: Supports all-day events, timed events, and period events
- π‘οΈ Duplicate Prevention: Prevents duplicate creation using Event IDs
βοΈ Bidirectional Sync: Reflects changes and deletions in Notion to the calendar
- Node.js (v16 or later)
- npm
- Google Account
- Notion Account
- Access Notion Developers
- Click "+ New integration"
- Enter integration name (e.g.,
GoogleCalendar-Sync) - Click "Submit"
- Copy and save the Internal Integration Token
- Open the Notion database to be synchronized
- Get the Database ID from the URL
https://notion.so/workspace/{database-id}?v={view-id}- The
{database-id}part is the database ID
- Get the "Schedule tag" Page ID
- Click on the Schedule tag β Get the page ID from the URL
- Click "β―" at the top right of the database β "Add connections"
- Select and add the created integration
- Access Google Cloud Console
- Create a new project or select an existing one
- Enable Google Calendar API
- "APIs & Services" β "Library"
- Search for "Google Calendar API" and enable it
- Enable Google Apps Script API
- Follow the same procedure to enable
# Navigate to the project folder
cd SyncNotionGoogleCalendar
# Install dependencies
npm install
# Login to Google account with clasp
npm run login# Create a new GAS project (first time only)
npm run create
# Push code to Google Apps Script
npm run push- Access Google Apps Script
- Open the created project
- Left menu "Project Settings" β "Script properties"
- Add the following properties:
| Property Name | Value | Description |
|---|---|---|
NOTION_API_KEY |
secret_xxxxx... |
Notion Internal Integration Token |
NOTION_DATABASE_ID |
xxxxxxxxx... |
Target Notion Database ID |
SCHEDULE_TAG_ID |
xxxxxxxxx... |
"Schedule" tag Page ID |
CALENDAR_ID |
primary or specific calendar ID |
Target Google Calendar (optional) |
- Left menu "Services"
- Enable Google Calendar API (select v3)
To ensure proper synchronization, the following properties are required in the Notion database:
| Property Name | Type | Required | Description |
|---|---|---|---|
| Title | Title | β | Event title |
| Action Day | Date | β | Event date and time |
| Tags | Relation | β | Relation containing "Schedule" tag |
| Status | Status | β | Task status |
| Event ID | Text | β | Google Calendar Event ID (automatically set) |
| URL | URL | β | Related links |
Execute initial setup in Google Apps Script editor:
// Execute initialization function (first time only)
initialize();This function performs the following:
- Verifies script properties
- Tests Google Calendar API connection
- Sets up automatic sync trigger (15-minute intervals)
- Create a new page in the Notion database
- Enter event name in Title
- Set date and time in Action Day:
- All-day event: Date only (e.g.,
2023-12-25) - Timed event: Specify date and time (e.g.,
2023-12-25 14:30) - Period event: Set start and end date/time
- All-day event: Date only (e.g.,
- Add "Schedule" tag to Tags
- β
"Schedule" tag is included in
Tags - β
Action Dayis set - β
Action Dayis within sync range (30 days ago to 90 days ahead) - β Items not meeting the above criteria are excluded from sync
- Automatic sync: Executes every 15 minutes
- Manual sync: Execute
manualSync()in Google Apps Script editor
| Notion Operation | Google Calendar |
|---|---|
| π Create new | β Create event |
| βοΈ Change title | π Update event |
| π Change date/time | π Update event |
| β Remove Schedule tag | ποΈ Delete event |
| ποΈ Delete page | ποΈ Delete event |
Title: Meeting Preparation
Action Day: 2023-12-25
β Google Calendar: 12/25 all-day event
Title: Team Meeting
Action Day: 2023-12-25 14:00 β 2023-12-25 15:30
β Google Calendar: 12/25 14:00-15:30
Title: Business Trip
Action Day: 2023-12-25 β 2023-12-27
β Google Calendar: 12/25-12/27 all-day event
- Synchronized Notion pages automatically have Event ID set
- This ID manages the connection with Google Calendar
- Pages with Event ID are already synchronized
Check sync status in Google Apps Script editor execution logs:
=== Sync Process Started ===
Retrieved 3 schedule items from Notion
Retrieved 5 events from Google Calendar
=== Sync Process Completed ===
Created: 1, Updated: 1, Deleted: 0
Error: Notion API Error (401): Unauthorized
Causes and Solutions:
- β NOTION_API_KEY is not set correctly
- β Verify the Internal Integration Token obtained from Notion Developers
- β Set correctly in Google Apps Script script properties
- β Integration not added to database
- β Notion database β "β―" β "Add connections" to add integration
Log: Retrieved 0 schedule items from Notion
Causes and Solutions:
- β SCHEDULE_TAG_ID is incorrect
- β Open "Schedule" tag page and verify page ID from URL
- β Page ID is a 32-character string including hyphens
- β No items with "Schedule" tag in database
- β Create items in Notion and add "Schedule" tag
- β Verify that Action Day is also set
Error: Google Calendar API is not enabled
Causes and Solutions:
- β Calendar API not enabled in Google Apps Script
- β Google Apps Script β "Services" β Add Google Calendar API v3
- β Calendar API disabled in Google Cloud Console
- β Google Cloud Console β APIs & Services β Library β Enable Google Calendar API
Log: Trigger not set
Causes and Solutions:
- β Periodic execution trigger not set
- β
Google Apps Script β Triggers β Verify 15-minute interval trigger for
syncNotionWithGoogleCalendarfunction - β
Or execute
initialize()function to automatically set trigger
- β
Google Apps Script β Triggers β Verify 15-minute interval trigger for
Error: Valid Action Day is not set
Causes and Solutions:
- β Notion Action Day property is empty
- β Set appropriate date in Notion Action Day
- β Action Day format is incorrect
- β
All-day:
2023-12-25 - β
Timed:
2023-12-25T14:30:00 - β Period: Set start date β end date
- β
All-day:
Error: Insufficient permissions
Causes and Solutions:
- β Calendar scope insufficient in Google Apps Script
- β Approve required permissions when executing script
- β Click "Review permissions" on "Authorization required" screen
Error: API call to calendar.events.insert failed with error: Calendar usage limits exceeded.
Causes and Solutions:
- β Events outside the sync range were repeatedly created, exceeding Google Calendar API quotas
- β
Run
cleanupDuplicateEvents()to delete duplicate events (run repeatedly until complete) - β Update to the latest version to apply the date range filter fix
- β
Run
- Google Apps Script β "Execute" β Run any function
- Check error details in "Execution log"
- Add
Logger.log()for detailed debugging
// Testing individual functions
function testNotionConnection() {
const items = getNotionScheduleItems();
Logger.log(`Number of items retrieved: ${items.length}`);
items.forEach(item => Logger.log(item.title));
}
function testCalendarConnection() {
const events = getGoogleCalendarEvents();
Logger.log(`Number of events retrieved: ${events.length}`);
}function checkConfiguration() {
const config = {
apiKey: CONFIG.NOTION_API_KEY ? 'Set' : 'Not set',
databaseId: CONFIG.NOTION_DATABASE_ID ? 'Set' : 'Not set',
scheduleTagId: CONFIG.SCHEDULE_TAG_ID ? 'Set' : 'Not set'
};
Logger.log(config);
}// Detect and delete duplicate events (resumable, run repeatedly until complete)
cleanupDuplicateEvents();
// Reset progress and start over
resetCleanupProgress();- Rate Limits: Notion API allows maximum 3 requests per second
- Time Zone: Set to
Asia/Tokyoby default - Sync Range: Only targets events from 30 days ago to 90 days in the future
- Duplicate Prevention: Prevents duplicate creation through Event ID linking
This project is licensed under the MIT License.
Contributions to this project are welcome!
- π Bug reports
- π‘ Feature suggestions
- π§ Pull requests
Please feel free to report details in GitHub Issues.

