code.dwrz.net

Go monorepo.
Log | Files | Refs

sm.go (1943B)


      1 package main
      2 
      3 import (
      4 	"encoding/base64"
      5 	"flag"
      6 	"fmt"
      7 	"net/http"
      8 	"net/smtp"
      9 	"os"
     10 	"strings"
     11 
     12 	"code.dwrz.net/pkg/gmail"
     13 	"code.dwrz.net/pkg/log"
     14 )
     15 
     16 var (
     17 	user = flag.String("user", "", "username")
     18 	pass = flag.String("pass", "", "password")
     19 
     20 	from = flag.String("from", "", "sender address")
     21 	to   = flag.String("to", "", "recipient address, comma delimited")
     22 	sbj  = flag.String("subject", "", "subject")
     23 
     24 	text = flag.String("text", "", "message text")
     25 	file = flag.String("file", "", "attachment filepath")
     26 )
     27 
     28 func main() {
     29 	l := log.New(os.Stderr)
     30 
     31 	// Parse flags.
     32 	flag.Parse()
     33 
     34 	// Compose email.
     35 	var str strings.Builder
     36 
     37 	fmt.Fprintf(&str, "From: %s\r\n", *from)
     38 	fmt.Fprintf(&str, "To: %s\r\n", *to)
     39 	fmt.Fprintf(&str, "Subject: %s\r\n", *sbj)
     40 
     41 	str.WriteString("MIME-Version: 1.0\n")
     42 	str.WriteString("Content-Type: multipart/mixed; boundary=\"=-=-=\"\n")
     43 	str.WriteString("\n")
     44 	str.WriteString("--=-=-=\n")
     45 	str.WriteString("Content-Type: text/plain; format=flowed\n")
     46 	str.WriteString("\n")
     47 	str.WriteString("\n")
     48 	str.WriteString(*text)
     49 	str.WriteString("\n")
     50 	str.WriteString("--=-=-=\n")
     51 
     52 	// Add the attachment, if provided.
     53 	if *file != "" {
     54 		data, err := os.ReadFile(*file)
     55 		if err != nil {
     56 			l.Error.Fatalf("failed to open file: %v", err)
     57 		}
     58 
     59 		fmt.Fprintf(
     60 			&str,
     61 			"Content-Type: %s\n", http.DetectContentType(data),
     62 		)
     63 		fmt.Fprintf(
     64 			&str,
     65 			"Content-Disposition: attachment; filename=%s\n",
     66 			*file,
     67 		)
     68 		str.WriteString("Content-Transfer-Encoding: base64\n")
     69 		fmt.Fprintf(&str, "Content-Description: %s\n", *file)
     70 		str.WriteString("\n")
     71 		str.WriteString(base64.StdEncoding.EncodeToString([]byte(data)))
     72 		str.WriteString("--=-=-=\n")
     73 	}
     74 
     75 	// Send the email.
     76 	if err := smtp.SendMail(
     77 		gmail.Address,
     78 		&gmail.Auth{
     79 			Username: *user,
     80 			Password: *pass,
     81 		},
     82 		*from,
     83 		strings.Split(*to, ","),
     84 		[]byte(str.String()),
     85 	); err != nil {
     86 		l.Error.Fatalf("failed to send email: %v", err)
     87 	}
     88 }