From 88216daac0f9a60de45eeb7e8e7e6997c090916d Mon Sep 17 00:00:00 2001 From: accius Date: Mon, 2 Feb 2026 21:51:05 -0500 Subject: [PATCH] wsjtx relay --- server.js | 128 ++++++++++++++++++++++++++++ src/components/PSKReporterPanel.jsx | 35 ++++++-- 2 files changed, 155 insertions(+), 8 deletions(-) diff --git a/server.js b/server.js index 70e09fd..9121886 100644 --- a/server.js +++ b/server.js @@ -4178,6 +4178,134 @@ app.post('/api/wsjtx/relay', (req, res) => { res.json({ ok: true, processed, timestamp: Date.now() }); }); +// API endpoint: download pre-configured relay agent script +// Embeds relay.js + server URL + relay key into a one-file launcher +app.get('/api/wsjtx/relay/download/:platform', (req, res) => { + if (!WSJTX_RELAY_KEY) { + return res.status(503).json({ error: 'Relay not configured โ€” set WSJTX_RELAY_KEY in .env' }); + } + + const platform = req.params.platform; // 'linux', 'mac', or 'windows' + const relayJsPath = path.join(__dirname, 'wsjtx-relay', 'relay.js'); + + let relayJs; + try { + relayJs = fs.readFileSync(relayJsPath, 'utf8'); + } catch (e) { + return res.status(500).json({ error: 'relay.js not found on server' }); + } + + // Detect server URL from request + const proto = req.headers['x-forwarded-proto'] || req.protocol || 'http'; + const host = req.headers['x-forwarded-host'] || req.headers.host; + const serverURL = proto + '://' + host; + + if (platform === 'linux' || platform === 'mac') { + // Build bash script with relay.js embedded as heredoc + const lines = [ + '#!/bin/bash', + '# OpenHamClock WSJT-X Relay โ€” Auto-configured', + '# Generated by ' + serverURL, + '#', + '# Usage: bash ' + (platform === 'mac' ? 'start-relay.command' : 'start-relay.sh'), + '# Stop: Ctrl+C', + '# Requires: Node.js 14+ (https://nodejs.org)', + '#', + '# In WSJT-X: Settings > Reporting > UDP Server', + '# Address: 127.0.0.1 Port: 2237', + '', + 'set -e', + '', + '# Check for Node.js', + 'if ! command -v node &> /dev/null; then', + ' echo ""', + ' echo "Node.js is not installed."', + ' echo "Install from https://nodejs.org (LTS recommended)"', + ' echo ""', + ' echo "Quick install:"', + ' echo " Ubuntu/Debian: sudo apt install nodejs"', + ' echo " Mac (Homebrew): brew install node"', + ' echo " Fedora: sudo dnf install nodejs"', + ' echo ""', + ' exit 1', + 'fi', + '', + '# Write relay agent to temp file', + 'RELAY_FILE=$(mktemp /tmp/ohc-relay-XXXXXX.js)', + 'trap "rm -f $RELAY_FILE" EXIT', + '', + "cat > \"$RELAY_FILE\" << 'OPENHAMCLOCK_RELAY_EOF'", + relayJs, + 'OPENHAMCLOCK_RELAY_EOF', + '', + '# Run relay', + 'exec node "$RELAY_FILE" \\', + ' --url "' + serverURL + '" \\', + ' --key "' + WSJTX_RELAY_KEY + '"', + ]; + + const script = lines.join('\n') + '\n'; + const filename = platform === 'mac' ? 'start-relay.command' : 'start-relay.sh'; + res.setHeader('Content-Type', 'application/x-sh'); + res.setHeader('Content-Disposition', 'attachment; filename="' + filename + '"'); + return res.send(script); + + } else if (platform === 'windows') { + // Build PowerShell script with relay.js embedded + const escapedJs = relayJs.replace(/'/g, "''"); + + const lines = [ + '# OpenHamClock WSJT-X Relay - Auto-configured', + '# Generated by ' + serverURL, + '# Right-click > "Run with PowerShell" or run from terminal', + '# Requires: Node.js 14+ (https://nodejs.org)', + '#', + '# In WSJT-X: Settings > Reporting > UDP Server', + '# Address: 127.0.0.1 Port: 2237', + '', + '# Check for Node.js', + 'try {', + ' $nv = (node -v 2>$null)', + ' if (-not $nv) { throw "missing" }', + ' Write-Host "Found Node.js $nv" -ForegroundColor Green', + '} catch {', + ' Write-Host "Node.js is not installed." -ForegroundColor Red', + ' Write-Host "Download from https://nodejs.org (LTS version)" -ForegroundColor Yellow', + ' Read-Host "Press Enter to exit"', + ' exit 1', + '}', + '', + '# Write relay agent to temp file', + '$relayFile = Join-Path $env:TEMP "ohc-relay.js"', + '', + "$relayCode = @'", + escapedJs, + "'@", + '', + '$relayCode | Out-File -FilePath $relayFile -Encoding UTF8', + '', + 'Write-Host "Starting WSJT-X relay agent..." -ForegroundColor Cyan', + 'Write-Host "Press Ctrl+C to stop" -ForegroundColor DarkGray', + 'Write-Host ""', + '', + '# Run relay', + 'try {', + ' node $relayFile --url "' + serverURL + '" --key "' + WSJTX_RELAY_KEY + '"', + '} finally {', + ' Remove-Item $relayFile -ErrorAction SilentlyContinue', + '}', + ]; + + const script = lines.join('\r\n') + '\r\n'; + res.setHeader('Content-Type', 'application/x-powershell'); + res.setHeader('Content-Disposition', 'attachment; filename="start-relay.ps1"'); + return res.send(script); + + } else { + return res.status(400).json({ error: 'Invalid platform. Use: linux, mac, or windows' }); + } +}); + // ============================================ // CATCH-ALL FOR SPA // ============================================ diff --git a/src/components/PSKReporterPanel.jsx b/src/components/PSKReporterPanel.jsx index 7755499..5b5aac9 100644 --- a/src/components/PSKReporterPanel.jsx +++ b/src/components/PSKReporterPanel.jsx @@ -347,14 +347,33 @@ const PSKReporterPanel = ({ }}>
Waiting for WSJT-X...
{wsjtxRelayEnabled ? ( -
- Relay mode โ€” run the relay agent locally: -
- - node relay.js --url {'{this server}'} --key {'{key}'} - -
- See wsjtx-relay/README.md +
+
+ Download the relay agent for your PC: +
+
+ ๐Ÿง Linux + ๐ŸŽ Mac + ๐ŸชŸ Windows +
+
+ Requires Node.js ยท Run the script, then start WSJT-X +
) : (