package main import ( "fmt" "log" "net/http" "os" "path/filepath" "strings" "time" ) // NOTE(jmug): Port here is not really important, choose at your convenience. const listenAddr = "127.0.0.1:" func main() { http.HandleFunc("/", handleSubmit) log.Printf("Listening on %s\n", listenAddr) log.Fatal(http.ListenAndServe(listenAddr, nil)) } func handleSubmit(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } if err := r.ParseForm(); err != nil { log.Printf("Error parsing form: %v", err) http.Redirect(w, r, "https://handmadecities.com/revolt/error", http.StatusSeeOther) return } name := r.FormValue("name") email := r.FormValue("email") website := r.FormValue("website") reason := r.FormValue("reason") // Basic validation if name == "" || email == "" { log.Println("Missing required fields") http.Redirect(w, r, "https://handmadecities.com/", http.StatusSeeOther) return } if err := appendToFile(name, email, website, reason); err != nil { log.Printf("Error writing to file: %v", err) http.Redirect(w, r, "https://handmadecities.com/", http.StatusSeeOther) return } log.Printf("New application from: %s <%s>", name, email) http.Redirect(w, r, "https://handmadecities.com/revolt-success", http.StatusSeeOther) // Send ntfy alert // NOTE(jmug): request secret from shhh, `revol-submission-ntfy-fqdn` _, err := http.Post( "", "text/plain", strings.NewReader(fmt.Sprintf("New Revolt application from %s", name)), ) if err != nil { log.Printf("Failed to send ntfy alert: %v", err) } } // NOTE(jmug): I think this is fine for now, but crazy idea: How about a simple // sqlite db, a cli, and mTLS auth so that an operator (Abner) can query submissions // without jumping on the server. func appendToFile(name, email, website, reason string) error { home, err := os.UserHomeDir() if err != nil { return err } filePath := filepath.Join(home, "revolt_applications.txt") f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err } defer f.Close() entry := fmt.Sprintf( "--- %s ---\nName: %s\nEmail: %s\nWebsite: %s\nReason: %s\n\n", time.Now().Format(time.RFC1123), name, email, website, reason, ) _, err = f.WriteString(entry) return err }