Last active
December 14, 2023 06:53
-
-
Save edr3x/907fef69681ecf3048a0bd01b8af951a to your computer and use it in GitHub Desktop.
bulk email sender
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net/smtp" | |
"os" | |
"sync" | |
"github.com/gofiber/fiber/v2" | |
"github.com/gofiber/fiber/v2/middleware/cors" | |
"github.com/xuri/excelize/v2" | |
) | |
type emailSenderBody struct { | |
FileName string `json:"file_name"` | |
Subject string `json:"subject"` | |
Body string `json:"body"` | |
Email string `json:"email"` | |
Password string `json:"password"` | |
} | |
func main() { | |
app := fiber.New() | |
app.Use(cors.New(cors.Config{ | |
AllowOrigins: "*", | |
AllowMethods: "GET,POST", | |
})) | |
app.Get("/", func(c *fiber.Ctx) error { | |
return c.Status(200).JSON(fiber.Map{ | |
"message": "Hello, World!", | |
}) | |
}) | |
app.Post("/upload", func(c *fiber.Ctx) error { | |
file, err := c.FormFile("file") | |
errResponse := c.Status(400).JSON(fiber.Map{ | |
"message": "Error uploading file", | |
}) | |
if err != nil { | |
log.Println(err) | |
return errResponse | |
} | |
err = os.MkdirAll("./uploads", os.ModePerm) | |
if err != nil { | |
log.Println(err) | |
return errResponse | |
} | |
err = c.SaveFile(file, fmt.Sprintf("./uploads/%s", file.Filename)) | |
if err != nil { | |
log.Println(err) | |
return errResponse | |
} | |
return c.Status(200).JSON(fiber.Map{ | |
"message": "File uploaded successfully", | |
"file": file.Filename, | |
}) | |
}) | |
app.Post("/send", func(c *fiber.Ctx) error { | |
var body emailSenderBody | |
if err := c.BodyParser(&body); err != nil { | |
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ | |
"message": "Error parsing body", | |
}) | |
} | |
emails, err := extractEmails(body.FileName) | |
if err != nil { | |
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ | |
"message": "Error parsing emails", | |
}) | |
} | |
msg, e := sendEmail(body.Subject, body.Body, emails, body.FileName, body.Email, body.Password) | |
if e != nil { | |
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ | |
"message": "Error sending email", | |
}) | |
} | |
return c.Status(200).JSON(fiber.Map{ | |
"message": msg, | |
}) | |
}) | |
port := os.Getenv("PORT") | |
if port == "" { | |
port = "8080" | |
} | |
fmt.Println("listening on port " + port + "...") | |
log.Fatal(app.Listen("0.0.0.0:" + port)) | |
} | |
func extractEmails(fileName string) ([]string, error) { | |
f, err := excelize.OpenFile("./uploads/" + fileName) | |
if err != nil { | |
log.Println(err) | |
return nil, err | |
} | |
defer func() { | |
if err := f.Close(); err != nil { | |
fmt.Println(err) | |
} | |
}() | |
rows, err := f.GetRows("Sheet1") // Replace "Sheet1" with the actual sheet name | |
if err != nil { | |
log.Fatal(err) | |
} | |
var entries []string | |
for _, row := range rows { | |
if len(row) > 0 { | |
entries = append(entries, row[0]) | |
} | |
} | |
return entries, nil | |
} | |
func sendEmail(subject string, body string, recipientEmails []string, filename string, email string, pass string) (string, error) { | |
smtpHost := "" // provide your smtp email provider host | |
smtpPort := 587 | |
senderEmail := email | |
senderPassword := pass | |
auth := smtp.PlainAuth("", senderEmail, senderPassword, smtpHost) | |
to := "To: me\r\n" | |
from := "From:" + email + "\r\n" | |
sub := "Subject:" + subject + "\r\n" | |
message := []byte(from + to + sub + "\r\n" + body) | |
concurrency := 5 | |
semaphore := make(chan struct{}, concurrency) | |
errCh := make(chan error, len(recipientEmails)) | |
var wg sync.WaitGroup | |
wg.Add(len(recipientEmails)) | |
for _, recipient := range recipientEmails { | |
semaphore <- struct{}{} | |
go func(recipient string) { | |
defer wg.Done() | |
defer func() { <-semaphore }() | |
err := smtp.SendMail(smtpHost+":"+fmt.Sprint(smtpPort), auth, senderEmail, []string{recipient}, message) | |
if err != nil { | |
log.Printf("Failed to send email to %s: %v", recipient, err) | |
errCh <- fmt.Errorf("failed to send email to %s: %v", recipient, err) | |
} else { | |
log.Printf("Email sent successfully to %s", recipient) | |
} | |
}(recipient) | |
} | |
wg.Wait() | |
close(errCh) | |
for err := range errCh { | |
os.Remove("./uploads/" + filename) | |
return "", err | |
} | |
os.Remove("./uploads/" + filename) | |
return "Email sent successfully", nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"net/smtp" | |
) | |
func main() { | |
// fill the credentials | |
smtpServer := "" | |
smtpPort := 587 | |
smtpUser := "" | |
smtpPassword := "" | |
// Recipient's email address | |
to := []string{""} | |
// Compose the email message | |
message := "Subject: Test Email\r\n\r\nThis is a test email sent from small go program" | |
// Set up authentication | |
auth := smtp.PlainAuth("", smtpUser, smtpPassword, smtpServer) | |
// Connect to the SMTP server | |
if err := smtp.SendMail(fmt.Sprintf("%s:%d", smtpServer, smtpPort), auth, smtpUser, to, []byte(message)); err != nil { | |
log.Fatal("Error sending email:", err) | |
} | |
log.Println("Email sent successfully.") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment