Files
studiobeve.no/application/libraries/GoogleCalendar.php
T
Astral04andClaude Sonnet 4.6 804d454618 Google Calendar: Domain-Wide Delegation support for attendee invitations
Service account can now impersonate a Workspace user (set gcal_impersonate_email
in config) to unlock attendee invitations with push notifications.
Falls back to silent event creation if impersonation is not configured.

Setup required in Google Admin Console:
  Security → API Controls → Domain-wide delegation
  → Add service account client_id with scope:
  https://www.googleapis.com/auth/calendar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 15:09:26 +01:00

106 lines
4.3 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class GoogleCalendar {
private $service = null;
private $canInvite = false;
public function __construct() {
require_once FCPATH . 'vendor/autoload.php';
$CI =& get_instance();
$CI->config->load('google_calendar');
$serviceAccountPath = $CI->config->item('gcal_service_account_path');
if (!file_exists($serviceAccountPath)) {
return;
}
try {
$client = new Google_Client();
$client->setAuthConfig($serviceAccountPath);
$client->setScopes([Google_Service_Calendar::CALENDAR]);
// Domain-Wide Delegation: impersonate a Workspace user to unlock attendee invitations
$impersonateEmail = $CI->config->item('gcal_impersonate_email');
if (!empty($impersonateEmail)) {
$client->setSubject($impersonateEmail);
$this->canInvite = true;
}
$this->service = new Google_Service_Calendar($client);
} catch (Exception $e) {
// Silently fail — calendar errors must never break the booking flow
}
}
/**
* Create a calendar event.
* If Domain-Wide Delegation is configured and $attendeeEmail is provided,
* the attendee receives an invitation push notification via Google Calendar.
* @return string|null The new event ID, or null on failure.
*/
public function createEvent($calendarId, $title, $description, $startDatetime, $endDatetime, $attendeeEmail = null) {
if (!$this->service || empty($calendarId)) return null;
try {
$eventData = [
'summary' => $title,
'description' => $description,
'start' => ['dateTime' => $startDatetime, 'timeZone' => 'Europe/Oslo'],
'end' => ['dateTime' => $endDatetime, 'timeZone' => 'Europe/Oslo'],
];
if ($this->canInvite && !empty($attendeeEmail)) {
$eventData['attendees'] = [['email' => $attendeeEmail]];
}
$event = new Google_Service_Calendar_Event($eventData);
$params = ($this->canInvite && !empty($attendeeEmail)) ? ['sendUpdates' => 'all'] : [];
$result = $this->service->events->insert($calendarId, $event, $params);
return $result->getId();
} catch (Exception $e) {
return null;
}
}
/**
* Update an existing calendar event.
* @return string|null The event ID, or null on failure.
*/
public function updateEvent($calendarId, $eventId, $title, $description, $startDatetime, $endDatetime, $attendeeEmail = null) {
if (!$this->service || empty($calendarId) || empty($eventId)) return null;
try {
$event = $this->service->events->get($calendarId, $eventId);
$event->setSummary($title);
$event->setDescription($description);
$event->setStart(new Google_Service_Calendar_EventDateTime([
'dateTime' => $startDatetime,
'timeZone' => 'Europe/Oslo',
]));
$event->setEnd(new Google_Service_Calendar_EventDateTime([
'dateTime' => $endDatetime,
'timeZone' => 'Europe/Oslo',
]));
if ($this->canInvite && !empty($attendeeEmail)) {
$event->setAttendees([new Google_Service_Calendar_EventAttendee(['email' => $attendeeEmail])]);
}
$params = ($this->canInvite && !empty($attendeeEmail)) ? ['sendUpdates' => 'all'] : [];
$result = $this->service->events->update($calendarId, $eventId, $event, $params);
return $result->getId();
} catch (Exception $e) {
return null;
}
}
/**
* Delete a calendar event. Silently skips if not found.
*/
public function deleteEvent($calendarId, $eventId) {
if (!$this->service || empty($calendarId) || empty($eventId)) return;
try {
$this->service->events->delete($calendarId, $eventId);
} catch (Exception $e) {
// Silently skip — event may already be gone
}
}
}