A macOS Python application that aggregates tech newsletters, synthesizes content using an LLM, and generates blog posts and TikTok scripts saved to Apple Notes.
- Newsletter Aggregation: Collect newsletters from email (IMAP), RSS feeds, and local files
- AI-Powered Synthesis: Use LLM to analyze, group by topic, and summarize content
- Blog Post Generation: Create formatted blog posts in Markdown (long-form, summary, or listicle)
- TikTok Script Generation: Generate short-form video scripts optimized for 15, 30, or 60 seconds
- Apple Notes Integration: Save all generated content directly to Apple Notes
- macOS (required for Apple Notes integration)
- Python 3.11 or higher
- OpenAI API key (or other supported LLM provider)
- Apple Notes.app
uv is a fast Python package manager. Install it first if you haven't:
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | shThen install the newsletter generator:
# Clone the repository
git clone https://github.com/your-username/newsletter-content-generator.git
cd newsletter-content-generator
# Install dependencies
uv sync --all-extras# Clone the repository
git clone https://github.com/your-username/newsletter-content-generator.git
cd newsletter-content-generator
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate
# Install the package with development dependencies
pip install -e ".[dev]"Copy the example configuration file and customize it:
cp config.example.yaml config.yamlThe application uses environment variables for sensitive data like API keys. Set the required variables:
# Required: OpenAI API key
export OPENAI_API_KEY="your-openai-api-key"
# Optional: Email password (if using email sources)
export GMAIL_APP_PASSWORD="your-gmail-app-password"For Gmail, you'll need to create an App Password since regular passwords won't work with IMAP.
Edit config.yaml to add your newsletter sources. You can use any combination of:
Email Sources (IMAP):
email_sources:
- host: imap.gmail.com
port: 993
username: your.email@gmail.com
password: ${GMAIL_APP_PASSWORD}
folder: Newsletters
use_ssl: trueRSS Feeds:
rss_sources:
- name: TechCrunch
url: https://techcrunch.com/feed/
- name: Hacker News
url: https://news.ycombinator.com/rssLocal Files:
file_sources:
- path: ~/newsletters
pattern: "*.html"Customize how blog posts and TikTok scripts are generated:
blog:
format: long-form # Options: long-form, summary, listicle
target_words: 1000
include_sources: true
tiktok:
duration: 60 # Options: 15, 30, 60 (seconds)
include_visual_cues: true
style: educational # Options: educational, entertaining, newsSpecify where to save generated content:
notes:
account: iCloud # Your Apple Notes account
blog_folder: Generated Blog Posts
tiktok_folder: TikTok ScriptsBefore running, validate your configuration file:
newsletter-generator validate --config config.yamlThis will check for:
- Valid YAML syntax
- Required fields
- Valid option values
- Environment variable availability
Execute the full pipeline:
newsletter-generator run --config config.yamlThe generator will:
- Fetch newsletters from all configured sources
- Parse and normalize the content
- Use the LLM to synthesize and group content by topic
- Generate a blog post and TikTok script
- Save both to Apple Notes
Preview generated content without saving to Apple Notes:
newsletter-generator run --config config.yaml --dry-runThis is useful for testing your configuration and seeing what content would be generated.
newsletter-generator --help
Commands:
run Run the newsletter content generation pipeline
validate Validate configuration file
Run Options:
--config, -c Path to configuration file (default: config.yaml)
--dry-run Preview content without saving to Apple Notes
Validate Options:
--config, -c Path to configuration file (default: config.yaml)
-
Set up your environment:
export OPENAI_API_KEY="sk-..."
-
Create and customize configuration:
cp config.example.yaml config.yaml # Edit config.yaml with your sources and preferences -
Validate configuration:
newsletter-generator validate -c config.yaml
-
Test with dry run:
newsletter-generator run -c config.yaml --dry-run
-
Run the full pipeline:
newsletter-generator run -c config.yaml
-
Check Apple Notes for your generated content!
Make sure you've created a config.yaml file or specify the correct path:
newsletter-generator run --config /path/to/your/config.yamlEnsure all required environment variables are exported:
export OPENAI_API_KEY="your-key"- Verify your email credentials
- For Gmail, use an App Password instead of your regular password
- Check that IMAP is enabled in your email settings
- Ensure Notes.app is installed and accessible
- The application will fall back to saving files locally if Notes is unavailable
uv sync --all-extras# Run all tests
pytest
# Run with coverage
pytest --cov=newsletter_generator
# Run property-based tests only
pytest -m property
# Run with more examples (CI profile)
HYPOTHESIS_PROFILE=ci pytest -m property# Format code
ruff format src tests
# Lint code
ruff check src tests
# Type checking
mypy srcMIT