Files
IRC-kosmi-relay/cmd/monitor-ws/main.go
2025-10-31 20:38:38 -04:00

227 lines
6.4 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"log"
"os"
"os/signal"
"time"
"github.com/playwright-community/playwright-go"
)
const (
roomURL = "https://app.kosmi.io/room/@hyperspaceout"
)
func main() {
log.Println("🔍 Starting Kosmi WebSocket Monitor")
log.Printf("📡 Room URL: %s", roomURL)
log.Println("This will capture ALL WebSocket traffic from the browser...")
log.Println()
// Set up interrupt handler
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
// Launch Playwright
pw, err := playwright.Run()
if err != nil {
log.Fatalf("Failed to start Playwright: %v", err)
}
defer pw.Stop()
// Launch browser
browser, err := pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{
Headless: playwright.Bool(false), // Keep visible so we can see what's happening
})
if err != nil {
log.Fatalf("Failed to launch browser: %v", err)
}
defer browser.Close()
// Create context
context, err := browser.NewContext(playwright.BrowserNewContextOptions{
UserAgent: playwright.String("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"),
})
if err != nil {
log.Fatalf("Failed to create context: %v", err)
}
// Create page
page, err := context.NewPage()
if err != nil {
log.Fatalf("Failed to create page: %v", err)
}
// Inject WebSocket monitoring script BEFORE navigation
log.Println("📝 Injecting WebSocket monitoring script...")
if err := page.AddInitScript(playwright.Script{
Content: playwright.String(`
(function() {
const OriginalWebSocket = window.WebSocket;
let messageCount = 0;
window.WebSocket = function(url, protocols) {
console.log('🔌 [WS MONITOR] WebSocket created:', url, 'protocols:', protocols);
const socket = new OriginalWebSocket(url, protocols);
socket.addEventListener('open', (event) => {
console.log('✅ [WS MONITOR] WebSocket OPENED');
});
socket.addEventListener('close', (event) => {
console.log('🔴 [WS MONITOR] WebSocket CLOSED:', event.code, event.reason);
});
socket.addEventListener('error', (event) => {
console.error('❌ [WS MONITOR] WebSocket ERROR:', event);
});
// Intercept outgoing messages
const originalSend = socket.send;
socket.send = function(data) {
messageCount++;
console.log('📤 [WS MONITOR] SEND #' + messageCount + ':', data);
try {
const parsed = JSON.parse(data);
console.log(' Type:', parsed.type, 'ID:', parsed.id);
if (parsed.payload) {
console.log(' Payload:', JSON.stringify(parsed.payload, null, 2));
}
} catch (e) {
// Not JSON
}
return originalSend.call(this, data);
};
// Intercept incoming messages
socket.addEventListener('message', (event) => {
messageCount++;
console.log('📥 [WS MONITOR] RECEIVE #' + messageCount + ':', event.data);
try {
const parsed = JSON.parse(event.data);
console.log(' Type:', parsed.type, 'ID:', parsed.id);
if (parsed.payload) {
console.log(' Payload:', JSON.stringify(parsed.payload, null, 2));
}
} catch (e) {
// Not JSON
}
});
return socket;
};
// Preserve WebSocket properties
window.WebSocket.prototype = OriginalWebSocket.prototype;
window.WebSocket.CONNECTING = OriginalWebSocket.CONNECTING;
window.WebSocket.OPEN = OriginalWebSocket.OPEN;
window.WebSocket.CLOSING = OriginalWebSocket.CLOSING;
window.WebSocket.CLOSED = OriginalWebSocket.CLOSED;
})();
`),
}); err != nil {
log.Fatalf("Failed to inject script: %v", err)
}
// Listen to console messages
page.On("console", func(msg playwright.ConsoleMessage) {
text := msg.Text()
msgType := msg.Type()
// Format the output nicely
prefix := "💬"
switch msgType {
case "log":
prefix = "📋"
case "error":
prefix = "❌"
case "warning":
prefix = "⚠️"
case "info":
prefix = ""
}
log.Printf("%s [BROWSER %s] %s", prefix, msgType, text)
})
// Navigate to room
log.Printf("🌐 Navigating to %s...", roomURL)
if _, err := page.Goto(roomURL, playwright.PageGotoOptions{
WaitUntil: playwright.WaitUntilStateDomcontentloaded,
}); err != nil {
log.Fatalf("Failed to navigate: %v", err)
}
log.Println("✅ Page loaded! Monitoring WebSocket traffic...")
log.Println("Press Ctrl+C to stop monitoring")
log.Println()
// Wait for a bit to see initial traffic
time.Sleep(5 * time.Second)
// Try to send a test message
log.Println("\n📝 Attempting to send a test message via UI...")
result, err := page.Evaluate(`
(async function() {
// Find the chat input
const textareas = document.querySelectorAll('textarea');
for (let ta of textareas) {
if (ta.offsetParent !== null) {
ta.value = 'Test message from monitor script 🔍';
ta.dispatchEvent(new Event('input', { bubbles: true }));
ta.dispatchEvent(new Event('change', { bubbles: true }));
ta.focus();
// Wait a bit
await new Promise(resolve => setTimeout(resolve, 100));
// Try to find and click send button
const buttons = document.querySelectorAll('button');
for (let btn of buttons) {
if (btn.textContent.toLowerCase().includes('send') ||
btn.getAttribute('aria-label')?.toLowerCase().includes('send')) {
btn.click();
return { success: true, method: 'button' };
}
}
// If no button, press Enter
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
which: 13,
bubbles: true,
cancelable: true
});
ta.dispatchEvent(enterEvent);
return { success: true, method: 'enter' };
}
}
return { success: false, error: 'No input found' };
})();
`)
if err != nil {
log.Printf("❌ Failed to send test message: %v", err)
} else {
resultMap := result.(map[string]interface{})
if success, ok := resultMap["success"].(bool); ok && success {
method := resultMap["method"].(string)
log.Printf("✅ Test message sent via %s", method)
log.Println("📊 Check the console output above to see the WebSocket traffic!")
} else {
log.Printf("❌ Failed to send: %v", resultMap["error"])
}
}
// Keep monitoring
log.Println("\n⏳ Continuing to monitor... Press Ctrl+C to stop")
// Wait for interrupt
<-interrupt
log.Println("\n👋 Stopping monitor...")
}