move up
This commit is contained in:
176
email.go
Executable file
176
email.go
Executable file
@@ -0,0 +1,176 @@
|
||||
package contact
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/mail"
|
||||
"net/smtp"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/bytbox/go-pop3"
|
||||
"github.com/emersion/go-imap"
|
||||
"github.com/emersion/go-imap/client"
|
||||
)
|
||||
|
||||
type Emailer struct {
|
||||
From string
|
||||
SMTP string
|
||||
POP3 string
|
||||
IMAP string
|
||||
Password string
|
||||
Limit int
|
||||
}
|
||||
|
||||
func NewEmailer() *Emailer {
|
||||
envOr := func(key, def string) string {
|
||||
if v, ok := os.LookupEnv(strings.ToUpper(key)); ok {
|
||||
return v
|
||||
}
|
||||
return def
|
||||
}
|
||||
return &Emailer{
|
||||
From: envOr("FROM", "breellocaldev@gmail.com"),
|
||||
SMTP: envOr("SMTP", "smtp.gmail.com:465"),
|
||||
Password: envOr("PASSWORD", "lhnjijrvqaesiufp"),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Emailer) Read() (chan *mail.Message, error) {
|
||||
return e.ReadIMAP()
|
||||
}
|
||||
|
||||
func (e *Emailer) ReadIMAP() (chan *mail.Message, error) {
|
||||
c, err := client.DialTLS(e.IMAP, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.Login(e.From, e.Password); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mbox, err := c.Select("INBOX", true) //readonly
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
from := uint32(1)
|
||||
to := mbox.Messages
|
||||
if e.Limit > 0 && to > uint32(e.Limit) {
|
||||
from = to - uint32(e.Limit-1)
|
||||
}
|
||||
seqset := new(imap.SeqSet)
|
||||
seqset.AddRange(from, to)
|
||||
emails := make(chan *mail.Message)
|
||||
messages := make(chan *imap.Message)
|
||||
go func() {
|
||||
defer c.Logout()
|
||||
section := &imap.BodySectionName{}
|
||||
if err := c.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}, messages); err != nil {
|
||||
log.Println("error fetching:", err)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer close(emails)
|
||||
for msg := range messages {
|
||||
for _, v := range msg.Body {
|
||||
m, err := mail.ReadMessage(v)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
} else {
|
||||
emails <- m
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
return emails, nil
|
||||
}
|
||||
|
||||
func (e *Emailer) ReadPOP3() (chan *mail.Message, error) {
|
||||
emails := []*mail.Message{}
|
||||
c, err := pop3.DialTLS(e.POP3)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.Rset()
|
||||
if err := c.Auth(e.From, e.Password); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids, _, err := c.ListAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for j, id := range ids {
|
||||
if e.Limit > 0 && len(ids)-1-j >= e.Limit {
|
||||
break
|
||||
}
|
||||
raw, err := c.Retr(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msg, err := mail.ReadMessage(strings.NewReader(raw))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
emails = append(emails, msg)
|
||||
}
|
||||
return nil, nil
|
||||
//return emails, nil //c.Quit()
|
||||
}
|
||||
|
||||
func (e *Emailer) Send(to, subj, msg string) error {
|
||||
headers := e.headers(to, e.From, subj)
|
||||
body := e.body(headers, msg)
|
||||
smtp, err := e.smtp()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer smtp.Quit()
|
||||
if err := smtp.Mail(e.From); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := smtp.Rcpt(to); err != nil {
|
||||
return err
|
||||
}
|
||||
w, err := smtp.Data()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte(body)); err != nil {
|
||||
return err
|
||||
}
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
func (e *Emailer) headers(to, from, subj string) map[string]string {
|
||||
return map[string]string{
|
||||
"To": to,
|
||||
"From": from,
|
||||
"Subject": subj,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Emailer) body(headers map[string]string, body string) string {
|
||||
b := ""
|
||||
for k, v := range headers {
|
||||
b += fmt.Sprintf("%s: %s\r\n", k, v)
|
||||
}
|
||||
return b + "\r\n" + body
|
||||
}
|
||||
|
||||
func (e *Emailer) smtp() (*smtp.Client, error) {
|
||||
host := strings.Split(e.SMTP, ":")[0]
|
||||
auth := smtp.PlainAuth("", e.From, e.Password, host)
|
||||
tlsconfig := &tls.Config{ServerName: host}
|
||||
conn, err := tls.Dial("tcp", e.SMTP, tlsconfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot dial %v: %v", e.SMTP, err)
|
||||
}
|
||||
smtp, err := smtp.NewClient(conn, host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot new client %v: %v", host, err)
|
||||
}
|
||||
if err := smtp.Auth(auth); err != nil {
|
||||
return nil, fmt.Errorf("cannot auth client: %v", err)
|
||||
}
|
||||
return smtp, nil
|
||||
}
|
||||
Reference in New Issue
Block a user