From f5fa9ce71757d6e5e26444744290f2389fb2bf3a Mon Sep 17 00:00:00 2001 From: Sabiha Khan <87858386+chewwbaka@users.noreply.github.com> Date: Wed, 8 Apr 2026 17:43:47 +0530 Subject: [PATCH] feat: add agent lifecycle events in widget (#226) * feat: add agent lifecycle events in widget * fix: remove container id --- ui/public/embed/dograh-widget.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ui/public/embed/dograh-widget.js b/ui/public/embed/dograh-widget.js index 7d4ae7c..18f2545 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,22 @@ 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 message = { + type: eventType, + agentId: state.config.workflowId || null, + token: state.config.token || null, + workflowRunId: state.workflowRunId || null, + ...detail + }; + window.postMessage(message, '*'); + } + /** * Generate unique peer ID */