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()
|
||
}
|