atproto-calendar-import is a library and CLI tool for importing calendar events in python & rust
📅 atproto-calendar-import#
A Rust library and CLI tool for importing calendar events from external providers (Google Calendar, Microsoft Outlook) into the AT Protocol ecosystem. Built with atrium-rs for robust AT Protocol integration.
🌟 Features#
- Multi-Provider Support: Import from Google Calendar and Microsoft Outlook
- OAuth2 Authentication: Secure authentication flows for external providers
- AT Protocol Integration: Seamless publishing to AT Protocol repositories
- Deduplication: Intelligent event deduplication to prevent duplicates
- CLI Interface: Easy-to-use command-line interface
- Configurable: Flexible configuration options
- Error Handling: Comprehensive error handling with structured error codes
📦 Repository Structure#
atproto-calendar-import/RUST/
├── src/
│ ├── main.rs # CLI binary entry point
│ ├── lib.rs # Core library exports
│ ├── auth.rs # OAuth2 + AT Protocol authentication
│ ├── cli.rs # Command-line interface
│ ├── dedup.rs # Event deduplication logic
│ ├── errors.rs # Centralized error definitions
│ ├── pds.rs # AT Protocol PDS interactions
│ ├── import/ # External calendar provider integrations
│ │ ├── mod.rs # Common import types and traits
│ │ ├── google.rs # Google Calendar API integration
│ │ └── outlook.rs # Microsoft Outlook/Graph API integration
│ └── transform/ # Event transformation and validation
│ ├── mod.rs # Transform module exports
│ ├── validate.rs # Event validation logic
│ └── convert.rs # Provider-to-AT Protocol conversion
├── docs/ # Additional documentation
├── import/ # Legacy import scripts (deprecated)
├── transform/ # Legacy transform scripts (deprecated)
├── target/ # Rust build artifacts
├── Cargo.toml # Project metadata and dependencies
├── Cargo.lock # Dependency lock file
└── README.md # This file
🚀 Quick Start#
Prerequisites#
- Rust ≥ 1.70
- Cargo (included with Rust)
- External calendar API credentials:
- Google OAuth2 credentials for Google Calendar
- Microsoft Graph API credentials for Outlook
- AT Protocol account and PDS access
Installation#
- Clone the repository:
git clone <repository-url>
cd atproto-calendar-import/RUST
- Build the project:
cargo build --release
- Set up environment variables:
# Google Calendar (optional)
export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"
# Microsoft Outlook (optional)
export OUTLOOK_CLIENT_ID="your-outlook-client-id"
export OUTLOOK_CLIENT_SECRET="your-outlook-client-secret"
# AT Protocol
export ATP_HANDLE="your-handle.bsky.social"
export ATP_PASSWORD="your-app-password"
export ATP_PDS_URL="https://bsky.social" # or your PDS URL
Basic Usage#
Import from Google Calendar:
cargo run -- import-google --interactive
Import from Microsoft Outlook:
cargo run -- import-outlook --interactive
Test AT Protocol connection:
cargo run -- test-connection
Clear deduplication cache:
cargo run -- clear-cache
🛠️ Development#
Build Commands#
| Task | Command | Description |
|---|---|---|
| Build (debug) | cargo build |
Build in debug mode |
| Build (release) | cargo build --release |
Build optimized release binary |
| Type Check | cargo check |
Fast type checking without building |
| Format Code | cargo fmt |
Format code using rustfmt |
| Lint Code | cargo clippy |
Run Clippy linter |
| Run Tests | cargo test |
Run all unit and integration tests |
| Run Specific Test | cargo test <test_name> |
Run a specific test |
| Generate Documentation | cargo doc --open |
Generate and open documentation |
Testing#
# Run all tests
cargo test
# Run tests with output
cargo test -- --nocapture
# Run integration tests only
cargo test --test integration
# Run specific test
cargo test test_google_import
📋 CLI Commands#
Import Commands#
import-google#
Import events from Google Calendar.
cargo run -- import-google [OPTIONS]
Options:
-a, --access-token <TOKEN>: Use existing access token--interactive: Start interactive OAuth2 flow--skip-dedup: Skip deduplication check--dry-run: Preview without publishing to AT Protocol
Examples:
# Interactive OAuth2 flow
cargo run -- import-google --interactive
# Use existing token
cargo run -- import-google --access-token "ya29.a0..."
# Dry run to preview events
cargo run -- import-google --interactive --dry-run
import-outlook#
Import events from Microsoft Outlook.
cargo run -- import-outlook [OPTIONS]
Options:
-a, --access-token <TOKEN>: Use existing access token--interactive: Start interactive OAuth2 flow--skip-dedup: Skip deduplication check--dry-run: Preview without publishing to AT Protocol
Utility Commands#
test-connection#
Test connectivity to AT Protocol PDS.
cargo run -- test-connection
clear-cache#
Clear the deduplication cache for the current user.
cargo run -- clear-cache
⚙️ Configuration#
Environment Variables#
Required for AT Protocol#
ATP_HANDLE: Your AT Protocol handle (e.g.,alice.bsky.social)ATP_PASSWORD: Your AT Protocol app passwordATP_PDS_URL: PDS endpoint URL (default:https://bsky.social)
Optional for Google Calendar#
GOOGLE_CLIENT_ID: Google OAuth2 client IDGOOGLE_CLIENT_SECRET: Google OAuth2 client secret
Optional for Microsoft Outlook#
OUTLOOK_CLIENT_ID: Microsoft Graph API client IDOUTLOOK_CLIENT_SECRET: Microsoft Graph API client secret
Optional Configuration#
RUST_LOG: Log level (trace,debug,info,warn,error)DATABASE_URL: PostgreSQL connection string (for persistent deduplication cache)
OAuth2 Setup#
Google Calendar API#
- Go to the Google Cloud Console
- Create a new project or select existing one
- Enable the Google Calendar API
- Create OAuth2 credentials
- Set redirect URI to
http://localhost:8080/callback
Microsoft Graph API#
- Go to Azure Portal
- Navigate to Azure Active Directory > App registrations
- Create a new application registration
- Add
Calendars.Readpermission - Set redirect URI to
http://localhost:8080/callback
🔧 Architecture#
Core Components#
auth.rs: Handles OAuth2 flows for external providers and AT Protocol authenticationimport/: Provider-specific importers (Google, Outlook) that fetch calendar eventstransform/: Converts external event formats to AT Protocol lexicon formatdedup.rs: Prevents duplicate events using content hashing and metadata comparisonpds.rs: Publishes events to AT Protocol repositories via atrium-rscli.rs: Command-line interface and argument parsing
Data Flow#
- Authentication: OAuth2 flow with calendar provider + AT Protocol session
- Import: Fetch events from external calendar API
- Transform: Convert events to AT Protocol format
- Deduplicate: Check against existing events to prevent duplicates
- Publish: Create records in AT Protocol repository
Error Handling#
The project uses structured error codes for easy debugging:
- 1xx: Authentication errors (
OAuth2TokenFailed,InvalidAccessToken, etc.) - 2xx: Import errors (
GoogleApiError,OutlookApiError, etc.) - 3xx: Transform errors (
InvalidDateTimeFormat,MissingRequiredField, etc.) - 4xx: PDS errors (
RecordCreationFailed,RepositoryNotFound, etc.) - 5xx: Internal errors (
DeduplicationError,ConfigurationError, etc.)
🤝 Contributing#
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Add tests for new functionality
- Ensure all tests pass:
cargo test - Format code:
cargo fmt - Run linter:
cargo clippy - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Create a Pull Request
Code Style#
- Follow Rust standard formatting (
cargo fmt) - Add documentation for public APIs
- Include unit tests for new functionality
- Use structured error types from
errors.rs - Add tracing instrumentation for important functions
📝 License#
This project is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
🔗 Related Projects#
- AT Protocol - The underlying protocol
- atrium-rs - Rust AT Protocol implementation
- Bluesky - Social network built on AT Protocol
📞 Support#
- 📧 Issues: GitHub Issues
- 📖 Documentation: Run
cargo doc --openfor API docs - 🌐 AT Protocol Docs: https://atproto.com/