main
parent
89e249a767
commit
f791d24ad7
6 changed files with 217 additions and 2 deletions
@ -0,0 +1,50 @@ |
|||||||
|
package postman |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"encoding/base64" |
||||||
|
"os" |
||||||
|
) |
||||||
|
|
||||||
|
// Вложение
|
||||||
|
type Attachment struct { |
||||||
|
name string |
||||||
|
contentType string |
||||||
|
withFile bool |
||||||
|
} |
||||||
|
|
||||||
|
func NewAttachment(file string) Attachment { |
||||||
|
return Attachment{ |
||||||
|
name: file, |
||||||
|
contentType: "application/octet-stream", |
||||||
|
withFile: true, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Импорт файла в тело письма
|
||||||
|
func (a *Attachment) WriteFile(buffer *bytes.Buffer) error { |
||||||
|
file, err := os.ReadFile(a.name) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
payload := make([]byte, base64.StdEncoding.EncodedLen(len(file))) |
||||||
|
base64.StdEncoding.Encode(payload, file) |
||||||
|
|
||||||
|
//
|
||||||
|
buffer.WriteString("\r\n") |
||||||
|
|
||||||
|
for index, line := 0, len(payload); index < line; index++ { |
||||||
|
buffer.WriteByte(payload[index]) |
||||||
|
|
||||||
|
if (index+1)%76 == 0 { |
||||||
|
_, era := buffer.WriteString("\r\n") |
||||||
|
if era != nil { |
||||||
|
return era |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
package postman |
||||||
|
|
||||||
|
// Почтовое сообщения предназначенное для отправки
|
||||||
|
type Message struct { |
||||||
|
to []string |
||||||
|
subject string |
||||||
|
body string |
||||||
|
contentType string |
||||||
|
attachments []Attachment |
||||||
|
} |
||||||
|
|
||||||
|
func NewMessage(subject string, body string) Message { |
||||||
|
return Message{ |
||||||
|
to: []string{}, |
||||||
|
subject: subject, |
||||||
|
contentType: "text/plain;charset=utf8", |
||||||
|
attachments: []Attachment{}, |
||||||
|
body: body, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Пополнение списка получателей
|
||||||
|
func (m *Message) AppendRecipient(recipient string) error { |
||||||
|
m.to = append(m.to, recipient) |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
// Пополнение списка вложений
|
||||||
|
func (m *Message) AppendAttachment(file string) error { |
||||||
|
a := NewAttachment(file) |
||||||
|
m.attachments = append(m.attachments, a) |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,87 @@ |
|||||||
|
package postman |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"errors" |
||||||
|
"net/smtp" |
||||||
|
"strconv" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
// SMTP сервис
|
||||||
|
type Service struct { |
||||||
|
user string |
||||||
|
password string |
||||||
|
host string |
||||||
|
port int |
||||||
|
} |
||||||
|
|
||||||
|
func NewService(host string, port int, sender string, password string) *Service { |
||||||
|
return &Service{ |
||||||
|
user: sender, |
||||||
|
password: password, |
||||||
|
host: host, |
||||||
|
port: port, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Отправка письма
|
||||||
|
func (s *Service) Send(message Message) error { |
||||||
|
if len(message.to) < 1 { |
||||||
|
return errors.New("empty list of recipients") |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
auth := smtp.PlainAuth("", s.user, s.password, s.host) |
||||||
|
|
||||||
|
//
|
||||||
|
buffer := bytes.NewBuffer(nil) |
||||||
|
boundary := "GoBoundary" |
||||||
|
headery := "" |
||||||
|
|
||||||
|
// header
|
||||||
|
header := make(map[string]string) |
||||||
|
header["From"] = s.user |
||||||
|
|
||||||
|
header["To"] = message.to[0] |
||||||
|
header["Cc"] = strings.Join(message.to[1:], ";") |
||||||
|
header["Subject"] = message.subject |
||||||
|
header["Content-Type"] = "multipart/mixed;boundary=" + boundary |
||||||
|
header["Mime-Version"] = "1.0" |
||||||
|
header["Date"] = time.Now().String() |
||||||
|
|
||||||
|
for key, value := range header { |
||||||
|
headery += key + ":" + value + "\r\n" |
||||||
|
} |
||||||
|
|
||||||
|
buffer.WriteString(headery + "\r\n") |
||||||
|
|
||||||
|
// body
|
||||||
|
body := "\r\n--" + boundary + "\r\n" |
||||||
|
body += "Content-Type:" + message.contentType + "\r\n" |
||||||
|
body += "\r\n" + message.body + "\r\n" |
||||||
|
|
||||||
|
buffer.WriteString(body) |
||||||
|
|
||||||
|
// attachments
|
||||||
|
for _, x := range message.attachments { |
||||||
|
if x.withFile { |
||||||
|
attachment := "\r\n--" + boundary + "\r\n" |
||||||
|
attachment += "Content-Transfer-Encoding:base64\r\n" |
||||||
|
attachment += "Content-Disposition:attachment\r\n" |
||||||
|
attachment += "Content-Type:" + x.contentType + ";name=\"" + x.name + "\"\r\n" |
||||||
|
|
||||||
|
//
|
||||||
|
buffer.WriteString(attachment) |
||||||
|
|
||||||
|
//
|
||||||
|
x.WriteFile(buffer) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
buffer.WriteString("\r\n--" + boundary + "--") |
||||||
|
|
||||||
|
// Sending message
|
||||||
|
return smtp.SendMail(s.host+":"+strconv.Itoa(s.port), auth, s.user, message.to, buffer.Bytes()) |
||||||
|
} |
Loading…
Reference in new issue