CLI email sender
This commit is contained in:
330
.email.go
Executable file
330
.email.go
Executable file
@@ -0,0 +1,330 @@
|
||||
package contact
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"local/system/sysconf"
|
||||
"log"
|
||||
"net"
|
||||
"net/smtp"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pop3 "github.com/taknb2nch/go-pop3"
|
||||
)
|
||||
|
||||
// Emailer allows sending of emails (or better
|
||||
// texts with the right address) with TLS.
|
||||
type Emailer interface {
|
||||
Send(string, string) error
|
||||
Check() []Email
|
||||
}
|
||||
|
||||
type emailer struct {
|
||||
to string
|
||||
from string
|
||||
smtpServer string
|
||||
pop3Server string
|
||||
pwd string
|
||||
}
|
||||
|
||||
type Email struct {
|
||||
To string
|
||||
From string
|
||||
Date time.Time
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
|
||||
func (e Email) String() string {
|
||||
return fmt.Sprintf("To: %q\nFrom: %q\nSubj: %q\nDate: %q\nBody: %q", e.To, e.From, e.Subject, e.Date.String(), e.Body)
|
||||
}
|
||||
|
||||
// NewEmailer returns a emailer capable of Send()ing
|
||||
// To the given address.
|
||||
func NewEmailer(To string) Emailer {
|
||||
config := sysconf.Get("email")
|
||||
return &emailer{
|
||||
smtpServer: config.IP,
|
||||
pop3Server: config.IP2,
|
||||
to: To,
|
||||
from: config.Log,
|
||||
pwd: config.Port,
|
||||
}
|
||||
}
|
||||
|
||||
// Send sends an email To the configured address with
|
||||
// the given Subject and message.
|
||||
func (e *emailer) Send(subj, msg string) error {
|
||||
// Setup headers
|
||||
headers := make(map[string]string)
|
||||
headers["From"] = e.from
|
||||
headers["To"] = e.to
|
||||
headers["Subject"] = subj
|
||||
Body := ""
|
||||
for k, v := range headers {
|
||||
Body += fmt.Sprintf("%s: %s\r\n", k, v)
|
||||
}
|
||||
Body += "\r\n" + msg
|
||||
|
||||
// Connect To the SMTP Server
|
||||
c := e.newSmtpClient()
|
||||
defer c.Quit()
|
||||
|
||||
// To && From
|
||||
if err := c.Mail(e.from); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
if err := c.Rcpt(e.to); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
// Data
|
||||
w, err := c.Data()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
_, err = w.Write([]byte(Body))
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
err = w.Close()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *emailer) newSmtpClient() *smtp.Client {
|
||||
host, _, _ := net.SplitHostPort(e.smtpServer)
|
||||
auth := smtp.PlainAuth("", e.from, e.pwd, host)
|
||||
conn := e.getConn(e.smtpServer)
|
||||
|
||||
c, err := smtp.NewClient(conn, host)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
// Auth
|
||||
if err = c.Auth(auth); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (e *emailer) getConn(remote string) net.Conn {
|
||||
host, _, _ := net.SplitHostPort(remote)
|
||||
tlsconfig := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
ServerName: host,
|
||||
}
|
||||
// Here is the key, you need To call tls.Dial instead of smtp.Dial
|
||||
// for smtp servers running on 465 that require an ssl connection
|
||||
// From the very beginning (no starttls)
|
||||
conn, err := tls.Dial("tcp", remote, tlsconfig)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
return conn
|
||||
}
|
||||
|
||||
func (e *emailer) newPop3Client() *pop3.Client {
|
||||
conn := e.getConn(e.pop3Server)
|
||||
client, err := pop3.NewClient(conn)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Dial Error: %v\n", err)
|
||||
}
|
||||
|
||||
if err = client.User(e.from); err != nil {
|
||||
log.Panicf("User Error: %v\n", err)
|
||||
}
|
||||
|
||||
if err = client.Pass(e.pwd); err != nil {
|
||||
log.Panicf("Pass Error: %v\n", err)
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
func (e *emailer) Check() []Email {
|
||||
client := e.newPop3Client()
|
||||
defer func() {
|
||||
client.Quit()
|
||||
client.Close()
|
||||
}()
|
||||
|
||||
var count int
|
||||
var err error
|
||||
|
||||
if count, _, err = client.Stat(); err != nil {
|
||||
log.Printf("Stat Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
var content string
|
||||
emails := make([]Email, count)
|
||||
|
||||
for i := 1; i <= count; i++ {
|
||||
if content, err = client.Retr(i); err != nil {
|
||||
log.Printf("Retr Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
emails[i-1] = parseEmail(content)
|
||||
}
|
||||
return emails
|
||||
}
|
||||
|
||||
func (e *emailer) pop3all() []Email {
|
||||
conn := e.getConn(e.pop3Server)
|
||||
client, err := pop3.NewClient(conn)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("Dial Error: %v\n", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
client.Quit()
|
||||
client.Close()
|
||||
}()
|
||||
|
||||
if err = client.User(e.from); err != nil {
|
||||
log.Printf("User Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = client.Pass(e.pwd); err != nil {
|
||||
log.Printf("Pass Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
var count int
|
||||
var size uint64
|
||||
|
||||
if count, size, err = client.Stat(); err != nil {
|
||||
log.Printf("Stat Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Count: %d, Size: %d\n", count, size)
|
||||
|
||||
if count, size, err = client.List(6); err != nil {
|
||||
log.Printf("List Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Number: %d, Size: %d\n", count, size)
|
||||
|
||||
var mis []pop3.MessageInfo
|
||||
|
||||
if mis, err = client.ListAll(); err != nil {
|
||||
log.Printf("LAll Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, mi := range mis {
|
||||
log.Printf("Number: %d, Size: %d\n", mi.Number, mi.Size)
|
||||
}
|
||||
|
||||
var number int
|
||||
var uid string
|
||||
|
||||
if number, uid, err = client.Uidl(6); err != nil {
|
||||
log.Printf("Uidl Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Number: %d, Uid: %s\n", number, uid)
|
||||
|
||||
if mis, err = client.UidlAll(); err != nil {
|
||||
log.Printf("UAll Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, mi := range mis {
|
||||
log.Printf("Number: %d, Uid: %s\n", mi.Number, mi.Uid)
|
||||
}
|
||||
|
||||
var content string
|
||||
|
||||
if content, err = client.Retr(8); err != nil {
|
||||
log.Printf("Retr Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Content:\n%s\n", content)
|
||||
|
||||
/*
|
||||
if err = client.Dele(6); err != nil {
|
||||
log.Printf("Dele Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
if err = client.Noop(); err != nil {
|
||||
log.Printf("Noop Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = client.Rset(); err != nil {
|
||||
log.Printf("Rset Error: %v\n", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
type Email struct {
|
||||
To string
|
||||
From string
|
||||
Date time.Time
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
*/
|
||||
func parseEmail(content string) Email {
|
||||
To := regexp.MustCompile("\n[Tt]o: .*\n").FindString(content)
|
||||
To = strings.TrimSpace(To)
|
||||
To = strings.Trim(To, "TTo")
|
||||
To = strings.Trim(To, ": {}<>")
|
||||
|
||||
Subject := regexp.MustCompile("\n[Ss]ubject: .*\n").FindString(content)
|
||||
Subject = strings.TrimSpace(Subject)
|
||||
Subject = strings.Trim(Subject, "SSubject")
|
||||
Subject = strings.Trim(Subject, ": ")
|
||||
|
||||
when := regexp.MustCompile("[Dd]ate: .*\n").FindString(content)
|
||||
when = strings.Trim(when, "DDate")
|
||||
when = strings.Trim(when, ":")
|
||||
when = strings.TrimSpace(when)
|
||||
Date, err := time.Parse("Mon, 2 Jan 2006 15:04:05 -0700 (MST)", when)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
parseFrom := regexp.MustCompile("[^ ]*@[^ ]*")
|
||||
From := regexp.MustCompile("\n[Ff]rom: .*\n").FindString(content)
|
||||
From = strings.TrimSpace(From)
|
||||
From = parseFrom.FindString(From)
|
||||
From = strings.Trim(From, "<>{}")
|
||||
|
||||
Body := ""
|
||||
Bodyarr := strings.Split(content, "\n")
|
||||
Body = Bodyarr[len(Bodyarr)-1]
|
||||
|
||||
return Email{
|
||||
To: To,
|
||||
From: From,
|
||||
Date: Date,
|
||||
Subject: Subject,
|
||||
Body: Body,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user