RosettaCodeData/Task/Send-email/Go/send-email.go

162 lines
2.9 KiB
Go

package main
import (
"bufio"
"bytes"
"errors"
"flag"
"fmt"
"io/ioutil"
"net/smtp"
"os"
"strings"
)
type Message struct {
From string
To []string
Cc []string
Subject string
Content string
}
func (m Message) Bytes() (r []byte) {
to := strings.Join(m.To, ",")
cc := strings.Join(m.Cc, ",")
r = append(r, []byte("From: "+m.From+"\n")...)
r = append(r, []byte("To: "+to+"\n")...)
r = append(r, []byte("Cc: "+cc+"\n")...)
r = append(r, []byte("Subject: "+m.Subject+"\n\n")...)
r = append(r, []byte(m.Content)...)
return
}
func (m Message) Send(host string, port int, user, pass string) (err error) {
err = check(host, user, pass)
if err != nil {
return
}
err = smtp.SendMail(fmt.Sprintf("%v:%v", host, port),
smtp.PlainAuth("", user, pass, host),
m.From,
m.To,
m.Bytes(),
)
return
}
func check(host, user, pass string) error {
if host == "" {
return errors.New("Bad host")
}
if user == "" {
return errors.New("Bad username")
}
if pass == "" {
return errors.New("Bad password")
}
return nil
}
func main() {
var flags struct {
host string
port int
user string
pass string
}
flag.StringVar(&flags.host, "host", "", "SMTP server to connect to")
flag.IntVar(&flags.port, "port", 587, "Port to connect to SMTP server on")
flag.StringVar(&flags.user, "user", "", "Username to authenticate with")
flag.StringVar(&flags.pass, "pass", "", "Password to authenticate with")
flag.Parse()
err := check(flags.host, flags.user, flags.pass)
if err != nil {
flag.Usage()
os.Exit(1)
}
bufin := bufio.NewReader(os.Stdin)
fmt.Printf("From: ")
from, err := bufin.ReadString('\n')
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
from = strings.Trim(from, " \t\n\r")
var to []string
for {
fmt.Printf("To (Blank to finish): ")
tmp, err := bufin.ReadString('\n')
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
tmp = strings.Trim(tmp, " \t\n\r")
if tmp == "" {
break
}
to = append(to, tmp)
}
var cc []string
for {
fmt.Printf("Cc (Blank to finish): ")
tmp, err := bufin.ReadString('\n')
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
tmp = strings.Trim(tmp, " \t\n\r")
if tmp == "" {
break
}
cc = append(cc, tmp)
}
fmt.Printf("Subject: ")
subject, err := bufin.ReadString('\n')
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
subject = strings.Trim(subject, " \t\n\r")
fmt.Printf("Content (Until EOF):\n")
content, err := ioutil.ReadAll(os.Stdin)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
content = bytes.Trim(content, " \t\n\r")
m := Message{
From: from,
To: to,
Cc: cc,
Subject: subject,
Content: string(content),
}
fmt.Printf("\nSending message...\n")
err = m.Send(flags.host, flags.port, flags.user, flags.pass)
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
fmt.Printf("Message sent.\n")
}