diff --git a/add-n8n-test-mode.sql b/add-n8n-test-mode.sql new file mode 100644 index 0000000..531fdd7 --- /dev/null +++ b/add-n8n-test-mode.sql @@ -0,0 +1,6 @@ +-- Add integration_n8n_test_mode column to platform_settings table +ALTER TABLE platform_settings +ADD COLUMN integration_n8n_test_mode BOOLEAN DEFAULT FALSE; + +-- Add a comment for documentation +COMMENT ON COLUMN platform_settings.integration_n8n_test_mode IS 'Toggle for n8n webhook test mode - uses /webhook-test/ when true, /webhook/ when false'; \ No newline at end of file diff --git a/deploy-edge-functions.sh b/deploy-edge-functions.sh index b6bb90d..b34fa71 100755 --- a/deploy-edge-functions.sh +++ b/deploy-edge-functions.sh @@ -2,7 +2,7 @@ # Configuration SUPABASE_URL="https://lovable.backoffice.biz.id" -SERVICE_ROLE_KEY="$SUPABASE_ACCESS_TOKEN" +SERVICE_ROLE_KEY="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTc2NjAzNzEyMCwiZXhwIjo0OTIxNzEwNzIwLCJyb2xlIjoic2VydmljZV9yb2xlIn0.t6D9VwaukYGq4c_VbW1bkd3ZkKgldpCKRR13nN14XXc" # Function to deploy edge function deploy_function() { diff --git a/docs/google-calendar-edge-function-setup.md b/docs/google-calendar-edge-function-setup.md new file mode 100644 index 0000000..c71c88f --- /dev/null +++ b/docs/google-calendar-edge-function-setup.md @@ -0,0 +1,219 @@ +# Google Calendar Integration with Supabase Edge Functions + +This guide walks you through setting up Google Calendar integration directly in Supabase Edge Functions, without needing n8n or OAuth. + +## Architecture + +``` +Access Hub App → Supabase Edge Function → Google Calendar API + ↓ + JWT Authentication + ↓ + Service Account JSON +``` + +## Setup Steps + +### 1. Create Google Service Account + +1. Go to [Google Cloud Console](https://console.cloud.google.com/) +2. Create a new project or select existing one +3. Navigate to **IAM & Admin** → **Service 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** (skip granting roles) +7. Click **Done** + +### 2. Enable Google Calendar API + +1. In Google Cloud Console, go to **APIs & Services** → **Library** +2. Search for "Google Calendar API" +3. Click **Enable** + +### 3. Create Service Account Key + +1. Go to your service account page +2. Click the **Keys** tab +3. Click **Add Key** → **Create New Key** +4. Select **JSON** format +5. Click **Create** - download the JSON file + +Keep this file secure! It contains your private key. + +### 4. Share Calendar with Service Account + +1. Go to [Google Calendar](https://calendar.google.com/) +2. Hover over the calendar you want to use +3. Click the **three dots (⋮)** → **Settings and sharing** +4. Scroll to **Share with specific people** +5. Click **+ Add people** +6. Enter the service account email from your JSON: `xxx@xxx.iam.gserviceaccount.com` +7. Set permissions to **Make changes to events** +8. Click **Send** + +### 5. Add Database Column + +Run this SQL in your Supabase SQL Editor: + +```sql +ALTER TABLE platform_settings +ADD COLUMN IF NOT EXISTS google_service_account_json TEXT; +``` + +### 6. Deploy Edge Function + +```bash +# Deploy the new function +supabase functions deploy create-google-meet-event --verify-jwt +``` + +Or use the deployment script: +```bash +./deploy-edge-functions.sh +``` + +### 7. Configure in Admin Panel + +1. Go to **Settings** → **Integrasi** +2. Find the **Google Calendar** section +3. Enter your **Calendar ID** (e.g., `your-email@gmail.com`) +4. Paste the **Service Account JSON** (entire content from the JSON file) +5. Click **Simpan Semua Pengaturan** +6. Click **Test Google Calendar Connection** + +If successful, you'll see a test event created in your Google Calendar with a Google Meet link. + +## How It Works + +### Authentication Flow + +1. Edge Function reads service account JSON +2. Creates a JWT signed with the private key +3. Exchanges JWT for an access token +4. Uses access token to call Google Calendar API + +### Event Creation + +When a consultation slot is confirmed: + +1. `create-google-meet-event` function is called +2. Creates a Google Calendar event with Meet link +3. Returns the Meet link to be stored in the database + +## API Reference + +### Request + +```typescript +POST /functions/v1/create-google-meet-event + +{ + slot_id: string; // Unique slot identifier + date: string; // YYYY-MM-DD + start_time: string; // HH:MM:SS + end_time: string; // HH:MM:SS + client_name: string; // Client's full name + client_email: string; // Client's email + topic: string; // Consultation topic + notes?: string; // Optional notes +} +``` + +### Response + +```typescript +{ + success: true; + meet_link: string; // https://meet.google.com/xxx-xxx-xxx + event_id: string; // Google Calendar event ID + html_link: string; // Link to event in Google Calendar +} +``` + +## Testing + +### Test via Admin Panel + +Use the **Test Google Calendar Connection** button in the Integrasi settings. + +### Test via Curl + +```bash +curl -X POST https://your-project.supabase.co/functions/v1/create-google-meet-event \ + -H "Authorization: Bearer YOUR_ANON_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "slot_id": "test-123", + "date": "2025-12-25", + "start_time": "14:00:00", + "end_time": "15:00:00", + "client_name": "Test Client", + "client_email": "test@example.com", + "topic": "Test Topic" + }' +``` + +## Security Notes + +1. **Never commit** the service account JSON to version control +2. **Store securely** in database (consider encryption for production) +3. **Rotate keys** if compromised +4. **Limit permissions** to only Calendar API +5. **Use separate service accounts** for different environments + +## Troubleshooting + +### Error: "Google Service Account JSON belum dikonfigurasi" +- Make sure you've saved the JSON in the admin settings +- Check the database column exists: `google_service_account_json` + +### Error: 403 Forbidden +- Verify calendar is shared with service account email +- Check service account has "Make changes to events" permission + +### Error: 401 Unauthorized +- Verify service account JSON is valid +- Check Calendar API is enabled in Google Cloud Console + +### Error: "Failed to parse service account JSON" +- Make sure you pasted the entire JSON content +- Check for any truncation or formatting issues + +### Error: "Gagal membuat event di Google Calendar" +- Check the error message for details +- Verify Calendar API is enabled +- Check service account has correct permissions + +## Comparison: n8n vs Edge Function + +| Feature | n8n Integration | Edge Function | +|---------|----------------|---------------| +| Setup Complexity | Medium | Low | +| OAuth Required | No (Service Account) | No (Service Account) | +| External Dependencies | n8n instance | None | +| Cost | Requires n8n hosting | Included in Supabase | +| Maintenance | n8n updates | Supabase updates | +| Performance | Extra hop | Direct API call | +| **Recommended** | For complex workflows | ✅ **For simple integrations** | + +## Next Steps + +1. ✅ Create service account +2. ✅ Share calendar with service account +3. ✅ Run database migration +4. ✅ Deploy edge function +5. ✅ Configure in admin panel +6. ✅ Test connection +7. ✅ Integrate with consultation booking flow + +## Files Modified/Created + +- `supabase/functions/create-google-meet-event/index.ts` - New edge function +- `supabase/migrations/20250323_add_google_service_account.sql` - Database migration +- `src/components/admin/settings/IntegrasiTab.tsx` - Admin UI for configuration + +--- + +**Need Help?** Check the Supabase Edge Functions logs in your dashboard for detailed error messages. diff --git a/docs/google-calendar-service-account-setup.md b/docs/google-calendar-service-account-setup.md new file mode 100644 index 0000000..32c4861 --- /dev/null +++ b/docs/google-calendar-service-account-setup.md @@ -0,0 +1,214 @@ +# 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](https://console.cloud.google.com/) +2. Create a new project or select existing one +3. Navigate to **IAM & Admin** → **Service 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 & Services** → **Library** +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 Key** → **Create 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: +```json +{ + "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](https://calendar.google.com/) +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 calendar** → **Calendar 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) + +```javascript +// 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: + +```json +{ + "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: + +```json +{ + "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 & Services** → **Credentials** +2. Click **Create Credentials** → **API 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. diff --git a/n8n-workflows/README.md b/n8n-workflows/README.md new file mode 100644 index 0000000..7d596c5 --- /dev/null +++ b/n8n-workflows/README.md @@ -0,0 +1,187 @@ +# n8n Workflows for Access Hub + +## Workflows + +### 1. Create Google Meet Event (Simple) +**File:** `create-google-meet-event.json` + +A simple 3-node workflow that: +1. Receives webhook POST from Supabase Edge Function +2. Creates event in Google Calendar using Google Calendar node +3. Returns the meet link + +**Best for:** Quick setup with minimal configuration + +--- + +### 2. Create Google Meet Event (Advanced) +**File:** `create-google-meet-event-advanced.json` + +An advanced workflow with more control: +1. Receives webhook POST from Supabase Edge Function +2. Prepares event data with Code node (custom formatting) +3. Creates event using Google Calendar API directly +4. Returns the meet link + +**Best for:** More customization, error handling, and control + +--- + +## Import Instructions + +### Option 1: Import from File +1. In n8n, click **+ Import from File** +2. Select the JSON file +3. Click **Import** + +### Option 2: Copy-Paste +1. In n8n, click **+ New Workflow** +2. Click **...** (menu) → **Import from URL** +3. Paste the JSON content +4. Click **Import** + +--- + +## Setup Instructions + +### 1. Configure Webhook +- **Path**: `create-meet` (already set) +- **Method**: POST +- **Production URL**: Will be auto-generated when you activate the workflow + +### 2. Configure Google Calendar Credentials + +#### For Simple Workflow: +1. Click on the **Google Calendar** node +2. Click **Create New Credential** +3. Select **Service Account** authentication +4. Paste the entire JSON content from your service account file +5. Give it a name: "Google Calendar (Service Account)" +6. Click **Create** + +#### For Advanced Workflow: +1. Click on the **Google Calendar API** node +2. Click **Create New Credential** +3. Select **Service Account** authentication for Google API +4. Paste the service account JSON +5. Give it a name: "Google Calendar API (Service Account)" +6. Click **Create** + +### 3. Activate Workflow +1. Click **Active** toggle in top right +2. n8n will generate your webhook URL +3. Your webhook URL will be: `https://api.backoffice.biz.id/webhook-test/create-meet` + +--- + +## Test the Workflow + +### Manual Test with Curl: +```bash +curl -X POST https://api.backoffice.biz.id/webhook-test/create-meet \ + -H "Content-Type: application/json" \ + -d '{ + "slot_id": "test-123", + "date": "2025-12-25", + "start_time": "14:00:00", + "end_time": "15:00:00", + "client_name": "Test Client", + "client_email": "test@example.com", + "topic": "Test Topic", + "notes": "Test notes", + "calendar_id": "your-email@gmail.com", + "brand_name": "Your Brand", + "test_mode": true + }' +``` + +### Expected Response: +```json +{ + "meet_link": "https://meet.google.com/abc-defg-hij", + "event_id": "event-id-from-google-calendar", + "html_link": "https://www.google.com/calendar/event?eid=..." +} +``` + +--- + +## Workflow Variables + +The webhook receives these fields from your Supabase Edge Function: + +| Field | Description | Example | +|-------|-------------|---------| +| `slot_id` | Unique slot identifier | `uuid-here` | +| `date` | Event date (YYYY-MM-DD) | `2025-12-25` | +| `start_time` | Start time (HH:MM:SS) | `14:00:00` | +| `end_time` | End time (HH:MM:SS) | `15:00:00` | +| `client_name` | Client's full name | `John Doe` | +| `client_email` | Client's email | `john@example.com` | +| `topic` | Consultation topic | `Business Consulting` | +| `notes` | Additional notes | `Discuss project roadmap` | +| `calendar_id` | Google Calendar ID | `your-email@gmail.com` | +| `brand_name` | Your brand name | `Access Hub` | +| `test_mode` | Test mode flag | `true` | + +--- + +## Troubleshooting + +### Error: 403 Forbidden +- Make sure calendar is shared with service account email +- Service account email format: `xxx@project-id.iam.gserviceaccount.com` +- Calendar permissions: "Make changes to events" + +### Error: 401 Unauthorized +- Check service account JSON is correct +- Verify Calendar API is enabled in Google Cloud Console + +### Error: 400 Invalid +- Check date format (YYYY-MM-DD) +- Check time format (HH:MM:SS) +- Verify calendar ID is correct + +### Webhook not triggering +- Make sure workflow is **Active** +- Check webhook URL matches: `/webhook-test/create-meet` +- Verify webhook method is **POST** not GET + +--- + +## Calendar ID + +To find your Calendar ID: +1. Go to Google Calendar Settings +2. Scroll to **Integrate calendar** +3. Copy the **Calendar ID** +4. For primary calendar: your Gmail address + +--- + +## Production vs Test + +- **Test Mode**: Uses `/webhook-test/` path +- **Production**: Uses `/webhook/` path +- Toggle in Admin Settings → Integrasi → Mode Test n8n + +--- + +## Next Steps + +1. Import workflow JSON +2. Set up Google Calendar credentials with service account +3. Activate workflow +4. Test with curl command above +5. Check your Google Calendar for the event +6. Verify meet link is returned + +--- + +## Support + +If you need help: +- Check n8n workflow execution logs +- Check Google Calendar API logs +- Verify service account permissions +- Check calendar sharing settings diff --git a/n8n-workflows/create-google-meet-event-advanced.json b/n8n-workflows/create-google-meet-event-advanced.json new file mode 100644 index 0000000..da9ac37 --- /dev/null +++ b/n8n-workflows/create-google-meet-event-advanced.json @@ -0,0 +1,127 @@ +{ + "name": "Create Google Meet Event - Access Hub (Advanced)", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "create-meet", + "responseMode": "responseNode", + "options": {} + }, + "id": "webhook-trigger", + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1.1, + "position": [250, 300], + "webhookId": "create-meet-webhook" + }, + { + "parameters": { + "jsCode": "const items = $input.all();\nconst data = items[0].json;\n\n// Parse date and time\nconst startDate = new Date(`${data.date}T${data.start_time}`);\nconst endDate = new Date(`${data.date}T${data.end_time}`);\n\n// Format for Google Calendar API (ISO 8601 with timezone)\nconst startTime = startDate.toISOString();\nconst endTime = endDate.toISOString();\n\n// Build event data\nconst eventData = {\n calendarId: data.calendar_id,\n summary: `Konsultasi: ${data.topic} - ${data.client_name}`,\n description: `Client: ${data.client_email}\\n\\nNotes: ${data.notes || '-'}\\n\\nSlot ID: ${data.slot_id}\\nBrand: ${data.brand_name || 'Access Hub'}`,\n start: {\n dateTime: startTime,\n timeZone: 'Asia/Jakarta'\n },\n end: {\n dateTime: endTime,\n timeZone: 'Asia/Jakarta'\n },\n attendees: [\n { email: data.client_email }\n ],\n conferenceData: {\n createRequest: {\n requestId: data.slot_id,\n conferenceSolutionKey: { type: 'hangoutsMeet' }\n }\n },\n sendUpdates: 'all',\n guestsCanInviteOthers: false,\n guestsCanModify: false,\n guestsCanSeeOtherGuests: false\n};\n\nreturn [{ json: eventData }];" + }, + "id": "prepare-event-data", + "name": "Prepare Event Data", + "type": "n8n-nodes-base.code", + "typeVersion": 2, + "position": [470, 300] + }, + { + "parameters": { + "authentication": "serviceAccount", + "resource": "calendar", + "operation": "insert", + "calendarId": "={{ $json.calendarId }}", + "body": "={{ { summary: $json.summary, description: $json.description, start: $json.start, end: $json.end, attendees: $json.attendees, conferenceData: $json.conferenceData, sendUpdates: $json.sendUpdates, guestsCanInviteOthers: $json.guestsCanInviteOthers, guestsCanModify: $json.guestsCanModify, guestsCanSeeOtherGuests: $json.guestsCanSeeOtherGuests } }}", + "options": { + "conferenceDataVersion": 1 + } + }, + "id": "google-calendar-api", + "name": "Google Calendar API", + "type": "n8n-nodes-base.googleApi", + "typeVersion": 1, + "position": [690, 300], + "credentials": { + "googleApi": { + "id": "REPLACE_WITH_YOUR_CREDENTIAL_ID", + "name": "Google Calendar API (Service Account)" + } + } + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ { \"meet_link\": $json.hangoutLink, \"event_id\": $json.id, \"html_link\": $json.htmlLink } }}" + }, + "id": "respond-to-webhook", + "name": "Respond to Webhook", + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.1, + "position": [910, 300] + }, + { + "parameters": { + "assignments": { + "assignments": [ + { + "id": "error-handler", + "name": "error", + "value": "={{ $json.error?.message || 'Unknown error' }}", + "type": "string" + } + ] + }, + "options": {} + }, + "id": "error-handler", + "name": "Error Handler", + "type": "n8n-nodes-base.set", + "typeVersion": 3.4, + "position": [910, 480] + } + ], + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Prepare Event Data", + "type": "main", + "index": 0 + } + ] + ] + }, + "Prepare Event Data": { + "main": [ + [ + { + "node": "Google Calendar API", + "type": "main", + "index": 0 + } + ] + ] + }, + "Google Calendar API": { + "main": [ + [ + { + "node": "Respond to Webhook", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "pinData": {}, + "settings": { + "executionOrder": "v1" + }, + "staticData": null, + "tags": ["access-hub", "calendar", "meet"], + "triggerCount": 1, + "updatedAt": "2025-12-23T00:00:00.000Z", + "versionId": "1" +} diff --git a/n8n-workflows/create-google-meet-event.json b/n8n-workflows/create-google-meet-event.json new file mode 100644 index 0000000..9689968 --- /dev/null +++ b/n8n-workflows/create-google-meet-event.json @@ -0,0 +1,89 @@ +{ + "name": "Create Google Meet Event - Access Hub", + "nodes": [ + { + "parameters": { + "httpMethod": "POST", + "path": "create-meet", + "responseMode": "responseNode", + "options": {} + }, + "id": "webhook-trigger", + "name": "Webhook", + "type": "n8n-nodes-base.webhook", + "typeVersion": 1.1, + "position": [250, 300], + "webhookId": "create-meet-webhook" + }, + { + "parameters": { + "operation": "create", + "calendarId": "={{ $json.calendar_id }}", + "title": "=Konsultasi: {{ $json.topic }} - {{ $json.client_name }}", + "description": "=Client: {{ $json.client_email }}\n\nNotes: {{ $json.notes }}\n\nSlot ID: {{ $json.slot_id }}", + "location": "Google Meet", + "attendees": "={{ $json.client_email }}", + "startsAt": "={{ $json.date }}T{{ $json.start_time }}", + "endsAt": "={{ $json.date }}T{{ $json.end_time }}", + "sendUpdates": "all", + "conferenceDataVersion": 1, + "options": {} + }, + "id": "google-calendar", + "name": "Google Calendar", + "type": "n8n-nodes-base.googleCalendar", + "typeVersion": 2, + "position": [470, 300], + "credentials": { + "googleCalendarApi": { + "id": "REPLACE_WITH_YOUR_CREDENTIAL_ID", + "name": "Google Calendar account (Service Account)" + } + } + }, + { + "parameters": { + "respondWith": "json", + "responseBody": "={{ { \"meet_link\": $json.hangoutLink, \"event_id\": $json.id, \"html_link\": $json.htmlLink } }}" + }, + "id": "respond-to-webhook", + "name": "Respond to Webhook", + "type": "n8n-nodes-base.respondToWebhook", + "typeVersion": 1.1, + "position": [690, 300] + } + ], + "connections": { + "Webhook": { + "main": [ + [ + { + "node": "Google Calendar", + "type": "main", + "index": 0 + } + ] + ] + }, + "Google Calendar": { + "main": [ + [ + { + "node": "Respond to Webhook", + "type": "main", + "index": 0 + } + ] + ] + } + }, + "pinData": {}, + "settings": { + "executionOrder": "v1" + }, + "staticData": null, + "tags": [], + "triggerCount": 1, + "updatedAt": "2025-12-23T00:00:00.000Z", + "versionId": "1" +} diff --git a/src/components/admin/settings/IntegrasiTab.tsx b/src/components/admin/settings/IntegrasiTab.tsx index 334982e..1498f0b 100644 --- a/src/components/admin/settings/IntegrasiTab.tsx +++ b/src/components/admin/settings/IntegrasiTab.tsx @@ -3,6 +3,7 @@ import { supabase } from '@/integrations/supabase/client'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { Alert, AlertDescription } from '@/components/ui/alert'; @@ -16,6 +17,7 @@ interface IntegrationSettings { integration_whatsapp_number: string; integration_whatsapp_url: string; integration_google_calendar_id: string; + integration_google_service_account_json?: string; integration_email_provider: string; integration_email_api_base_url: string; integration_privacy_url: string; @@ -74,6 +76,7 @@ export function IntegrasiTab() { integration_whatsapp_number: platformData.integration_whatsapp_number || '', integration_whatsapp_url: platformData.integration_whatsapp_url || '', integration_google_calendar_id: platformData.integration_google_calendar_id || '', + integration_google_service_account_json: platformData.integration_google_service_account_json || '', integration_email_provider: platformData.integration_email_provider || 'mailketing', integration_email_api_base_url: platformData.integration_email_api_base_url || '', integration_privacy_url: platformData.integration_privacy_url || '/privacy', @@ -99,6 +102,7 @@ export function IntegrasiTab() { integration_whatsapp_number: settings.integration_whatsapp_number, integration_whatsapp_url: settings.integration_whatsapp_url, integration_google_calendar_id: settings.integration_google_calendar_id, + integration_google_service_account_json: settings.integration_google_service_account_json, integration_email_provider: settings.integration_email_provider, integration_email_api_base_url: settings.integration_email_api_base_url, integration_privacy_url: settings.integration_privacy_url, @@ -305,9 +309,69 @@ export function IntegrasiTab() { className="border-2" />
- Backend/n8n akan menggunakan ID ini untuk membuat event + Backend akan menggunakan ID ini untuk membuat event
+ +