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>
This commit is contained in:
@@ -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"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Backend/n8n akan menggunakan ID ini untuk membuat event
|
||||
Backend akan menggunakan ID ini untuk membuat event
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label className="flex items-center gap-2">
|
||||
<Key className="w-4 h-4" />
|
||||
Google Service Account JSON
|
||||
</Label>
|
||||
<Textarea
|
||||
value={settings.integration_google_service_account_json || ''}
|
||||
onChange={(e) => setSettings({ ...settings, integration_google_service_account_json: e.target.value })}
|
||||
placeholder='{"type": "service_account", "project_id": "...", "private_key": "...", "client_email": "..."}'
|
||||
className="min-h-[120px] font-mono text-sm border-2"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Paste entire service account JSON from Google Cloud Console. Calendar must be shared with the service account email.
|
||||
</p>
|
||||
{settings.integration_google_service_account_json && (
|
||||
<Alert>
|
||||
<AlertTriangle className="w-4 h-4" />
|
||||
<AlertDescription>
|
||||
Service account configured. Calendar ID: {settings.integration_google_calendar_id || 'Not set'}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={async () => {
|
||||
if (!settings.integration_google_calendar_id || !settings.integration_google_service_account_json) {
|
||||
toast({ title: "Error", description: "Lengkapi Calendar ID dan Service Account JSON", variant: "destructive" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { data, error } = await supabase.functions.invoke('create-google-meet-event', {
|
||||
body: {
|
||||
slot_id: 'test-connection',
|
||||
date: new Date().toISOString().split('T')[0],
|
||||
start_time: '14:00:00',
|
||||
end_time: '15:00:00',
|
||||
client_name: 'Test Connection',
|
||||
client_email: 'test@example.com',
|
||||
topic: 'Connection Test',
|
||||
},
|
||||
});
|
||||
|
||||
if (error) throw error;
|
||||
if (data?.success) {
|
||||
toast({ title: "Berhasil", description: "Google Calendar API berfungsi! Event test dibuat." });
|
||||
} else {
|
||||
throw new Error(data?.message || 'Connection failed');
|
||||
}
|
||||
} catch (err: any) {
|
||||
toast({ title: "Error", description: err.message, variant: "destructive" });
|
||||
}
|
||||
}}
|
||||
className="w-full border-2"
|
||||
>
|
||||
Test Google Calendar Connection
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user