Sending Bulk Emails with Golang using SMTP
Build a bulk email sender in Go with SMTP, HTML support, and custom reply-to. Complete tutorial with code examples and environment setup.
In this tutorial, we’ll build a Go program that sends bulk emails through SMTP with custom reply-to addresses and rich HTML content. We’ll use Go’s built-in net/smtp
package alongside github.com/joho/godotenv
for managing environment variables securely.
You can find the complete source code in my GitHub repository.
🚀 Prerequisites
Before we begin, make sure you have:
- Go installed on your system
- Access to an SMTP server (Gmail, SendGrid, etc.)
- Basic understanding of Go syntax
📦 Setting Up Dependencies
First, let’s install the required package for environment variable management:
1
go get github.com/joho/godotenv
🔧 Configuration Setup
Create a .env
file in your project root to store sensitive SMTP credentials:
1
2
3
4
5
6
7
8
9
10
11
12
# Rename this file to .env
# SMTP credentials
SMTP_USERNAME=""
SMTP_PASSWORD=""
# SMTP server information
SMTP_HOST=""
SMTP_PORT=""
# Sender's email address
FROM_EMAIL=""
Important: Never commit your .env
file to version control. Add it to your .gitignore
file.
💻 Implementation
Now let’s create our main Go file with the bulk email functionality:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main
import (
"fmt"
"github.com/joho/godotenv"
"log"
"os"
"net/smtp"
)
func main() {
// Loading environment variables
err := godotenv.Load(".env")
if err != nil {
log.Fatalf("Error loading environment variables file")
}
// SMTP server credentials from .env file
SMTP_USERNAME := os.Getenv("SMTP_USERNAME")
SMTP_PASSWORD := os.Getenv("SMTP_PASSWORD")
SMTP_HOST := os.Getenv("SMTP_HOST")
FROM_EMAIL := os.Getenv("FROM_EMAIL")
SMTP_PORT := os.Getenv("SMTP_PORT")
log.Println("SMTP credentials initialized for:", SMTP_USERNAME)
// Setup authentication
auth := smtp.PlainAuth("", SMTP_USERNAME, SMTP_PASSWORD, SMTP_HOST)
// List of recipient emails
toList := []string{"recipient1@gmail.com"}
// For multiple recipients:
// toList := []string{"email1@gmail.com", "email2@gmail.com", "email3@gmail.com"}
// Email content
subject := "Test Golang Program"
body := "Hello, this is an HTML-rich email template!"
// Custom reply-to email (optional)
reply_to := ""
if reply_to == "" {
reply_to = FROM_EMAIL
}
// Construct email message with HTML support
var msg []byte
msg = []byte(
"From: " + FROM_EMAIL + "\r\n" +
"Reply-To: " + reply_to + "\r\n" +
"Subject: " + subject + "\r\n" +
"MIME-version: 1.0;\nContent-Type: text/html; charset=\"UTF-8\";\r\n" +
"\r\n" +
body + "\r\n")
// Send the email
err = smtp.SendMail(SMTP_HOST+":"+SMTP_PORT, auth, FROM_EMAIL, toList, msg)
// Handle any errors
if err != nil {
log.Println("Failed to send email:", err)
os.Exit(1)
}
fmt.Println("✅ Successfully sent emails to all recipients!")
}
🏃♂️ Running the Program
Execute your program with:
1
go run .
If everything is configured correctly, you should see a success message indicating that emails were sent to all recipients.
🎨 Customization Options
For Plain Text Emails
If you prefer plain text over HTML, replace the message construction with:
1
2
3
4
5
msg = []byte(
"Reply-To: " + reply_to + "\r\n" +
"Subject: " + subject + "\r\n" +
"\r\n" +
body + "\r\n")
Adding More Recipients
Simply expand the toList
slice:
1
2
3
4
5
toList := []string{
"user1@example.com",
"user2@example.com",
"user3@example.com",
}
🛡️ Best Practices
- Rate Limiting: Most SMTP providers have sending limits. Consider adding delays between emails for large batches.
- Error Handling: Implement retry logic for failed sends.
- Security: Never hardcode credentials. Always use environment variables.
- Validation: Validate email addresses before sending.
🎯 Conclusion
You’ve successfully built a Go program that can send bulk emails with HTML content and custom reply-to addresses. This foundation can be extended to include templates, better error handling, and more sophisticated email features.
The combination of Go’s simplicity and the power of SMTP makes email automation straightforward and efficient. Feel free to customize this code for your specific use cases—whether it’s newsletters, notifications, or marketing campaigns.
Happy coding! 🚀