add attachments to the email
This commit is contained in:
parent
dd9018bcef
commit
d3189b0840
96
mail/mail.go
96
mail/mail.go
@ -1,9 +1,14 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
@ -11,12 +16,34 @@ import (
|
||||
|
||||
var validate *validator.Validate
|
||||
|
||||
// getgetAttachmentsContent collects attachment data from a list of attachment paths.
|
||||
func getAttachmentsContent(attachments []string) (map[string][]byte, error) {
|
||||
if len(attachments) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
attachmentsData := map[string][]byte{}
|
||||
|
||||
for _, attachmentPath := range attachments {
|
||||
b, err := os.ReadFile(attachmentPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, filename := filepath.Split(attachmentPath)
|
||||
attachmentsData[filename] = b
|
||||
}
|
||||
|
||||
return attachmentsData, nil
|
||||
}
|
||||
|
||||
type Email struct {
|
||||
Path string
|
||||
Sender string `json:"sender" validate:"required,email"`
|
||||
Receivers string `json:"receivers" validate:"required"`
|
||||
Subject string `json:"subject" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Path string
|
||||
Sender string `json:"sender" validate:"required,email"`
|
||||
Receivers string `json:"receivers" validate:"required"`
|
||||
Subject string `json:"subject" validate:"required"`
|
||||
Content string `json:"content" validate:"required"`
|
||||
Attachments string `json:"attachments,omitempty"`
|
||||
}
|
||||
|
||||
func FromJSON(path string) (Email, error) {
|
||||
@ -42,15 +69,56 @@ func (e *Email) GetReceivers() []string {
|
||||
return strings.Split(e.Receivers, ",")
|
||||
}
|
||||
|
||||
func (e *Email) Generate() []byte {
|
||||
mail := fmt.Sprintf(
|
||||
"To: %s\nFrom: %s\nContent-Type: text/html;charset=utf-8\nSubject: %s\n\n%s",
|
||||
e.Receivers,
|
||||
e.Sender,
|
||||
e.Subject,
|
||||
e.Content,
|
||||
)
|
||||
return []byte(mail)
|
||||
func (e *Email) GetAttachments() []string {
|
||||
if e.Attachments == "" {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
return strings.Split(e.Attachments, ",")
|
||||
}
|
||||
|
||||
func (e *Email) Generate() ([]byte, error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
attachments := e.GetAttachments()
|
||||
withAttachments := len(attachments) != 0
|
||||
|
||||
fmt.Fprintf(buf, "To: %s\n", strings.Join(e.GetReceivers(), ","))
|
||||
fmt.Fprintf(buf, "From: %s\n", e.Sender)
|
||||
fmt.Fprintf(buf, "Subject: %s\n", e.Subject)
|
||||
buf.WriteString("MIME-Version: 1.0\n")
|
||||
|
||||
writer := multipart.NewWriter(buf)
|
||||
boundary := writer.Boundary()
|
||||
if withAttachments {
|
||||
fmt.Fprintf(buf, "Content-Type: multipart/mixed; boundary=%s\n\n", boundary)
|
||||
fmt.Fprintf(buf, "--%s\n", boundary)
|
||||
}
|
||||
|
||||
buf.WriteString("Content-Type: text/html; charset=utf-8\n\n")
|
||||
buf.WriteString(e.Content)
|
||||
|
||||
if withAttachments {
|
||||
attachmentsData, err := getAttachmentsContent(attachments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for filename, data := range attachmentsData {
|
||||
fmt.Fprintf(buf, "\n\n--%s\n", boundary)
|
||||
fmt.Fprintf(buf, "Content-Type: %s\n", http.DetectContentType(data))
|
||||
buf.WriteString("Content-Transfer-Encoding: base64\n")
|
||||
fmt.Fprintf(buf, "Content-Disposition: attachment; filename=%s\n\n", filename)
|
||||
|
||||
b := make([]byte, base64.StdEncoding.EncodedLen(len(data)))
|
||||
base64.StdEncoding.Encode(b, data)
|
||||
buf.Write(b)
|
||||
fmt.Fprintf(buf, "\n\n--%s", boundary)
|
||||
}
|
||||
|
||||
buf.WriteString("--")
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (e *Email) Validate() error {
|
||||
|
||||
@ -33,7 +33,12 @@ func NewSender(config cfg.SMTPConfig, outboxPath string) Sender {
|
||||
}
|
||||
|
||||
func (s Sender) SendMail(email *mail.Email) error {
|
||||
if err := smtp.SendMail(s.smtpURL, s.auth, email.Sender, email.GetReceivers(), email.Generate()); err != nil {
|
||||
content, err := email.Generate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := smtp.SendMail(s.smtpURL, s.auth, email.Sender, email.GetReceivers(), content); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user