#!/bin/bash # send_test_email.sh - Send test emails via SMTP to MailHog # Usage: ./send_test_email.sh [OPTIONS] set -e # Default values SMTP_HOST="localhost" SMTP_PORT="1025" TO="test@recipient.local" FROM="test@sender.local" SUBJECT="Test Email from MailHog Skill" BODY="This is a test email sent via the MailHog skill script." HTML=false ATTACHMENT="" VERBOSE=false # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Print colored output print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Show usage information show_usage() { cat << EOF Send Test Email Script Usage: $0 [OPTIONS] OPTIONS: -h, --help Show this help message -t, --to EMAIL Recipient email address (default: test@recipient.local) -f, --from EMAIL Sender email address (default: test@sender.local) -s, --subject SUBJECT Email subject (default: "Test Email from MailHog Skill") -b, --body TEXT Email body text (default: simple test message) --html Send as HTML email --attachment FILE Attach file to email --smtp-host HOST SMTP server host (default: localhost) --smtp-port PORT SMTP server port (default: 1025) -v, --verbose Enable verbose output --template TEMPLATE Use predefined template (welcome, notification, reset) --multiple COUNT Send multiple emails (for testing) TEMPLATES: welcome - Welcome email template notification - Notification email template reset - Password reset email template bulk - Bulk email test template EXAMPLES: # Send simple test email $0 --to user@test.local --subject "Welcome!" # Send HTML email with template $0 --html --template welcome --to newuser@test.local # Send multiple emails for load testing $0 --multiple 100 --subject "Load Test" # Send email with attachment $0 --attachment ./test.pdf --to recipient@test.local EOF } # Email templates get_template_content() { local template="$1" local to="$2" case "$template" in "welcome") echo "

Welcome to Our Service!

Hello $to,

Thank you for signing up for our service. We're excited to have you on board!

Here's what you can do next:

Best regards,
The Team

" echo "Welcome to Our Service!" ;; "notification") echo "

Important Notification

Hello $to,

You have an important notification that requires your attention.

Action Required: Please review your account settings.

Thank you for your prompt attention to this matter.

" echo "Important Notification" ;; "reset") echo "

Password Reset Request

Hello $to,

You requested a password reset for your account. Click the link below to reset your password:

Reset Password

If you didn't request this reset, please ignore this email. The link will expire in 1 hour.

Best regards,
Support Team

" echo "Password Reset Request" ;; "bulk") echo "

Bulk Communication

This is a test email for bulk communication testing.

Message ID: $(date +%s)

Timestamp: $(date)

" echo "Bulk Communication Test" ;; *) print_error "Unknown template: $template" exit 1 ;; esac } # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_usage exit 0 ;; -t|--to) TO="$2" shift 2 ;; -f|--from) FROM="$2" shift 2 ;; -s|--subject) SUBJECT="$2" shift 2 ;; -b|--body) BODY="$2" shift 2 ;; --html) HTML=true shift ;; --attachment) ATTACHMENT="$2" if [[ ! -f "$ATTACHMENT" ]]; then print_error "Attachment file not found: $ATTACHMENT" exit 1 fi shift 2 ;; --smtp-host) SMTP_HOST="$2" shift 2 ;; --smtp-port) SMTP_PORT="$2" shift 2 ;; -v|--verbose) VERBOSE=true shift ;; --template) TEMPLATE="$2" shift 2 ;; --multiple) MULTIPLE="$2" shift 2 ;; *) print_error "Unknown option: $1" show_usage exit 1 ;; esac done # Check if netcat is available check_dependencies() { local missing_deps=() if ! command -v nc >/dev/null 2>&1 && ! command -v telnet >/dev/null 2>&1; then missing_deps+=("nc or telnet") fi if [[ ${#missing_deps[@]} -gt 0 ]]; then print_error "Missing required dependencies: ${missing_deps[*]}" print_info "Install missing dependencies and try again." exit 1 fi } # Test SMTP connection test_smtp_connection() { print_info "Testing SMTP connection to $SMTP_HOST:$SMTP_PORT..." if command -v nc >/dev/null 2>&1; then if echo "" | nc -w 5 "$SMTP_HOST" "$SMTP_PORT" >/dev/null 2>&1; then print_success "SMTP connection successful" return 0 else print_error "Failed to connect to SMTP server" return 1 fi elif command -v telnet >/dev/null 2>&1; then timeout 5 telnet "$SMTP_HOST" "$SMTP_PORT" /dev/null 2>&1 if [[ $? -eq 0 ]]; then print_success "SMTP connection successful" return 0 else print_error "Failed to connect to SMTP server" return 1 fi fi } # Create temporary file for email create_email_file() { local temp_file=$(mktemp) local boundary="MAILHOG-$(date +%s%N)" cat << EOF > "$temp_file" From: $FROM To: $TO Subject: $SUBJECT Date: $(date -R) MIME-Version: 1.0 EOF if [[ -n "$ATTACHMENT" ]]; then echo "Content-Type: multipart/mixed; boundary=\"$boundary\"" >> "$temp_file" echo "" >> "$temp_file" echo "--$boundary" >> "$temp_file" if [[ "$HTML" == true ]]; then echo "Content-Type: text/html; charset=UTF-8" >> "$temp_file" echo "Content-Transfer-Encoding: 7bit" >> "$temp_file" else echo "Content-Type: text/plain; charset=UTF-8" >> "$temp_file" echo "Content-Transfer-Encoding: 7bit" >> "$temp_file" fi echo "" >> "$temp_file" echo "$BODY" >> "$temp_file" echo "" >> "$temp_file" echo "--$boundary" >> "$temp_file" # Add attachment local attachment_name=$(basename "$ATTACHMENT") echo "Content-Type: application/octet-stream" >> "$temp_file" echo "Content-Transfer-Encoding: base64" >> "$temp_file" echo "Content-Disposition: attachment; filename=\"$attachment_name\"" >> "$temp_file" echo "" >> "$temp_file" base64 "$ATTACHMENT" >> "$temp_file" echo "" >> "$temp_file" echo "--$boundary--" >> "$temp_file" else if [[ "$HTML" == true ]]; then echo "Content-Type: text/html; charset=UTF-8" >> "$temp_file" echo "Content-Transfer-Encoding: 7bit" >> "$temp_file" else echo "Content-Type: text/plain; charset=UTF-8" >> "$temp_file" fi echo "" >> "$temp_file" echo "$BODY" >> "$temp_file" fi echo "$temp_file" } # Send email using SMTP send_email_smtp() { local email_file="$1" if [[ "$VERBOSE" == true ]]; then print_info "Sending email with the following content:" cat "$email_file" echo "" fi # Connect to SMTP and send email ( echo "EHLO mailhog-test.local" echo "MAIL FROM:<$FROM>" echo "RCPT TO:<$TO>" echo "DATA" cat "$email_file" echo "." echo "QUIT" ) | nc "$SMTP_HOST" "$SMTP_PORT" 2>/dev/null if [[ $? -eq 0 ]]; then print_success "Email sent successfully" return 0 else print_error "Failed to send email" return 1 fi } # Send email using Python if available send_email_python() { local email_file="$1" if command -v python3 >/dev/null 2>&1; then python3 << EOF import smtplib import ssl from email import message_from_file try: with open('$email_file', 'r') as f: msg = message_from_file(f) # Convert to string for sending email_string = msg.as_string() # Connect to SMTP server server = smtplib.SMTP('$SMTP_HOST', $SMTP_PORT) server.set_debuglevel(1 if '$VERBOSE' == 'true' else 0) # Send email server.sendmail('$FROM', ['$TO'], email_string) server.quit() print("Email sent successfully via Python") except Exception as e: print(f"Failed to send email via Python: {e}") exit(1) EOF return $? else return 1 fi } # Send multiple emails for testing send_multiple_emails() { local count="$1" local success_count=0 local failed_count=0 print_info "Sending $count emails..." for ((i=1; i<=count; i++)); do local temp_subject="$SUBJECT - #$i" local temp_body="This is test email #$i\n\nSent at: $(date)" if [[ "$HTML" == true ]]; then temp_body="

This is test email #$i

Sent at: $(date)

" fi local temp_file=$(mktemp) cat << EOF > "$temp_file" From: $FROM To: $TO Subject: $temp_subject Date: $(date -R) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 $temp_body EOF if send_email_smtp "$temp_file"; then ((success_count++)) else ((failed_count++)) fi rm -f "$temp_file" # Progress indicator if [[ $((i % 10)) -eq 0 ]]; then print_info "Sent $i/$count emails..." fi # Small delay to avoid overwhelming the server sleep 0.1 done print_success "Email sending complete: $success_count successful, $failed_count failed" } # Check MailHog for the sent email verify_email_received() { local max_attempts=10 local attempt=1 print_info "Verifying email was received by MailHog..." while [[ $attempt -le $max_attempts ]]; do local response=$(curl -s "http://localhost:8025/api/v1/messages?limit=1" 2>/dev/null) if [[ $? -eq 0 ]] && echo "$response" | grep -q "\"total\":1"; then print_success "Email verified in MailHog" if [[ "$VERBOSE" == true ]]; then echo "$response" | jq '.' fi return 0 fi sleep 1 ((attempt++)) done print_warning "Email not found in MailHog after verification attempts" return 1 } # Main execution main() { print_info "MailHog Test Email Sender" # Check dependencies check_dependencies # Apply template if specified if [[ -n "$TEMPLATE" ]]; then if [[ "$VERBOSE" == true ]]; then print_info "Using template: $TEMPLATE" fi local template_result=$(get_template_content "$TEMPLATE" "$TO") BODY=$(echo "$template_result" | sed -n '1p') SUBJECT=$(echo "$template_result" | sed -n '2p') HTML=true fi # Test SMTP connection test_smtp_connection # Send multiple emails if requested if [[ -n "$MULTIPLE" ]]; then send_multiple_emails "$MULTIPLE" exit 0 fi # Create email file local email_file=$(create_email_file) # Send email print_info "Sending email to $TO from $FROM via $SMTP_HOST:$SMTP_PORT..." if ! send_email_smtp "$email_file"; then # Fallback to Python if netcat fails if send_email_python "$email_file"; then print_success "Email sent successfully via Python fallback" else print_error "All email sending methods failed" rm -f "$email_file" exit 1 fi fi # Clean up rm -f "$email_file" # Verify email was received (only if running on same host as MailHog) if [[ "$SMTP_HOST" == "localhost" ]] || [[ "$SMTP_HOST" == "127.0.0.1" ]]; then verify_email_received fi print_success "Test email sending completed successfully" } # Run main function main "$@"