7 minutes
Daily Dashboard in Notion with AWS Lambda
Introduction
I’ve always wanted a personalized dashboard that greets me every morning with relevant information: today’s weather, my calendar events, currency rates, and curated tech news. Instead of checking multiple apps, I built StartPage - an automated system that aggregates data from various sources and publishes it daily to a Notion page.
It runs completely serverless on AWS Lambda, costing virtually nothing (within the free tier) and requiring zero maintenance.
You can check code in GitHub
What script can do:
- 🌤️ Daily weather updates for your city
- 📅 Today’s calendar events from iCloud
- 💱 Currency and cryptocurrency rates
- 📰 Curated tech news from RSS feeds
- 🎲 A random interesting fact to start your day
Tech stack:
- Python 3.12 with asyncio for concurrent data fetching
- Notion API for publishing content
- AWS Lambda for serverless execution
- AWS CloudFormation for infrastructure as code
- AWS EventBridge for daily scheduling
- GitHub Actions for CI/CD
Part 1: Understanding the Project
StartPage is a Python application that:
- Fetches data concurrently from multiple APIs (weather, calendar, RSS feeds, currency rates)
- Formats the data as Notion blocks
- Publishes everything to your Notion page as a daily summary
- Updates a “fact of the day” callout block
The architecture is simple:
Runtime:
┌─────────────────┐
│ EventBridge │ Triggers daily at 6 AM UTC
│ (Scheduler) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ AWS Lambda │ Runs StartPage application
│ (Python 3.12) │
└────────┬────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Concurrent Data Fetching (asyncio.gather) │
├──────────┬──────────┬──────────┬──────────┬─────┤
│ Weather │ Calendar │ Currency │ RSS │ Fact│
└──────────┴──────────┴──────────┴──────────┴─────┘
│
▼
┌─────────────────┐
│ Notion API │ Publishes formatted blocks
└─────────────────┘
The entire execution takes about 10-15 seconds, well within Lambda’s free tier limits.
Part 2: Setting Up Your Notion Page
Step 1: Create a Notion Integration
- Go to Notion Integrations
- Click "+ New integration"
- Give it a name (e.g., “StartPage Bot”)
- Select the workspace where you want to use it
- Click “Submit”
- Copy the Internal Integration Token - you’ll need this for your
.envfile
Step 2: Create Your Dashboard Page
- In Notion, create a new page (this will be your daily dashboard)
- Give it a title like “📊 Daily Dashboard” or “Morning Briefing”
- Add a Callout block at the top - this will display your daily random fact
- You can add any other static content you want (headers, dividers, etc.)
Your page structure should look like this:
📊 Daily Dashboard
├── 💡 [Callout Block] ← This will show the daily fact
└── [Daily updates will appear here]
Step 3: Get Your Page ID and Block ID
To get the Page ID:
- Click “Share” on your Notion page
- Click “Copy link”
- The URL will look like:
https://www.notion.so/Your-Page-Title-abc123def456... - The Page ID is the part after the last dash:
abc123def456...
To get the Block ID (Callout):
- Hover over your callout block
- Click the ⋮⋮ (six dots) icon
- Click “Copy link to block”
- The URL will look like:
https://www.notion.so/...#xyz789abc123... - The Block ID is the part after the
#:xyz789abc123...
Step 4: Share Page with Integration
- Open your dashboard page in Notion
- Click the "…" menu in the top right
- Scroll down and click “Add connections”
- Find and select your integration (e.g., “StartPage Bot”)
- Click “Confirm”
Now your integration has access to read and write to this page!
Part 3: Gathering Environment Variables
Create a .env file in the project root with all necessary credentials:
# Notion Configuration
NOTION_TOKEN=secret_xxx... # From Step 2.1
PAGE_ID=abc123def456ghi789 # From Step 2.3
BLOCK_ID=xyz789abc123def456 # From Step 2.3
# Location Settings
CITY=London # Or your preferred city
TIMEZONE=Europe/London # IANA timezone
# iCloud Calendar (for calendar events)
ICLOUD_USERNAME=your.email@icloud.com
ICLOUD_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx # See below
# AWS Deployment (needed for `make deploy`)
S3_BUCKET=your-startpage-bucket # S3 bucket for Lambda package
Getting iCloud App-Specific Password
Apple requires app-specific passwords for third-party access:
- Go to appleid.apple.com
- Sign in with your Apple ID
- In the Security section, find App-Specific Passwords
- Click “Generate an app-specific password”
- Enter a label (e.g., “StartPage Calendar”)
- Copy the generated password (format:
xxxx-xxxx-xxxx-xxxx) - Paste it into your
.envfile asICLOUD_APP_PASSWORD
Note: You only see this password once, so save it immediately!
Configuration Checklist
Before proceeding, verify you have:
- ✅ Notion integration token
- ✅ Page ID (no hyphens)
- ✅ Block ID (no hyphens)
- ✅ City name for weather
- ✅ Your timezone
- ✅ iCloud username
- ✅ iCloud app-specific password
Part 4: Testing Locally
Now let’s make sure everything works before deploying to AWS.
Step 1: Install Dependencies
# Install Poetry if you haven't already
curl -sSL https://install.python-poetry.org | python3 -
# Install project dependencies
poetry install
Step 2: Run the Application
poetry run python -m startpage.startpage
You should see output like:
2026-02-09 10:30:45 - startpage.startpage - INFO - Starting StartPage application
2026-02-09 10:30:45 - startpage.startpage - INFO - Fetching data from all sources concurrently
2026-02-09 10:30:52 - startpage.startpage - INFO - All data fetched successfully, building Notion page
2026-02-09 10:30:52 - startpage.startpage - INFO - Appending new day section: Sunday 09 of February
2026-02-09 10:30:53 - startpage.startpage - INFO - Updating fact block
2026-02-09 10:30:53 - startpage.startpage - INFO - StartPage update completed successfully
Step 3: Verify in Notion
Open your Notion page and you should see:
- A new header with today’s date (e.g., “Sunday 09 of February”)
- Weather information for your city
- Currency rates (₽ and $ based)
- Cryptocurrency prices
- Your calendar events for today
- 5 curated tech news articles
- Updated fact in the callout block
Part 5: Deploying with CloudFormation
Now let’s deploy StartPage to AWS Lambda so it runs automatically every day.
Step 1: Install AWS CLI
macOS:
brew install awscli
Linux/Windows: Follow the official installation guide
Verify installation:
aws --version
Step 2: Configure AWS Credentials
aws configure
You’ll be prompted for:
- AWS Access Key ID
- AWS Secret Access Key
- Default region (e.g.,
us-east-1) - Output format (just press Enter for default)
Don’t have AWS credentials?
- Log into AWS Console
- Go to IAM → Users
- Click “Add users”
- Enable “Programmatic access”
- Attach “AdministratorAccess” policy (or create a custom policy)
- Save the Access Key ID and Secret Access Key
Step 3: Create an S3 Bucket
You need an S3 bucket to store the Lambda deployment package:
aws s3 mb s3://your-startpage-bucket --region us-east-1
Step 4: Build and Upload the Lambda Package
# Install the Lambda build plugin (one-time setup)
poetry self add poetry-plugin-lambda-build
# Build the deployment package
poetry build-lambda
# Upload to S3
aws s3 cp package.zip s3://your-startpage-bucket/startpage/package.zip
Step 5: Deploy with CloudFormation
The project includes a template.yaml that defines all AWS resources: Lambda function, IAM role, EventBridge schedule, and CloudWatch log group.
aws cloudformation deploy \
--template-file template.yaml \
--stack-name startpage \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
S3Bucket=your-startpage-bucket \
S3Key=startpage/package.zip \
NotionToken=secret_xxx \
PageId=your_page_id \
BlockId=your_block_id \
City=London \
ICloudUsername=your@icloud.com \
ICloudAppPassword=xxxx-xxxx-xxxx-xxxx \
Timezone=Europe/London \
ScheduleExpression='cron(0 6 * * ? *)'
This creates the entire infrastructure in one command. CloudFormation will:
- Create an IAM role with basic Lambda execution permissions
- Deploy your Lambda function with the code from S3
- Create an EventBridge rule to trigger the function daily
- Set up CloudWatch log group with 7-day retention
Alternatively, if you have your .env file configured with all the variables (including S3_BUCKET), you can use the Makefile shortcut which handles building, uploading to S3, and deploying in one command:
make deploy
The process takes 2-3 minutes. When complete, you’ll see:
Successfully created/updated stack - startpage in us-east-1
Step 6: Test Your Lambda Function
Invoke your function manually to verify it works, before invoking check name of the function, CloudFormation use uniq name:
aws lambda invoke \
--function-name startpage \
--invocation-type RequestResponse \
--log-type Tail \
output.json
# View the response
cat output.json
You should see:
{
"statusCode": 200,
"body": "StartPage updated successfully"
}
Check your Notion page - you should see a new daily entry!
Step 7: Monitor Execution
View your Lambda logs:
# See recent logs
aws logs tail /aws/lambda/startpage --since 1h
# Follow logs in real-time
aws logs tail /aws/lambda/startpage --follow
Adjusting the Schedule
To run at a different time, redeploy with a new ScheduleExpression:
aws cloudformation deploy \
--template-file template.yaml \
--stack-name startpage \
--capabilities CAPABILITY_IAM \
--parameter-overrides ScheduleExpression='cron(0 8 * * ? *)' ...
Common schedules:
cron(0 6 * * ? *)- Daily at 6 AM UTCcron(0 */6 * * ? *)- Every 6 hourscron(0 8 * * MON *)- Every Monday at 8 AM UTC
Note: AWS EventBridge uses UTC time. Convert your local time to UTC for the schedule.