Here are practical implementations for bulk email sending in popular programming languages:
Python with smtplib
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import os
from typing import List, Dict
def create_email_message(recipient: Dict, email_data: Dict) -> MIMEMultipart:
message = MIMEMultipart("alternative")
message["Subject"] = email_data['subject']
message["From"] = email_data['from_email']
message["To"] = recipient['email']
# Create HTML and text versions
html = email_data['html_template'].format(**recipient)
text = email_data['text_template'].format(**recipient)
# Add HTML and text parts
part1 = MIMEText(text, "plain")
part2 = MIMEText(html, "html")
message.attach(part1)
message.attach(part2)
return message
def send_bulk_emails(recipients: List[Dict], email_data: Dict) -> List[Dict]:
results = []
# Create secure connection
context = ssl.create_default_context()
try:
with smtplib.SMTP_SSL(email_data['smtp_server'], email_data['smtp_port'], context=context) as server:
server.login(email_data['username'], email_data['password'])
for recipient in recipients:
try:
message = create_email_message(recipient, email_data)
server.sendmail(
email_data['from_email'],
recipient['email'],
message.as_string()
)
results.append({
'email': recipient['email'],
'status': 'sent',
'recipient_id': recipient.get('id')
})
except Exception as e:
results.append({
'email': recipient['email'],
'status': 'failed',
'error': str(e),
'recipient_id': recipient.get('id')
})
except Exception as e:
print(f"SMTP connection failed: {e}")
return []
return results
# Usage example
recipients = [
{'id': 1, 'email': 'user1@example.com', 'name': 'John Doe'},
{'id': 2, 'email': 'user2@example.com', 'name': 'Jane Smith'}
]
email_data = {
'subject': 'Welcome to Our Newsletter!',
'from_email': 'noreply@yourcompany.com',
'smtp_server': 'smtp.gmail.com',
'smtp_port': 465,
'username': os.getenv('SMTP_USERNAME'),
'password': os.getenv('SMTP_PASSWORD'),
'html_template': 'Hello {name}!
Welcome to our newsletter.
',
'text_template': 'Hello {name}! Welcome to our newsletter.'
}
results = send_bulk_emails(recipients, email_data)
PHP with PHPMailer
mailer = new PHPMailer(true);
// Server settings
$this->mailer->isSMTP();
$this->mailer->Host = getenv('SMTP_HOST');
$this->mailer->SMTPAuth = true;
$this->mailer->Username = getenv('SMTP_USERNAME');
$this->mailer->Password = getenv('SMTP_PASSWORD');
$this->mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$this->mailer->Port = 587;
// Default settings
$this->mailer->setFrom(getenv('FROM_EMAIL'), getenv('FROM_NAME'));
$this->mailer->isHTML(true);
}
public function sendBulkEmails($recipients, $emailData) {
$results = [];
foreach ($recipients as $recipient) {
try {
// Clear previous recipients
$this->mailer->clearAddresses();
// Set recipient
$this->mailer->addAddress($recipient['email'], $recipient['name']);
// Personalize content
$subject = str_replace('{name}', $recipient['name'], $emailData['subject']);
$htmlBody = str_replace('{name}', $recipient['name'], $emailData['html']);
$textBody = str_replace('{name}', $recipient['name'], $emailData['text']);
$this->mailer->Subject = $subject;
$this->mailer->Body = $htmlBody;
$this->mailer->AltBody = $textBody;
$this->mailer->send();
$results[] = [
'email' => $recipient['email'],
'status' => 'sent',
'message_id' => $this->mailer->getLastMessageID(),
'recipient_id' => $recipient['id']
];
} catch (Exception $e) {
$results[] = [
'email' => $recipient['email'],
'status' => 'failed',
'error' => $this->mailer->ErrorInfo,
'recipient_id' => $recipient['id']
];
}
}
return $results;
}
}
// Usage example
$recipients = [
['id' => 1, 'email' => 'user1@example.com', 'name' => 'John Doe'],
['id' => 2, 'email' => 'user2@example.com', 'name' => 'Jane Smith']
];
$emailData = [
'subject' => 'Hello {name}!',
'html' => 'Hello {name}!
Welcome to our service.
',
'text' => 'Hello {name}! Welcome to our service.'
];
$sender = new BulkEmailSender();
$results = $sender->sendBulkEmails($recipients, $emailData);
?>
Ruby with Mail Gem
require 'mail'
require 'dotenv/load'
class BulkEmailService
def initialize
Mail.defaults do
delivery_method :smtp,
address: ENV['SMTP_HOST'],
port: ENV['SMTP_PORT'],
user_name: ENV['SMTP_USERNAME'],
password: ENV['SMTP_PASSWORD'],
authentication: 'plain',
enable_starttls_auto: true
end
end
def send_bulk_emails(recipients, email_data)
results = []
recipients.each do |recipient|
begin
mail = Mail.new do
from email_data['from_email']
to recipient['email']
subject email_data['subject'].gsub('{name}', recipient['name'])
html_part do
content_type 'text/html; charset=UTF-8'
body email_data['html_template'].gsub('{name}', recipient['name'])
end
text_part do
body email_data['text_template'].gsub('{name}', recipient['name'])
end
end
mail.deliver!
results << {
email: recipient['email'],
status: 'sent',
message_id: mail.message_id,
recipient_id: recipient['id']
}
rescue StandardError => e
results << {
email: recipient['email'],
status: 'failed',
error: e.message,
recipient_id: recipient['id']
}
end
end
results
end
end
# Usage example
recipients = [
{ id: 1, email: 'user1@example.com', name: 'John Doe' },
{ id: 2, email: 'user2@example.com', name: 'Jane Smith' }
]
email_data = {
'from_email' => 'noreply@yourcompany.com',
'subject' => 'Welcome {name}!',
'html_template' => 'Hello {name}!
Welcome to our service.
',
'text_template' => 'Hello {name}! Welcome to our service.'
}
service = BulkEmailService.new
results = service.send_bulk_emails(recipients, email_data)