Skip to content

Instantly share code, notes, and snippets.

@edr3x
Last active December 14, 2023 06:53
Show Gist options
  • Save edr3x/907fef69681ecf3048a0bd01b8af951a to your computer and use it in GitHub Desktop.
Save edr3x/907fef69681ecf3048a0bd01b8af951a to your computer and use it in GitHub Desktop.
bulk email sender
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
}
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