gomail/mail/mail.go
Michael f12e865042 added support for socks5 proxy
Signed-off-by: Michael <michael.lindman@gmail.com>
2021-12-10 04:26:47 +00:00

131 lines
2.8 KiB
Go

package mail
import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"strconv"
"time"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"golang.org/x/net/proxy"
)
type Mail struct {
Client *client.Client
}
type Message struct {
SeqNum uint32
Subject string
To []*imap.Address
From []*imap.Address
Date time.Time
Body imap.Literal
}
type Messages struct {
Message []Message
}
type Conn struct {
Addr string
Username string
Password string
}
func login(conn Conn, client *client.Client) (mail *Mail, err error) {
fmt.Fprintf(os.Stdout, "\x1b[32mConnecting to %s\n\x1b[0m", conn.Addr)
if err = client.Login(conn.Username, conn.Password); err != nil {
return nil, err
}
log.Println("Logged in as", conn.Username)
return &Mail{
Client: client,
}, nil
}
func LoginWithProxy(conn Conn, network string, proxyAddress string, auth *proxy.Auth) (mail *Mail, err error) {
proxy, err := proxy.SOCKS5("tcp", proxyAddress, auth, proxy.Direct)
if err != nil {
return nil, err
}
client, err := client.DialWithDialerTLS(proxy, conn.Addr, nil)
if err != nil {
return nil, err
}
mail, err = login(conn, client)
if err != nil {
return nil, err
}
return mail, nil
}
func Login(conn Conn) (mail *Mail, err error) {
client, err := client.DialTLS(conn.Addr, nil)
if err != nil {
return nil, err
}
mail, err = login(conn, client)
if err != nil {
return nil, err
}
return mail, nil
}
func (mail *Mail) GetMessages(mailbox string, msgs int32) (*Messages, error) {
var messages Messages
mbox, err := mail.Client.Select(mailbox, true)
if err != nil {
return nil, err
}
if mbox.Messages == 0 {
return nil, errors.New("no messages in mailbox")
}
seqSet := new(imap.SeqSet)
seqSet.AddRange(1, mbox.Messages)
var section imap.BodySectionName
imapMessages := make(chan *imap.Message, msgs)
done := make(chan error, 1)
go func() {
done <- mail.Client.Fetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, section.FetchItem()}, imapMessages)
}()
for msg := range imapMessages {
body := msg.GetBody(&section)
if body == nil {
return nil, errors.New("server didn't returned message body")
}
message := Message{
SeqNum: msg.SeqNum,
Subject: msg.Envelope.Subject,
To: msg.Envelope.To,
From: msg.Envelope.From,
Date: msg.Envelope.Date,
Body: body,
}
messages.Message = append(messages.Message, message)
}
if err := <-done; err != nil {
return nil, err
}
return &messages, nil
}
func WriteMessages(path string, messages *Messages) error {
for _, msg := range messages.Message {
body, err := ioutil.ReadAll(msg.Body)
if err != nil {
return err
}
if err := ioutil.WriteFile(path+"/"+strconv.Itoa(int(msg.SeqNum))+"_"+msg.Date.String()+".eml", body, 0644); err != nil {
return err
}
}
return nil
}