Skip to content

Calendar Sync & iCal Feeds

Salamandr keeps support agents’ schedules synchronized with their enterprise calendars to prevent double-bookings, automate availability detection during ticket triage, and synchronize call invitations.


Salamandr interfaces with Google Calendar (Google Workspace API) and Microsoft Outlook (Microsoft Graph API) using a tenant-managed OAuth 2.0 credential model:

┌─────────────────────────┐ ┌─────────────────────────┐
│ Google Workspace │ │ Microsoft 365 Graph │
│ (Google Calendar API) │ │ (Outlook API) │
└────────────┬────────────┘ └────────────┬────────────┘
│ │
│ OAuth 2.0 Free/Busy │ OAuth 2.0 Free/Busy
│ Webhook Push Events │ Webhook Subscriptions
▼ ▼
┌─────────────────────────────────────────────────────────────────────┐
│ Salamandr Calendar Engine │
│ (internal/meeting) │
├─────────────────────────────────────────────────────────────────────┤
│ • Aggregates multi-calendar busy blocks per agent │
│ • Detects conflicts during ticket meeting scheduling │
│ • Mirrors meeting events into organizer/attendee calendars │
│ • Provides private, revocable Webcal (.ics) subscription feeds │
└─────────────────────────────────────────────────────────────────────┘

  1. In Azure Portal → App Registrations, create an application.
  2. Under API Permissions, grant:
    • Calendars.ReadWrite (Delegated)
    • offline_access
  3. Add redirect URI: https://helpdesk.yourcompany.com/api/v1/connectors/outlookcal/callback.
  4. In Salamandr Admin Panel → Settings → Connectors, save your Client ID and Client Secret.
  1. In Google Cloud Console, enable the Google Calendar API.
  2. Under Credentials → OAuth 2.0 Client IDs, configure redirect URI:
    • https://helpdesk.yourcompany.com/api/v1/connectors/googlecal/callback
  3. In Salamandr Admin Panel → Settings → Connectors, save your Client ID and Client Secret.

Once the tenant app is configured, each agent connects their account:

  1. Navigate to Profile → Connections.
  2. Click Connect Google Calendar or Connect Outlook.
  3. Authorize via your organization’s Single Sign-On.

When scheduling a meeting from a ticket, Salamandr checks agent availability:

  • Aggregated Busy Windows: Queries both internal Salamandr meetings and connected external calendars (calendarView on Graph, events.list on Google).
  • Self-Exclusion Invariant: When editing an existing meeting, its own calendar event is excluded from the query so it doesn’t trigger a false conflict against itself.
  • Visual Warning: Conflicts are displayed in the scheduling modal without blocking ticket workflows.

Every staff agent and customer has access to a private, dynamic calendar feed:

  • Subscribe in Desktop/Mobile Apps: Compatible with Apple Calendar, Google Calendar, Thunderbird, and mobile OS calendars.
  • Feed URL Format: webcal://helpdesk.yourcompany.com/meetings/feed/{token}.ics
  • Dynamic Window: Automatically serves meetings within a ±180-day sliding window.
  • Revocation: If a token is compromised or a device is lost, clicking Regenerate Feed Token invalidates the old URL instantly.

5. Bidirectional Sync & Webhook Subscriptions

Section titled “5. Bidirectional Sync & Webhook Subscriptions”

When an agent alters or deletes a mirrored support meeting directly in Google Calendar or Outlook:

  1. Inbound Webhook Delivery:
    • Microsoft Graph sends change alerts to /integrations/outlook_calendar/webhook.
    • Google Calendar sends channel notifications to /integrations/google_calendar/webhook.
  2. State Reconciliation:
    • Salamandr re-fetches the modified event from the vendor API.
    • Updates start/end times or cancels the meeting within Salamandr.
    • Logs an automated note on any linked ticket conversation.
  3. Automatic Watch Renewal:
    • cmd/worker’s calendarWatchRenewalRunner runs hourly to renew expiring push channels before they lapse.

Check Availability Across All Connected Calendars

Section titled “Check Availability Across All Connected Calendars”
GET /api/v1/meetings/availability?from=2026-09-01T08:00:00Z&to=2026-09-01T18:00:00Z&attendee_ids=u_1001,u_1002
Authorization: Bearer <API_TOKEN>
POST /api/v1/meetings/feed-token/regenerate
Authorization: Bearer <API_TOKEN>