@@ -25,6 +25,8 @@ let latestStatus = {
2525 obsStats : obsStats
2626} ;
2727
28+ let debuggeeId = null ;
29+
2830chrome . runtime . onMessage . addListener ( ( request , sender , sendResponse ) => {
2931 switch ( request . action ) {
3032 case "getStatus" :
@@ -42,26 +44,87 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
4244 disconnectFromObs ( ) ;
4345 sendResponse ( { success : true } ) ;
4446 break ;
47+ case "toggleChromeWs" :
48+ if ( debuggeeId ) {
49+ chrome . debugger . detach ( debuggeeId ) ;
50+ debuggeeId = null ;
51+ updateStatus ( 'chromeWebSocket' , 'disconnected' ) ;
52+ } else {
53+ attachDebugger ( request . tabId ) ;
54+ }
55+ sendResponse ( { success : true } ) ;
56+ break ;
4557 }
4658 return true ; // Indicates that the response is sent asynchronously
4759} ) ;
4860
4961chrome . action . onClicked . addListener ( ( tab ) => {
50- connectToChromeWebSocket ( tab . id ) ;
51- connectToObs ( ) ; // You might want to make this optional or triggered separately
62+ if ( debuggeeId ) {
63+ chrome . debugger . detach ( debuggeeId ) ;
64+ debuggeeId = null ;
65+ updateStatus ( 'chromeWebSocket' , 'disconnected' ) ;
66+ } else {
67+ attachDebugger ( tab . id ) ;
68+ }
5269} ) ;
5370
71+ function attachDebugger ( tabId ) {
72+ chrome . debugger . attach ( { tabId : tabId } , "1.3" , ( ) => {
73+ if ( chrome . runtime . lastError ) {
74+ console . error ( chrome . runtime . lastError . message ) ;
75+ return ;
76+ }
77+ debuggeeId = { tabId : tabId } ;
78+ chrome . debugger . sendCommand ( debuggeeId , "Network.enable" ) ;
79+ chrome . debugger . onEvent . addListener ( onEvent ) ;
80+ updateStatus ( 'chromeWebSocket' , 'connected' ) ;
81+ } ) ;
82+ }
83+
84+ function onEvent ( debuggeeId , message , params ) {
85+ if ( message === "Network.webSocketFrameReceived" ) {
86+ const payload = params . response ?. payloadData || params . request ?. payloadData ;
87+ if ( payload ) {
88+ console . log ( "WebSocket Frame Received:" , payload ) ;
89+ messageStats . received ++ ;
90+ try {
91+ // Attempt to parse the message to ensure it's valid JSON
92+ JSON . parse ( payload ) ;
93+ forwardToObs ( payload ) ;
94+ } catch ( error ) {
95+ console . error ( "Error parsing WebSocket frame:" , error ) ;
96+ messageStats . lost ++ ;
97+ }
98+ } else {
99+ console . warn ( "Received WebSocket frame without payload data" ) ;
100+ }
101+ } else if ( message === "Network.webSocketFrameSent" ) {
102+ const payload = params . request ?. payloadData ;
103+ if ( payload ) {
104+ console . log ( "WebSocket Frame Sent:" , payload ) ;
105+ messageStats . sent ++ ;
106+ } else {
107+ console . warn ( "Sent WebSocket frame without payload data" ) ;
108+ }
109+ }
110+ updateStatus ( 'chromeWebSocket' , 'connected' ) ;
111+ }
112+
54113function onWebSocketEvent ( debuggeeId , message , params ) {
55114 if ( message === "Network.webSocketFrameReceived" ) {
56115 console . log ( "WebSocket Frame Received:" , params . response . payloadData ) ;
57116 messageStats . received ++ ;
58117 // Here you would process and potentially forward the message to OBS
59118 } else if ( message === "Network.webSocketFrameSent" ) {
60- console . log ( "WebSocket Frame Sent:" , params . request . payloadData ) ;
61- messageStats . sent ++ ;
119+ const payload = params . response ?. payloadData || params . request ?. payloadData ;
120+ if ( payload ) {
121+ console . log ( "WebSocket Frame Sent:" , payload ) ;
122+ messageStats . sent ++ ;
123+ } else {
124+ console . warn ( "Sent WebSocket frame without payload data. Full params:" , JSON . stringify ( params ) ) ;
125+ }
62126 }
63-
64- updateStatus ( 'chromeWebSocket' , 'connected' ) ; // Ensure status stays updated
127+ updateStatus ( 'chromeWebSocket' , 'connected' ) ;
65128}
66129
67130function connectToObs ( ) {
@@ -181,6 +244,9 @@ function handleOBSResponse(message) {
181244 console . log ( 'Updated recording status:' , obsStats . recording ) ;
182245 }
183246 break ;
247+ case 'BroadcastCustomMessage' :
248+ console . log ( 'Custom message broadcasted successfully' ) ;
249+ break ;
184250 default :
185251 console . log ( 'Unhandled response type:' , message . d . requestType ) ;
186252 }
@@ -216,35 +282,87 @@ function handleAuthChallenge(message, password) {
216282}
217283
218284function updateStatus ( type , status ) {
219- connectionStatus [ type ] = status ;
220- console . log ( `Updating status: ${ type } = ${ status } ` ) ;
221-
222- latestStatus = {
223- connectionStatus : connectionStatus ,
224- messageStats : messageStats ,
225- obsStats : obsStats
226- } ;
285+ // Only update if the status has changed
286+ if ( connectionStatus [ type ] !== status ) {
287+ connectionStatus [ type ] = status ;
288+ console . log ( `Updating status: ${ type } = ${ status } ` ) ;
289+
290+ latestStatus = {
291+ connectionStatus : connectionStatus ,
292+ messageStats : messageStats ,
293+ obsStats : obsStats
294+ } ;
227295
228- // Attempt to send update to popup (if open)
229- chrome . runtime . sendMessage ( {
230- action : 'statusUpdate' ,
231- ...latestStatus
232- } , ( ) => {
233- if ( chrome . runtime . lastError ) {
234- console . log ( 'Error sending status update (this is normal if popup is closed):' , chrome . runtime . lastError . message ) ;
235- } else {
236- console . log ( 'Status update sent successfully' ) ;
237- }
238- } ) ;
296+ // Use chrome.runtime.sendMessage instead of chrome.tabs.sendMessage
297+ chrome . runtime . sendMessage ( {
298+ action : 'statusUpdate' ,
299+ ...latestStatus
300+ } ) . catch ( error => {
301+ console . log ( 'Error sending status update:' , error . message ) ;
302+ } ) ;
303+
304+ // Update extension icon
305+ const iconPath = status === 'connected' ? {
306+ 16 : 'images/icon_active_16.png' ,
307+ 32 : 'images/icon_active_32.png' ,
308+ 48 : 'images/icon_active_48.png' ,
309+ 128 : 'images/icon_active_128.png'
310+ } : {
311+ 16 : 'images/icon_inactive_16.png' ,
312+ 32 : 'images/icon_inactive_32.png' ,
313+ 48 : 'images/icon_inactive_48.png' ,
314+ 128 : 'images/icon_inactive_128.png'
315+ } ;
316+ chrome . action . setIcon ( { path : iconPath } ) ;
317+ }
239318}
240319
241320function forwardToObs ( message ) {
242321 if ( obsSocket && obsSocket . readyState === WebSocket . OPEN ) {
243- obsSocket . send ( message ) ;
244- messageStats . forwarded ++ ;
322+ try {
323+ // Parse the Phoenix framework message
324+ const parsedMessage = JSON . parse ( message ) ;
325+ if ( ! Array . isArray ( parsedMessage ) ) {
326+ throw new Error ( "Unexpected message format" ) ;
327+ }
328+
329+ // Transform the message into OBS WebSocket format
330+ const obsMessage = {
331+ op : 6 ,
332+ d : {
333+ requestType : "BroadcastCustomMessage" ,
334+ requestId : generateUniqueId ( ) ,
335+ requestData : {
336+ realm : "obs-websocket" ,
337+ data : {
338+ eventType : "ChromeWebSocketMessage" ,
339+ eventData : {
340+ channel : parsedMessage [ 2 ] ,
341+ event : parsedMessage [ 3 ] ,
342+ payload : parsedMessage [ 4 ]
343+ }
344+ }
345+ }
346+ }
347+ } ;
348+
349+ // Send the transformed message to OBS
350+ obsSocket . send ( JSON . stringify ( obsMessage ) ) ;
351+ messageStats . forwarded ++ ;
352+ console . log ( "Forwarded to OBS:" , obsMessage ) ;
353+ } catch ( error ) {
354+ console . error ( "Error forwarding message to OBS:" , error ) ;
355+ messageStats . lost ++ ;
356+ }
245357 } else {
246358 console . warn ( 'OBS WebSocket not connected. Message not forwarded.' ) ;
359+ messageStats . lost ++ ;
247360 }
361+ updateStatus ( 'obsWebSocket' , obsSocket && obsSocket . readyState === WebSocket . OPEN ? 'connected' : 'disconnected' ) ;
362+ }
363+
364+ function generateUniqueId ( ) {
365+ return Date . now ( ) . toString ( 36 ) + Math . random ( ) . toString ( 36 ) . substr ( 2 ) ;
248366}
249367
250368function getOBSStats ( ) {
0 commit comments