Contents

Chapter 1

Scheduling Automations

Overview

The example scripts are designed to be run on a schedule — daily standups, weekly reports, periodic task checks. This guide covers the three most common approaches to scheduling: cron, systemd timers, and cloud functions.

Option 1: Cron (Linux / macOS)

Cron is the simplest option. Edit your crontab:

bash
crontab -e

Common Schedules

cron
# Daily standup page at 8:00 AM on weekdays (Mon-Fri)
0 8 * * 1-5 /usr/bin/python3 /path/to/examples/daily_standup_page.py >> /var/log/notion-automation.log 2>&1

# Weekly metrics report every Monday at 9:00 AM
0 9 * * 1 /usr/bin/python3 /path/to/examples/weekly_metrics_report.py >> /var/log/notion-automation.log 2>&1

# Stale task check every day at 10:00 AM
0 10 * * * /usr/bin/python3 /path/to/examples/stale_task_alerter.py >> /var/log/notion-automation.log 2>&1

# Database backup every night at 2:00 AM
0 2 * * * /usr/bin/python3 /path/to/examples/database_backup.py >> /var/log/notion-automation.log 2>&1

# Cross-database sync every 4 hours
0 */4 * * * /usr/bin/python3 /path/to/examples/cross_db_sync.py >> /var/log/notion-automation.log 2>&1

Cron Gotchas

cron
  0 8 * * 1-5 cd /path/to/project && /usr/bin/python3 examples/daily_standup_page.py
  • Environment variables: Cron runs in a minimal environment. Either use absolute paths for Python and your scripts, or source your .env at the top of the cron entry:
  • Timezone: Cron uses the system timezone. If your server is in UTC but you want 8 AM in your local time, calculate the offset.
  • Logging: Always redirect stdout and stderr to a log file for debugging.

Option 2: Systemd Timer (Linux)

Systemd timers are more robust than cron — they survive reboots, have better logging, and support randomized delays to avoid thundering herd problems.

Create the Service File

Save as /etc/systemd/system/notion-standup.service:

ini
[Unit]
Description=Create daily Notion standup page

[Service]
Type=oneshot
WorkingDirectory=/path/to/notion-automation-system
ExecStart=/usr/bin/python3 examples/daily_standup_page.py
EnvironmentFile=/path/to/notion-automation-system/configs/.env

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/path/to/notion-automation-system

Create the Timer File

Save as /etc/systemd/system/notion-standup.timer:

ini
[Unit]
Description=Run standup creator on weekday mornings

[Timer]
OnCalendar=Mon..Fri 08:00
# Add up to 5 minutes of random delay to avoid exact-second API spikes
RandomizedDelaySec=300
Persistent=true

[Install]
WantedBy=timers.target

Enable and Start

bash
sudo systemctl daemon-reload
sudo systemctl enable notion-standup.timer
sudo systemctl start notion-standup.timer

# Check status
systemctl status notion-standup.timer
systemctl list-timers --all

# View logs
journalctl -u notion-standup.service

Option 3: Cloud Functions (Serverless)

For a fully managed solution, deploy your scripts as cloud functions triggered by a scheduler.

AWS Lambda + EventBridge

1. Package the src/ directory and your script into a ZIP

2. Create a Lambda function with Python 3.10+ runtime

3. Set environment variables in the Lambda configuration

4. Create an EventBridge rule with a cron schedule

5. Target the Lambda function

Google Cloud Functions + Cloud Scheduler

1. Deploy as a Cloud Function (HTTP-triggered)

2. Create a Cloud Scheduler job that calls the function URL

3. Set environment variables in the function configuration

4. Use a service account with minimal permissions

Key Considerations for Cloud Functions

  • Cold starts: The first invocation after idle time takes longer. This is fine for scheduled tasks — they're not latency-sensitive.
  • Execution time limit: Most providers cap at 5-15 minutes. The scripts should finish well within that for most databases (under 10,000 pages).
  • Secrets management: Don't bake your Notion token into the deployment. Use the cloud provider's secrets manager (AWS Secrets Manager, Google Secret Manager, etc.).
  • Cost: Running a few scheduled scripts costs pennies per month on any cloud provider. The free tier usually covers it.

Monitoring Your Automations

Basic: Log File Review

Check your log files periodically for errors:

bash
# Recent entries
tail -50 /var/log/notion-automation.log

# Errors only
grep -i "error\|failed\|exception" /var/log/notion-automation.log

Better: Self-Monitoring with Notifications

Add a try/except wrapper to your scripts that sends a notification if something fails:

python
import sys
import traceback

try:
    # Your automation code here
    main()
except Exception:
    error_msg = traceback.format_exc()
    # Send the error to Slack/email using the notification module
    from src.notifications import SlackChannel
    slack = SlackChannel()
    slack.send("Automation Error", f"```\n{error_msg}\n```")
    sys.exit(1)

Advanced: Health Check Endpoint

If you're running on a server, create a simple health check that verifies your Notion connection is still working:

python
from src.client import NotionClient

def health_check():
    try:
        client = NotionClient()
        client.search(filter_type="database")
        return {"status": "healthy"}
    except Exception as e:
        return {"status": "unhealthy", "error": str(e)}

Point an uptime monitor (UptimeRobot, Healthchecks.io, etc.) at this endpoint.

Chapter 2

Setup Guide

Prerequisites

  • Python 3.10 or higher — the scripts use modern syntax like match statements and X | Y type unions
  • A Notion account — free or paid, any plan works
  • A Notion integration — internal integration with access to your databases

Step 1: Create a Notion Integration

1. Go to notion.so/my-integrations

2. Click "+ New integration"

3. Give it a name (e.g., "Automation Scripts")

4. Select your workspace

5. Under Capabilities, ensure these are checked:

  • Read content
  • Update content
  • Insert content

6. Click Submit

7. Copy the Internal Integration Secret (starts with ntn_)

Step 2: Share Databases with Your Integration

Notion integrations can only access databases you explicitly share with them:

1. Open the database you want to automate

2. Click the "..." menu in the top-right corner

3. Click "Add connections"

4. Search for your integration name and select it

5. Click "Confirm"

Repeat this for every database you want the scripts to interact with.

Step 3: Find Your Database IDs

Each database has a unique ID in its URL. Open a database in your browser and look at the URL:

https://www.notion.so/yourworkspace/abc123def456...?v=...
                                     ^^^^^^^^^^^^^^^^
                                     This is the database ID

Copy the 32-character hex string (with or without dashes — the scripts accept both formats).

Step 4: Configure Your Environment

bash
# Copy the example env file
cp configs/.env.example configs/.env

# Edit with your credentials
nano configs/.env   # or use any text editor

Fill in at minimum:

  • NOTION_TOKEN — your integration secret from Step 1
  • NOTION_DATABASE_ID — your default database ID from Step 3

Step 5: Install Dependencies

bash
pip install -r requirements.txt

This installs only requests — everything else is Python standard library.

Step 6: Test Your Connection

bash
python src/client.py

This runs a quick smoke test that connects to the Notion API and lists all databases your integration can access. If you see your database names, everything is configured correctly.

Step 7: Run an Example

bash
# Create a daily standup page
python examples/daily_standup_page.py

# Export a database to JSON
python examples/database_backup.py

Troubleshooting

"No Notion token found"

→ Make sure configs/.env exists and has NOTION_TOKEN=ntn_... set.

"API returned 401 Unauthorized"

→ Your token is invalid or expired. Create a new integration at notion.so/my-integrations.

"API returned 404 Not Found"

→ The database ID is wrong, or you haven't shared the database with your integration (Step 2).

"API returned 403 Forbidden"

→ Your integration doesn't have the required capabilities. Edit it at notion.so/my-integrations and ensure Read, Update, and Insert are all enabled.

Rate limit errors (429)

→ The client handles these automatically with exponential backoff. If you're hitting them constantly, reduce the frequency of your scripts or add longer pauses between operations.

Next Steps

  • Read guides/SCHEDULING.md to run scripts automatically on a schedule
  • Read guides/ZAPIER_GUIDE.md to set up webhook integrations
  • Browse the examples/ directory for real-world script templates
  • Customize configs/automation_rules.yaml to adjust behavior without code changes
Chapter 3
🔒 Available in full product

Zapier Integration Guide

You’ve reached the end of the free preview

Get the full Notion Automation System and unlock everything.

All Chapters

Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.

Full Tool Suite

Access all interactive tools with complete data, all workload profiles, and the full scenario library.

Source Files

Downloadable source code, configuration files, and working examples from every chapter.

Lifetime Updates

Free updates for life. Every new chapter, tool, and improvement included.

Buy Now — $29 →
📦 Free sample included — download another copy for the full product.
Notion Automation System v1.0.0 — Free Preview