From df1b3a5b9b4e023fce5fbaf5db6466fa38368a01 Mon Sep 17 00:00:00 2001 From: Sabiha Khan Date: Wed, 8 Apr 2026 13:01:25 +0530 Subject: [PATCH] feat: add agent lifecycle events in widget --- ui/public/embed/dograh-widget.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ui/public/embed/dograh-widget.js b/ui/public/embed/dograh-widget.js index 7d4ae7c..0e52eab 100644 --- a/ui/public/embed/dograh-widget.js +++ b/ui/public/embed/dograh-widget.js @@ -29,6 +29,7 @@ connectionStatus: 'idle', // idle, connecting, connected, failed audioElement: null, turnCredentials: null, // TURN server credentials + callStartedAt: null, // Timestamp when call connected (for duration tracking) callbacks: { onReady: null, onCallStart: null, @@ -761,6 +762,8 @@ if (state.pc.iceConnectionState === 'connected' || state.pc.iceConnectionState === 'completed') { updateStatus('connected', 'Connected', 'Your voice call is now active'); + state.callStartedAt = Date.now(); + emitMessage('dograh:call_started', {}); } else if (state.pc.iceConnectionState === 'failed' || state.pc.iceConnectionState === 'disconnected') { updateStatus('failed', 'Connection lost', 'The call has been disconnected'); stopCall(); @@ -893,6 +896,13 @@ * Stop voice call */ function stopCall() { + // Emit end message before clearing state so identifiers are still available + const durationSeconds = state.callStartedAt + ? Math.round((Date.now() - state.callStartedAt) / 1000) + : 0; + emitMessage('dograh:call_ended', { durationSeconds }); + state.callStartedAt = null; + updateStatus('idle', 'Call ended', 'Click below to start a new call'); // Trigger call end callback @@ -932,6 +942,26 @@ setTimeout(() => startCall(), 500); } + /** + * Emit a postMessage event to the host window + * Allows the embedding website to listen for agent lifecycle events via: + * window.addEventListener('message', (event) => { ... }) + */ + function emitMessage(eventType, detail) { + const containerId = state.config.embedMode === 'inline' + ? state.config.containerId + : 'dograh-widget'; + const message = { + type: eventType, + agentId: state.config.workflowId || null, + token: state.config.token || null, + workflowRunId: state.workflowRunId || null, + containerId: containerId, + ...detail + }; + window.postMessage(message, '*'); + } + /** * Generate unique peer ID */