UnixDevel Posted December 8 Report Posted December 8 Astazi am avut nevoie sa trimit niste notificari la 1000 de persoane si am scris prostia asta pentru trimis: package main import ( "bufio" "encoding/json" "errors" "fmt" "log" "math/rand" "net/http" "net/smtp" "os" "path/filepath" "strings" "time" "mime/multipart" "github.com/gorilla/mux" ) type spaHandler struct { staticPath string indexPath string } // ServeHTTP inspects the URL path to locate a file within the static dir // on the SPA handler. If a file is found, it will be served. func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { path := filepath.Join(h.staticPath, r.URL.Path) fi, err := os.Stat(path) if os.IsNotExist(err) || fi.IsDir() { http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath)) return } if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r) } type loginAuth struct { username, password string } // LoginAuth is used for smtp login auth func LoginAuth(username, password string) smtp.Auth { return &loginAuth{username, password} } func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { return "LOGIN", []byte(a.username), nil } func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { if more { switch string(fromServer) { case "Username:": return []byte(a.username), nil case "Password:": return []byte(a.password), nil default: return nil, errors.New("Unknown from server") } } return nil, nil } // Function to read email credentials from the file func readEmailCredentials(filename string) ([]string, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() var credentials []string scanner := bufio.NewScanner(file) for scanner.Scan() { credentials = append(credentials, scanner.Text()) } if err := scanner.Err(); err != nil { return nil, err } return credentials, nil } // Function to read email addresses from an uploaded file func readEmailAddressesFromFile(file multipart.File) ([]string, error) { var emailAddresses []string scanner := bufio.NewScanner(file) for scanner.Scan() { emailAddresses = append(emailAddresses, scanner.Text()) } if err := scanner.Err(); err != nil { return nil, err } return emailAddresses, nil } // Function to send an email using random credentials func sendEmail(fromAddr, password, smtpServer, port, toAddr, subject, body string) error { smtpAddr := fmt.Sprintf("%s:%s", smtpServer, port) // Use the custom LOGIN authentication method auth := LoginAuth(fromAddr, password) msg := []byte(fmt.Sprintf("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\n", fromAddr, toAddr, subject, body)) err := smtp.SendMail(smtpAddr, auth, fromAddr, []string{toAddr}, msg) return err } func main() { router := mux.NewRouter() router.HandleFunc("/api/health", func(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(map[string]bool{"ok": true}) }) // New API endpoint for sending email using email addresses from the uploaded file and the user-written message router.HandleFunc("/api/send-email", func(w http.ResponseWriter, r *http.Request) { // Parse the form data err := r.ParseMultipartForm(10 << 20) // Limit the file size to 10MB if err != nil { http.Error(w, "Error parsing form", http.StatusBadRequest) return } // Get the uploaded file file, _, err := r.FormFile("emails") if err != nil { http.Error(w, "Error getting file", http.StatusBadRequest) return } defer file.Close() // Read email addresses from the uploaded file emailAddresses, err := readEmailAddressesFromFile(file) if err != nil { http.Error(w, fmt.Sprintf("Error reading email addresses: %v", err), http.StatusInternalServerError) return } // Read the credentials from the file credentials, err := readEmailCredentials("smtps.txt") if err != nil { http.Error(w, fmt.Sprintf("Error reading credentials: %v", err), http.StatusInternalServerError) return } // Select a random credential line credential := credentials[rand.Intn(len(credentials))] parts := strings.Split(credential, "|") if len(parts) != 4 { http.Error(w, "Invalid credential format", http.StatusInternalServerError) return } // Extract the SMTP server, port, and email credentials smtpServer := parts[0] port := parts[1] fromAddr := parts[2] password := parts[3] // Use a random email from the uploaded file if len(emailAddresses) == 0 { http.Error(w, "No email addresses found in the uploaded file", http.StatusBadRequest) return } // Get the user-written message from the form message := r.FormValue("message") // Loop through all email addresses and send an email to each for _, email := range emailAddresses { err = sendEmail(fromAddr, password, smtpServer, port, email, "Sorry :( I'm not sure what to do with the information I've found !", message) if err != nil { // If an email fails, log the error and continue with the next email log.Printf("Failed to send email to %s: %v\n", email, err) } else { log.Printf("Successfully sent email to %s\n", email) } } // Return success w.Write([]byte("Emails sent successfully")) }) // Serve SPA (static) files spa := spaHandler{staticPath: "build", indexPath: "index.html"} router.PathPrefix("/").Handler(spa) // Start the server srv := &http.Server{ Handler: router, Addr: "0.0.0.0:8001", WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, } log.Fatal(srv.ListenAndServe()) } Si pentru verificat liste prostia asta: package main import ( "bufio" "errors" "fmt" "net" "net/smtp" "os" "strings" "sync" "time" ) const maxWorkers = 2 // Limit the number of concurrent workers type loginAuth struct { username, password string } // LoginAuth is used for smtp login auth func LoginAuth(username, password string) smtp.Auth { return &loginAuth{username, password} } func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { return "LOGIN", []byte(a.username), nil } func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) { if more { switch string(fromServer) { case "Username:": return []byte(a.username), nil case "Password:": return []byte(a.password), nil default: return nil, errors.New("Unknown from server") } } return nil, nil } func processCredential(line string, successChan chan<- string, failedChan chan<- string, wg *sync.WaitGroup) { defer wg.Done() // Split the line based on the pipe delimiter "|" parts := strings.Split(line, "|") if len(parts) != 4 { fmt.Printf("Invalid line format: %s\n", line) failedChan <- line return } // Extract the SMTP server, port, email address, and password smtpServer := parts[0] port := parts[1] fromAddr := parts[2] password := parts[3] smtpAddr := smtpServer + ":" + port // Check port availability with a timeout fmt.Printf("Trying to connect to %s for %s\n", smtpAddr, fromAddr) conn, err := net.DialTimeout("tcp", smtpAddr, 5*time.Second) if err != nil { fmt.Printf("Connection to %s failed: %v\n", smtpAddr, err) failedChan <- line return } conn.Close() fmt.Printf("Connection to %s succeeded for %s\n", smtpAddr, fromAddr) // Prepare SMTP authentication using LOGIN method auth := LoginAuth(fromAddr, password) // Message msg := []byte("From: " + fromAddr + "\r\n" + "To: stefan@izdrail.com\r\n" + "Subject: Test Email\r\n" + "\r\n" + "This is a test email.\r\n") // Attempt to send the email err = smtp.SendMail(smtpAddr, auth, fromAddr, []string{"stefan@izdrail.com"}, msg) if err != nil { fmt.Printf("Failed to send email for %s using server %s: %v\n", fromAddr, smtpServer, err) failedChan <- line } else { fmt.Printf("Email sent successfully for %s using server %s\n", fromAddr, smtpServer) successChan <- line } } func main() { // Open the credentials file file, err := os.Open("verify.txt") if err != nil { fmt.Println("Error opening file:", err) return } defer file.Close() // Open success log file for writing successFile, err := os.OpenFile("success.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println("Error opening success file:", err) return } defer successFile.Close() // Open failed log file for writing failedFile, err := os.OpenFile("failed.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println("Error opening failed file:", err) return } defer failedFile.Close() successChan := make(chan string, maxWorkers) failedChan := make(chan string, maxWorkers) var wg sync.WaitGroup // Worker to write successes go func() { for success := range successChan { if _, err := successFile.WriteString(success + "\n"); err != nil { fmt.Printf("Error writing to success file: %v\n", err) } } }() // Worker to write failures go func() { for failed := range failedChan { if _, err := failedFile.WriteString(failed + "\n"); err != nil { fmt.Printf("Error writing to failed file: %v\n", err) } } }() // Read the file line by line scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() wg.Add(1) go processCredential(line, successChan, failedChan, &wg) } if err := scanner.Err(); err != nil { fmt.Println("Error reading file:", err) } wg.Wait() close(successChan) // Close the channel when all work is done close(failedChan) // Close the channel when all work is done } formatul pentru smtp trebuie sa fie de tipul acesta : smtp.adress|port|email|password 1 Quote
dimss Posted December 9 Report Posted December 9 Nu mai bine le pui intr-un git? Poate te fork-uieste cineva Quote