Files
meet-hub/docs/google-calendar-service-account-setup.md
dwindown 631dc9a083 Add Google Calendar integration via Supabase Edge Functions
- Create new create-google-meet-event edge function
- Use service account authentication (no OAuth needed)
- Add google_service_account_json field to platform_settings
- Add admin UI for service account JSON configuration
- Include test connection button in Integrasi tab
- Add comprehensive setup documentation
- Keep n8n workflows as alternative option

Features:
- Direct Google Calendar API integration
- JWT authentication with service account
- Auto-create Google Meet links
- No external dependencies needed
- Simple configuration via admin panel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 01:32:23 +07:00

6.0 KiB

Google Calendar Integration with Service Account

Overview

Using a Service Account to integrate Google Calendar API without OAuth user consent.

Setup Instructions

1. Create Service Account in Google Cloud Console

  1. Go to Google Cloud Console
  2. Create a new project or select existing one
  3. Navigate to IAM & AdminService Accounts
  4. Click Create Service Account
  5. Fill in details:
    • Name: access-hub-calendar
    • Description: Service account for Access Hub calendar integration
  6. Click Create and Continue
  7. Skip granting roles (not needed for Calendar API)
  8. Click Done

2. Enable Google Calendar API

  1. In Google Cloud Console, go to APIs & ServicesLibrary
  2. Search for "Google Calendar API"
  3. Click on it and press Enable

3. Create Service Account Key

  1. Go to your service account page
  2. Click on the Keys tab
  3. Click Add KeyCreate New Key
  4. Select JSON format
  5. Click Create - this will download a JSON file with credentials
  6. Keep this file secure - it contains your private key

The JSON file looks like:

{
  "type": "service_account",
  "project_id": "your-project-id",
  "private_key_id": "...",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...",
  "client_email": "access-hub-calendar@your-project-id.iam.gserviceaccount.com",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token"
}

4. Share Calendar with Service Account

  1. Go to Google Calendar
  2. Find the calendar you want to use (e.g., your main calendar)
  3. Click the three dots next to the calendar name
  4. Select Settings and sharing
  5. Scroll to Share with specific people
  6. Click + Add people
  7. Enter the service account email: access-hub-calendar@your-project-id.iam.gserviceaccount.com
  8. Set permissions to Editor (can make changes to events)
  9. Click Send (ignore the email notification)

5. Get Calendar ID

  • For your primary calendar: your-email@gmail.com
  • For other calendars: Go to Calendar Settings → Integrate calendarCalendar ID

n8n Workflow Configuration

Option A: Using Google Calendar Node

  1. Add a Google Calendar node to your workflow
  2. Select Service Account as authentication
  3. Paste the entire Service Account JSON content
  4. Select the calendar ID
  5. Choose operation: Create Event

Option B: Using HTTP Request Node (More Control)

// In n8n Code node or HTTP Request node

const { GoogleToken } = require('gtoken');
const { google } = require('googleapis');

// Service account credentials
const serviceAccount = {
  type: 'service_account',
  project_id: 'your-project-id',
  private_key_id: '...',
  private_key: '-----BEGIN PRIVATE KEY-----\n...',
  client_email: 'access-hub-calendar@your-project-id.iam.gserviceaccount.com',
  client_id: '...',
};

// Create JWT client
const jwtClient = new google.auth.JWT(
  serviceAccount.client_email,
  null,
  serviceAccount.private_key,
  ['https://www.googleapis.com/auth/calendar']
);

// Authorize and create event
jwtClient.authorize(async (err, tokens) => {
  if (err) {
    console.error('JWT authorization error:', err);
    return;
  }

  const calendar = google.calendar({ version: 'v3', auth: jwtClient });

  const event = {
    summary: 'Konsultasi: ' + $json.topic + ' - ' + $json.client_name,
    start: {
      dateTime: new Date($json.date + 'T' + $json.start_time).toISOString(),
      timeZone: 'Asia/Jakarta',
    },
    end: {
      dateTime: new Date($json.date + 'T' + $json.end_time).toISOString(),
      timeZone: 'Asia/Jakarta',
    },
    description: 'Client: ' + $json.client_email + '\n\n' + $json.notes,
    attendees: [
      { email: $json.client_email },
    ],
    conferenceData: {
      createRequest: {
        requestId: $json.slot_id,
        conferenceSolutionKey: { type: 'hangoutsMeet' },
      },
    },
  };

  try {
    const result = await calendar.events.insert({
      calendarId: $json.calendar_id,
      resource: event,
      conferenceDataVersion: 1,
    });

    return {
      meet_link: result.data.hangoutLink,
      event_id: result.data.id,
    };
  } catch (error) {
    console.error('Error creating calendar event:', error);
    throw error;
  }
});

Incoming Webhook Payload

Your n8n webhook at /webhook-test/create-meet will receive:

{
  "slot_id": "uuid-of-slot",
  "date": "2025-12-25",
  "start_time": "14:00:00",
  "end_time": "15:00:00",
  "client_name": "John Doe",
  "client_email": "john@example.com",
  "topic": "Business Consulting",
  "notes": "Discuss project roadmap",
  "calendar_id": "your-calendar@gmail.com",
  "brand_name": "Your Brand",
  "test_mode": true
}

Expected Response

Your n8n workflow should return:

{
  "meet_link": "https://meet.google.com/abc-defg-hij",
  "event_id": "event-id-from-google-calendar"
}

Security Notes

  1. Never commit the service account JSON to version control
  2. Store it securely in n8n credentials
  3. Rotate the key if compromised
  4. Only grant minimum necessary permissions to the service account

Troubleshooting

Error: 403 Forbidden

  • Check if the calendar is shared with the service account email
  • Verify the service account has Editor permissions

Error: 401 Unauthorized

  • Verify the service account JSON is correct
  • Check if Calendar API is enabled in Google Cloud Console

Error: 400 Invalid

  • Check date/time format (should be ISO 8601)
  • Verify calendar ID is correct
  • Ensure the service account email format is correct

Alternative: Use Google Calendar API Key (Less Secure)

If you don't want to use service accounts, you can create an API key:

  1. Go to Google Cloud Console → APIs & ServicesCredentials
  2. Click Create CredentialsAPI Key
  3. Restrict the key to Google Calendar API only
  4. Use it with HTTP requests

However, this is not recommended for production as it's less secure than service accounts.