From 735ba2f3b318b04a1d2e3c969888c66f2e6a8036 Mon Sep 17 00:00:00 2001 From: Johan Jongsma Date: Sun, 1 Feb 2026 08:03:36 +0000 Subject: [PATCH] Initial commit --- .gitignore | 5 +++ main.go | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++ server.js | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 .gitignore create mode 100644 main.go create mode 100755 server.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d82971 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.env +*.log +.DS_Store + diff --git a/main.go b/main.go new file mode 100644 index 0000000..830230f --- /dev/null +++ b/main.go @@ -0,0 +1,111 @@ +package main + +import ( + "encoding/json" + "fmt" + "io" + "log" + "net/http" + "os" + "time" +) + +var logFile *os.File + +func main() { + // Open log file + var err error + logFile, err = os.OpenFile("/tmp/clawdnode-debug.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) + if err != nil { + log.Fatal(err) + } + defer logFile.Close() + + // Log to both file and stdout + log.SetOutput(io.MultiWriter(os.Stdout, logFile)) + log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds) + + http.HandleFunc("/", handleRoot) + http.HandleFunc("/log", handleLog) + http.HandleFunc("/notification", handleNotification) + http.HandleFunc("/call", handleCall) + http.HandleFunc("/event", handleEvent) + http.HandleFunc("/health", handleHealth) + + port := "9876" + log.Printf("🚀 ClawdNode Debug Server starting on :%s", port) + log.Printf("📝 Logging to /tmp/clawdnode-debug.log") + log.Printf("Endpoints: /log, /notification, /call, /event, /health") + + if err := http.ListenAndServe(":"+port, nil); err != nil { + log.Fatal(err) + } +} + +func handleRoot(w http.ResponseWriter, r *http.Request) { + log.Printf("[%s] %s %s from %s", r.Method, r.URL.Path, r.URL.RawQuery, r.RemoteAddr) + fmt.Fprintf(w, "ClawdNode Debug Server\n\nEndpoints:\n- POST /log\n- POST /notification\n- POST /call\n- POST /event\n- GET /health\n") +} + +func handleHealth(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "ok", + "time": time.Now().UTC().Format(time.RFC3339), + }) +} + +func handleLog(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + log.Printf("📋 [LOG] from %s:\n%s", r.RemoteAddr, string(body)) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]string{"status": "logged"}) +} + +func handleNotification(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + + var data map[string]interface{} + json.Unmarshal(body, &data) + + log.Printf("🔔 [NOTIFICATION] from %s:", r.RemoteAddr) + log.Printf(" App: %v", data["app"]) + log.Printf(" Title: %v", data["title"]) + log.Printf(" Text: %v", data["text"]) + log.Printf(" Package: %v", data["package"]) + log.Printf(" Raw: %s", string(body)) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]string{"status": "received"}) +} + +func handleCall(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + + var data map[string]interface{} + json.Unmarshal(body, &data) + + log.Printf("📞 [CALL] from %s:", r.RemoteAddr) + log.Printf(" Number: %v", data["number"]) + log.Printf(" Contact: %v", data["contact"]) + log.Printf(" State: %v", data["state"]) + log.Printf(" Raw: %s", string(body)) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]string{"status": "received"}) +} + +func handleEvent(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + + var data map[string]interface{} + json.Unmarshal(body, &data) + + eventType := data["type"] + log.Printf("⚡ [EVENT:%v] from %s:", eventType, r.RemoteAddr) + log.Printf(" Raw: %s", string(body)) + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(map[string]string{"status": "received"}) +} diff --git a/server.js b/server.js new file mode 100755 index 0000000..498d37a --- /dev/null +++ b/server.js @@ -0,0 +1,106 @@ +#!/usr/bin/env node + +const http = require('http'); +const fs = require('fs'); + +const PORT = 9876; +const LOG_FILE = '/tmp/clawdnode-debug.log'; + +// Open log file +const logStream = fs.createWriteStream(LOG_FILE, { flags: 'a' }); + +function log(msg) { + const ts = new Date().toISOString(); + const line = `[${ts}] ${msg}`; + console.log(line); + logStream.write(line + '\n'); +} + +function parseBody(req) { + return new Promise((resolve) => { + let body = ''; + req.on('data', chunk => body += chunk); + req.on('end', () => { + try { + resolve(JSON.parse(body || '{}')); + } catch { + resolve({ raw: body }); + } + }); + }); +} + +const server = http.createServer(async (req, res) => { + const body = await parseBody(req); + + res.setHeader('Content-Type', 'application/json'); + res.setHeader('Access-Control-Allow-Origin', '*'); + + if (req.method === 'OPTIONS') { + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + res.end(); + return; + } + + const ip = req.socket.remoteAddress; + + switch (req.url) { + case '/health': + res.end(JSON.stringify({ status: 'ok', time: new Date().toISOString() })); + break; + + case '/log': + log(`📋 [LOG] from ${ip}: ${JSON.stringify(body)}`); + res.end(JSON.stringify({ status: 'logged' })); + break; + + case '/notification': + log(`🔔 [NOTIFICATION] from ${ip}:`); + log(` App: ${body.app || body.packageName}`); + log(` Title: ${body.title}`); + log(` Text: ${body.text}`); + log(` Package: ${body.package || body.packageName}`); + log(` Actions: ${JSON.stringify(body.actions || [])}`); + log(` Full: ${JSON.stringify(body)}`); + res.end(JSON.stringify({ status: 'received', id: body.id })); + break; + + case '/call': + log(`📞 [CALL] from ${ip}:`); + log(` Number: ${body.number}`); + log(` Contact: ${body.contact}`); + log(` State: ${body.state}`); + log(` Full: ${JSON.stringify(body)}`); + res.end(JSON.stringify({ status: 'received' })); + break; + + case '/event': + log(`⚡ [EVENT:${body.type}] from ${ip}: ${JSON.stringify(body)}`); + res.end(JSON.stringify({ status: 'received' })); + break; + + case '/error': + log(`❌ [ERROR] from ${ip}: ${JSON.stringify(body)}`); + res.end(JSON.stringify({ status: 'logged' })); + break; + + case '/lifecycle': + log(`🔄 [LIFECYCLE:${body.event}] from ${ip}: ${body.message || ''}`); + res.end(JSON.stringify({ status: 'logged' })); + break; + + default: + log(`[${req.method}] ${req.url} from ${ip}`); + res.end(JSON.stringify({ + status: 'ok', + endpoints: ['/health', '/log', '/notification', '/call', '/event', '/error', '/lifecycle'] + })); + } +}); + +server.listen(PORT, '0.0.0.0', () => { + log(`🚀 ClawdNode Debug Server starting on :${PORT}`); + log(`📝 Logging to ${LOG_FILE}`); + log(`🌐 Accessible at http://100.123.216.65:${PORT} (Tailscale)`); +});