/** * 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 (
{/* AgentGate Integration */}

AgentGate Integration

Receive approval events from AgentGate to see human-in-the-loop decisions in your agent timelines.

{error && (
{error}
)}
{/* Webhook URL (read-only) */}

Webhook URL

Configure this URL in AgentGate's webhook settings

{webhookUrl}
{/* Webhook Secret */}

Webhook Secret

HMAC-SHA256 shared secret for signature verification

{loading ? ( Loading… ) : ( {configData?.agentGateSecret || 'Not set'} )}
{/* Update Secret */}
setSecretForm(e.target.value)} placeholder="Enter new webhook secret" className="flex-1 rounded border border-gray-300 px-3 py-1.5 text-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500" />
{saveSuccess && (

✓ Secret updated successfully

)}
{/* Test Webhook */}

Test Webhook

Send a test approval event to verify the connection

{testResult && (
{testResult.message}
)}
{/* Setup Instructions */}

Setup Instructions

  1. Copy the webhook URL above
  2. In AgentGate, go to Settings → Webhooks
  3. Add a new webhook with the URL and a shared secret
  4. Select events: request.created, request.approved, request.denied, request.expired
  5. Set the same secret in the field above
  6. Click "Send Test Event" to verify
); }