# 📅 atproto-calendar-import A Rust library and CLI tool for importing calendar events from external providers (Google Calendar, Microsoft Outlook) into the [AT Protocol](https://atproto.com/) ecosystem. Built with [atrium-rs](https://github.com/atrium-rs/atrium) for robust AT Protocol integration. [![Rust](https://img.shields.io/badge/rust-1.70+-blue.svg)](https://rust-lang.org) [![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE) --- ## 🌟 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 ```text 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 1. Clone the repository: ```bash git clone cd atproto-calendar-import/RUST ``` 2. Build the project: ```bash cargo build --release ``` 3. Set up environment variables: ```bash # 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: ```bash cargo run -- import-google --interactive ``` Import from Microsoft Outlook: ```bash cargo run -- import-outlook --interactive ``` Test AT Protocol connection: ```bash cargo run -- test-connection ``` Clear deduplication cache: ```bash 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 ` | Run a specific test | | Generate Documentation| `cargo doc --open` | Generate and open documentation | ### Testing ```bash # 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. ```bash cargo run -- import-google [OPTIONS] ``` **Options:** - `-a, --access-token `: Use existing access token - `--interactive`: Start interactive OAuth2 flow - `--skip-dedup`: Skip deduplication check - `--dry-run`: Preview without publishing to AT Protocol **Examples:** ```bash # 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. ```bash cargo run -- import-outlook [OPTIONS] ``` **Options:** - `-a, --access-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. ```bash cargo run -- test-connection ``` #### `clear-cache` Clear the deduplication cache for the current user. ```bash 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 password - `ATP_PDS_URL`: PDS endpoint URL (default: `https://bsky.social`) #### Optional for Google Calendar - `GOOGLE_CLIENT_ID`: Google OAuth2 client ID - `GOOGLE_CLIENT_SECRET`: Google OAuth2 client secret #### Optional for Microsoft Outlook - `OUTLOOK_CLIENT_ID`: Microsoft Graph API client ID - `OUTLOOK_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 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) 2. Create a new project or select existing one 3. Enable the Google Calendar API 4. Create OAuth2 credentials 5. Set redirect URI to `http://localhost:8080/callback` #### Microsoft Graph API 1. Go to [Azure Portal](https://portal.azure.com/) 2. Navigate to Azure Active Directory > App registrations 3. Create a new application registration 4. Add `Calendars.Read` permission 5. Set redirect URI to `http://localhost:8080/callback` --- ## 🔧 Architecture ### Core Components - **`auth.rs`**: Handles OAuth2 flows for external providers and AT Protocol authentication - **`import/`**: Provider-specific importers (Google, Outlook) that fetch calendar events - **`transform/`**: Converts external event formats to AT Protocol lexicon format - **`dedup.rs`**: Prevents duplicate events using content hashing and metadata comparison - **`pds.rs`**: Publishes events to AT Protocol repositories via atrium-rs - **`cli.rs`**: Command-line interface and argument parsing ### Data Flow 1. **Authentication**: OAuth2 flow with calendar provider + AT Protocol session 2. **Import**: Fetch events from external calendar API 3. **Transform**: Convert events to AT Protocol format 4. **Deduplicate**: Check against existing events to prevent duplicates 5. **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 1. Fork the repository 2. Create a feature branch: `git checkout -b feature/amazing-feature` 3. Make your changes 4. Add tests for new functionality 5. Ensure all tests pass: `cargo test` 6. Format code: `cargo fmt` 7. Run linter: `cargo clippy` 8. Commit changes: `git commit -m 'Add amazing feature'` 9. Push to branch: `git push origin feature/amazing-feature` 10. 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](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. --- ## 🔗 Related Projects - [AT Protocol](https://atproto.com/) - The underlying protocol - [atrium-rs](https://github.com/atrium-rs/atrium) - Rust AT Protocol implementation - [Bluesky](https://bsky.app/) - Social network built on AT Protocol --- ## 📞 Support - 📧 **Issues**: [GitHub Issues](../../issues) - 📖 **Documentation**: Run `cargo doc --open` for API docs - 🌐 **AT Protocol Docs**: https://atproto.com/