Jump to content
UnixDevel

Sender

Recommended Posts

Posted

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
 

  • Upvote 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...