worker/clients/mailclient/message.go

105 lines
2.6 KiB
Go
Raw Normal View History

2024-02-19 18:20:09 +00:00
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()
}