105 lines
2.6 KiB
Go
105 lines
2.6 KiB
Go
|
package mailclient
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"encoding/base64"
|
|||
|
"fmt"
|
|||
|
"net/http"
|
|||
|
"os"
|
|||
|
"path/filepath"
|
|||
|
"strings"
|
|||
|
)
|
|||
|
|
|||
|
type Message struct {
|
|||
|
To []string
|
|||
|
From string
|
|||
|
Subject string
|
|||
|
Body string
|
|||
|
Attachments []Attachment
|
|||
|
}
|
|||
|
|
|||
|
type Attachment struct {
|
|||
|
Name string
|
|||
|
Data []byte
|
|||
|
}
|
|||
|
|
|||
|
func NewMessage(subject, body string) *Message {
|
|||
|
if subject == "" {
|
|||
|
subject = "Вам пришла заявка с PenaQuiz"
|
|||
|
}
|
|||
|
return &Message{Subject: subject, Body: body, Attachments: []Attachment{}}
|
|||
|
}
|
|||
|
|
|||
|
func (m *Message) AttachFile(src string) error {
|
|||
|
data, err := os.ReadFile(src)
|
|||
|
if err != nil {
|
|||
|
return err
|
|||
|
}
|
|||
|
|
|||
|
_, filename := filepath.Split(src)
|
|||
|
m.Attachments = append(m.Attachments, Attachment{Name: filename, Data: data})
|
|||
|
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
func (m *Message) AttachBytesFile(filename string, data []byte) {
|
|||
|
m.Attachments = append(m.Attachments, Attachment{Name: filename, Data: data})
|
|||
|
}
|
|||
|
|
|||
|
func (m *Message) ToBytes() []byte {
|
|||
|
buf := bytes.NewBuffer(nil)
|
|||
|
|
|||
|
buf.WriteString("MIME-Version: 1.0\r\n")
|
|||
|
fmt.Fprintf(buf, "From: %s\r\n", m.From)
|
|||
|
fmt.Fprintf(buf, "Subject: %s\r\n", m.Subject)
|
|||
|
fmt.Fprintf(buf, "To: %s\r\n", strings.Join(m.To, ","))
|
|||
|
|
|||
|
boundary := randomBoundary()
|
|||
|
|
|||
|
if len(m.Attachments) > 0 {
|
|||
|
buf.WriteString("Content-Type: multipart/mixed;\r\n")
|
|||
|
|
|||
|
fmt.Fprintf(buf, " boundary=\"%s\"\r\n", boundary)
|
|||
|
|
|||
|
fmt.Fprintf(buf, "\r\n--%s", boundary)
|
|||
|
for _, attachment := range m.Attachments {
|
|||
|
buf.WriteString("\r\n")
|
|||
|
switch strings.Split(attachment.Name, ".")[1] {
|
|||
|
case "htmlmsg":
|
|||
|
|
|||
|
buf.WriteString("Content-Type: text/html; charset=\"utf-8\"\r\n")
|
|||
|
buf.WriteString("Content-Transfer-Encoding: base64\r\n")
|
|||
|
case "docx":
|
|||
|
|
|||
|
buf.WriteString("Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document\r\n")
|
|||
|
buf.WriteString("Content-Transfer-Encoding: base64\r\n")
|
|||
|
fmt.Fprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n", attachment.Name)
|
|||
|
default:
|
|||
|
fmt.Fprintf(buf, "Content-Type: %s\r\n", http.DetectContentType(attachment.Data))
|
|||
|
buf.WriteString("Content-Transfer-Encoding: base64\r\n")
|
|||
|
fmt.Fprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n", attachment.Name)
|
|||
|
}
|
|||
|
|
|||
|
buf.WriteString("\r\n")
|
|||
|
|
|||
|
b := make([]byte, base64.StdEncoding.EncodedLen(len(attachment.Data)))
|
|||
|
base64.StdEncoding.Encode(b, attachment.Data)
|
|||
|
|
|||
|
writer := NewLineWriter(buf, 76)
|
|||
|
_, err := writer.Write(b)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("mailclient-client err:", err)
|
|||
|
}
|
|||
|
|
|||
|
fmt.Fprintf(buf, "\r\n\r\n--%s", boundary)
|
|||
|
}
|
|||
|
|
|||
|
buf.WriteString("--")
|
|||
|
} else {
|
|||
|
buf.WriteString("Content-Type: text/plain; charset=utf-8\r\n")
|
|||
|
buf.WriteString(m.Body)
|
|||
|
}
|
|||
|
|
|||
|
return buf.Bytes()
|
|||
|
}
|