src

Go monorepo.
Log | Files | Refs

commit 0017e12f942c741362ee5305930055a0de8fd494
parent d5f0f7daf9c4c382bb314c024cae1c98f8f139fe
Author: dwrz <dwrz@dwrz.net>
Date:   Fri,  2 Dec 2022 16:00:08 +0000

Add sgm command

Diffstat:
Acmd/sgm/config/config.go | 47+++++++++++++++++++++++++++++++++++++++++++++++
Acmd/sgm/config/config.json.template | 4++++
Acmd/sgm/main.go | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/cmd/sgm/config/config.go b/cmd/sgm/config/config.go @@ -0,0 +1,47 @@ +package config + +import ( + _ "embed" + "encoding/json" + "flag" + "fmt" +) + +var ( + //go:embed config.json + configuration []byte + + attachment = flag.String("a", "", "attachment path") + from = flag.String("f", "", "sender address") + subject = flag.String("s", "", "subject") + text = flag.String("m", "", "message text") + to = flag.String("t", "", "recipient address, comma delimited") +) + +type Config struct { + Attachment string + From string + Pass string + Subject string + Text string + To string + User string +} + +func New() (*Config, error) { + flag.Parse() + + var cfg = &Config{ + Attachment: *attachment, + From: *from, + Subject: *subject, + Text: *text, + To: *to, + } + // Load the username and password from the embedded configuration. + if err := json.Unmarshal(configuration, cfg); err != nil { + return nil, fmt.Errorf("failed to parse config file: %v", err) + } + + return cfg, nil +} diff --git a/cmd/sgm/config/config.json.template b/cmd/sgm/config/config.json.template @@ -0,0 +1,4 @@ +{ + "user": "", + "pass": "" +} diff --git a/cmd/sgm/main.go b/cmd/sgm/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "encoding/base64" + "fmt" + "net/http" + "net/smtp" + "os" + "strings" + + "code.dwrz.net/src/cmd/sgm/config" + "code.dwrz.net/src/pkg/gmail" + "code.dwrz.net/src/pkg/log" +) + +func main() { + var l = log.New(os.Stderr) + + // Get the configuration. + cfg, err := config.New() + if err != nil { + l.Error.Fatalf("failed to get config: %v", err) + } + + // Compose email. + var str strings.Builder + + fmt.Fprintf(&str, "From: %s\r\n", cfg.From) + fmt.Fprintf(&str, "To: %s\r\n", cfg.To) + fmt.Fprintf(&str, "Subject: %s\r\n", cfg.Subject) + + str.WriteString("MIME-Version: 1.0\n") + str.WriteString("Content-Type: multipart/mixed; boundary=\"=-=-=\"\n") + str.WriteString("\n") + str.WriteString("--=-=-=\n") + str.WriteString("Content-Type: text/plain; format=flowed\n") + str.WriteString("\n") + str.WriteString("\n") + str.WriteString(cfg.Text) + str.WriteString("\n") + str.WriteString("--=-=-=\n") + + // Add the attachment, if provided. + if cfg.Attachment != "" { + data, err := os.ReadFile(cfg.Attachment) + if err != nil { + l.Error.Fatalf("failed to open file: %v", err) + } + + fmt.Fprintf( + &str, + "Content-Type: %s\n", http.DetectContentType(data), + ) + fmt.Fprintf( + &str, + "Content-Disposition: attachment; filename=%s\n", + *&cfg.Attachment, + ) + str.WriteString("Content-Transfer-Encoding: base64\n") + fmt.Fprintf(&str, "Content-Description: %s\n", cfg.Attachment) + str.WriteString("\n") + str.WriteString(base64.StdEncoding.EncodeToString([]byte(data))) + str.WriteString("--=-=-=\n") + } + + // Send the email. + if err := smtp.SendMail( + gmail.Address, + &gmail.Auth{ + Username: cfg.User, + Password: cfg.Pass, + }, + cfg.From, + strings.Split(cfg.To, ","), + []byte(str.String()), + ); err != nil { + l.Error.Fatalf("failed to send email: %v", err) + } +}