include/CalendarSync/migrations/.google_sync_migrated_checked
This guide provides comprehensive technical reference material for advanced Calendar Sync configuration and migration from legacy Google Sync. Use this as your authoritative reference for complete configuration options, migration procedures, and system disabling instructions.
For initial setup, see Administrator Setup Guide and User Guide.
If you were previously using the legacy Google Calendar sync (available in SuiteCRM 7.11+), the new Calendar Sync framework provides enhanced capabilities including multi-provider support, configurable conflict resolution, and improved architecture.
Understanding the differences between legacy and new systems helps you plan your migration:
| Feature | Legacy Google Sync | New Calendar Sync |
|---|---|---|
Provider Support |
Google Calendar only |
Google Calendar, CalDAV servers, extensible architecture |
Configuration Location |
Admin panel only |
Admin panel (global settings) + per-user Calendar Accounts |
User Authorization |
User profile Advanced tab |
Calendar Accounts module with dedicated interface |
Conflict Resolution |
Fixed behavior (most recent change wins) |
Configurable strategies (timestamp, external priority, SuiteCRM priority) |
Scheduler Job |
"Google Sync Calendars" job |
"Calendar Accounts Sync" job |
Deletion Behavior |
Fixed bidirectional sync |
Configurable per-direction deletion controls |
Real-time Sync |
Not available |
Optional logic hooks for immediate sync on save/delete |
Data Model |
Legacy tables and relationships |
Modernized data structure with Calendar Account entity |
When upgrading to a version with the new Calendar Sync framework, migration runs automatically during the upgrade process. The system detects existing legacy Google Sync configuration and migrates it seamlessly.
The automatic migration performs these operations:
1. External OAuth Provider Creation
Creates an External OAuth Provider from your existing Google API credentials (Client ID and Client Secret)
Migrates OAuth configuration from config.php or config_override.php
Sets the provider status to Active
Associates the provider with Google Calendar service
2. Scheduler Job Migration
Locates the legacy Google Sync Calendars scheduler job
Creates a new Calendar Accounts Sync scheduler job with the same interval and status
Preserves time range and frequency settings
3. Calendar Account Creation
Scans all users with legacy Google sync configured (user profile Advanced tab settings)
Creates Calendar Account records for each user with active Google sync
Migrates user-specific settings (calendar selection, sync preferences)
Links Calendar Accounts to the newly created External OAuth Provider
4. OAuth Token Migration
Transfers OAuth access tokens and refresh tokens to the new data structure
Preserves token expiration timestamps
Maintains token encryption and security
Associates tokens with the correct Calendar Account records
5. Meeting Sync Data Migration
Migrates existing meeting-to-event mappings from legacy tables
Populates External Calendar ID fields in meeting records
Preserves sync history and last sync timestamps
Updates data relationships to use the new Calendar Account structure
After successful migration, the system creates a marker file to prevent re-running:
include/CalendarSync/migrations/.google_sync_migrated_checked
This file is checked on each system startup. If present, automatic migration is skipped.
The automatic migration preserves all existing OAuth tokens and calendar connections. You do not need to re-authorize your Google account after upgrade. If migration encounters errors, check suitecrm.log for entries tagged [CalendarSyncMigration].
After automatic migration completes, verify the migration succeeded:
1. Check External OAuth Provider
Navigate to Administration > External OAuth Providers
Verify a Google OAuth Provider exists with your credentials
Confirm the provider status is Active
2. Verify Calendar Accounts
Navigate to Calendar Accounts module
Check that Calendar Account records exist for users who had legacy sync configured
Verify OAuth Connection field is populated
Check Last Sync Date updates after the first scheduled sync
3. Test Synchronization
Edit a Calendar Account and click Test Connection
Verify the test completes successfully
Click Sync Now to trigger manual sync
Confirm meetings sync between SuiteCRM and Google Calendar
4. Review Scheduler
Go to Administration > Scheduler
Verify Calendar Accounts Sync job exists and is Active
Check the job runs successfully (review Last Successful Run timestamp)
Optionally disable the legacy Google Sync Calendars job if it still exists
If automatic migration did not run or you need to set up a fresh installation without legacy data, follow these manual steps:
1. Create External OAuth Provider
Navigate to Administration > External OAuth Providers
Click Create External OAuth Provider
Configure the provider:
Name: "Google Calendar OAuth" or similar
Type: Google
Client ID: From Google Developer Console
Client Secret: From Google Developer Console
Status: Active
Click Save
See External OAuth Provider documentation for detailed Google Developer Console setup.
2. Create Calendar Accounts for Users
Each user must create their own Calendar Account:
User navigates to Calendar Accounts module
Clicks Create Calendar Account
Fills in required fields:
Name: Descriptive name (e.g., "My Google Calendar")
Calendar Source: Google Calendar
OAuth Connection: Select the External OAuth Connection recently created
Calendar User: The user’s SuiteCRM account
Click Authenticate to complete OAuth authorization
Click Save to create the account
See User Guide for detailed Calendar Account creation instructions.
3. Verify Scheduler Configuration
Go to Administration > Scheduler
Find the Calendar Accounts Sync job
Verify it is set to Active
Configure sync interval (default: every 15 minutes)
Save scheduler configuration
See Scheduler Configuration for frequency adjustment guidance.
4. Test Synchronization
Edit the Calendar Account
Click Test Connection to verify OAuth and API access
Click Save
From the detail view, click Sync Now to trigger immediate sync
Verify meetings sync between SuiteCRM and Google Calendar
This section provides a comprehensive reference of all available configuration options for Calendar Sync. These settings are configured in config_override.php and offer fine-grained control over synchronization behavior beyond what’s available in the administration UI.
Add this to your config_override.php file to customize calendar sync behavior. Only include the settings you want to override - all settings have sensible defaults.
<?php
// Add to config_override.php
$sugar_config['calendar_sync'] = [
// ===================================
// Sync Window
// ===================================
// Number of days in the past to include in synchronization
'sync_window_past_days' => 30,
// Number of days in the future to include in synchronization
'sync_window_future_days' => 90,
// ===================================
// Conflict Resolution
// ===================================
// Strategy for resolving conflicts when the same event is modified in both systems
// Valid values: 'timestamp', 'external_based', 'internal_based'
'conflict_resolution' => 'timestamp',
// ===================================
// Deletion Behavior
// ===================================
// Allow deletions in external calendar to delete meetings in SuiteCRM
'allow_internal_event_deletion' => true,
// Allow deletions in SuiteCRM to delete events in external calendar
'allow_external_event_deletion' => true,
// ===================================
// Real-time Sync
// ===================================
// Enable logic hooks to trigger immediate sync when meetings are saved/deleted
'enable_calendar_sync_logic_hooks' => false,
// ===================================
// External Calendar Settings
// ===================================
// Name displayed in external calendar for SuiteCRM events
'external_calendar_name' => 'SuiteCRM',
];
Always test configuration changes in a development or staging environment before applying them to production. Incorrect configuration can cause sync failures or data loss.
Detailed reference for each configuration option, including type, default value, valid range, impact, and recommendations.
Number of days in the past to include in synchronization. Events older than this are ignored.
Type: Integer
Default: 30
Valid Range: 0 to 365
Impact: Larger values increase the number of events synchronized, affecting performance and sync duration. Smaller values improve performance but exclude historical events.
Recommendation:
30 days for standard usage (recent history)
0 days to sync only today and future events (minimal resource usage)
90 days or more for historical event analysis or reporting
365 days for complete calendar history (use only with adequate resources)
Performance Note: Past events are more numerous than future events, so larger past windows have significant performance impact
Example:
// Sync only today and future (minimal resource usage)
$sugar_config['calendar_sync']['sync_window_past_days'] = 0;
// Or sync 90 days of history for reporting
$sugar_config['calendar_sync']['sync_window_past_days'] = 90;
Number of days in the future to include in synchronization. Events beyond this are ignored.
Type: Integer
Default: 90
Valid Range: 1 to 730 (2 years)
Impact: Determines how far ahead meetings are synchronized. Larger values have minimal performance impact since future events are less numerous.
Recommendation:
90 days (3 months) for standard planning horizons
180 days (6 months) for medium-term planning
365 days (1 year) for long-term planning and project management
730 days (2 years) for very long-term planning (rarely needed)
Performance Note: Future events are typically sparse, so larger future windows have minimal impact
Example:
// Sync 1 year ahead for long-term planning
$sugar_config['calendar_sync']['sync_window_future_days'] = 365;
Strategy for resolving conflicts when the same event is modified in both SuiteCRM and the external calendar between sync runs.
Type: String (enum)
Default: 'timestamp'
Valid Values:
'timestamp': Most recent change wins (compares modification timestamps)
'external_based': External calendar changes always take precedence
'internal_based': SuiteCRM changes always take precedence
Impact: Determines which version of an event is kept when conflicts occur. Incorrect strategy can cause user frustration when their changes are overwritten.
Recommendation:
Use 'timestamp' for balanced collaboration (recommended for most installations)
Use 'external_based' when external calendar (mobile apps) is primary interface for most users
Use 'internal_based' when SuiteCRM is the authoritative source and external calendar is view-only
Consider user workflows and communication patterns when choosing
For detailed conflict resolution scenarios, see Conflict Resolution Strategy.
Example:
// External calendar is primary (mobile users)
$sugar_config['calendar_sync']['conflict_resolution'] = 'external_based';
// Or SuiteCRM is authoritative source
$sugar_config['calendar_sync']['conflict_resolution'] = 'internal_based';
Controls whether events deleted in the external calendar are also deleted in SuiteCRM.
Type: Boolean
Default: true
Valid Values: true or false
Impact: When false, deleting an event in the external calendar will NOT delete the meeting in SuiteCRM. The meeting will be re-synced back to the external calendar on the next sync run.
Recommendation:
Keep as true for true bidirectional sync (recommended for most installations)
Set to false to preserve SuiteCRM meeting records when users delete events in external calendar
Set to false if SuiteCRM is the system of record for meeting history
Consider data retention policies and compliance requirements
Example:
// Preserve SuiteCRM meetings when external calendar events are deleted
$sugar_config['calendar_sync']['allow_internal_event_deletion'] = false;
Controls whether meetings deleted in SuiteCRM are also deleted in the external calendar.
Type: Boolean
Default: true
Valid Values: true or false
Impact: When false, deleting a meeting in SuiteCRM will NOT delete the event in the external calendar. The event will be re-synced back to SuiteCRM on the next sync run.
Recommendation:
Keep as true for true bidirectional sync (recommended for most installations)
Set to false to preserve external calendar events when SuiteCRM meetings are deleted
Set to false if external calendar is the system of record
Useful when external calendar contains events from multiple sources
Example:
// Preserve external calendar events when SuiteCRM meetings are deleted
$sugar_config['calendar_sync']['allow_external_event_deletion'] = false;
Disabling either deletion setting can lead to orphaned events that exist in one system but not the other. Events will be re-created on the next sync run. Consider implementing manual cleanup procedures if you disable deletion sync.
Enables real-time synchronization via logic hooks triggered on meeting save/delete operations in SuiteCRM.
Type: Boolean
Default: false
Valid Values: true or false
Impact: When enabled, changes to meetings in SuiteCRM trigger immediate sync to external calendar (in addition to scheduled sync). This provides near real-time synchronization but adds processing overhead to meeting save/delete operations.
Recommendation:
Enable for near real-time synchronization requirements
Enable if users expect immediate reflection of changes in external calendar
Disable if you prefer batch processing only (scheduled sync)
Disable if you experience performance issues during meeting operations
Disable during bulk imports or data migrations to avoid triggering sync for every meeting
Example:
// Enable real-time sync for immediate updates
$sugar_config['calendar_sync']['enable_calendar_sync_logic_hooks'] = true;
Logic hooks only affect SuiteCRM-to-external sync direction. Changes in external calendar are always detected during scheduled sync runs, regardless of this setting.
The name displayed in the external calendar for events created or synced by SuiteCRM. This helps users identify which calendar system created an event.
Type: String
Default: 'SuiteCRM'
Valid Range: Any string (typically 3-50 characters)
Impact: This name may appear in event descriptions, metadata, or calendar source information in the external calendar system. It does not affect synchronization logic.
Recommendation:
Use your company name for branding (e.g., "Acme Corp CRM")
Use a descriptive identifier like "CRM Calendar" or "Company Calendar"
Keep it concise for better display in mobile and desktop calendar apps
Avoid special characters that may not display correctly in all calendar systems
Example:
// Brand with company name
$sugar_config['calendar_sync']['external_calendar_name'] = 'Acme Corp CRM';
// Or use descriptive identifier
$sugar_config['calendar_sync']['external_calendar_name'] = 'Business Calendar';
These examples demonstrate complete configuration setups for common scenarios. Use these as starting points and adjust based on your specific requirements.
SuiteCRM is the source of truth, external calendar is primarily for viewing.
<?php
// CRM-Authoritative Setup
// Best for: Sales teams, CRM-first workflows, controlled planning
$sugar_config['calendar_sync'] = [
// SuiteCRM changes always win conflicts
'conflict_resolution' => 'internal_based',
// Preserve SuiteCRM meetings when external events are deleted
'allow_internal_event_deletion' => false,
// Enable logic hooks for immediate sync to external calendar
'enable_calendar_sync_logic_hooks' => true,
// Standard sync window
'sync_window_past_days' => 30,
'sync_window_future_days' => 90,
];
Rationale:
SuiteCRM priority ensures CRM data is never overwritten
Deleting external events won’t remove SuiteCRM meetings (data preservation)
Logic hooks provide immediate updates to external calendar after CRM changes
Users rely on CRM for scheduling, external calendar for viewing only
Use Cases:
Sales teams who plan all meetings in SuiteCRM
Organizations where CRM is the system of record for meeting history
Environments where external calendar edits should not affect CRM data
External calendar (mobile apps) is the primary interface, SuiteCRM syncs for record-keeping.
<?php
// External Calendar Primary Setup
// Best for: Mobile-first users, field teams, external calendar as source
$sugar_config['calendar_sync'] = [
// External calendar changes always win conflicts
'conflict_resolution' => 'external_based',
// Preserve external events when SuiteCRM meetings are deleted
'allow_external_event_deletion' => false,
// Disable logic hooks (batch sync only)
'enable_calendar_sync_logic_hooks' => false,
// Longer sync window for comprehensive history
'sync_window_past_days' => 60,
'sync_window_future_days' => 180,
];
Rationale:
External priority ensures mobile edits are never overwritten
Deleting SuiteCRM meetings won’t remove external events (data preservation)
Logic hooks disabled - users edit in external calendar, not CRM
Longer sync windows capture more planning data for reporting
Use Cases:
Field teams who primarily use mobile calendar apps
Organizations where Google Calendar or Outlook is the primary scheduling tool
Users who rarely edit meetings directly in SuiteCRM
Optimized for resource-constrained environments or small installations.
<?php
// Minimal Resource Usage Setup
// Best for: Small installations, limited server resources, low meeting volume
$sugar_config['calendar_sync'] = [
// Minimal sync window to reduce event count
'sync_window_past_days' => 0, // Only today and future
'sync_window_future_days' => 30, // Only 1 month ahead
// Disable logic hooks to avoid overhead
'enable_calendar_sync_logic_hooks' => false,
// Standard conflict resolution
'conflict_resolution' => 'timestamp',
];
Rationale:
Zero past days eliminates historical event processing
Short future window (30 days) reduces API calls and processing time
No logic hooks means no overhead during meeting operations
Use Cases:
Small businesses with 5-20 users
Shared hosting environments with resource limits
Installations where sync speed is not critical
You may need to temporarily or permanently disable calendar synchronization for maintenance, troubleshooting, or if you no longer use the feature.
To completely disable calendar synchronization for all users:
1. Disable the Scheduler Job
Navigate to Administration > Scheduler
Locate the Calendar Accounts Sync job
Edit the job
Change Status to Inactive
Click Save
This stops all automatic synchronization. Manual sync via Sync Now button is still possible.
2. Disable Logic Hooks (Optional)
If logic hooks are enabled, disable them to prevent real-time sync:
Add to config_override.php:
$sugar_config['calendar_sync']['enable_calendar_sync_logic_hooks'] = false;
Or uncheck Enable Calendar Sync Logic Hooks in Calendar Sync Settings.
3. Verify Synchronization Stopped
Wait for the next scheduled sync interval to pass
Check Calendar Sync Settings status page
Verify Last Scheduled Run timestamp is not updating
Review suitecrm.log to confirm no sync operations are occurring
Disabling the scheduler and logic hooks prevents new sync operations but does not delete existing Calendar Account configurations or synced meeting data. Users' Calendar Accounts remain configured and can be re-activated by enabling the scheduler.
To disable synchronization for a specific user without affecting other users, delete their Calendar Account:
Navigate to Calendar Accounts module
Open the user’s Calendar Account
Click Delete
Confirm deletion
Deleting a Calendar Account removes all sync configuration and mapping history for that user. The user must recreate the Calendar Account and re-authorize to resume synchronization. Meeting records are preserved, but external calendar event mappings are lost. On next sync, meetings will be re-matched with external calendar events.
To temporarily disable sync during system maintenance:
1. Before Maintenance
Disable the Calendar Accounts Sync scheduler job
Wait for any running sync operations to complete (check scheduler status)
Optionally notify users that sync is temporarily unavailable
2. During Maintenance
Perform system upgrades, data migrations, or other maintenance tasks
Sync operations will not interfere with maintenance
3. After Maintenance
Re-enable the Calendar Accounts Sync scheduler job
Optionally trigger manual sync for all users via Sync All Users Now
Monitor the first sync run to ensure no errors
To re-enable previously disabled synchronization:
1. Enable Scheduler Job
Navigate to Administration > Scheduler
Locate the Calendar Accounts Sync job
Edit the job
Change Status to Active
Click Save
2. Re-enable Logic Hooks (If Needed)
If you disabled logic hooks:
$sugar_config['calendar_sync']['enable_calendar_sync_logic_hooks'] = true;
Or check Enable Calendar Sync Logic Hooks in Calendar Sync Settings.
3. Verify Synchronization Resumed
Wait for the next scheduled sync interval
Check Calendar Sync Settings status page
Verify Last Scheduled Run timestamp updates
Test with a Calendar Account using Test Connection and Sync Now
Understanding security implications helps you maintain secure calendar synchronization and protect sensitive data.
Direct Connection Model:
Data flows directly between your SuiteCRM instance and the calendar provider’s servers
No intermediary services or third-party servers are involved
SuiteCRM acts as a client to the external calendar API
Network traffic is encrypted when using HTTPS (required)
Data Transmitted:
The following meeting data is transmitted over the network:
Meeting titles and subjects
Start and end dates/times
Descriptions and meeting notes
Location information
External calendar identifiers (for matching)
Data NOT Transmitted:
SuiteCRM user passwords
Assigned user information
Parent record details (related Accounts, Contacts, Opportunities)
Custom fields (SuiteCRM-specific metadata)
Meeting invitees and attendees (managed independently)
Meeting status (Planned, Held, Not Held)
Provider Privacy Policies:
External calendar providers have their own data retention and privacy policies:
Google Calendar: Data stored on Google servers, subject to Google’s privacy policy and data retention practices
Self-Hosted CalDAV: Full control over data storage, retention, and privacy policies
Cloud CalDAV Providers: Review provider-specific privacy policies
Ensure your calendar provider’s privacy policy meets your organization’s compliance requirements (GDPR, HIPAA, CCPA, etc.).
Per-User Authorization:
Each user authorizes only their own calendar connection via Calendar Accounts module
Users cannot access other users' external calendars through this system
Calendar Account records are owned by individual users
Administrators can view Calendar Accounts but cannot authorize OAuth on behalf of users
Token Storage:
OAuth Tokens (Google Calendar):
OAuth access and refresh tokens are stored encrypted in the SuiteCRM database
Tokens are encrypted using SuiteCRM’s encryption key (config.php)
Tokens are transmitted over HTTPS during OAuth authorization flow
Token refresh happens automatically without user interaction
Expired tokens require re-authorization by the user
CalDAV Credentials:
Username and password are stored in the SuiteCRM database
Credentials ARE encrypted by default using Blowfish encryption (db_encrypted ⇒ true)
Consider using app-specific passwords instead of main account passwords for additional security
Administrator Privileges:
Administrators have these privileges:
Configure global sync settings (sync window, conflict resolution, deletion behavior)
Trigger manual sync for all users via Sync All Users Now
View all Calendar Account records (but cannot authorize OAuth on behalf of users)
Access sync logs and diagnostic information
Modify advanced configuration options via config_override.php
Administrators CANNOT:
Access the content of users' external calendars directly
Re-authorize OAuth connections on behalf of users without their credentials
View encrypted OAuth tokens in plain text
Decrypt stored CalDAV passwords
Use HTTPS:
Production: HTTPS is mandatory to protect OAuth tokens and credentials in transit
Development/Testing: Use HTTPS even in development environments when possible
SSL Configuration: Use valid SSL certificates from trusted CAs (not self-signed in production)
Use App Passwords:
When available, always use app-specific passwords for CalDAV connections.
Benefits of App Passwords:
Limited scope (calendar access only, no admin privileges)
Easy revocation without changing main account password
Better security audit trail
Compliance with multi-factor authentication (MFA) policies
Isolation from primary account credentials
Regular Auditing:
Maintain security through periodic audits:
Monthly Review: Check active Calendar Accounts for unused or orphaned connections
Quarterly Audit: Verify OAuth tokens are still valid and users still require access
Log Monitoring: Review sync logs for suspicious activity or repeated authentication failures
Access Review: Ensure only authorized users have active Calendar Accounts
Audit Checklist:
❏ Review all active Calendar Accounts in the module
❏ Verify Last Sync Date is recent for all accounts (within expected sync interval)
❏ Check for accounts with failed connection tests
❏ Remove Calendar Accounts for departed or inactive users
❏ Review suitecrm.log for authentication failures or repeated errors
❏ Verify external calendar access permissions are still appropriate
❏ Confirm OAuth providers have current credentials
Secure Credential Management:
Store database backups in encrypted storage
Enable database encryption for sensitive fields if available (third-party solutions)
Use strong passwords for CalDAV accounts (minimum 16 characters)
Rotate CalDAV passwords and app passwords regularly (quarterly or annually)
Implement IP restrictions on external calendar access when possible (self-hosted CalDAV)
Use VPN or private networks for CalDAV connections to self-hosted servers (enhanced security)
Document which users have calendar sync enabled and review access permissions
You’ve completed the Calendar Sync documentation. For ongoing reference:
Review Administrator Setup Guide for configuration changes
Consult User Guide when assisting users with calendar connections
Reference CalDAV Provider Guide for CalDAV-specific troubleshooting
See Understanding Sync & Troubleshooting for diagnostic procedures
Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.