package main import ( "encoding/csv" "encoding/json" "log" "net/http" "os" "path/filepath" "shared" "strings" "sync" "time" ) type EmailEntry struct { Email string FormName string } var ( emailQueue []EmailEntry // Changed to struct slice queueLock sync.Mutex dbdir string PORT string fpath string ) func saveEmails() { queueLock.Lock() defer queueLock.Unlock() if len(emailQueue) == 0 { return } fileExists := true if _, err := os.Stat(fpath); os.IsNotExist(err) { fileExists = false } f, err := os.OpenFile(fpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { log.Println("Failed to open file:", err) return } defer f.Close() writer := csv.NewWriter(f) defer writer.Flush() // Write header if file is new if !fileExists { if err := writer.Write([]string{"email", "formname", "timestamp"}); err != nil { log.Println("Failed to write header:", err) return } } // Write each entry for _, entry := range emailQueue { timestamp := time.Now().Format(time.RFC3339) if err := writer.Write([]string{entry.Email, entry.FormName, timestamp}); err != nil { log.Println("Failed to write email:", err) return } } emailQueue = emailQueue[:0] // Clear queue } func init() { go func() { for { time.Sleep(5 * time.Second) queueLock.Lock() hasEmails := len(emailQueue) > 0 queueLock.Unlock() if hasEmails { log.Println("Flushing email queue...") saveEmails() } } }() } func handler(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { if r.Method != http.MethodGet { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } w.WriteHeader(http.StatusOK) w.Write([]byte("Batched Write Server is running")) return } if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } formName := strings.Trim(r.URL.Path, "/") if formName == "" { http.Error(w, "Form name required", http.StatusBadRequest) return } email := strings.TrimSpace(r.FormValue("email")) if email == "" { http.Error(w, "Email required", http.StatusBadRequest) return } queueLock.Lock() emailQueue = append(emailQueue, EmailEntry{Email: email, FormName: formName}) shouldFlush := len(emailQueue) >= 100 queueLock.Unlock() if shouldFlush { saveEmails() } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]string{"message": "data received"}) } func main() { _, PORT, dbdir = shared.GetArgs() fpath = filepath.Join(dbdir, "emails.csv") shared.StartAdminServer(dbdir) http.HandleFunc("/", handler) // Single handler for all routes log.Println("Starting server on port", PORT) log.Fatal(http.ListenAndServe(":"+PORT, nil)) }