/** * Integrations tab — extracted from Settings.tsx (cq-002) */ import React, { useState } from 'react'; import { getConfig, updateConfig, } from '../../api/client'; import { useApi } from '../../hooks/useApi'; export function IntegrationsTab(): React.ReactElement { const { data: configData, loading, error, refetch } = useApi(() => getConfig(), []); const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState<{ ok: boolean; message: string } | null>(null); const [secretForm, setSecretForm] = useState(''); const [saving, setSaving] = useState(false); const [saveSuccess, setSaveSuccess] = useState(false); // Infer the webhook receiver URL from the current page origin const webhookUrl = `${window.location.origin}/api/events/ingest`; const handleTestWebhook = async () => { setTesting(true); setTestResult(null); try { const testPayload = { source: 'agentgate' as const, event: 'request.created', data: { requestId: `test_${Date.now()}`, action: 'agentlens_webhook_test', params: { test: true }, urgency: 'low', }, timestamp: new Date().toISOString(), }; const res = await fetch('/api/events/ingest', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(testPayload), }); if (res.ok) { const json = await res.json(); setTestResult({ ok: true, message: `✅ Webhook received successfully! Event ID: ${json.eventId}`, }); } else { const json = await res.json().catch(() => ({ error: `HTTP ${res.status}` })); setTestResult({ ok: false, message: `❌ Webhook failed: ${json.error || `HTTP ${res.status}`}`, }); } } catch (err) { setTestResult({ ok: false, message: `❌ Connection failed: ${err instanceof Error ? err.message : String(err)}`, }); } finally { setTesting(false); } }; const handleSaveSecret = async () => { if (!secretForm.trim()) return; setSaving(true); setSaveSuccess(false); try { await updateConfig({ agentGateSecret: secretForm.trim() }); setSaveSuccess(true); setSecretForm(''); refetch(); } catch { // Error handling is already shown via the config state } finally { setSaving(false); } }; const [copied, setCopied] = useState(false); const handleCopyUrl = async () => { await navigator.clipboard.writeText(webhookUrl); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return (
Receive approval events from AgentGate to see human-in-the-loop decisions in your agent timelines.
{error && (Webhook URL
Configure this URL in AgentGate's webhook settings
{webhookUrl}
Webhook Secret
HMAC-SHA256 shared secret for signature verification
✓ Secret updated successfully
)}Test Webhook
Send a test approval event to verify the connection
request.created, request.approved, request.denied, request.expired