diff --git a/config.go b/config.go index baf4086..2691532 100644 --- a/config.go +++ b/config.go @@ -1,33 +1,33 @@ -package main - -import ( - "encoding/json" - "os" -) - -// For config file -type Config struct { - SMTPServer string `json:"smtp_server"` - SMTPPort int `json:"smtp_port"` - SMTPUsername string `json:"smtp_username"` - SMTPPassword string `json:"smtp_password"` - FromEmail string `json:"from_email"` -} - -func loadConfig(filePath string) (Config, error) { - var config Config - - file, err := os.Open(filePath) - if err != nil { - return config, err - } - defer file.Close() - - decoder := json.NewDecoder(file) - err = decoder.Decode(&config) - if err != nil { - return config, err - } - - return config, nil -} +package main + +import ( + "encoding/json" + "os" +) + +// For config file +type Config struct { + SMTPServer string `json:"smtp_server"` + SMTPPort int `json:"smtp_port"` + SMTPUsername string `json:"smtp_username"` + SMTPPassword string `json:"smtp_password"` + FromEmail string `json:"from_email"` +} + +func loadConfig(filePath string) (Config, error) { + var config Config + + file, err := os.Open(filePath) + if err != nil { + return config, err + } + defer file.Close() + + decoder := json.NewDecoder(file) + err = decoder.Decode(&config) + if err != nil { + return config, err + } + + return config, nil +} diff --git a/main.go b/main.go index e1d1daa..0107da5 100644 --- a/main.go +++ b/main.go @@ -1,185 +1,185 @@ -package main - -import ( - "flag" - "fmt" - "log" - "os" - "strings" -) - -var ( - // Long-form flags - smtpServer string - smtpPort int - username string - password string - - configFile string - - fromEmail string - toEmail string - - subject string - body string - - attachmentsFiles string - bodyFile string - - // Short-form flags - smtpServerShort string - smtpPortShort int - usernameShort string - passwordShort string - - configFileShort string - - fromEmailShort string - toEmailShort string - - subjectShort string - bodyShort string - - attachmentsFilesShort string - bodyFileShort string -) - -func init() { - // Long-form flags - flag.StringVar(&smtpServer, "smtp-server", "", "SMTP server for sending emails") - flag.IntVar(&smtpPort, "smtp-port", 587, "SMTP server port") - flag.StringVar(&username, "smtp-username", "", "Username for SMTP authentication") - flag.StringVar(&password, "smtp-password", "", "Password for SMTP authentication") - - flag.StringVar(&configFile, "config", "", "Path to the SMTP config file") - - flag.StringVar(&fromEmail, "from-email", "", "Email address to send from") - flag.StringVar(&toEmail, "to-email", "", "Email addresses that will receive the email, comma-separated") - - flag.StringVar(&subject, "subject", "", "Subject of the email") - flag.StringVar(&body, "body", "", "Body of the email") - - flag.StringVar(&attachmentsFiles, "attachments", "", "File paths for attachments, comma-separated") - flag.StringVar(&bodyFile, "body-file", "", "File path for email body") - - // Short-form flags - flag.StringVar(&smtpServerShort, "s", "", "SMTP server for sending emails (short)") - flag.IntVar(&smtpPortShort, "p", 587, "SMTP server port (short)") - flag.StringVar(&usernameShort, "u", "", "Username for SMTP authentication (short)") - flag.StringVar(&passwordShort, "w", "", "Password for SMTP authentication (short)") - - flag.StringVar(&configFileShort, "c", "", "Path to the SMTP config file (short)") - - flag.StringVar(&fromEmailShort, "f", "", "Email address to send from (short)") - flag.StringVar(&toEmailShort, "t", "", "Email addresses that will receive the email, comma-separated (short)") - - flag.StringVar(&subjectShort, "h", "", "Subject of the email (short)") - flag.StringVar(&bodyShort, "b", "", "Body of the email (short)") - - flag.StringVar(&attachmentsFilesShort, "af", "", "File paths for attachments, comma-separated (short)") - flag.StringVar(&bodyFileShort, "bf", "", "File path for email body (short)") -} - -func main() { - flag.Parse() - - // Override long-form flags with short-form flags if set - if smtpServerShort != "" { - smtpServer = smtpServerShort - } - if smtpPortShort != 587 { - smtpPort = smtpPortShort - } - if usernameShort != "" { - username = usernameShort - } - if passwordShort != "" { - password = passwordShort - } - if configFileShort != "" { - configFile = configFileShort - } - if fromEmailShort != "" { - fromEmail = fromEmailShort - } - if toEmailShort != "" { - toEmail = toEmailShort - } - if subjectShort != "" { - subject = subjectShort - } - if bodyShort != "" { - body = bodyShort - } - if attachmentsFilesShort != "" { - attachmentsFiles = attachmentsFilesShort - } - if bodyFileShort != "" { - bodyFile = bodyFileShort - } - - // Load config from file if provided - if configFile != "" { - config, err := loadConfig(configFile) - if err != nil { - log.Fatalf("Error loading config file: %v", err) - } - - // Override flags with config file values if set - if config.SMTPServer != "" { - smtpServer = config.SMTPServer - } - if config.SMTPPort != 0 { - smtpPort = config.SMTPPort - } - if config.SMTPUsername != "" { - username = config.SMTPUsername - } - if config.SMTPPassword != "" { - password = config.SMTPPassword - } - if config.FromEmail != "" { - fromEmail = config.FromEmail - } - } - - // Check if required flags or config values are missing - if smtpServer == "" || username == "" || password == "" || fromEmail == "" || toEmail == "" || subject == "" { - fmt.Fprintln(os.Stderr, "Error: Required flags or config values are missing.") - usage() - } - - // Check if either direct input or file path is provided for body - if body == "" && bodyFile == "" { - fmt.Fprintln(os.Stderr, "Error: Subject and body are required, either directly or through a specified file.") - usage() - } - - // Read body from files if provided - if bodyFile != "" { - content, err := os.ReadFile(bodyFile) - if err != nil { - log.Fatalf("\nError reading body file: %v\n", err) - } - body = string(content) - } - - // Split attachment file paths - var attachmentPaths []string - if attachmentsFiles != "" { - attachmentPaths = strings.Split(attachmentsFiles, ",") - } - - // Split recipient email addresses - var toEmails []string - if toEmail != "" { - toEmails = strings.Split(toEmail, ",") - } - - if len(toEmails) == 0 { - fmt.Fprintln(os.Stderr, "Error: At least one recipient email address is required.") - usage() - } - - sendEmail(smtpServer, smtpPort, username, password, fromEmail, toEmails, subject, body, bodyFile, attachmentPaths) -} +package main + +import ( + "flag" + "fmt" + "log" + "os" + "strings" +) + +var ( + // Long-form flags + smtpServer string + smtpPort int + username string + password string + + configFile string + + fromEmail string + toEmail string + + subject string + body string + + attachmentsFiles string + bodyFile string + + // Short-form flags + smtpServerShort string + smtpPortShort int + usernameShort string + passwordShort string + + configFileShort string + + fromEmailShort string + toEmailShort string + + subjectShort string + bodyShort string + + attachmentsFilesShort string + bodyFileShort string +) + +func init() { + // Long-form flags + flag.StringVar(&smtpServer, "smtp-server", "", "SMTP server for sending emails") + flag.IntVar(&smtpPort, "smtp-port", 587, "SMTP server port") + flag.StringVar(&username, "smtp-username", "", "Username for SMTP authentication") + flag.StringVar(&password, "smtp-password", "", "Password for SMTP authentication") + + flag.StringVar(&configFile, "config", "", "Path to the SMTP config file") + + flag.StringVar(&fromEmail, "from-email", "", "Email address to send from") + flag.StringVar(&toEmail, "to-email", "", "Email addresses that will receive the email, comma-separated") + + flag.StringVar(&subject, "subject", "", "Subject of the email") + flag.StringVar(&body, "body", "", "Body of the email") + + flag.StringVar(&attachmentsFiles, "attachments", "", "File paths for attachments, comma-separated") + flag.StringVar(&bodyFile, "body-file", "", "File path for email body") + + // Short-form flags + flag.StringVar(&smtpServerShort, "s", "", "SMTP server for sending emails (short)") + flag.IntVar(&smtpPortShort, "p", 587, "SMTP server port (short)") + flag.StringVar(&usernameShort, "u", "", "Username for SMTP authentication (short)") + flag.StringVar(&passwordShort, "w", "", "Password for SMTP authentication (short)") + + flag.StringVar(&configFileShort, "c", "", "Path to the SMTP config file (short)") + + flag.StringVar(&fromEmailShort, "f", "", "Email address to send from (short)") + flag.StringVar(&toEmailShort, "t", "", "Email addresses that will receive the email, comma-separated (short)") + + flag.StringVar(&subjectShort, "h", "", "Subject of the email (short)") + flag.StringVar(&bodyShort, "b", "", "Body of the email (short)") + + flag.StringVar(&attachmentsFilesShort, "af", "", "File paths for attachments, comma-separated (short)") + flag.StringVar(&bodyFileShort, "bf", "", "File path for email body (short)") +} + +func main() { + flag.Parse() + + // Override long-form flags with short-form flags if set + if smtpServerShort != "" { + smtpServer = smtpServerShort + } + if smtpPortShort != 587 { + smtpPort = smtpPortShort + } + if usernameShort != "" { + username = usernameShort + } + if passwordShort != "" { + password = passwordShort + } + if configFileShort != "" { + configFile = configFileShort + } + if fromEmailShort != "" { + fromEmail = fromEmailShort + } + if toEmailShort != "" { + toEmail = toEmailShort + } + if subjectShort != "" { + subject = subjectShort + } + if bodyShort != "" { + body = bodyShort + } + if attachmentsFilesShort != "" { + attachmentsFiles = attachmentsFilesShort + } + if bodyFileShort != "" { + bodyFile = bodyFileShort + } + + // Load config from file if provided + if configFile != "" { + config, err := loadConfig(configFile) + if err != nil { + log.Fatalf("Error loading config file: %v", err) + } + + // Override flags with config file values if set + if config.SMTPServer != "" { + smtpServer = config.SMTPServer + } + if config.SMTPPort != 0 { + smtpPort = config.SMTPPort + } + if config.SMTPUsername != "" { + username = config.SMTPUsername + } + if config.SMTPPassword != "" { + password = config.SMTPPassword + } + if config.FromEmail != "" { + fromEmail = config.FromEmail + } + } + + // Check if required flags or config values are missing + if smtpServer == "" || username == "" || password == "" || fromEmail == "" || toEmail == "" || subject == "" { + fmt.Fprintln(os.Stderr, "Error: Required flags or config values are missing.") + usage() + } + + // Check if either direct input or file path is provided for body + if body == "" && bodyFile == "" { + fmt.Fprintln(os.Stderr, "Error: Subject and body are required, either directly or through a specified file.") + usage() + } + + // Read body from files if provided + if bodyFile != "" { + content, err := os.ReadFile(bodyFile) + if err != nil { + log.Fatalf("\nError reading body file: %v\n", err) + } + body = string(content) + } + + // Split attachment file paths + var attachmentPaths []string + if attachmentsFiles != "" { + attachmentPaths = strings.Split(attachmentsFiles, ",") + } + + // Split recipient email addresses + var toEmails []string + if toEmail != "" { + toEmails = strings.Split(toEmail, ",") + } + + if len(toEmails) == 0 { + fmt.Fprintln(os.Stderr, "Error: At least one recipient email address is required.") + usage() + } + + sendEmail(smtpServer, smtpPort, username, password, fromEmail, toEmails, subject, body, bodyFile, attachmentPaths) +} diff --git a/smtp.go b/smtp.go index 51c8669..72c93f3 100644 --- a/smtp.go +++ b/smtp.go @@ -1,42 +1,42 @@ -package main - -import ( - "fmt" - "strings" - - "gopkg.in/mail.v2" -) - -// sendEmail constructs and sends an email with the specified HTML body and attachments. -func sendEmail(smtpServer string, smtpPort int, username string, password string, from string, to []string, subject, body, bodyFile string, attachments []string) error { - m := mail.NewMessage() - - // Set the main email parts - m.SetHeader("From", from) - m.SetHeader("To", to...) - m.SetHeader("Subject", subject) - - // Check if the body is provided via a file - if bodyFile != "" { - m.SetBody("text/html", body) - } else { - m.SetBody("text/plain", body) - } - - // Add attachments - for _, attachment := range attachments { - m.Attach(attachment) - } - - // Set up SMTP information - d := mail.NewDialer(smtpServer, smtpPort, username, password) - - // Send the email - if err := d.DialAndSend(m); err != nil { - fmt.Printf("Error sending email: %v", err) - return err - } - - fmt.Printf("\nEmail sent successfully to %s from %s\n", strings.Join(to, ", "), from) - return nil -} +package main + +import ( + "fmt" + "strings" + + "gopkg.in/mail.v2" +) + +// sendEmail constructs and sends an email with the specified HTML body and attachments. +func sendEmail(smtpServer string, smtpPort int, username string, password string, from string, to []string, subject, body, bodyFile string, attachments []string) error { + m := mail.NewMessage() + + // Set the main email parts + m.SetHeader("From", from) + m.SetHeader("To", to...) + m.SetHeader("Subject", subject) + + // Check if the body is provided via a file + if bodyFile != "" { + m.SetBody("text/html", body) + } else { + m.SetBody("text/plain", body) + } + + // Add attachments + for _, attachment := range attachments { + m.Attach(attachment) + } + + // Set up SMTP information + d := mail.NewDialer(smtpServer, smtpPort, username, password) + + // Send the email + if err := d.DialAndSend(m); err != nil { + fmt.Printf("Error sending email: %v", err) + return err + } + + fmt.Printf("\nEmail sent successfully to %s from %s\n", strings.Join(to, ", "), from) + return nil +} diff --git a/usage.go b/usage.go index 8030bd1..e247836 100644 --- a/usage.go +++ b/usage.go @@ -1,25 +1,25 @@ -package main - -import ( - "fmt" - "os" -) - -func usage() { - fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", os.Args[0]) - fmt.Fprintln(os.Stderr, "") - fmt.Fprintln(os.Stderr, " -s, --smtp-server SMTP server for sending emails") - fmt.Fprintln(os.Stderr, " -p, --smtp-port SMTP server port (Default: 587)") - fmt.Fprintln(os.Stderr, " -u, --smtp-username Username for SMTP authentication") - fmt.Fprintln(os.Stderr, " -w, --smtp-password Password for SMTP authentication") - fmt.Fprintln(os.Stderr, " -f, --from-email Email address to send from") - fmt.Fprintln(os.Stderr, " -c, --config Path to the SMTP json config file which replaces the above arguments") - fmt.Fprintln(os.Stderr, " -t, --to-email Email addresses that will receive the email, comma-separated") - fmt.Fprintln(os.Stderr, " -h, --subject Subject of the email") - fmt.Fprintln(os.Stderr, " -b, --body Body of the email") - fmt.Fprintln(os.Stderr, " -af, --attachments File paths for attachments, comma-separated") - fmt.Fprintln(os.Stderr, " -bf, --body-file File path for email body") - fmt.Fprintln(os.Stderr, "") - fmt.Fprintln(os.Stderr, " Ensure all required flags are provided.") - os.Exit(1) -} +package main + +import ( + "fmt" + "os" +) + +func usage() { + fmt.Fprintf(os.Stderr, "Usage: %s [options]\n", os.Args[0]) + fmt.Fprintln(os.Stderr, "") + fmt.Fprintln(os.Stderr, " -s, --smtp-server SMTP server for sending emails") + fmt.Fprintln(os.Stderr, " -p, --smtp-port SMTP server port (Default: 587)") + fmt.Fprintln(os.Stderr, " -u, --smtp-username Username for SMTP authentication") + fmt.Fprintln(os.Stderr, " -w, --smtp-password Password for SMTP authentication") + fmt.Fprintln(os.Stderr, " -f, --from-email Email address to send from") + fmt.Fprintln(os.Stderr, " -c, --config Path to the SMTP json config file which replaces the above arguments") + fmt.Fprintln(os.Stderr, " -t, --to-email Email addresses that will receive the email, comma-separated") + fmt.Fprintln(os.Stderr, " -h, --subject Subject of the email") + fmt.Fprintln(os.Stderr, " -b, --body Body of the email") + fmt.Fprintln(os.Stderr, " -af, --attachments File paths for attachments, comma-separated") + fmt.Fprintln(os.Stderr, " -bf, --body-file File path for email body") + fmt.Fprintln(os.Stderr, "") + fmt.Fprintln(os.Stderr, " Ensure all required flags are provided.") + os.Exit(1) +}